Skip to content

Commit

Permalink
DOP-4540: Simplify versioned prefix generation (#1113)
Browse files Browse the repository at this point in the history
  • Loading branch information
rayangler authored Jun 6, 2024
1 parent c416657 commit 52b3a19
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 157 deletions.
4 changes: 2 additions & 2 deletions plugins/gatsby-source-snooty-prod/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,11 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
throw errMsg;
}

// Handle inconsistent env names. Default to 'dotcomprd' when possible since this is what we will most likely use.
// Handle inconsistent env names. Default to 'dotcomstg' for staging data on local builds.
// dotcom environments seem to be consistent.
let envKey = siteMetadata.snootyEnv;
if (!envKey || envKey === 'development') {
envKey = 'dotcomprd';
envKey = 'dotcomstg';
} else if (envKey === 'production') {
envKey = 'prd';
} else if (envKey === 'staging') {
Expand Down
22 changes: 0 additions & 22 deletions src/components/VersionDropdown/utils.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/context/version-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ const VersionContextProvider = ({ repoBranches, slug, children }) => {
gitBranchName === LEGACY_GIT_BRANCH
? gitBranchName
: targetBranch.urlSlug || targetBranch.urlAliases[0] || targetBranch.gitBranchName;
const urlTarget = getUrl(target, metadata.project, metadata, repoBranches?.siteBasePrefix, slug);
const urlTarget = getUrl(target, metadata.project, repoBranches?.siteBasePrefix, slug);
navigate(urlTarget);
},
[availableVersions, metadata, repoBranches, slug]
Expand Down
8 changes: 5 additions & 3 deletions src/hooks/use-canonical-url.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { assertTrailingSlash } from '../utils/assert-trailing-slash';
import { generatePrefix } from '../components/VersionDropdown/utils';
import { normalizePath } from '../utils/normalize-path';
import { generateVersionedPrefix } from '../utils/generate-versioned-prefix';
import { useSiteMetadata } from './use-site-metadata';

export const useCanonicalUrl = (meta, metadata, slug, repoBranches) => {
const siteMetadata = useSiteMetadata();
const { siteUrl, parserBranch } = siteMetadata;
const urlSlug = repoBranches.branches.find((branch) => branch.gitBranchName === parserBranch)?.urlSlug;
// Use parserBranch by default to avoid undefined slugs when testing
const urlSlug =
repoBranches.branches.find((branch) => branch.gitBranchName === parserBranch)?.urlSlug ?? parserBranch;
const siteBasePrefix = repoBranches.siteBasePrefix;
const pathPrefix = generatePrefix(urlSlug, siteMetadata, siteBasePrefix);
const pathPrefix = generateVersionedPrefix(urlSlug, siteBasePrefix);

// Use default logic assuming there is no canonical provided from the meta directive
let canonical = `${siteUrl}${normalizePath(`${pathPrefix}/${slug === '/' ? '' : slug}`)}`;
Expand Down
12 changes: 12 additions & 0 deletions src/utils/generate-versioned-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Generates the prefix to be used for a version's URL. The prefix will typically consist of the docs repo's
* set prefix, with the new version appended at the end.
*
* Use this when the target URL needs to point to a version
* of the docs site that does not use the same exact path prefix (i.e. an aliased docs site needs its exact URL slug).
* @param {string} version The version to include at the end of the prefix.
* @param {string} siteBasePrefix The current docs site's base prefix to append the version to.
*/
export const generateVersionedPrefix = (version, siteBasePrefix) => {
return `/${siteBasePrefix}/${version}`;
};
6 changes: 3 additions & 3 deletions src/utils/url-utils.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { generatePrefix } from '../components/VersionDropdown/utils';
import { assertTrailingSlash } from './assert-trailing-slash';
import { DOTCOM_BASE_URL } from './base-url';
import { generateVersionedPrefix } from './generate-versioned-prefix';
import { localizePath } from './locale';

export const getUrl = (branchUrlSlug, project, siteMetadata, siteBasePrefix, slug) => {
export const getUrl = (branchUrlSlug, project, siteBasePrefix, slug) => {
if (branchUrlSlug === 'legacy') {
// Avoid trailing slash to ensure query param remains valid
const legacyPath = localizePath(`/docs/legacy/?site=${project}`);
return DOTCOM_BASE_URL + legacyPath;
}
const prefixWithVersion = generatePrefix(branchUrlSlug, siteMetadata, siteBasePrefix);
const prefixWithVersion = generateVersionedPrefix(branchUrlSlug, siteBasePrefix);
return assertTrailingSlash(localizePath(`${prefixWithVersion}/${slug}`));
};
101 changes: 87 additions & 14 deletions tests/unit/Head.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import { Head } from '../../src/components/DocumentBody';
import mockStaticQuery from '../utils/mockStaticQuery';
import { useSiteMetadata } from '../../src/hooks/use-site-metadata';
import { generatePrefix } from '../../src/components/VersionDropdown/utils';
import * as siteMetadata from '../../src/hooks/use-site-metadata';
import useSnootyMetadata from '../../src/utils/use-snooty-metadata';
import { AVAILABLE_LANGUAGES } from '../../src/utils/locale';
import { DOTCOM_BASE_URL } from '../../src/utils/base-url';
Expand All @@ -12,6 +11,8 @@ import mockEOLSnootyMetadata from './data/EOLSnootyMetadata.json';
import mockHeadPageContext from './data/HeadPageContext.test.json';
import metadataWithoutToc from './data/MetadataWithoutToc.json';

const siteMetadataMock = jest.spyOn(siteMetadata, 'useSiteMetadata');

jest.mock(`../../src/utils/use-snooty-metadata`, () => jest.fn());

describe('Head', () => {
Expand Down Expand Up @@ -41,12 +42,15 @@ describe('Head', () => {
useSnootyMetadata.mockImplementation(() => mockEOLSnootyMetadata);
});
it('renders the canonical tag structured from the Head component with trailing slash', () => {
const mockSiteUrl = 'https://www.mongodb.com';
siteMetadataMock.mockImplementation(() => ({
siteUrl: mockSiteUrl,
}));
render(<Head pageContext={mockHeadPageContext} />);
const { siteUrl } = useSiteMetadata();
const urlSlug = 'stable';
const siteBasePrefix = mockHeadPageContext.repoBranches.siteBasePrefix;

const currentVersion = `${siteUrl}/${siteBasePrefix}/${urlSlug}/`;
const currentVersion = `${mockSiteUrl}/${siteBasePrefix}/${urlSlug}/`;

const canonicalTag = screen.getByTestId('canonical');
expect(canonicalTag).toBeInTheDocument();
Expand All @@ -62,23 +66,92 @@ describe('Head', () => {
useSnootyMetadata.mockImplementation(() => modMockEOLSnootyMetadataToBeNotEOL);
});

it('renders the canonical tag that points to itself', () => {
it("uses the branch's url slug as the canonical for versioned docs", () => {
siteMetadataMock.mockImplementation(() => ({
siteUrl: 'https://www.mongodb.com',
parserBranch: 'master',
}));
render(<Head pageContext={mockHeadPageContext} />);

const expectedCanonical = 'https://www.mongodb.com/docs/mongocli/upcoming/';

const canonicalTag = screen.getByTestId('canonical');
expect(canonicalTag).toBeInTheDocument();
expect(canonicalTag).toHaveAttribute('id', 'canonical');
expect(canonicalTag).toHaveAttribute('rel', 'canonical');
expect(canonicalTag).toHaveAttribute('href', expectedCanonical);
});

it('includes the correct page slug', () => {
siteMetadataMock.mockImplementation(() => ({
siteUrl: 'https://www.mongodb.com',
parserBranch: 'v1.26',
}));

const pageContext = { ...mockHeadPageContext, slug: '/introduction' };
render(<Head pageContext={pageContext} />);

const expectedCanonical = 'https://www.mongodb.com/docs/mongocli/stable/introduction/';

const canonicalTag = screen.getByTestId('canonical');
expect(canonicalTag).toBeInTheDocument();
expect(canonicalTag).toHaveAttribute('id', 'canonical');
expect(canonicalTag).toHaveAttribute('rel', 'canonical');
expect(canonicalTag).toHaveAttribute('href', expectedCanonical);
});

it('gracefully uses parserBranch for missing branches', () => {
const mockedParserBranch = 'DOP-staging-branch';
siteMetadataMock.mockImplementation(() => ({
siteUrl: 'https://www.mongodb.com',
parserBranch: mockedParserBranch,
}));
render(<Head pageContext={mockHeadPageContext} />);
const siteMetadata = useSiteMetadata();
const { siteUrl, parserBranch } = siteMetadata;
const urlSlug = mockHeadPageContext.repoBranches.branches.find(
(branch) => branch.gitBranchName === parserBranch
)?.urlSlug;
const pathPrefix = generatePrefix(urlSlug, siteMetadata);
const slug = mockHeadPageContext.slug;

const canonical = `${siteUrl}${pathPrefix}/${slug === '/' ? '' : slug}`;
const expectedCanonical = `https://www.mongodb.com/docs/mongocli/${mockedParserBranch}/`;

const canonicalTag = screen.getByTestId('canonical');
expect(canonicalTag).toBeInTheDocument();
expect(canonicalTag).toHaveAttribute('id', 'canonical');
expect(canonicalTag).toHaveAttribute('rel', 'canonical');
expect(canonicalTag).toHaveAttribute('href', expectedCanonical);
});

it("uses the branch's url slug as the canonical for non-versioned docs", () => {
siteMetadataMock.mockImplementation(() => ({
siteUrl: 'https://www.mongodb.com',
parserBranch: 'master',
}));

const nonVersionedBranchArr = [
{
gitBranchName: 'master',
active: true,
urlAliases: null,
publishOriginalBranchName: false,
urlSlug: '',
versionSelectorLabel: 'master',
isStableBranch: true,
buildsWithSnooty: true,
},
];
const mockNonVersionedContext = {
...mockHeadPageContext,
slug: '/atlas-search/introduction',
repoBranches: {
branches: nonVersionedBranchArr,
siteBasePrefix: 'docs/atlas',
},
};
render(<Head pageContext={mockNonVersionedContext} />);

const expectedCanonical = 'https://www.mongodb.com/docs/atlas/atlas-search/introduction/';

const canonicalTag = screen.getByTestId('canonical');
expect(canonicalTag).toBeInTheDocument();
expect(canonicalTag).toHaveAttribute('id', 'canonical');
expect(canonicalTag).toHaveAttribute('rel', 'canonical');
expect(canonicalTag).toHaveAttribute('href', canonical);
expect(canonicalTag).toHaveAttribute('href', expectedCanonical);
});
});

Expand Down
Loading

0 comments on commit 52b3a19

Please sign in to comment.