Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: match full browser locale case-insensitively (same as short) #655

Merged
merged 1 commit into from Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/templates/utils-common.js
Expand Up @@ -24,8 +24,9 @@ export const matchBrowserLocale = (appLocales, browserLocales) => {

// First pass: match exact locale.
for (const [index, browserCode] of browserLocales.entries()) {
if (appLocales.includes(browserCode)) {
matchedLocales.push({ code: browserCode, score: 1 - index / browserLocales.length })
const matchedCode = appLocales.find(appCode => appCode.toLowerCase() === browserCode.toLowerCase())
if (matchedCode) {
matchedLocales.push({ code: matchedCode, score: 1 - index / browserLocales.length })
break
}
}
Expand Down
47 changes: 23 additions & 24 deletions test/unit.test.js
@@ -1,4 +1,5 @@
import path from 'path'
import { matchBrowserLocale, parseAcceptLanguage } from '../src/templates/utils-common'

describe('parsePages', () => {
test('parses in-component options', async () => {
Expand All @@ -22,27 +23,21 @@ describe('parsePages', () => {
})

describe('parseAcceptLanguage', () => {
test('parses browser accept-language', async () => {
const { parseAcceptLanguage } = await import('../src/templates/utils-common')

test('parses browser accept-language', () => {
expect(parseAcceptLanguage('en-US,en;q=0.9,nb;q=0.8,no;q=0.7')).toStrictEqual(['en-US', 'en', 'nb', 'no'])
})
})

describe('matchBrowserLocale', () => {
test('matches highest-ranked full locale', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('matches highest-ranked full locale', () => {
// Both locales match first browser locale - full locale should win.
const appLocales = ['en', 'en-US']
const browserLocales = ['en-US', 'en']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en-US')
})

test('matches highest-ranked short locale', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('matches highest-ranked short locale', () => {
// Both locales match first browser locale - short locale should win.
// This is because browser locale order defines scoring so we prefer higher-scored over exact.
const appLocales = ['en', 'en-US']
Expand All @@ -51,48 +46,52 @@ describe('matchBrowserLocale', () => {
expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en')
})

test('matches highest-ranked short locale (only short defined)', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('matches highest-ranked short locale (only short defined)', () => {
const appLocales = ['en']
const browserLocales = ['en-US', 'en']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en')
})

test('matches highest-ranked short locale', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('matches highest-ranked short locale', () => {
const appLocales = ['en', 'fr']
const browserLocales = ['en-US', 'en-GB']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en')
})

test('does not match any locale', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('does not match any locale', () => {
const appLocales = ['pl', 'fr']
const browserLocales = ['en-US', 'en']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe(null)
})

test('matches full locale with mixed short and full, full having highest rank', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('matches full locale with mixed short and full, full having highest rank', () => {
const appLocales = ['en-US', 'en-GB', 'en']
const browserLocales = ['en-GB', 'en-US', 'en']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en-GB')
})

test('matches short locale with mixed short and full, short having highest rank', async () => {
const { matchBrowserLocale } = await import('../src/templates/utils-common')

test('matches short locale with mixed short and full, short having highest rank', () => {
const appLocales = ['en-US', 'en-GB', 'en']
const browserLocales = ['en', 'en-GB', 'en-US']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en')
})

test('matches short locale case-insensitively', () => {
const appLocales = ['EN', 'en-GB']
const browserLocales = ['en', 'en-GB', 'en-US']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('EN')
})

test('matches long locale case-insensitively', () => {
const appLocales = ['en-gb', 'en-US']
const browserLocales = ['en-GB', 'en-US']

expect(matchBrowserLocale(appLocales, browserLocales)).toBe('en-gb')
})
})