-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(common): CHECKOUT-4223 Add locale context provider
- Loading branch information
Showing
14 changed files
with
291 additions
and
312 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { CurrencyService, LanguageService } from '@bigcommerce/checkout-sdk'; | ||
import { createContext } from 'react'; | ||
|
||
export interface LocaleContextType { | ||
language: LanguageService; | ||
currency?: CurrencyService; | ||
} | ||
|
||
const LocaleContext = createContext<LocaleContextType | undefined>(undefined); | ||
|
||
export default LocaleContext; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { createCheckoutService, CheckoutService } from '@bigcommerce/checkout-sdk'; | ||
import { mount } from 'enzyme'; | ||
import React, { FunctionComponent } from 'react'; | ||
|
||
import { getStoreConfig } from '../config/config.mock'; | ||
|
||
import LocaleContext, { LocaleContextType } from './LocaleContext'; | ||
import LocaleProvider from './LocaleProvider'; | ||
|
||
describe('LocaleProvider', () => { | ||
let checkoutService: CheckoutService; | ||
|
||
beforeEach(() => { | ||
checkoutService = createCheckoutService(); | ||
|
||
jest.spyOn(checkoutService.getState().data, 'getConfig') | ||
.mockReturnValue(getStoreConfig()); | ||
}); | ||
|
||
it('provides locale context to child components', () => { | ||
const Child: FunctionComponent<LocaleContextType> = jest.fn(() => null); | ||
const component = mount( | ||
<LocaleProvider checkoutService={ checkoutService }> | ||
<LocaleContext.Consumer> | ||
{ props => props && <Child { ...props } /> } | ||
</LocaleContext.Consumer> | ||
</LocaleProvider> | ||
); | ||
|
||
expect(component.find(Child).prop('currency')) | ||
.toBeDefined(); | ||
|
||
expect(component.find(Child).prop('language')) | ||
.toBeDefined(); | ||
}); | ||
|
||
it('provides locale context without currency service to child components when config is not available yet', () => { | ||
jest.spyOn(checkoutService.getState().data, 'getConfig') | ||
.mockReturnValue(undefined); | ||
|
||
const Child: FunctionComponent<LocaleContextType> = jest.fn(() => null); | ||
const component = mount( | ||
<LocaleProvider checkoutService={ checkoutService }> | ||
<LocaleContext.Consumer> | ||
{ props => props && <Child { ...props } /> } | ||
</LocaleContext.Consumer> | ||
</LocaleProvider> | ||
); | ||
|
||
expect(component.find(Child).prop('currency')) | ||
.not.toBeDefined(); | ||
|
||
expect(component.find(Child).prop('language')) | ||
.toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { createCurrencyService, CheckoutService, LanguageService, StoreConfig } from '@bigcommerce/checkout-sdk'; | ||
import React, { Component, ReactNode } from 'react'; | ||
|
||
import getLanguageService from './getLanguageService'; | ||
import LocaleContext from './LocaleContext'; | ||
|
||
export interface LocaleProviderProps { | ||
checkoutService: CheckoutService; | ||
} | ||
|
||
export interface LocaleProviderState { | ||
config?: StoreConfig; | ||
} | ||
|
||
class LocaleProvider extends Component<LocaleProviderProps> { | ||
state: Readonly<LocaleProviderState>; | ||
|
||
private languageService: LanguageService; | ||
private unsubscribe?: () => void; | ||
|
||
constructor(props: Readonly<LocaleProviderProps>) { | ||
super(props); | ||
|
||
this.state = {}; | ||
this.languageService = getLanguageService(); | ||
} | ||
|
||
componentDidMount(): void { | ||
const { checkoutService } = this.props; | ||
|
||
this.unsubscribe = checkoutService.subscribe( | ||
({ data }) => { | ||
this.setState({ config: data.getConfig() }); | ||
}, | ||
({ data }) => data.getConfig() | ||
); | ||
} | ||
|
||
componentWillUnmount(): void { | ||
if (this.unsubscribe) { | ||
this.unsubscribe(); | ||
this.unsubscribe = undefined; | ||
} | ||
} | ||
|
||
render(): ReactNode { | ||
const { children } = this.props; | ||
const { config } = this.state; | ||
const context = { | ||
currency: config ? createCurrencyService(config) : undefined, | ||
language: this.languageService, | ||
}; | ||
|
||
return ( | ||
<LocaleContext.Provider value={ context }> | ||
{ children } | ||
</LocaleContext.Provider> | ||
); | ||
} | ||
} | ||
|
||
export default LocaleProvider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { getStoreConfig } from '../config/config.mock'; | ||
|
||
import createLocaleContext from './createLocaleContext'; | ||
import { LocaleContextType } from './LocaleContext.js'; | ||
|
||
describe('createLocaleContext', () => { | ||
let localeContext: LocaleContextType; | ||
|
||
beforeEach(() => { | ||
localeContext = createLocaleContext(getStoreConfig()); | ||
}); | ||
|
||
it('returns an object with currency', () => { | ||
expect(localeContext).toHaveProperty('currency'); | ||
// tslint:disable-next-line:no-non-null-assertion | ||
expect(localeContext.currency!.toStoreCurrency).toBeDefined(); | ||
}); | ||
|
||
it('returns an object with language', () => { | ||
expect(localeContext).toHaveProperty('language'); | ||
expect(localeContext.language.translate).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { createCurrencyService, StoreConfig } from '@bigcommerce/checkout-sdk'; | ||
|
||
import getLanguageService from './getLanguageService'; | ||
import { LocaleContextType } from './LocaleContext'; | ||
|
||
export default function createLocaleContext(config: StoreConfig): Required<LocaleContextType> { | ||
if (!config) { | ||
throw new Error('Missing configuration data'); | ||
} | ||
|
||
return { | ||
currency: createCurrencyService(config), | ||
language: getLanguageService(), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { createLanguageService, LanguageService } from '@bigcommerce/checkout-sdk'; | ||
|
||
import defaultTranslations from '../language/en.json'; | ||
|
||
export default function getLanguageService(): LanguageService { | ||
return createLanguageService({ ...(window as any).language, defaultTranslations }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { WithCurrencyProps } from './withCurrency'; | ||
import { WithLanguageProps } from './withLanguage'; | ||
import { LocaleContextType } from './LocaleContext'; | ||
|
||
export type LocaleContextType = LocaleContextType; | ||
export type WithCurrencyProps = WithCurrencyProps; | ||
export type WithLanguageProps = WithLanguageProps; | ||
|
||
export { default as LocaleContext } from './LocaleContext'; | ||
export { default as createLocaleContext } from './createLocaleContext'; | ||
export { default as getLanguageService } from './getLanguageService'; | ||
export { default as withCurrency } from './withCurrency'; | ||
export { default as withLanguage } from './withLanguage'; | ||
export { default as LocaleProvider } from './LocaleProvider'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { createCurrencyService, createLanguageService } from '@bigcommerce/checkout-sdk'; | ||
|
||
import { getStoreConfig } from '../config/config.mock'; | ||
import defaultTranslations from '../language/en.json'; | ||
|
||
import { LocaleContextType } from './LocaleContext'; | ||
|
||
export function getLocaleContext(): Required<LocaleContextType> { | ||
return { | ||
currency: createCurrencyService(getStoreConfig()), | ||
language: createLanguageService({ ...(window as any).language, defaultTranslations }), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { mount } from 'enzyme'; | ||
import React from 'react'; | ||
|
||
import { getStoreConfig } from '../config/config.mock'; | ||
|
||
import createLocaleContext from './createLocaleContext'; | ||
import withCurrency from './withCurrency'; | ||
import LocaleContext, { LocaleContextType } from './LocaleContext'; | ||
|
||
describe('withCurrency()', () => { | ||
let contextValue: LocaleContextType; | ||
|
||
beforeEach(() => { | ||
contextValue = createLocaleContext(getStoreConfig()); | ||
}); | ||
|
||
it('injects currency service to inner component', () => { | ||
const Inner = () => <div />; | ||
const Outer = withCurrency(Inner); | ||
const container = mount( | ||
<LocaleContext.Provider value={ contextValue }> | ||
<Outer /> | ||
</LocaleContext.Provider> | ||
); | ||
|
||
expect(container.find(Inner).prop('currency')) | ||
.toEqual(contextValue.currency); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { CurrencyService } from '@bigcommerce/checkout-sdk'; | ||
|
||
import { createInjectHoc, InjectHoc } from '../common/hoc'; | ||
|
||
import LocaleContext from './LocaleContext'; | ||
|
||
export interface WithCurrencyProps { | ||
currency: CurrencyService; | ||
} | ||
|
||
const withCurrency: InjectHoc<WithCurrencyProps> = createInjectHoc(LocaleContext, { | ||
displayNamePrefix: 'WithCurrency', | ||
pickProps: (value, key) => key === 'currency' && !!value, | ||
}); | ||
|
||
export default withCurrency; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { mount } from 'enzyme'; | ||
import React from 'react'; | ||
|
||
import { getStoreConfig } from '../config/config.mock'; | ||
|
||
import createLocaleContext from './createLocaleContext'; | ||
import withLanguage from './withLanguage'; | ||
import LocaleContext, { LocaleContextType } from './LocaleContext'; | ||
|
||
describe('withLanguage()', () => { | ||
let contextValue: LocaleContextType; | ||
|
||
beforeEach(() => { | ||
contextValue = createLocaleContext(getStoreConfig()); | ||
}); | ||
|
||
it('injects language service to inner component', () => { | ||
const Inner = () => <div />; | ||
const Outer = withLanguage(Inner); | ||
const container = mount( | ||
<LocaleContext.Provider value={ contextValue }> | ||
<Outer /> | ||
</LocaleContext.Provider> | ||
); | ||
|
||
expect(container.find(Inner).prop('language')) | ||
.toEqual(contextValue.language); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { LanguageService } from '@bigcommerce/checkout-sdk'; | ||
|
||
import { createInjectHoc, InjectHoc } from '../common/hoc'; | ||
|
||
import LocaleContext from './LocaleContext'; | ||
|
||
export interface WithLanguageProps { | ||
language: LanguageService; | ||
} | ||
|
||
const withLanguage: InjectHoc<WithLanguageProps> = createInjectHoc(LocaleContext, { | ||
displayNamePrefix: 'WithLanguage', | ||
pickProps: (value, key) => key === 'language' && !!value, | ||
}); | ||
|
||
export default withLanguage; |