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 navigation to defaultLanguage when redirectToDefaultLang=false #123

Merged
merged 1 commit into from Apr 15, 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
64 changes: 54 additions & 10 deletions __tests__/Link.test.js
Expand Up @@ -3,55 +3,99 @@ import React from 'react'
import I18nProvider from '../src/I18nProvider'
import Link from '../src/Link'

function StaticModeLink(props) {
function CustomServerModeLink(props) {
return (
<I18nProvider lang="en" namespaces={{}} isStaticMode>
<I18nProvider lang="en" namespaces={{}}>
<Link {...props} />
</I18nProvider>
)
}

function CustomServerModeLink(props) {
function StaticModeLinkWithRedirect(props) {
return (
<I18nProvider lang="en" namespaces={{}}>
<I18nProvider
lang="en"
namespaces={{}}
internals={{
isStaticMode: true,
redirectToDefaultLang: true,
defaultLanguage: 'en',
}}
>
<Link {...props} />
</I18nProvider>
)
}

function StaticModeLinkWithoutRedirect(props) {
return (
<I18nProvider
lang="en"
namespaces={{}}
internals={{
isStaticMode: true,
redirectToDefaultLang: false,
defaultLanguage: 'en',
}}
>
<Link {...props} />
</I18nProvider>
)
}

StaticModeLink.displayName = 'StaticMode'
StaticModeLinkWithRedirect.displayName = 'StaticModeWithRedirect'
CustomServerModeLink.displayName = 'CustomServerMode'
StaticModeLinkWithoutRedirect.displayName = 'StaticModeWithoutRedirect'

const modes = [StaticModeLink, CustomServerModeLink]
const modes = [
CustomServerModeLink,
StaticModeLinkWithRedirect,
StaticModeLinkWithoutRedirect,
]

describe('Link', () => {
afterEach(cleanup)

modes.forEach(LinkComponent => {
modes.forEach((LinkComponent) => {
describe(`${LinkComponent.displayName}`, () => {
test('Should add the current language navigating to homepage', () => {
const expected = {
StaticModeWithRedirect: '<a href="/en">home</a>',
CustomServerMode: '<a href="/en">home</a>',
StaticModeWithoutRedirect: '<a href="/">home</a>',
}[LinkComponent.displayName]
const { container } = render(
<LinkComponent href="/">
<a>home</a>
</LinkComponent>
)
expect(container.innerHTML).toBe('<a href="/en">home</a>')
expect(container.innerHTML).toBe(expected)
})
test('Should add the current language navigating to homepage with "as"', () => {
const expected = {
StaticModeWithRedirect: '<a href="/en/homepage">home</a>',
CustomServerMode: '<a href="/en/homepage">home</a>',
StaticModeWithoutRedirect: '<a href="/homepage">home</a>',
}[LinkComponent.displayName]
const { container } = render(
<LinkComponent href="/" as="/homepage">
<a>home</a>
</LinkComponent>
)
expect(container.innerHTML).toBe('<a href="/en/homepage">home</a>')
expect(container.innerHTML).toBe(expected)
})
test('Should add the current language using nested route ', () => {
const expected = {
StaticModeWithRedirect: '<a href="/en/some/route">link</a>',
CustomServerMode: '<a href="/en/some/route">link</a>',
StaticModeWithoutRedirect: '<a href="/some/route">link</a>',
}[LinkComponent.displayName]
const { container } = render(
<LinkComponent href="/some/route">
<a>link</a>
</LinkComponent>
)
expect(container.innerHTML).toBe('<a href="/en/some/route">link</a>')
expect(container.innerHTML).toBe(expected)
})
test('Should add the defined language navigating to homepage', () => {
const { container } = render(
Expand Down
139 changes: 114 additions & 25 deletions __tests__/Router.test.js
Expand Up @@ -16,26 +16,55 @@ function Navigate({ href, as, lang }) {
return <button onClick={nav}>Navigate</button>
}

function CustomServerModeRouter(props) {
return (
<I18nProvider lang="en" namespaces={{}}>
<Navigate {...props} />
</I18nProvider>
)
}

function StaticModeRouter(props) {
return (
<I18nProvider lang="en" namespaces={{}} isStaticMode>
<I18nProvider
lang="en"
namespaces={{}}
internals={{
isStaticMode: true,
redirectToDefaultLang: true,
defaultLanguage: 'en',
}}
>
<Navigate {...props} />
</I18nProvider>
)
}

function CustomServerModeRouter(props) {
function StaticModeRouterNoRedirect(props) {
return (
<I18nProvider lang="en" namespaces={{}}>
<I18nProvider
lang="en"
namespaces={{}}
internals={{
isStaticMode: true,
redirectToDefaultLang: false,
defaultLanguage: 'en',
}}
>
<Navigate {...props} />
</I18nProvider>
)
}

StaticModeRouter.displayName = 'StaticMode'
StaticModeRouter.displayName = 'StaticModeWithRedirect'
CustomServerModeRouter.displayName = 'CustomServerMode'
StaticModeRouterNoRedirect.displayName = 'StaticModeWithoutRedirect'

const modes = [StaticModeRouter, CustomServerModeRouter]
const modes = [
CustomServerModeRouter,
StaticModeRouter,
StaticModeRouterNoRedirect,
]

function expectNavigation({ href, as }) {
expect(
Expand All @@ -49,23 +78,25 @@ function expectNavigation({ href, as }) {
describe('Router', () => {
afterEach(cleanup)

modes.forEach(RouterComponent => {
const isStatic = RouterComponent.displayName === 'StaticMode'

modes.forEach((RouterComponent) => {
describe(`${RouterComponent.displayName}`, () => {
test('Should add the current language navigating to homepage', () => {
const expected = isStatic
? { href: '/en', as: undefined }
: { href: '/', as: '/en' }
const expected = {
StaticModeWithRedirect: { href: '/en', as: undefined },
CustomServerMode: { href: '/', as: '/en' },
StaticModeWithoutRedirect: { href: '/', as: undefined },
}[RouterComponent.displayName]

const { container } = render(<RouterComponent href="/" />)
fireEvent.click(container.firstChild)
expectNavigation(expected)
})
test('Should add the current language navigating to homepage with "as"', () => {
const expected = isStatic
? { href: '/en', as: '/en/homepage' }
: { href: '/', as: '/en/homepage' }
const expected = {
StaticModeWithRedirect: { href: '/en', as: '/en/homepage' },
CustomServerMode: { href: '/', as: '/en/homepage' },
StaticModeWithoutRedirect: { href: '/', as: '/homepage' },
}[RouterComponent.displayName]

const { container } = render(
<RouterComponent href="/" as="/homepage" />
Expand All @@ -74,27 +105,33 @@ describe('Router', () => {
expectNavigation(expected)
})
test('Should add the current language using nested route ', () => {
const expected = isStatic
? { href: '/en/some/route', as: undefined }
: { href: '/some/route', as: '/en/some/route' }
const expected = {
StaticModeWithRedirect: { href: '/en/some/route', as: undefined },
CustomServerMode: { href: '/some/route', as: '/en/some/route' },
StaticModeWithoutRedirect: { href: '/some/route', as: undefined },
}[RouterComponent.displayName]

const { container } = render(<RouterComponent href="/some/route" />)
fireEvent.click(container.firstChild)
expectNavigation(expected)
})
test('Should add the defined language navigating to homepage', () => {
const expected = isStatic
? { href: '/es', as: undefined }
: { href: '/', as: '/es' }
const expected = {
StaticModeWithRedirect: { href: '/es', as: undefined },
CustomServerMode: { href: '/', as: '/es' },
StaticModeWithoutRedirect: { href: '/es', as: undefined },
}[RouterComponent.displayName]

const { container } = render(<RouterComponent href="/" lang="es" />)
fireEvent.click(container.firstChild)
expectNavigation(expected)
})
test('Should add the defined language using nested route ', () => {
const expected = isStatic
? { href: '/es/some/route', as: undefined }
: { href: '/some/route', as: '/es/some/route' }
const expected = {
StaticModeWithRedirect: { href: '/es/some/route', as: undefined },
CustomServerMode: { href: '/some/route', as: '/es/some/route' },
StaticModeWithoutRedirect: { href: '/es/some/route', as: undefined },
}[RouterComponent.displayName]

const { container } = render(
<RouterComponent href="/some/route" lang="es" />
Expand All @@ -105,13 +142,65 @@ describe('Router', () => {
})
})

test('should work without specifying a language', () => {
test('should work without specifying a language | to another language', () => {
function nav() {
Router.pushI18n('/some/route')
}
function Component() {
return (
<I18nProvider
lang="es"
namespaces={{}}
internals={{ isStaticMode: true }}
>
<button onClick={nav}>Navigate</button>
</I18nProvider>
)
}
const { container } = render(<Component />)
fireEvent.click(container.firstChild)
expectNavigation({ href: '/es/some/route', as: undefined })
})

test('should work without specifying a language | to default language (no redirect)', () => {
function nav() {
Router.pushI18n('/some/route')
}
function Component() {
return (
<I18nProvider
lang="en"
namespaces={{}}
internals={{
isStaticMode: true,
redirectToDefaultLang: false,
defaultLanguage: 'en',
}}
>
<button onClick={nav}>Navigate</button>
</I18nProvider>
)
}
const { container } = render(<Component />)
fireEvent.click(container.firstChild)
expectNavigation({ href: '/some/route', as: undefined })
})

test('should work without specifying a language | to default language (with redirect)', () => {
function nav() {
Router.pushI18n('/some/route')
}
function Component() {
return (
<I18nProvider lang="en" namespaces={{}} isStaticMode>
<I18nProvider
lang="en"
namespaces={{}}
internals={{
isStaticMode: true,
redirectToDefaultLang: true,
defaultLanguage: 'en',
}}
>
<button onClick={nav}>Navigate</button>
</I18nProvider>
)
Expand Down
25 changes: 13 additions & 12 deletions __tests__/builder.test.js
Expand Up @@ -30,6 +30,7 @@ describe('builder', () => {
expect(fs.existsSync('examples/static-site/pages/_app.js')).toBe(true)
expect(fs.existsSync('examples/static-site/pages/index.js')).toBe(true)

// Default language
expect(
fs.existsSync(
'examples/static-site/pages/more-examples/dynamic-namespace.js'
Expand All @@ -39,6 +40,7 @@ describe('builder', () => {
fs.existsSync('examples/static-site/pages/more-examples/index.js')
).toBe(true)

// Rest of languages
expect(fs.existsSync('examples/static-site/pages/ca/index.js')).toBe(true)
expect(
fs.existsSync(
Expand All @@ -49,25 +51,28 @@ describe('builder', () => {
fs.existsSync('examples/static-site/pages/ca/more-examples/index.js')
).toBe(true)

expect(fs.existsSync('examples/static-site/pages/en/index.js')).toBe(true)
expect(fs.existsSync('examples/static-site/pages/es/index.js')).toBe(true)
expect(
fs.existsSync(
'examples/static-site/pages/en/more-examples/dynamic-namespace.js'
'examples/static-site/pages/es/more-examples/dynamic-namespace.js'
)
).toBe(true)
expect(
fs.existsSync('examples/static-site/pages/en/more-examples/index.js')
fs.existsSync('examples/static-site/pages/es/more-examples/index.js')
).toBe(true)

expect(fs.existsSync('examples/static-site/pages/es/index.js')).toBe(true)
// The default language should be not generated when redirectToDefaultLang=false
expect(fs.existsSync('examples/static-site/pages/en/index.js')).toBe(
false
)
expect(
fs.existsSync(
'examples/static-site/pages/es/more-examples/dynamic-namespace.js'
'examples/static-site/pages/en/more-examples/dynamic-namespace.js'
)
).toBe(true)
).toBe(false)
expect(
fs.existsSync('examples/static-site/pages/es/more-examples/index.js')
).toBe(true)
fs.existsSync('examples/static-site/pages/en/more-examples/index.js')
).toBe(false)
})
})

Expand All @@ -94,7 +99,6 @@ describe('builder', () => {
const deflt = fs.readFileSync('examples/static-site/pages/index.js')
const es = fs.readFileSync('examples/static-site/pages/es/index.js')
const ca = fs.readFileSync('examples/static-site/pages/ca/index.js')
const en = fs.readFileSync('examples/static-site/pages/en/index.js')

expect(deflt.toString()).toContain(
`export const getStaticProps = ctx => _rest.getStaticProps({ ...ctx, lang: 'en' })`
Expand All @@ -105,9 +109,6 @@ describe('builder', () => {
expect(ca.toString()).toContain(
`export const getStaticProps = ctx => _rest.getStaticProps({ ...ctx, lang: 'ca' })`
)
expect(en.toString()).toContain(
`export const getStaticProps = ctx => _rest.getStaticProps({ ...ctx, lang: 'en' })`
)
})
})
})