diff --git a/data/glossaries/external.yml b/data/glossaries/external.yml index f495c0316e..2b3295b411 100644 --- a/data/glossaries/external.yml +++ b/data/glossaries/external.yml @@ -37,7 +37,7 @@ - term: bio description: >- The user-generated description found on a profile: - https://help.github.com/articles/adding-a-bio-to-your-profile/ + [Adding a bio to your profile](/articles/adding-a-bio-to-your-profile) - term: billing cycle description: The interval of time for your specific billing plan. - term: billing email @@ -160,8 +160,8 @@ - term: contributions description: >- Specific activities on GitHub that will: - - Add a square to a user's contribution graph: "[What counts as a contribution](https://help.github.com/articles/viewing-contributions-on-your-profile/#what-counts-as-a-contribution)" - - Add activities to a user's timeline on their profile: "[Contribution activity](https://help.github.com/articles/viewing-contributions-on-your-profile/#contribution-activity)" + - Add a square to a user's contribution graph: "[What counts as a contribution](/articles/viewing-contributions-on-your-profile/#what-counts-as-a-contribution)" + - Add activities to a user's timeline on their profile: "[Contribution activity](/articles/viewing-contributions-on-your-profile/#contribution-activity)" - term: contributor description: >- A contributor is someone who does not have collaborator access to a repository but has contributed to a project and had a pull request they opened merged into the repository. @@ -230,7 +230,7 @@ description: >- A branch used to experiment with a new feature or fix an issue that is not in production. Also called a topic branch. - term: fenced code block - description: An indented block of code you can create with GitHub Flavored Markdown using triple backticks \`\`\` before and after the code block. See this [example](https://help.github.com/en/articles/creating-and-highlighting-code-blocks#fenced-code-blocks). + description: An indented block of code you can create with GitHub Flavored Markdown using triple backticks \`\`\` before and after the code block. See this [example](/articles/creating-and-highlighting-code-blocks#fenced-code-blocks). - term: fetch description: >- When you use `git fetch`, you're adding changes from the remote repository to diff --git a/package.json b/package.json index b2d2360a17..5e68103448 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "test": "jest && eslint . && prettier -c \"**/*.{yml,yaml}\" && npm run check-deps", "prebrowser-test": "npm run build", "browser-test": "start-server-and-test browser-test-server 4001 browser-test-tests", - "browser-test-server": "cross-env NODE_ENV=production ENABLED_LANGUAGES='en,ja' PORT=4001 node server.js", + "browser-test-server": "cross-env NODE_ENV=production PORT=4001 node server.js", "browser-test-tests": "cross-env BROWSER=1 jest tests/browser/browser.js", "sync-search": "start-server-and-test sync-search-server 4002 sync-search-indices", "sync-search-dry-run": "DRY_RUN=1 npm run sync-search", diff --git a/tests/browser/browser.js b/tests/browser/browser.js index aa4e15ba19..4952f1dd23 100644 --- a/tests/browser/browser.js +++ b/tests/browser/browser.js @@ -1,6 +1,7 @@ /* global page, browser */ const sleep = require('await-sleep') const { latest } = require('../../lib/enterprise-server-releases') +const languages = require('../../lib/languages') describe('homepage', () => { jest.setTimeout(60 * 1000) @@ -264,3 +265,19 @@ describe('card filters', () => { expect(noResultsClasses).not.toContain('d-none') }) }) + +describe('language banner', () => { + it('directs user to the English version of the article', async () => { + const wipLanguageKey = Object.keys(languages).find(key => languages[key].wip) + + // This kinda sucks, but if we don't have a WIP language, we currently can't + // run a reliable test. But hey, on the bright side, if we don't have a WIP + // language then this code will never run anyway! + if (wipLanguageKey) { + const res = await page.goto(`http://localhost:4001/${wipLanguageKey}/actions`) + expect(res.ok()).toBe(true) + const href = await page.$eval('a#to-english-doc', el => el.href) + expect(href.endsWith('/en/actions')).toBe(true) + } + }) +}) diff --git a/tests/content/lint-files.js b/tests/content/lint-files.js index 757e4b2c46..e58a587c03 100644 --- a/tests/content/lint-files.js +++ b/tests/content/lint-files.js @@ -17,6 +17,7 @@ const rootDir = path.join(__dirname, '../..') const contentDir = path.join(rootDir, 'content') const reusablesDir = path.join(rootDir, 'data/reusables') const variablesDir = path.join(rootDir, 'data/variables') +const glossariesDir = path.join(rootDir, 'data/glossaries') const languageCodes = Object.keys(languages) @@ -320,7 +321,19 @@ describe('lint-files', () => { const variableYamlRelPaths = variableYamlAbsPaths.map(p => slash(path.relative(rootDir, p))) const variableYamlTuples = zip(variableYamlRelPaths, variableYamlAbsPaths) - describe.each(variableYamlTuples)( + const glossariesYamlAbsPaths = walk(glossariesDir, yamlWalkOptions).sort() + const glossariesYamlRelPaths = glossariesYamlAbsPaths.map(p => slash(path.relative(rootDir, p))) + const glossariesYamlTuples = zip(glossariesYamlRelPaths, glossariesYamlAbsPaths) + + // Returns `content` if its a string, or `content.description` if it can. + // Used for getting the nested `description` key in glossary files. + function getContent (content) { + if (typeof content === 'string') return content + if (typeof content.description === 'string') return content.description + return null + } + + describe.each([...variableYamlTuples, ...glossariesYamlTuples])( 'in "%s"', (yamlRelPath, yamlAbsPath) => { let dictionary, isEarlyAccess @@ -336,8 +349,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(relativeArticleLinkRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(relativeArticleLinkRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -351,8 +365,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(languageLinkRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(languageLinkRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -366,8 +381,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(versionLinkRegEx) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(versionLinkRegEx) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -381,8 +397,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(domainLinkRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(domainLinkRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -398,8 +415,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(earlyAccessLinkRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(earlyAccessLinkRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -416,8 +434,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(earlyAccessImageRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(earlyAccessImageRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -434,8 +453,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(badEarlyAccessImageRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(badEarlyAccessImageRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -449,8 +469,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(oldVariableRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(oldVariableRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => { const example = match @@ -468,8 +489,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(oldOcticonRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(oldOcticonRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) } @@ -483,8 +505,9 @@ describe('lint-files', () => { const matches = [] for (const [key, content] of Object.entries(dictionary)) { - if (typeof content !== 'string') continue - const valMatches = (content.match(oldExtendedMarkdownRegex) || []) + const contentStr = getContent(content) + if (!contentStr) continue + const valMatches = (contentStr.match(oldExtendedMarkdownRegex) || []) if (valMatches.length > 0) { matches.push(...valMatches.map((match) => `Key "${key}": ${match}`)) }