@openedx/frontend-base 1.0.0-alpha.0 → 1.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/types.js +0 -2
- package/config/webpack/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.js +66 -0
- package/package.json +8 -1
- package/runtime/__mocks__/file.js +1 -0
- package/runtime/__mocks__/svg.js +1 -0
- package/runtime/__mocks__/universal-cookie.js +6 -0
- package/runtime/analytics/interface.test.js +242 -0
- package/runtime/auth/AxiosJwtAuthService.test.jsx +1076 -0
- package/runtime/auth/interceptors/createRetryInterceptor.test.js +23 -0
- package/runtime/config/getExternalLinkUrl.test.js +76 -0
- package/runtime/i18n/lib.test.js +230 -0
- package/runtime/initialize.async.function.config.test.js +43 -0
- package/runtime/initialize.const.config.test.js +41 -0
- package/runtime/initialize.function.config.test.js +41 -0
- package/runtime/initialize.test.js +356 -0
- package/runtime/logging/NewRelicLoggingService.test.js +214 -0
- package/runtime/react/AuthenticatedPageRoute.test.jsx +135 -0
- package/runtime/react/ErrorBoundary.test.jsx +83 -0
- package/runtime/react/SiteProvider.test.jsx +66 -0
- package/runtime/react/hooks.test.jsx +104 -0
- package/runtime/routing/utils.test.ts +7 -0
- package/runtime/scripts/GoogleAnalyticsLoader.test.ts +77 -0
- package/runtime/site.config.test.tsx +33 -0
- package/runtime/slots/Slot.test.tsx +40 -0
- package/runtime/slots/layout/DefaultSlotLayout.test.tsx +31 -0
- package/runtime/slots/layout/hooks.test.tsx +178 -0
- package/runtime/slots/layout/utils.test.ts +67 -0
- package/runtime/slots/types.ts +1 -0
- package/runtime/slots/utils.test.ts +64 -0
- package/runtime/slots/utils.ts +28 -9
- package/runtime/testing/initializeMockApp.test.ts +66 -0
- package/runtime/utils.test.js +116 -0
- package/shell/Logo.test.tsx +32 -0
- package/shell/__mocks__/file.js +1 -0
- package/shell/__mocks__/svg.js +1 -0
- package/shell/__mocks__/universal-cookie.js +6 -0
- package/shell/app.ts +14 -0
- package/shell/dev/devHome/app.ts +2 -2
- package/shell/dev/slotShowcase/app.tsx +9 -9
- package/shell/header/app.tsx +3 -3
- package/shell/router/createRouter.test.tsx +50 -0
- package/shell/router/getAppRoutes.test.tsx +59 -0
- package/shell/site.config.dev.tsx +3 -3
- package/shell/site.config.test.tsx +16 -0
- package/tools/dist/cli/intl-imports.test.js +146 -0
- package/tools/dist/cli/openedx.js +1 -15
- package/tools/dist/cli/utils/printUsage.js +0 -9
- package/tools/dist/types.js +0 -2
- package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.js +66 -0
- package/types.ts +1 -1
- package/eslint.config.js +0 -18
- package/frontend-base.d.ts +0 -8
- package/jest.config.js +0 -7
- package/openedx-frontend-base.tgz +0 -0
- package/test-site/app.d.ts +0 -15
- package/test-site/dist/176.436443549ebb858db483.js +0 -2
- package/test-site/dist/176.436443549ebb858db483.js.map +0 -1
- package/test-site/dist/362.536eff787d2380fe246c.js +0 -2
- package/test-site/dist/362.536eff787d2380fe246c.js.map +0 -1
- package/test-site/dist/653.486966b108d224551296.js +0 -2
- package/test-site/dist/653.486966b108d224551296.js.map +0 -1
- package/test-site/dist/74e025d3fe9a7b7f8503054e2563b353.jpg +0 -0
- package/test-site/dist/806.323cf6496ad0a7fe73a7.js +0 -3
- package/test-site/dist/806.323cf6496ad0a7fe73a7.js.LICENSE.txt +0 -106
- package/test-site/dist/806.323cf6496ad0a7fe73a7.js.map +0 -1
- package/test-site/dist/95ec738c0b7faac5b5c9126794446bbd.svg +0 -4
- package/test-site/dist/app.612058b36c74787759ac.css +0 -61
- package/test-site/dist/app.612058b36c74787759ac.css.map +0 -1
- package/test-site/dist/app.612058b36c74787759ac.js +0 -2
- package/test-site/dist/app.612058b36c74787759ac.js.map +0 -1
- package/test-site/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +0 -1
- package/test-site/dist/index.html +0 -1
- package/test-site/dist/report.html +0 -39
- package/test-site/dist/runtime.c7aeaf7b967496cb076f.js +0 -2
- package/test-site/dist/runtime.c7aeaf7b967496cb076f.js.map +0 -1
- package/test-site/eslint.config.js +0 -12
- package/test-site/package-lock.json +0 -19226
- package/test-site/package.json +0 -29
- package/test-site/public/index.html +0 -10
- package/test-site/site.config.build.tsx +0 -27
- package/test-site/site.config.dev.tsx +0 -27
- package/test-site/src/authenticated-page/AuthenticatedPage.tsx +0 -18
- package/test-site/src/authenticated-page/i18n/index.ts +0 -27
- package/test-site/src/authenticated-page/index.tsx +0 -28
- package/test-site/src/example-page/ExamplePage.tsx +0 -79
- package/test-site/src/example-page/Image.tsx +0 -11
- package/test-site/src/example-page/ParagonPreview.jsx +0 -66
- package/test-site/src/example-page/apple.jpg +0 -0
- package/test-site/src/example-page/apple.svg +0 -1
- package/test-site/src/example-page/index.ts +0 -16
- package/test-site/src/i18n/README.md +0 -3
- package/test-site/src/i18n/messages/frontend-app-sample/ar.json +0 -4
- package/test-site/src/i18n/messages/frontend-app-sample/eo.json +0 -1
- package/test-site/src/i18n/messages/frontend-app-sample/es_419.json +0 -4
- package/test-site/src/i18n/messages/frontend-component-emptylangs/ar.json +0 -1
- package/test-site/src/i18n/messages/frontend-component-singlelang/ar.json +0 -3
- package/test-site/src/iframe-widget/IframeWidget.tsx +0 -14
- package/test-site/src/iframe-widget/index.ts +0 -16
- package/test-site/src/index.tsx +0 -3
- package/test-site/src/messages.js +0 -11
- package/test-site/src/site.scss +0 -11
- package/test-site/tsconfig.json +0 -14
- package/tools/babel/babel.config.js +0 -27
- package/tools/babel.config.js +0 -3
- package/tools/cli/README.md +0 -29
- package/tools/cli/commands/pack.ts +0 -9
- package/tools/cli/commands/release.ts +0 -27
- package/tools/cli/commands/serve.ts +0 -43
- package/tools/cli/intl-imports.ts +0 -274
- package/tools/cli/openedx.ts +0 -101
- package/tools/cli/transifex-utils.ts +0 -75
- package/tools/cli/utils/ensureConfigFilenameOption.ts +0 -40
- package/tools/cli/utils/formatter.ts +0 -10
- package/tools/cli/utils/getResolvedConfigPath.ts +0 -23
- package/tools/cli/utils/prettyPrintTitle.ts +0 -15
- package/tools/cli/utils/printUsage.ts +0 -53
- package/tools/config-helpers/createConfig.ts +0 -8
- package/tools/config-helpers/createLintConfig.ts +0 -14
- package/tools/config-helpers/getBaseConfig.ts +0 -11
- package/tools/defaultConfigPaths.ts +0 -30
- package/tools/dist/cli/commands/pack.js +0 -14
- package/tools/dist/cli/commands/release.js +0 -28
- package/tools/eslint/base.eslint.config.js +0 -124
- package/tools/eslint/modules.d.ts +0 -5
- package/tools/eslint.config.js +0 -15
- package/tools/index.ts +0 -3
- package/tools/jest/jest.config.js +0 -30
- package/tools/jest.config.js +0 -19
- package/tools/tsconfig.json +0 -24
- package/tools/types.ts +0 -21
- package/tools/typescript/tsconfig.json +0 -32
- package/tools/webpack/common-config/README.md +0 -15
- package/tools/webpack/common-config/all/getCodeRules.ts +0 -51
- package/tools/webpack/common-config/all/getFileLoaderRules.ts +0 -23
- package/tools/webpack/common-config/all/getIgnoreWarnings.ts +0 -13
- package/tools/webpack/common-config/all/getImageMinimizer.ts +0 -26
- package/tools/webpack/common-config/all/getStylesheetRule.ts +0 -111
- package/tools/webpack/common-config/dev/getDevServer.ts +0 -35
- package/tools/webpack/common-config/index.ts +0 -6
- package/tools/webpack/common-config/site/getHtmlWebpackPlugin.ts +0 -11
- package/tools/webpack/modules.d.ts +0 -6
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.ts +0 -102
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/LICENSE +0 -21
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/README.md +0 -7
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/index.js +0 -3
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +0 -1
- package/tools/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.ts +0 -134
- package/tools/webpack/plugins/paragon-webpack-plugin/index.ts +0 -3
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.ts +0 -71
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.ts +0 -72
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/index.ts +0 -6
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.ts +0 -131
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.ts +0 -144
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.ts +0 -106
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.ts +0 -54
- package/tools/webpack/types.ts +0 -69
- package/tools/webpack/utils/getLocalAliases.ts +0 -65
- package/tools/webpack/utils/getPublicPath.ts +0 -3
- package/tools/webpack/utils/getResolvedSiteConfigPath.ts +0 -28
- package/tools/webpack/utils/paragonUtils.ts +0 -152
- package/tools/webpack/webpack.config.build.ts +0 -93
- package/tools/webpack/webpack.config.dev.shell.ts +0 -122
- package/tools/webpack/webpack.config.dev.ts +0 -90
- package/tsconfig.json +0 -23
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defaultGetBackoffMilliseconds } from './createRetryInterceptor';
|
|
2
|
+
|
|
3
|
+
describe('createRetryInterceptor: defaultGetBackoffMilliseconds', () => {
|
|
4
|
+
it('returns a number between 2000 and 3000 on the first retry', () => {
|
|
5
|
+
const backoffInMilliseconds = defaultGetBackoffMilliseconds(1);
|
|
6
|
+
expect(backoffInMilliseconds).toBeGreaterThanOrEqual(2000);
|
|
7
|
+
expect(backoffInMilliseconds).toBeLessThanOrEqual(3000);
|
|
8
|
+
});
|
|
9
|
+
it('returns a number between 4000 and 5000 on the second retry', () => {
|
|
10
|
+
const backoffInMilliseconds = defaultGetBackoffMilliseconds(2);
|
|
11
|
+
expect(backoffInMilliseconds).toBeGreaterThanOrEqual(4000);
|
|
12
|
+
expect(backoffInMilliseconds).toBeLessThanOrEqual(5000);
|
|
13
|
+
});
|
|
14
|
+
it('returns a number between 8000 and 9000 on the third retry', () => {
|
|
15
|
+
const backoffInMilliseconds = defaultGetBackoffMilliseconds(3);
|
|
16
|
+
expect(backoffInMilliseconds).toBeGreaterThanOrEqual(8000);
|
|
17
|
+
expect(backoffInMilliseconds).toBeLessThanOrEqual(9000);
|
|
18
|
+
});
|
|
19
|
+
it('returns 16000 fourth or later retry', () => {
|
|
20
|
+
const backoffInMilliseconds = defaultGetBackoffMilliseconds(4);
|
|
21
|
+
expect(backoffInMilliseconds).toEqual(16000);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getExternalLinkUrl, setSiteConfig } from '.';
|
|
2
|
+
|
|
3
|
+
describe('getExternalLinkUrl', () => {
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
// Reset config after each test to avoid cross-test pollution
|
|
6
|
+
setSiteConfig({});
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('should return the url passed in when externalLinkUrlOverrides is not set', () => {
|
|
10
|
+
setSiteConfig({});
|
|
11
|
+
const url = 'https://foo.example.com';
|
|
12
|
+
expect(getExternalLinkUrl(url)).toBe(url);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return the url passed in when externalLinkUrlOverrides does not have the url mapping', () => {
|
|
16
|
+
setSiteConfig({
|
|
17
|
+
externalLinkUrlOverrides: {
|
|
18
|
+
'https://bar.example.com': 'https://mapped.example.com',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
const url = 'https://foo.example.com';
|
|
22
|
+
expect(getExternalLinkUrl(url)).toBe(url);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should return the mapped url when externalLinkUrlOverrides has the url mapping', () => {
|
|
26
|
+
const url = 'https://foo.example.com';
|
|
27
|
+
const mappedUrl = 'https://mapped.example.com';
|
|
28
|
+
setSiteConfig({ externalLinkUrlOverrides: { [url]: mappedUrl } });
|
|
29
|
+
expect(getExternalLinkUrl(url)).toBe(mappedUrl);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should handle empty externalLinkUrlOverrides object', () => {
|
|
33
|
+
setSiteConfig({ externalLinkUrlOverrides: {} });
|
|
34
|
+
const url = 'https://foo.example.com';
|
|
35
|
+
expect(getExternalLinkUrl(url)).toBe(url);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should guard against empty string argument', () => {
|
|
39
|
+
const fallbackResult = '#';
|
|
40
|
+
setSiteConfig({ externalLinkUrlOverrides: { foo: 'bar' } });
|
|
41
|
+
expect(getExternalLinkUrl(undefined)).toBe(fallbackResult);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should guard against non-string argument', () => {
|
|
45
|
+
const fallbackResult = '#';
|
|
46
|
+
setSiteConfig({ externalLinkUrlOverrides: { foo: 'bar' } });
|
|
47
|
+
expect(getExternalLinkUrl(null)).toBe(fallbackResult);
|
|
48
|
+
expect(getExternalLinkUrl(42)).toBe(fallbackResult);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should not throw if externalLinkUrlOverrides is not an object', () => {
|
|
52
|
+
setSiteConfig({ externalLinkUrlOverrides: null });
|
|
53
|
+
const url = 'https://foo.example.com';
|
|
54
|
+
expect(getExternalLinkUrl(url)).toBe(url);
|
|
55
|
+
setSiteConfig({ externalLinkUrlOverrides: 42 });
|
|
56
|
+
expect(getExternalLinkUrl(url)).toBe(url);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should work with multiple mappings', () => {
|
|
60
|
+
setSiteConfig({
|
|
61
|
+
externalLinkUrlOverrides: {
|
|
62
|
+
'https://a.example.com': 'https://mapped-a.example.com',
|
|
63
|
+
'https://b.example.com': 'https://mapped-b.example.com',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
expect(getExternalLinkUrl('https://a.example.com')).toBe(
|
|
67
|
+
'https://mapped-a.example.com',
|
|
68
|
+
);
|
|
69
|
+
expect(getExternalLinkUrl('https://b.example.com')).toBe(
|
|
70
|
+
'https://mapped-b.example.com',
|
|
71
|
+
);
|
|
72
|
+
expect(getExternalLinkUrl('https://c.example.com')).toBe(
|
|
73
|
+
'https://c.example.com',
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import {
|
|
2
|
+
configureI18n,
|
|
3
|
+
getCookies,
|
|
4
|
+
getLocale,
|
|
5
|
+
getMessages,
|
|
6
|
+
getPrimaryLanguageSubtag,
|
|
7
|
+
handleRtl,
|
|
8
|
+
isRtl,
|
|
9
|
+
mergeMessages,
|
|
10
|
+
} from './lib';
|
|
11
|
+
|
|
12
|
+
jest.mock('universal-cookie');
|
|
13
|
+
|
|
14
|
+
describe('lib', () => {
|
|
15
|
+
describe('getPrimaryLanguageSubtag', () => {
|
|
16
|
+
it('should work for primary language subtags', () => {
|
|
17
|
+
expect(getPrimaryLanguageSubtag('en')).toEqual('en');
|
|
18
|
+
expect(getPrimaryLanguageSubtag('ars')).toEqual('ars');
|
|
19
|
+
expect(getPrimaryLanguageSubtag('a')).toEqual('a');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should work for longer language codes', () => {
|
|
23
|
+
expect(getPrimaryLanguageSubtag('en-us')).toEqual('en');
|
|
24
|
+
expect(getPrimaryLanguageSubtag('es-419')).toEqual('es');
|
|
25
|
+
expect(getPrimaryLanguageSubtag('zh-hans-CN')).toEqual('zh');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('getLocale', () => {
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
configureI18n({
|
|
32
|
+
messages: {
|
|
33
|
+
'es-419': {},
|
|
34
|
+
de: {},
|
|
35
|
+
'en-us': {},
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should return a supported locale as supplied', () => {
|
|
41
|
+
expect(getLocale('es-419')).toEqual('es-419');
|
|
42
|
+
expect(getLocale('en-us')).toEqual('en-us');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return the supported primary language tag of a not-quite-supported locale', () => {
|
|
46
|
+
expect(getLocale('de-de')).toEqual('de');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should return en if the locale is not supported at all', () => {
|
|
50
|
+
expect(getLocale('oh-no')).toEqual('en');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should look up a locale in the language preference cookie if one was not supplied', () => {
|
|
54
|
+
getCookies().get = jest.fn(() => 'es-419');
|
|
55
|
+
expect(getLocale()).toEqual('es-419');
|
|
56
|
+
|
|
57
|
+
getCookies().get = jest.fn(() => 'pl');
|
|
58
|
+
expect(getLocale()).toEqual('en');
|
|
59
|
+
|
|
60
|
+
getCookies().get = jest.fn(() => 'de-bah');
|
|
61
|
+
expect(getLocale()).toEqual('de');
|
|
62
|
+
});
|
|
63
|
+
it('should fallback to the browser locale if the cookie does not exist', () => {
|
|
64
|
+
getCookies().get = jest.fn(() => null);
|
|
65
|
+
expect(getLocale()).toEqual(global.navigator.language.toLowerCase());
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('getMessages', () => {
|
|
70
|
+
beforeEach(() => {
|
|
71
|
+
configureI18n({
|
|
72
|
+
messages: {
|
|
73
|
+
'es-419': { message: 'es-hah' },
|
|
74
|
+
de: { message: 'de-hah' },
|
|
75
|
+
'en-us': { message: 'en-us-hah' },
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
getCookies().get = jest.fn(() => 'es-419'); // Means the cookie will be set to es-419
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should return the messages for the provided locale', () => {
|
|
83
|
+
expect(getMessages('en-us').message).toEqual('en-us-hah');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should return the messages for the preferred locale if no argument is passed', () => {
|
|
87
|
+
expect(getMessages().message).toEqual('es-hah');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('isRtl', () => {
|
|
92
|
+
it('should be true for RTL languages', () => {
|
|
93
|
+
expect(isRtl('ar')).toBe(true);
|
|
94
|
+
expect(isRtl('he')).toBe(true);
|
|
95
|
+
expect(isRtl('fa')).toBe(true);
|
|
96
|
+
expect(isRtl('fa-ir')).toBe(true);
|
|
97
|
+
expect(isRtl('ur')).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should be false for anything else', () => {
|
|
101
|
+
expect(isRtl('en')).toBe(false);
|
|
102
|
+
expect(isRtl('blah')).toBe(false);
|
|
103
|
+
expect(isRtl('es-419')).toBe(false);
|
|
104
|
+
expect(isRtl('de')).toBe(false);
|
|
105
|
+
expect(isRtl('ru')).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('handleRtl', () => {
|
|
110
|
+
let setAttribute;
|
|
111
|
+
beforeEach(() => {
|
|
112
|
+
setAttribute = jest.fn();
|
|
113
|
+
|
|
114
|
+
global.document.getElementsByTagName = jest.fn(() => [
|
|
115
|
+
{
|
|
116
|
+
setAttribute,
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should do the right thing for non-RTL languages', () => {
|
|
122
|
+
getCookies().get = jest.fn(() => 'es-419');
|
|
123
|
+
configureI18n({
|
|
124
|
+
messages: {
|
|
125
|
+
'es-419': { message: 'es-hah' },
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
handleRtl();
|
|
130
|
+
expect(setAttribute).toHaveBeenCalledWith('dir', 'ltr');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should do the right thing for RTL languages', () => {
|
|
134
|
+
getCookies().get = jest.fn(() => 'ar');
|
|
135
|
+
configureI18n({
|
|
136
|
+
messages: {
|
|
137
|
+
ar: { message: 'ar-hah' },
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
handleRtl();
|
|
142
|
+
expect(setAttribute).toHaveBeenCalledWith('dir', 'rtl');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('mergeMessages', () => {
|
|
148
|
+
it('should merge objects', () => {
|
|
149
|
+
configureI18n({
|
|
150
|
+
messages: {
|
|
151
|
+
ar: { message: 'ar-hah' },
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
const result = mergeMessages({ en: { foo: 'bar' }, de: { buh: 'baz' }, jp: { gah: 'wut' } });
|
|
155
|
+
expect(result).toEqual({
|
|
156
|
+
ar: { message: 'ar-hah' },
|
|
157
|
+
en: { foo: 'bar' },
|
|
158
|
+
de: { buh: 'baz' },
|
|
159
|
+
jp: { gah: 'wut' },
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('should merge objects from an array', () => {
|
|
164
|
+
configureI18n({
|
|
165
|
+
messages: {
|
|
166
|
+
ar: { message: 'ar-hah' },
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
const result = mergeMessages([{ foo: 'bar' }, { buh: 'baz' }, { gah: 'wut' }]);
|
|
170
|
+
expect(result).toEqual({
|
|
171
|
+
ar: { message: 'ar-hah' },
|
|
172
|
+
foo: 'bar',
|
|
173
|
+
buh: 'baz',
|
|
174
|
+
gah: 'wut',
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('should merge nested objects from an array', () => {
|
|
179
|
+
configureI18n({
|
|
180
|
+
messages: {
|
|
181
|
+
en: { init: 'initial' },
|
|
182
|
+
es: { init: 'inicial' },
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
const messages = [
|
|
186
|
+
{
|
|
187
|
+
en: { hello: 'hello' },
|
|
188
|
+
es: { hello: 'hola' },
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
en: { goodbye: 'goodbye' },
|
|
192
|
+
es: { goodbye: 'adiós' },
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
const result = mergeMessages(messages);
|
|
197
|
+
expect(result).toEqual({
|
|
198
|
+
en: {
|
|
199
|
+
init: 'initial',
|
|
200
|
+
hello: 'hello',
|
|
201
|
+
goodbye: 'goodbye',
|
|
202
|
+
},
|
|
203
|
+
es: {
|
|
204
|
+
init: 'inicial',
|
|
205
|
+
hello: 'hola',
|
|
206
|
+
goodbye: 'adiós',
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should return an empty object if no messages', () => {
|
|
212
|
+
configureI18n({
|
|
213
|
+
messages: {},
|
|
214
|
+
});
|
|
215
|
+
expect(mergeMessages(undefined)).toEqual({});
|
|
216
|
+
expect(mergeMessages(null)).toEqual({});
|
|
217
|
+
expect(mergeMessages([])).toEqual({});
|
|
218
|
+
expect(mergeMessages({})).toEqual({});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should return the original object if no messages', () => {
|
|
222
|
+
configureI18n({
|
|
223
|
+
messages: { en: { hello: 'world ' } },
|
|
224
|
+
});
|
|
225
|
+
expect(mergeMessages(undefined)).toEqual({ en: { hello: 'world ' } });
|
|
226
|
+
expect(mergeMessages(null)).toEqual({ en: { hello: 'world ' } });
|
|
227
|
+
expect(mergeMessages([])).toEqual({ en: { hello: 'world ' } });
|
|
228
|
+
expect(mergeMessages({})).toEqual({ en: { hello: 'world ' } });
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureAuthenticatedUser,
|
|
3
|
+
fetchAuthenticatedUser,
|
|
4
|
+
hydrateAuthenticatedUser,
|
|
5
|
+
} from './auth';
|
|
6
|
+
import { getSiteConfig } from './config';
|
|
7
|
+
import { initialize } from './initialize';
|
|
8
|
+
import {
|
|
9
|
+
logError,
|
|
10
|
+
} from './logging';
|
|
11
|
+
import { clearAllSubscriptions } from './subscriptions';
|
|
12
|
+
|
|
13
|
+
jest.mock('./logging');
|
|
14
|
+
jest.mock('./auth');
|
|
15
|
+
jest.mock('./analytics');
|
|
16
|
+
jest.mock('./i18n');
|
|
17
|
+
jest.mock('./auth/LocalForageCache');
|
|
18
|
+
jest.mock('site.config', () => async () => new Promise((resolve) => {
|
|
19
|
+
resolve({
|
|
20
|
+
JS_FILE_VAR: 'JS_FILE_VAR_VALUE_ASYNC_FUNCTION',
|
|
21
|
+
});
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
let config = null;
|
|
25
|
+
|
|
26
|
+
describe('initialize with async function js file config', () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
jest.resetModules();
|
|
29
|
+
config = getSiteConfig();
|
|
30
|
+
fetchAuthenticatedUser.mockReset();
|
|
31
|
+
ensureAuthenticatedUser.mockReset();
|
|
32
|
+
hydrateAuthenticatedUser.mockReset();
|
|
33
|
+
logError.mockReset();
|
|
34
|
+
clearAllSubscriptions();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should initialize the app with async function javascript file configuration', async () => {
|
|
38
|
+
const messages = { i_am: 'a message' };
|
|
39
|
+
await initialize({ messages });
|
|
40
|
+
|
|
41
|
+
expect(config.JS_FILE_VAR).toEqual('JS_FILE_VAR_VALUE_ASYNC_FUNCTION');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureAuthenticatedUser,
|
|
3
|
+
fetchAuthenticatedUser,
|
|
4
|
+
hydrateAuthenticatedUser,
|
|
5
|
+
} from './auth';
|
|
6
|
+
import { getSiteConfig } from './config';
|
|
7
|
+
import { initialize } from './initialize';
|
|
8
|
+
import {
|
|
9
|
+
logError,
|
|
10
|
+
} from './logging';
|
|
11
|
+
import { clearAllSubscriptions } from './subscriptions';
|
|
12
|
+
|
|
13
|
+
jest.mock('./logging');
|
|
14
|
+
jest.mock('./auth');
|
|
15
|
+
jest.mock('./analytics');
|
|
16
|
+
jest.mock('./i18n');
|
|
17
|
+
jest.mock('./auth/LocalForageCache');
|
|
18
|
+
jest.mock('site.config', () => ({
|
|
19
|
+
JS_FILE_VAR: 'JS_FILE_VAR_VALUE_CONSTANT',
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
let config = null;
|
|
23
|
+
|
|
24
|
+
describe('initialize with constant js file config', () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.resetModules();
|
|
27
|
+
config = getSiteConfig();
|
|
28
|
+
fetchAuthenticatedUser.mockReset();
|
|
29
|
+
ensureAuthenticatedUser.mockReset();
|
|
30
|
+
hydrateAuthenticatedUser.mockReset();
|
|
31
|
+
logError.mockReset();
|
|
32
|
+
clearAllSubscriptions();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should initialize the app with javascript file configuration', async () => {
|
|
36
|
+
const messages = { i_am: 'a message' };
|
|
37
|
+
await initialize({ messages });
|
|
38
|
+
|
|
39
|
+
expect(config.JS_FILE_VAR).toEqual('JS_FILE_VAR_VALUE_CONSTANT');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureAuthenticatedUser,
|
|
3
|
+
fetchAuthenticatedUser,
|
|
4
|
+
hydrateAuthenticatedUser,
|
|
5
|
+
} from './auth';
|
|
6
|
+
import { getSiteConfig } from './config';
|
|
7
|
+
import { initialize } from './initialize';
|
|
8
|
+
import {
|
|
9
|
+
logError,
|
|
10
|
+
} from './logging';
|
|
11
|
+
import { clearAllSubscriptions } from './subscriptions';
|
|
12
|
+
|
|
13
|
+
jest.mock('./logging');
|
|
14
|
+
jest.mock('./auth');
|
|
15
|
+
jest.mock('./analytics');
|
|
16
|
+
jest.mock('./i18n');
|
|
17
|
+
jest.mock('./auth/LocalForageCache');
|
|
18
|
+
jest.mock('site.config', () => () => ({
|
|
19
|
+
JS_FILE_VAR: 'JS_FILE_VAR_VALUE_FUNCTION',
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
let config = null;
|
|
23
|
+
|
|
24
|
+
describe('initialize with function js file config', () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.resetModules();
|
|
27
|
+
config = getSiteConfig();
|
|
28
|
+
fetchAuthenticatedUser.mockReset();
|
|
29
|
+
ensureAuthenticatedUser.mockReset();
|
|
30
|
+
hydrateAuthenticatedUser.mockReset();
|
|
31
|
+
logError.mockReset();
|
|
32
|
+
clearAllSubscriptions();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should initialize the app with javascript file configuration', async () => {
|
|
36
|
+
const messages = { i_am: 'a message' };
|
|
37
|
+
await initialize({ messages });
|
|
38
|
+
|
|
39
|
+
expect(config.JS_FILE_VAR).toEqual('JS_FILE_VAR_VALUE_FUNCTION');
|
|
40
|
+
});
|
|
41
|
+
});
|