@akemona-org/strapi-plugin-i18n 3.7.0

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.
Files changed (147) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +19 -0
  3. package/admin/src/assets/images/logo.svg +1 -0
  4. package/admin/src/components/CMEditViewCopyLocale/index.js +183 -0
  5. package/admin/src/components/CMEditViewCopyLocale/utils/cleanData.js +36 -0
  6. package/admin/src/components/CMEditViewCopyLocale/utils/generateOptions.js +22 -0
  7. package/admin/src/components/CMEditViewCopyLocale/utils/index.js +2 -0
  8. package/admin/src/components/CMEditViewCopyLocale/utils/removePasswordAndRelationsFieldFromData.js +54 -0
  9. package/admin/src/components/CMEditViewCopyLocale/utils/tests/cleanData.test.js +83 -0
  10. package/admin/src/components/CMEditViewCopyLocale/utils/tests/data.js +219 -0
  11. package/admin/src/components/CMEditViewCopyLocale/utils/tests/generateOptions.test.js +79 -0
  12. package/admin/src/components/CMEditViewCopyLocale/utils/tests/removePasswordAndRelationsFieldFromData.test.js +40 -0
  13. package/admin/src/components/CMEditViewInjectedComponents/index.js +58 -0
  14. package/admin/src/components/CMEditViewLocalePicker/Option.js +66 -0
  15. package/admin/src/components/CMEditViewLocalePicker/Wrapper.js +8 -0
  16. package/admin/src/components/CMEditViewLocalePicker/index.js +160 -0
  17. package/admin/src/components/CMEditViewLocalePicker/utils/addStatusColorToLocale.js +24 -0
  18. package/admin/src/components/CMEditViewLocalePicker/utils/createLocalesOption.js +20 -0
  19. package/admin/src/components/CMEditViewLocalePicker/utils/index.js +2 -0
  20. package/admin/src/components/CheckboxConfirmation/Wrapper.js +12 -0
  21. package/admin/src/components/CheckboxConfirmation/index.js +70 -0
  22. package/admin/src/components/DeleteModalAdditionalInfos/index.js +25 -0
  23. package/admin/src/components/LocaleList/index.js +101 -0
  24. package/admin/src/components/LocaleListCell/LocaleListCell.js +90 -0
  25. package/admin/src/components/LocaleListCell/tests/LocaleListCell.test.js +128 -0
  26. package/admin/src/components/LocalePicker/index.js +126 -0
  27. package/admin/src/components/LocaleRow/index.js +77 -0
  28. package/admin/src/components/ModalCreate/AdvancedForm.js +45 -0
  29. package/admin/src/components/ModalCreate/BaseForm.js +103 -0
  30. package/admin/src/components/ModalCreate/index.js +136 -0
  31. package/admin/src/components/ModalDelete/index.js +49 -0
  32. package/admin/src/components/ModalEdit/AdvancedForm.js +51 -0
  33. package/admin/src/components/ModalEdit/BaseForm.js +91 -0
  34. package/admin/src/components/ModalEdit/index.js +122 -0
  35. package/admin/src/components/SettingsModal.js +66 -0
  36. package/admin/src/components/index.js +2 -0
  37. package/admin/src/containers/Initializer.js +31 -0
  38. package/admin/src/containers/SettingsPage/LocaleSettingsPage.js +69 -0
  39. package/admin/src/containers/SettingsPage/index.js +33 -0
  40. package/admin/src/containers/SettingsPage/tests/SettingsPage.test.js +744 -0
  41. package/admin/src/containers/SettingsPage/tests/__snapshots__/SettingsPage.test.js.snap +241 -0
  42. package/admin/src/hooks/constants.js +6 -0
  43. package/admin/src/hooks/reducers.js +63 -0
  44. package/admin/src/hooks/tests/reducers.test.js +203 -0
  45. package/admin/src/hooks/useAddLocale/index.js +60 -0
  46. package/admin/src/hooks/useContentTypePermissions/index.js +16 -0
  47. package/admin/src/hooks/useDefaultLocales/index.js +27 -0
  48. package/admin/src/hooks/useDeleteLocale/index.js +45 -0
  49. package/admin/src/hooks/useEditLocale/index.js +46 -0
  50. package/admin/src/hooks/useHasI18n/index.js +13 -0
  51. package/admin/src/hooks/useLocales/index.js +35 -0
  52. package/admin/src/index.js +169 -0
  53. package/admin/src/middlewares/addCommonFieldsToInitialDataMiddleware.js +83 -0
  54. package/admin/src/middlewares/addLocaleColumnToListViewMiddleware.js +32 -0
  55. package/admin/src/middlewares/addLocaleToCollectionTypesMiddleware.js +25 -0
  56. package/admin/src/middlewares/addLocaleToSingleTypesMiddleware.js +25 -0
  57. package/admin/src/middlewares/extendCMEditViewLayoutMiddleware.js +159 -0
  58. package/admin/src/middlewares/extendCTBAttributeInitialDataMiddleware.js +58 -0
  59. package/admin/src/middlewares/extendCTBInitialDataMiddleware.js +33 -0
  60. package/admin/src/middlewares/index.js +21 -0
  61. package/admin/src/middlewares/localePermissionMiddleware.js +39 -0
  62. package/admin/src/middlewares/tests/addCommonFieldsToInitialDataMiddleware.test.js +97 -0
  63. package/admin/src/middlewares/tests/addLocaleColumnToListViewMiddleware.test.js +68 -0
  64. package/admin/src/middlewares/tests/addLocaleToCollectionTypesMiddleware.test.js +200 -0
  65. package/admin/src/middlewares/tests/addLocaleToSingleTypesMiddleware.test.js +193 -0
  66. package/admin/src/middlewares/tests/extendCMEditViewLayoutMiddleware.test.js +556 -0
  67. package/admin/src/middlewares/tests/extendCTBAttrributeInitialDataMiddleware.test.js +124 -0
  68. package/admin/src/middlewares/tests/extendCTBInitialDataMiddleware.test.js +92 -0
  69. package/admin/src/middlewares/tests/localePermissionMiddleware.test.js +150 -0
  70. package/admin/src/middlewares/utils/addLocaleToLinksSearch.js +56 -0
  71. package/admin/src/middlewares/utils/tests/addLocaleToLinksSearch.test.js +137 -0
  72. package/admin/src/permissions.js +9 -0
  73. package/admin/src/pluginId.js +5 -0
  74. package/admin/src/schemas.js +7 -0
  75. package/admin/src/selectors/selectCollectionTypesRelatedPermissions.js +4 -0
  76. package/admin/src/selectors/selectI18nLocales.js +3 -0
  77. package/admin/src/translations/en.json +60 -0
  78. package/admin/src/translations/fr.json +9 -0
  79. package/admin/src/translations/index.js +11 -0
  80. package/admin/src/translations/zh-Hans.json +60 -0
  81. package/admin/src/utils/getDefaultLocale.js +60 -0
  82. package/admin/src/utils/getInitialLocale.js +14 -0
  83. package/admin/src/utils/getLocaleFromQuery.js +7 -0
  84. package/admin/src/utils/getTrad.js +5 -0
  85. package/admin/src/utils/index.js +2 -0
  86. package/admin/src/utils/localizedFields.js +23 -0
  87. package/admin/src/utils/mutateCTBContentTypeSchema.js +66 -0
  88. package/admin/src/utils/tests/getDefaultLocale.test.js +337 -0
  89. package/admin/src/utils/tests/getInitialLocale.test.js +106 -0
  90. package/admin/src/utils/tests/mutateCTBContentTypeSchema.test.js +205 -0
  91. package/config/functions/bootstrap.js +57 -0
  92. package/config/functions/migrations/__tests__/content-type.test.js +255 -0
  93. package/config/functions/migrations/__tests__/field.test.js +150 -0
  94. package/config/functions/migrations/content-type/disable/index.js +34 -0
  95. package/config/functions/migrations/content-type/disable/migrate-for-bookshelf.js +58 -0
  96. package/config/functions/migrations/content-type/disable/migrate-for-mongoose.js +39 -0
  97. package/config/functions/migrations/content-type/enable/index.js +40 -0
  98. package/config/functions/migrations/content-type/utils/index.js +27 -0
  99. package/config/functions/migrations/field/__tests__/utils.test.js +53 -0
  100. package/config/functions/migrations/field/index.js +37 -0
  101. package/config/functions/migrations/field/migrate-for-bookshelf.js +72 -0
  102. package/config/functions/migrations/field/migrate-for-mongoose.js +24 -0
  103. package/config/functions/migrations/field/migrate.js +55 -0
  104. package/config/functions/migrations/field/utils.js +58 -0
  105. package/config/functions/register.js +46 -0
  106. package/config/policies/validateLocaleCreation.js +68 -0
  107. package/config/routes.json +64 -0
  108. package/constants/__tests__/index.test.js +27 -0
  109. package/constants/index.js +36 -0
  110. package/constants/iso-locales.json +2002 -0
  111. package/controllers/__tests__/content-types.test.js +113 -0
  112. package/controllers/__tests__/iso-locales.test.js +26 -0
  113. package/controllers/__tests__/locales.test.js +308 -0
  114. package/controllers/content-types.js +64 -0
  115. package/controllers/iso-locales.js +11 -0
  116. package/controllers/locales.js +104 -0
  117. package/domain/locale.js +10 -0
  118. package/middlewares/i18n/defaults.json +5 -0
  119. package/middlewares/i18n/index.js +28 -0
  120. package/models/Locale.settings.json +31 -0
  121. package/oas.yml +195 -0
  122. package/package.json +31 -0
  123. package/services/__tests__/__snapshots__/iso-locales.test.js.snap +2006 -0
  124. package/services/__tests__/content-types.test.js +545 -0
  125. package/services/__tests__/core-api.test.js +106 -0
  126. package/services/__tests__/entity-service-decorator.test.js +280 -0
  127. package/services/__tests__/iso-locales.test.js +11 -0
  128. package/services/__tests__/locales.test.js +237 -0
  129. package/services/__tests__/localizations.test.js +187 -0
  130. package/services/__tests__/metrics.test.js +90 -0
  131. package/services/content-types.js +200 -0
  132. package/services/core-api.js +296 -0
  133. package/services/entity-service-decorator.js +155 -0
  134. package/services/iso-locales.js +9 -0
  135. package/services/locales.js +97 -0
  136. package/services/localizations.js +65 -0
  137. package/services/metrics.js +24 -0
  138. package/services/permissions/actions.js +124 -0
  139. package/services/permissions/engine.js +63 -0
  140. package/services/permissions/sections-builder.js +48 -0
  141. package/services/permissions.js +11 -0
  142. package/tests/content-manager/list-relation.test.e2e.js +122 -0
  143. package/tests/graphql.test.e2e.js +120 -0
  144. package/tests/locales.test.e2e.js +414 -0
  145. package/utils/index.js +20 -0
  146. package/validation/content-types.js +30 -0
  147. package/validation/locales.js +39 -0
@@ -0,0 +1,60 @@
1
+ import get from 'lodash/get';
2
+
3
+ const hasLocalePermission = (permissions, localeCode) => {
4
+ if (permissions) {
5
+ const hasPermission = permissions.some(permission =>
6
+ get(permission, 'properties.locales', []).includes(localeCode)
7
+ );
8
+
9
+ if (hasPermission) {
10
+ return true;
11
+ }
12
+ }
13
+
14
+ return false;
15
+ };
16
+
17
+ const getFirstLocale = permissions => {
18
+ if (permissions && permissions.length > 0) {
19
+ const firstAuthorizedNonDefaultLocale = get(permissions, [0, 'properties', 'locales', 0], null);
20
+
21
+ if (firstAuthorizedNonDefaultLocale) {
22
+ return firstAuthorizedNonDefaultLocale;
23
+ }
24
+ }
25
+
26
+ return null;
27
+ };
28
+
29
+ /**
30
+ * Entry point of the module
31
+ */
32
+ const getDefaultLocale = (ctPermissions, locales = []) => {
33
+ const defaultLocale = locales.find(locale => locale.isDefault);
34
+
35
+ if (!defaultLocale) {
36
+ return null;
37
+ }
38
+
39
+ const readPermissions = ctPermissions['plugins::content-manager.explorer.read'];
40
+ const createPermissions = ctPermissions['plugins::content-manager.explorer.create'];
41
+
42
+ if (hasLocalePermission(readPermissions, defaultLocale.code)) {
43
+ return defaultLocale.code;
44
+ }
45
+
46
+ if (hasLocalePermission(createPermissions, defaultLocale.code)) {
47
+ return defaultLocale.code;
48
+ }
49
+
50
+ // When the default locale is not authorized, we return the first authorized locale
51
+ const firstAuthorizedForReadNonDefaultLocale = getFirstLocale(readPermissions);
52
+
53
+ if (firstAuthorizedForReadNonDefaultLocale) {
54
+ return firstAuthorizedForReadNonDefaultLocale;
55
+ }
56
+
57
+ return getFirstLocale(createPermissions);
58
+ };
59
+
60
+ export default getDefaultLocale;
@@ -0,0 +1,14 @@
1
+ import getLocaleFromQuery from './getLocaleFromQuery';
2
+
3
+ const getInitialLocale = (query, locales = []) => {
4
+ const localeFromQuery = getLocaleFromQuery(query);
5
+
6
+ if (localeFromQuery) {
7
+ return locales.find(locale => locale.code === localeFromQuery);
8
+ }
9
+
10
+ // Returns the default locale when nothing is in the query
11
+ return locales.find(locale => locale.isDefault);
12
+ };
13
+
14
+ export default getInitialLocale;
@@ -0,0 +1,7 @@
1
+ import get from 'lodash/get';
2
+
3
+ const getLocaleFromQuery = query => {
4
+ return get(query, 'plugins.i18n.locale', undefined);
5
+ };
6
+
7
+ export default getLocaleFromQuery;
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getTrad = id => `${pluginId}.${id}`;
4
+
5
+ export default getTrad;
@@ -0,0 +1,2 @@
1
+ // eslint-disable-next-line import/prefer-default-export
2
+ export { default as getTrad } from './getTrad';
@@ -0,0 +1,23 @@
1
+ const LOCALIZED_FIELDS = [
2
+ 'biginteger',
3
+ 'boolean',
4
+ 'component',
5
+ 'date',
6
+ 'datetime',
7
+ 'decimal',
8
+ 'dynamiczone',
9
+ 'email',
10
+ 'enumeration',
11
+ 'float',
12
+ 'integer',
13
+ 'json',
14
+ 'media',
15
+ 'number',
16
+ 'password',
17
+ 'richtext',
18
+ 'string',
19
+ 'text',
20
+ 'time',
21
+ ];
22
+
23
+ export default LOCALIZED_FIELDS;
@@ -0,0 +1,66 @@
1
+ import { has, get, omit } from 'lodash';
2
+ import LOCALIZED_FIELDS from './localizedFields';
3
+
4
+ const localizedPath = ['pluginOptions', 'i18n', 'localized'];
5
+
6
+ const addLocalisationToFields = attributes =>
7
+ Object.keys(attributes).reduce((acc, current) => {
8
+ const currentAttribute = attributes[current];
9
+
10
+ if (LOCALIZED_FIELDS.includes(currentAttribute.type)) {
11
+ const i18n = { localized: true };
12
+
13
+ const pluginOptions = currentAttribute.pluginOptions
14
+ ? { ...currentAttribute.pluginOptions, i18n }
15
+ : { i18n };
16
+
17
+ acc[current] = { ...currentAttribute, pluginOptions };
18
+
19
+ return acc;
20
+ }
21
+
22
+ acc[current] = currentAttribute;
23
+
24
+ return acc;
25
+ }, {});
26
+
27
+ const disableAttributesLocalisation = attributes =>
28
+ Object.keys(attributes).reduce((acc, current) => {
29
+ acc[current] = omit(attributes[current], 'pluginOptions.i18n');
30
+
31
+ return acc;
32
+ }, {});
33
+
34
+ const mutateCTBContentTypeSchema = (nextSchema, prevSchema) => {
35
+ // Don't perform mutations components
36
+ if (!has(nextSchema, localizedPath)) {
37
+ return nextSchema;
38
+ }
39
+
40
+ const isNextSchemaLocalized = get(nextSchema, localizedPath, false);
41
+ const isPrevSchemaLocalized = get(prevSchema, ['schema', ...localizedPath], false);
42
+
43
+ // No need to perform modification on the schema, if the i18n feature was not changed
44
+ // at the ct level
45
+ if (isNextSchemaLocalized && isPrevSchemaLocalized) {
46
+ return nextSchema;
47
+ }
48
+
49
+ if (isNextSchemaLocalized) {
50
+ const attributes = addLocalisationToFields(nextSchema.attributes);
51
+
52
+ return { ...nextSchema, attributes };
53
+ }
54
+
55
+ // Remove the i18n object from the pluginOptions
56
+ if (!isNextSchemaLocalized) {
57
+ const pluginOptions = omit(nextSchema.pluginOptions, 'i18n');
58
+ const attributes = disableAttributesLocalisation(nextSchema.attributes);
59
+
60
+ return { ...nextSchema, pluginOptions, attributes };
61
+ }
62
+
63
+ return nextSchema;
64
+ };
65
+ export default mutateCTBContentTypeSchema;
66
+ export { addLocalisationToFields, disableAttributesLocalisation };
@@ -0,0 +1,337 @@
1
+ import getDefaultLocale from '../getDefaultLocale';
2
+
3
+ describe('getDefaultLocale', () => {
4
+ it('gives fr-FR when it s the default locale and that it has read access to it', () => {
5
+ const locales = [
6
+ {
7
+ id: 1,
8
+ name: 'English',
9
+ code: 'en',
10
+ created_at: '2021-03-09T14:57:03.016Z',
11
+ updated_at: '2021-03-09T14:57:03.016Z',
12
+ isDefault: false,
13
+ },
14
+ {
15
+ id: 2,
16
+ name: 'French (France) (fr-FR)',
17
+ code: 'fr-FR',
18
+ created_at: '2021-03-09T15:03:06.992Z',
19
+ updated_at: '2021-03-17T13:01:03.569Z',
20
+ isDefault: true,
21
+ },
22
+ ];
23
+
24
+ const ctPermissions = {
25
+ 'plugins::content-manager.explorer.create': [
26
+ {
27
+ id: 1325,
28
+ action: 'plugins::content-manager.explorer.create',
29
+ subject: 'application::address.address',
30
+ properties: {
31
+ fields: [
32
+ 'postal_coder',
33
+ 'categories',
34
+ 'cover',
35
+ 'images',
36
+ 'city',
37
+ 'likes',
38
+ 'json',
39
+ 'slug',
40
+ ],
41
+ locales: [],
42
+ },
43
+ conditions: [],
44
+ },
45
+ ],
46
+ 'plugins::content-manager.explorer.read': [
47
+ {
48
+ id: 1326,
49
+ action: 'plugins::content-manager.explorer.read',
50
+ subject: 'application::address.address',
51
+ properties: {
52
+ fields: [],
53
+ locales: ['en', 'fr-FR'],
54
+ },
55
+ conditions: [],
56
+ },
57
+ ],
58
+ };
59
+
60
+ const expected = 'fr-FR';
61
+ const actual = getDefaultLocale(ctPermissions, locales);
62
+
63
+ expect(actual).toEqual(expected);
64
+ });
65
+
66
+ it('gives fr-FR when it s the default locale and that it has create access to it', () => {
67
+ const locales = [
68
+ {
69
+ id: 1,
70
+ name: 'English',
71
+ code: 'en',
72
+ created_at: '2021-03-09T14:57:03.016Z',
73
+ updated_at: '2021-03-09T14:57:03.016Z',
74
+ isDefault: false,
75
+ },
76
+ {
77
+ id: 2,
78
+ name: 'French (France) (fr-FR)',
79
+ code: 'fr-FR',
80
+ created_at: '2021-03-09T15:03:06.992Z',
81
+ updated_at: '2021-03-17T13:01:03.569Z',
82
+ isDefault: true,
83
+ },
84
+ ];
85
+
86
+ const ctPermissions = {
87
+ 'plugins::content-manager.explorer.create': [
88
+ {
89
+ id: 1325,
90
+ action: 'plugins::content-manager.explorer.create',
91
+ subject: 'application::address.address',
92
+ properties: {
93
+ fields: [
94
+ 'postal_coder',
95
+ 'categories',
96
+ 'cover',
97
+ 'images',
98
+ 'city',
99
+ 'likes',
100
+ 'json',
101
+ 'slug',
102
+ ],
103
+ locales: ['fr-FR'],
104
+ },
105
+ conditions: [],
106
+ },
107
+ ],
108
+ 'plugins::content-manager.explorer.read': [
109
+ {
110
+ id: 1326,
111
+ action: 'plugins::content-manager.explorer.read',
112
+ subject: 'application::address.address',
113
+ properties: {
114
+ fields: [],
115
+ locales: ['en'],
116
+ },
117
+ conditions: [],
118
+ },
119
+ ],
120
+ };
121
+
122
+ const expected = 'fr-FR';
123
+ const actual = getDefaultLocale(ctPermissions, locales);
124
+
125
+ expect(actual).toEqual(expected);
126
+ });
127
+
128
+ it('gives gives the first locale with read permission ("en") when the locale is allowed', () => {
129
+ const locales = [
130
+ {
131
+ id: 1,
132
+ name: 'English',
133
+ code: 'en',
134
+ created_at: '2021-03-09T14:57:03.016Z',
135
+ updated_at: '2021-03-09T14:57:03.016Z',
136
+ isDefault: false,
137
+ },
138
+ {
139
+ id: 2,
140
+ name: 'French (France) (fr-FR)',
141
+ code: 'fr-FR',
142
+ created_at: '2021-03-09T15:03:06.992Z',
143
+ updated_at: '2021-03-17T13:01:03.569Z',
144
+ isDefault: true,
145
+ },
146
+ {
147
+ id: 3,
148
+ name: 'Another lang',
149
+ code: 'de',
150
+ created_at: '2021-03-09T15:03:06.992Z',
151
+ updated_at: '2021-03-17T13:01:03.569Z',
152
+ isDefault: false,
153
+ },
154
+ ];
155
+
156
+ const ctPermissions = {
157
+ 'plugins::content-manager.explorer.create': [
158
+ {
159
+ id: 1325,
160
+ action: 'plugins::content-manager.explorer.create',
161
+ subject: 'application::address.address',
162
+ properties: {
163
+ fields: [
164
+ 'postal_coder',
165
+ 'categories',
166
+ 'cover',
167
+ 'images',
168
+ 'city',
169
+ 'likes',
170
+ 'json',
171
+ 'slug',
172
+ ],
173
+ locales: [],
174
+ },
175
+ conditions: [],
176
+ },
177
+ ],
178
+ 'plugins::content-manager.explorer.read': [
179
+ {
180
+ id: 1326,
181
+ action: 'plugins::content-manager.explorer.read',
182
+ subject: 'application::address.address',
183
+ properties: {
184
+ fields: [],
185
+ locales: ['en', 'de'],
186
+ },
187
+ conditions: [],
188
+ },
189
+ ],
190
+ };
191
+
192
+ const expected = 'en';
193
+ const actual = getDefaultLocale(ctPermissions, locales);
194
+
195
+ expect(actual).toEqual(expected);
196
+ });
197
+
198
+ it('gives gives the first locale with create permission ("en") when the locale is allowed', () => {
199
+ const locales = [
200
+ {
201
+ id: 1,
202
+ name: 'English',
203
+ code: 'en',
204
+ created_at: '2021-03-09T14:57:03.016Z',
205
+ updated_at: '2021-03-09T14:57:03.016Z',
206
+ isDefault: false,
207
+ },
208
+ {
209
+ id: 2,
210
+ name: 'French (France) (fr-FR)',
211
+ code: 'fr-FR',
212
+ created_at: '2021-03-09T15:03:06.992Z',
213
+ updated_at: '2021-03-17T13:01:03.569Z',
214
+ isDefault: true,
215
+ },
216
+ {
217
+ id: 3,
218
+ name: 'Another lang',
219
+ code: 'de',
220
+ created_at: '2021-03-09T15:03:06.992Z',
221
+ updated_at: '2021-03-17T13:01:03.569Z',
222
+ isDefault: false,
223
+ },
224
+ ];
225
+
226
+ const ctPermissions = {
227
+ 'plugins::content-manager.explorer.create': [
228
+ {
229
+ id: 1325,
230
+ action: 'plugins::content-manager.explorer.create',
231
+ subject: 'application::address.address',
232
+ properties: {
233
+ fields: [
234
+ 'postal_coder',
235
+ 'categories',
236
+ 'cover',
237
+ 'images',
238
+ 'city',
239
+ 'likes',
240
+ 'json',
241
+ 'slug',
242
+ ],
243
+ locales: ['en', 'de'],
244
+ },
245
+ conditions: [],
246
+ },
247
+ ],
248
+ 'plugins::content-manager.explorer.read': [
249
+ {
250
+ id: 1326,
251
+ action: 'plugins::content-manager.explorer.read',
252
+ subject: 'application::address.address',
253
+ properties: {
254
+ fields: [],
255
+ locales: [],
256
+ },
257
+ conditions: [],
258
+ },
259
+ ],
260
+ };
261
+
262
+ const expected = 'en';
263
+ const actual = getDefaultLocale(ctPermissions, locales);
264
+
265
+ expect(actual).toEqual(expected);
266
+ });
267
+
268
+ it('gives null when the user has no permission on any locale', () => {
269
+ const locales = [
270
+ {
271
+ id: 1,
272
+ name: 'English',
273
+ code: 'en',
274
+ created_at: '2021-03-09T14:57:03.016Z',
275
+ updated_at: '2021-03-09T14:57:03.016Z',
276
+ isDefault: false,
277
+ },
278
+ {
279
+ id: 2,
280
+ name: 'French (France) (fr-FR)',
281
+ code: 'fr-FR',
282
+ created_at: '2021-03-09T15:03:06.992Z',
283
+ updated_at: '2021-03-17T13:01:03.569Z',
284
+ isDefault: true,
285
+ },
286
+ {
287
+ id: 3,
288
+ name: 'Another lang',
289
+ code: 'de',
290
+ created_at: '2021-03-09T15:03:06.992Z',
291
+ updated_at: '2021-03-17T13:01:03.569Z',
292
+ isDefault: false,
293
+ },
294
+ ];
295
+
296
+ const ctPermissions = {
297
+ 'plugins::content-manager.explorer.create': [
298
+ {
299
+ id: 1325,
300
+ action: 'plugins::content-manager.explorer.create',
301
+ subject: 'application::address.address',
302
+ properties: {
303
+ fields: [
304
+ 'postal_coder',
305
+ 'categories',
306
+ 'cover',
307
+ 'images',
308
+ 'city',
309
+ 'likes',
310
+ 'json',
311
+ 'slug',
312
+ ],
313
+ locales: [],
314
+ },
315
+ conditions: [],
316
+ },
317
+ ],
318
+ 'plugins::content-manager.explorer.read': [
319
+ {
320
+ id: 1326,
321
+ action: 'plugins::content-manager.explorer.read',
322
+ subject: 'application::address.address',
323
+ properties: {
324
+ fields: [],
325
+ locales: [],
326
+ },
327
+ conditions: [],
328
+ },
329
+ ],
330
+ };
331
+
332
+ const expected = null;
333
+ const actual = getDefaultLocale(ctPermissions, locales);
334
+
335
+ expect(actual).toEqual(expected);
336
+ });
337
+ });
@@ -0,0 +1,106 @@
1
+ import getInitialLocale from '../getInitialLocale';
2
+
3
+ describe('getInitialLocale', () => {
4
+ it('gives "fr-FR" when the query.plugins.locale is "fr-FR"', () => {
5
+ const query = {
6
+ page: '1',
7
+ pageSize: '10',
8
+ _sort: 'Name:ASC',
9
+ plugins: {
10
+ i18n: { locale: 'fr-FR' },
11
+ },
12
+ };
13
+
14
+ const locales = [
15
+ {
16
+ id: 1,
17
+ name: 'English',
18
+ code: 'en',
19
+ created_at: '2021-03-09T14:57:03.016Z',
20
+ updated_at: '2021-03-09T14:57:03.016Z',
21
+ isDefault: true,
22
+ },
23
+ {
24
+ id: 2,
25
+ name: 'French (France) (fr-FR)',
26
+ code: 'fr-FR',
27
+ created_at: '2021-03-09T15:03:06.992Z',
28
+ updated_at: '2021-03-09T15:03:06.996Z',
29
+ isDefault: false,
30
+ },
31
+ ];
32
+
33
+ const expected = {
34
+ id: 2,
35
+ name: 'French (France) (fr-FR)',
36
+ code: 'fr-FR',
37
+ created_at: '2021-03-09T15:03:06.992Z',
38
+ updated_at: '2021-03-09T15:03:06.996Z',
39
+ isDefault: false,
40
+ };
41
+ const actual = getInitialLocale(query, locales);
42
+
43
+ expect(actual).toEqual(expected);
44
+ });
45
+
46
+ it('gives the default locale ("en") when there s no locale in the query', () => {
47
+ const query = {
48
+ page: '1',
49
+ pageSize: '10',
50
+ _sort: 'Name:ASC',
51
+ plugins: {
52
+ something: 'great',
53
+ },
54
+ };
55
+
56
+ const locales = [
57
+ {
58
+ id: 2,
59
+ name: 'French (France) (fr-FR)',
60
+ code: 'fr-FR',
61
+ created_at: '2021-03-09T15:03:06.992Z',
62
+ updated_at: '2021-03-09T15:03:06.996Z',
63
+ isDefault: false,
64
+ },
65
+ {
66
+ id: 1,
67
+ name: 'English',
68
+ code: 'en',
69
+ created_at: '2021-03-09T14:57:03.016Z',
70
+ updated_at: '2021-03-09T14:57:03.016Z',
71
+ isDefault: true,
72
+ },
73
+ ];
74
+
75
+ const expected = {
76
+ id: 1,
77
+ name: 'English',
78
+ code: 'en',
79
+ created_at: '2021-03-09T14:57:03.016Z',
80
+ updated_at: '2021-03-09T14:57:03.016Z',
81
+ isDefault: true,
82
+ };
83
+
84
+ const actual = getInitialLocale(query, locales);
85
+
86
+ expect(actual).toEqual(expected);
87
+ });
88
+
89
+ it('gives "undefined" when theres no locale. IMPORTANT: such case should not exist since at least one locale is created on the backend when plug-in i18n', () => {
90
+ const query = {
91
+ page: '1',
92
+ pageSize: '10',
93
+ _sort: 'Name:ASC',
94
+ plugins: {
95
+ something: 'great',
96
+ },
97
+ };
98
+
99
+ const locales = [];
100
+
101
+ const expected = undefined;
102
+ const actual = getInitialLocale(query, locales);
103
+
104
+ expect(actual).toEqual(expected);
105
+ });
106
+ });