@flusys/nestjs-localization 6.0.2 → 6.1.1
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/cjs/controllers/language.controller.spec.js +154 -0
- package/cjs/controllers/translation-key.controller.spec.js +70 -0
- package/cjs/controllers/translation.controller.spec.js +169 -0
- package/cjs/docs/localization-swagger.config.spec.js +30 -0
- package/cjs/entities/index.spec.js +18 -0
- package/cjs/modules/localization.module.spec.js +132 -0
- package/cjs/services/language.service.spec.js +151 -0
- package/cjs/services/localization-config.service.spec.js +80 -0
- package/cjs/services/localization-datasource.provider.spec.js +85 -0
- package/cjs/services/translation-key.service.spec.js +282 -0
- package/cjs/services/translation.service.spec.js +426 -0
- package/fesm/controllers/language.controller.spec.js +150 -0
- package/fesm/controllers/translation-key.controller.spec.js +66 -0
- package/fesm/controllers/translation.controller.spec.js +165 -0
- package/fesm/docs/localization-swagger.config.spec.js +26 -0
- package/fesm/entities/index.spec.js +14 -0
- package/fesm/modules/localization.module.spec.js +128 -0
- package/fesm/services/language.service.spec.js +147 -0
- package/fesm/services/localization-config.service.spec.js +76 -0
- package/fesm/services/localization-datasource.provider.spec.js +81 -0
- package/fesm/services/translation-key.service.spec.js +278 -0
- package/fesm/services/translation.service.spec.js +422 -0
- package/package.json +3 -3
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _testing = require("@nestjs/testing");
|
|
6
|
+
const _modules = require("@flusys/nestjs-shared/modules");
|
|
7
|
+
const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
|
|
8
|
+
const _languagecontroller = require("./language.controller");
|
|
9
|
+
const _services = require("../services");
|
|
10
|
+
function buildLanguage(overrides = {}) {
|
|
11
|
+
return {
|
|
12
|
+
id: 'lang-en',
|
|
13
|
+
code: 'en',
|
|
14
|
+
name: 'English',
|
|
15
|
+
nativeName: 'English',
|
|
16
|
+
direction: 'ltr',
|
|
17
|
+
isActive: true,
|
|
18
|
+
isDefault: false,
|
|
19
|
+
serial: 1,
|
|
20
|
+
isReadonly: false,
|
|
21
|
+
createdAt: new Date(),
|
|
22
|
+
updatedAt: new Date(),
|
|
23
|
+
deletedAt: null,
|
|
24
|
+
createdById: null,
|
|
25
|
+
updatedById: null,
|
|
26
|
+
deletedById: null,
|
|
27
|
+
...overrides
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
describe('LanguageController', ()=>{
|
|
31
|
+
let controller;
|
|
32
|
+
let mockService;
|
|
33
|
+
beforeEach(async ()=>{
|
|
34
|
+
mockService = {
|
|
35
|
+
insert: jest.fn(),
|
|
36
|
+
findById: jest.fn(),
|
|
37
|
+
getAll: jest.fn(),
|
|
38
|
+
update: jest.fn(),
|
|
39
|
+
delete: jest.fn(),
|
|
40
|
+
getActiveLanguages: jest.fn(),
|
|
41
|
+
getDefaultLanguage: jest.fn(),
|
|
42
|
+
setAsDefault: jest.fn()
|
|
43
|
+
};
|
|
44
|
+
const module = await _testing.Test.createTestingModule({
|
|
45
|
+
controllers: [
|
|
46
|
+
_languagecontroller.LanguageController
|
|
47
|
+
],
|
|
48
|
+
providers: [
|
|
49
|
+
{
|
|
50
|
+
provide: _services.LanguageService,
|
|
51
|
+
useValue: mockService
|
|
52
|
+
},
|
|
53
|
+
// The base ApiController wires the Slug interceptor (needs UtilsService) on several
|
|
54
|
+
// inherited endpoints, so it must be resolvable even though these tests only hit custom routes.
|
|
55
|
+
{
|
|
56
|
+
provide: _modules.UtilsService,
|
|
57
|
+
useValue: {}
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}).compile();
|
|
61
|
+
controller = module.get(_languagecontroller.LanguageController);
|
|
62
|
+
});
|
|
63
|
+
describe('getActive', ()=>{
|
|
64
|
+
it('returns all active languages with a full-length meta block', async ()=>{
|
|
65
|
+
const languages = [
|
|
66
|
+
buildLanguage({
|
|
67
|
+
code: 'en'
|
|
68
|
+
}),
|
|
69
|
+
buildLanguage({
|
|
70
|
+
id: 'lang-bn',
|
|
71
|
+
code: 'bn'
|
|
72
|
+
})
|
|
73
|
+
];
|
|
74
|
+
mockService.getActiveLanguages.mockResolvedValue(languages);
|
|
75
|
+
const result = await controller.getActive();
|
|
76
|
+
expect(result).toEqual({
|
|
77
|
+
success: true,
|
|
78
|
+
message: 'Active languages retrieved successfully',
|
|
79
|
+
messageKey: 'language.active.success',
|
|
80
|
+
data: languages,
|
|
81
|
+
meta: {
|
|
82
|
+
total: 2,
|
|
83
|
+
page: 0,
|
|
84
|
+
pageSize: 2,
|
|
85
|
+
count: 2
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
it('returns an empty list with zeroed meta when no languages are active', async ()=>{
|
|
90
|
+
mockService.getActiveLanguages.mockResolvedValue([]);
|
|
91
|
+
const result = await controller.getActive();
|
|
92
|
+
expect(result.data).toEqual([]);
|
|
93
|
+
expect(result.meta).toEqual({
|
|
94
|
+
total: 0,
|
|
95
|
+
page: 0,
|
|
96
|
+
pageSize: 0,
|
|
97
|
+
count: 0
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('getDefault', ()=>{
|
|
102
|
+
it('returns the default language', async ()=>{
|
|
103
|
+
const defaultLanguage = buildLanguage({
|
|
104
|
+
isDefault: true
|
|
105
|
+
});
|
|
106
|
+
mockService.getDefaultLanguage.mockResolvedValue(defaultLanguage);
|
|
107
|
+
const result = await controller.getDefault();
|
|
108
|
+
expect(result).toEqual({
|
|
109
|
+
success: true,
|
|
110
|
+
message: 'Default language retrieved successfully',
|
|
111
|
+
messageKey: 'language.get.default.success',
|
|
112
|
+
data: defaultLanguage
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
it('falls back to undefined data when no default language is configured', async ()=>{
|
|
116
|
+
mockService.getDefaultLanguage.mockResolvedValue(null);
|
|
117
|
+
const result = await controller.getDefault();
|
|
118
|
+
expect(result.data).toBeUndefined();
|
|
119
|
+
expect(result.success).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe('setDefault', ()=>{
|
|
123
|
+
it('sets the given language id as default and returns it', async ()=>{
|
|
124
|
+
const updated = buildLanguage({
|
|
125
|
+
id: 'lang-bn',
|
|
126
|
+
isDefault: true
|
|
127
|
+
});
|
|
128
|
+
mockService.setAsDefault.mockResolvedValue(updated);
|
|
129
|
+
const result = await controller.setDefault({
|
|
130
|
+
id: 'lang-bn'
|
|
131
|
+
}, (0, _loggedusermock.buildMockUser)());
|
|
132
|
+
expect(mockService.setAsDefault).toHaveBeenCalledWith('lang-bn');
|
|
133
|
+
expect(result).toEqual({
|
|
134
|
+
success: true,
|
|
135
|
+
message: 'Default language updated successfully',
|
|
136
|
+
messageKey: 'language.set.default.success',
|
|
137
|
+
data: updated
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
it('returns undefined data when the id does not match any language', async ()=>{
|
|
141
|
+
mockService.setAsDefault.mockResolvedValue(null);
|
|
142
|
+
const result = await controller.setDefault({
|
|
143
|
+
id: 'unknown-id'
|
|
144
|
+
}, (0, _loggedusermock.buildMockUser)());
|
|
145
|
+
expect(result.data).toBeUndefined();
|
|
146
|
+
});
|
|
147
|
+
it('propagates errors raised by the service unchanged', async ()=>{
|
|
148
|
+
mockService.setAsDefault.mockRejectedValue(new Error('database unavailable'));
|
|
149
|
+
await expect(controller.setDefault({
|
|
150
|
+
id: 'lang-en'
|
|
151
|
+
}, (0, _loggedusermock.buildMockUser)())).rejects.toThrow('database unavailable');
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _testing = require("@nestjs/testing");
|
|
6
|
+
const _modules = require("@flusys/nestjs-shared/modules");
|
|
7
|
+
const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
|
|
8
|
+
const _translationkeycontroller = require("./translation-key.controller");
|
|
9
|
+
const _services = require("../services");
|
|
10
|
+
describe('TranslationKeyController', ()=>{
|
|
11
|
+
let controller;
|
|
12
|
+
let mockService;
|
|
13
|
+
beforeEach(async ()=>{
|
|
14
|
+
mockService = {
|
|
15
|
+
insert: jest.fn(),
|
|
16
|
+
findById: jest.fn(),
|
|
17
|
+
getAll: jest.fn(),
|
|
18
|
+
update: jest.fn(),
|
|
19
|
+
delete: jest.fn(),
|
|
20
|
+
getModules: jest.fn(),
|
|
21
|
+
findByModule: jest.fn()
|
|
22
|
+
};
|
|
23
|
+
const module = await _testing.Test.createTestingModule({
|
|
24
|
+
controllers: [
|
|
25
|
+
_translationkeycontroller.TranslationKeyController
|
|
26
|
+
],
|
|
27
|
+
providers: [
|
|
28
|
+
{
|
|
29
|
+
provide: _services.TranslationKeyService,
|
|
30
|
+
useValue: mockService
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
provide: _modules.UtilsService,
|
|
34
|
+
useValue: {}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}).compile();
|
|
38
|
+
controller = module.get(_translationkeycontroller.TranslationKeyController);
|
|
39
|
+
});
|
|
40
|
+
describe('getModules', ()=>{
|
|
41
|
+
it('returns the distinct module names from the service', async ()=>{
|
|
42
|
+
mockService.getModules.mockResolvedValue([
|
|
43
|
+
'auth',
|
|
44
|
+
'shared',
|
|
45
|
+
'storage'
|
|
46
|
+
]);
|
|
47
|
+
const result = await controller.getModules((0, _loggedusermock.buildMockUser)());
|
|
48
|
+
expect(result).toEqual({
|
|
49
|
+
success: true,
|
|
50
|
+
message: 'Modules retrieved successfully',
|
|
51
|
+
messageKey: 'translation.key.modules.success',
|
|
52
|
+
data: [
|
|
53
|
+
'auth',
|
|
54
|
+
'shared',
|
|
55
|
+
'storage'
|
|
56
|
+
]
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
it('returns an empty array when no translation keys have been created yet', async ()=>{
|
|
60
|
+
mockService.getModules.mockResolvedValue([]);
|
|
61
|
+
const result = await controller.getModules((0, _loggedusermock.buildMockUser)());
|
|
62
|
+
expect(result.data).toEqual([]);
|
|
63
|
+
expect(result.success).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it('propagates unexpected errors from the service', async ()=>{
|
|
66
|
+
mockService.getModules.mockRejectedValue(new Error('query failed'));
|
|
67
|
+
await expect(controller.getModules((0, _loggedusermock.buildMockUser)())).rejects.toThrow('query failed');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _testing = require("@nestjs/testing");
|
|
6
|
+
const _modules = require("@flusys/nestjs-shared/modules");
|
|
7
|
+
const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
|
|
8
|
+
const _translationcontroller = require("./translation.controller");
|
|
9
|
+
const _services = require("../services");
|
|
10
|
+
function buildTranslation(overrides = {}) {
|
|
11
|
+
return {
|
|
12
|
+
id: 'translation-1',
|
|
13
|
+
languageId: 'lang-en',
|
|
14
|
+
translationKeyId: 'tkey-1',
|
|
15
|
+
value: 'Login successful',
|
|
16
|
+
isVerified: false,
|
|
17
|
+
isActive: true,
|
|
18
|
+
createdAt: new Date(),
|
|
19
|
+
updatedAt: new Date(),
|
|
20
|
+
deletedAt: null,
|
|
21
|
+
createdById: null,
|
|
22
|
+
updatedById: null,
|
|
23
|
+
deletedById: null,
|
|
24
|
+
...overrides
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
describe('TranslationController', ()=>{
|
|
28
|
+
let controller;
|
|
29
|
+
let mockService;
|
|
30
|
+
beforeEach(async ()=>{
|
|
31
|
+
mockService = {
|
|
32
|
+
insert: jest.fn(),
|
|
33
|
+
findById: jest.fn(),
|
|
34
|
+
getAll: jest.fn(),
|
|
35
|
+
update: jest.fn(),
|
|
36
|
+
delete: jest.fn(),
|
|
37
|
+
getByLanguageCode: jest.fn(),
|
|
38
|
+
bulkUpdate: jest.fn(),
|
|
39
|
+
getTranslationCounts: jest.fn()
|
|
40
|
+
};
|
|
41
|
+
const module = await _testing.Test.createTestingModule({
|
|
42
|
+
controllers: [
|
|
43
|
+
_translationcontroller.TranslationController
|
|
44
|
+
],
|
|
45
|
+
providers: [
|
|
46
|
+
{
|
|
47
|
+
provide: _services.TranslationService,
|
|
48
|
+
useValue: mockService
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
provide: _modules.UtilsService,
|
|
52
|
+
useValue: {}
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}).compile();
|
|
56
|
+
controller = module.get(_translationcontroller.TranslationController);
|
|
57
|
+
});
|
|
58
|
+
describe('getByLanguage', ()=>{
|
|
59
|
+
it('returns the translations map for the requested language and modules', async ()=>{
|
|
60
|
+
mockService.getByLanguageCode.mockResolvedValue({
|
|
61
|
+
'auth.login.success': 'Login successful'
|
|
62
|
+
});
|
|
63
|
+
const result = await controller.getByLanguage({
|
|
64
|
+
languageCode: 'en',
|
|
65
|
+
modules: [
|
|
66
|
+
'auth'
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
expect(mockService.getByLanguageCode).toHaveBeenCalledWith('en', [
|
|
70
|
+
'auth'
|
|
71
|
+
]);
|
|
72
|
+
expect(result).toEqual({
|
|
73
|
+
success: true,
|
|
74
|
+
message: 'Translations retrieved successfully',
|
|
75
|
+
messageKey: 'translation.by.language.success',
|
|
76
|
+
data: {
|
|
77
|
+
'auth.login.success': 'Login successful'
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
it('returns an empty map (fallback) for an unknown language code without throwing', async ()=>{
|
|
82
|
+
mockService.getByLanguageCode.mockResolvedValue({});
|
|
83
|
+
const result = await controller.getByLanguage({
|
|
84
|
+
languageCode: 'xx'
|
|
85
|
+
});
|
|
86
|
+
expect(result.success).toBe(true);
|
|
87
|
+
expect(result.data).toEqual({});
|
|
88
|
+
});
|
|
89
|
+
it('requests translations for all modules when modules is omitted', async ()=>{
|
|
90
|
+
mockService.getByLanguageCode.mockResolvedValue({});
|
|
91
|
+
await controller.getByLanguage({
|
|
92
|
+
languageCode: 'en'
|
|
93
|
+
});
|
|
94
|
+
expect(mockService.getByLanguageCode).toHaveBeenCalledWith('en', undefined);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('updateManyValues', ()=>{
|
|
98
|
+
it('bulk updates translations and reports the updated count', async ()=>{
|
|
99
|
+
const updated = [
|
|
100
|
+
buildTranslation(),
|
|
101
|
+
buildTranslation({
|
|
102
|
+
id: 'translation-2'
|
|
103
|
+
})
|
|
104
|
+
];
|
|
105
|
+
mockService.bulkUpdate.mockResolvedValue(updated);
|
|
106
|
+
const result = await controller.updateManyValues({
|
|
107
|
+
translations: [
|
|
108
|
+
{
|
|
109
|
+
languageId: 'lang-en',
|
|
110
|
+
translationKeyId: 'tkey-1',
|
|
111
|
+
value: 'Login successful'
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}, (0, _loggedusermock.buildMockUser)());
|
|
115
|
+
expect(result).toEqual({
|
|
116
|
+
success: true,
|
|
117
|
+
message: '2 translations updated',
|
|
118
|
+
messageKey: 'translation.update.many.success',
|
|
119
|
+
messageVariables: {
|
|
120
|
+
count: 2
|
|
121
|
+
},
|
|
122
|
+
data: updated,
|
|
123
|
+
meta: {
|
|
124
|
+
count: 2
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
it('reports zero updates for an empty batch without calling the service twice', async ()=>{
|
|
129
|
+
mockService.bulkUpdate.mockResolvedValue([]);
|
|
130
|
+
const result = await controller.updateManyValues({
|
|
131
|
+
translations: []
|
|
132
|
+
}, (0, _loggedusermock.buildMockUser)());
|
|
133
|
+
expect(mockService.bulkUpdate).toHaveBeenCalledTimes(1);
|
|
134
|
+
expect(result.meta).toEqual({
|
|
135
|
+
count: 0
|
|
136
|
+
});
|
|
137
|
+
expect(result.message).toBe('0 translations updated');
|
|
138
|
+
});
|
|
139
|
+
it('propagates errors raised during the bulk transaction (e.g. rollback surfaced as a rejection)', async ()=>{
|
|
140
|
+
mockService.bulkUpdate.mockRejectedValue(new Error('transaction rolled back'));
|
|
141
|
+
await expect(controller.updateManyValues({
|
|
142
|
+
translations: []
|
|
143
|
+
}, (0, _loggedusermock.buildMockUser)())).rejects.toThrow('transaction rolled back');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe('getCounts', ()=>{
|
|
147
|
+
it('returns translation counts keyed by translation key id', async ()=>{
|
|
148
|
+
mockService.getTranslationCounts.mockResolvedValue({
|
|
149
|
+
'tkey-1': 3,
|
|
150
|
+
'tkey-2': 1
|
|
151
|
+
});
|
|
152
|
+
const result = await controller.getCounts((0, _loggedusermock.buildMockUser)());
|
|
153
|
+
expect(result).toEqual({
|
|
154
|
+
success: true,
|
|
155
|
+
message: 'Translation counts retrieved successfully',
|
|
156
|
+
messageKey: 'translation.get.all.success',
|
|
157
|
+
data: {
|
|
158
|
+
'tkey-1': 3,
|
|
159
|
+
'tkey-2': 1
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
it('returns an empty object when there are no translations yet', async ()=>{
|
|
164
|
+
mockService.getTranslationCounts.mockResolvedValue({});
|
|
165
|
+
const result = await controller.getCounts((0, _loggedusermock.buildMockUser)());
|
|
166
|
+
expect(result.data).toEqual({});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _localizationswaggerconfig = require("./localization-swagger.config");
|
|
6
|
+
describe('localizationSwaggerConfig', ()=>{
|
|
7
|
+
it('should build a static config with no multi-tenant note by default', ()=>{
|
|
8
|
+
const config = (0, _localizationswaggerconfig.localizationSwaggerConfig)();
|
|
9
|
+
expect(config.title).toBe('Localization API');
|
|
10
|
+
expect(config.path).toBe('api/docs/localization');
|
|
11
|
+
expect(config.bearerAuth).toBe(true);
|
|
12
|
+
expect(config.description).not.toContain('Multi-Tenant Mode');
|
|
13
|
+
});
|
|
14
|
+
it('should include the multi-tenant note only for multi-tenant database mode', ()=>{
|
|
15
|
+
const multiTenant = (0, _localizationswaggerconfig.localizationSwaggerConfig)({
|
|
16
|
+
databaseMode: 'multi-tenant'
|
|
17
|
+
});
|
|
18
|
+
const single = (0, _localizationswaggerconfig.localizationSwaggerConfig)({
|
|
19
|
+
databaseMode: 'single'
|
|
20
|
+
});
|
|
21
|
+
expect(multiTenant.description).toContain('Multi-Tenant Mode');
|
|
22
|
+
expect(single.description).not.toContain('Multi-Tenant Mode');
|
|
23
|
+
});
|
|
24
|
+
it('should treat any non-"multi-tenant" value as single-database mode', ()=>{
|
|
25
|
+
const config = (0, _localizationswaggerconfig.localizationSwaggerConfig)({
|
|
26
|
+
databaseMode: 'unexpected-value'
|
|
27
|
+
});
|
|
28
|
+
expect(config.description).not.toContain('Multi-Tenant Mode');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _index = require("./index");
|
|
6
|
+
const _languageentity = require("./language.entity");
|
|
7
|
+
const _translationkeyentity = require("./translation-key.entity");
|
|
8
|
+
const _translationentity = require("./translation.entity");
|
|
9
|
+
describe('getLocalizationEntities', ()=>{
|
|
10
|
+
it('returns the fixed entity list (no company/core split for localization)', ()=>{
|
|
11
|
+
expect((0, _index.getLocalizationEntities)()).toBe(_index.LocalizationEntities);
|
|
12
|
+
expect((0, _index.getLocalizationEntities)()).toEqual([
|
|
13
|
+
_languageentity.Language,
|
|
14
|
+
_translationkeyentity.TranslationKey,
|
|
15
|
+
_translationentity.Translation
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _localizationmodule = require("./localization.module");
|
|
6
|
+
const _localizationconstants = require("../config/localization.constants");
|
|
7
|
+
const _controllers = require("../controllers");
|
|
8
|
+
function _define_property(obj, key, value) {
|
|
9
|
+
if (key in obj) {
|
|
10
|
+
Object.defineProperty(obj, key, {
|
|
11
|
+
value: value,
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true
|
|
15
|
+
});
|
|
16
|
+
} else {
|
|
17
|
+
obj[key] = value;
|
|
18
|
+
}
|
|
19
|
+
return obj;
|
|
20
|
+
}
|
|
21
|
+
function providerTokens(providers) {
|
|
22
|
+
return providers.map((p)=>typeof p === 'function' ? p : p.provide);
|
|
23
|
+
}
|
|
24
|
+
describe('LocalizationModule', ()=>{
|
|
25
|
+
describe('forRoot', ()=>{
|
|
26
|
+
it('should default to a non-global module with all controllers registered', ()=>{
|
|
27
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRoot({});
|
|
28
|
+
expect(dynamicModule.module).toBe(_localizationmodule.LocalizationModule);
|
|
29
|
+
expect(dynamicModule.global).toBe(false);
|
|
30
|
+
expect(dynamicModule.controllers).toEqual([
|
|
31
|
+
_controllers.LanguageController,
|
|
32
|
+
_controllers.TranslationKeyController,
|
|
33
|
+
_controllers.TranslationController
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
36
|
+
it('should respect global: true', ()=>{
|
|
37
|
+
expect(_localizationmodule.LocalizationModule.forRoot({
|
|
38
|
+
global: true
|
|
39
|
+
}).global).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
it('should register no controllers when includeController is false', ()=>{
|
|
42
|
+
expect(_localizationmodule.LocalizationModule.forRoot({
|
|
43
|
+
includeController: false
|
|
44
|
+
}).controllers).toEqual([]);
|
|
45
|
+
});
|
|
46
|
+
it('should register a LOCALIZATION_MODULE_OPTIONS provider carrying the given options', ()=>{
|
|
47
|
+
const options = {
|
|
48
|
+
bootstrapAppConfig: {}
|
|
49
|
+
};
|
|
50
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRoot(options);
|
|
51
|
+
const provider = dynamicModule.providers.find((p)=>p.provide === _localizationconstants.LOCALIZATION_MODULE_OPTIONS);
|
|
52
|
+
expect(provider.useValue).toBe(options);
|
|
53
|
+
});
|
|
54
|
+
it('should always export the same fixed set of services', ()=>{
|
|
55
|
+
expect(_localizationmodule.LocalizationModule.forRoot({}).exports).toHaveLength(5);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe('forRootAsync', ()=>{
|
|
59
|
+
it('should forward external imports alongside CacheModule/UtilsModule', ()=>{
|
|
60
|
+
let FakeImportedModule = class FakeImportedModule {
|
|
61
|
+
};
|
|
62
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRootAsync({
|
|
63
|
+
imports: [
|
|
64
|
+
FakeImportedModule
|
|
65
|
+
]
|
|
66
|
+
});
|
|
67
|
+
expect(dynamicModule.imports).toEqual(expect.arrayContaining([
|
|
68
|
+
FakeImportedModule
|
|
69
|
+
]));
|
|
70
|
+
});
|
|
71
|
+
it('useFactory: builds a LOCALIZATION_MODULE_OPTIONS provider merging resolved config', async ()=>{
|
|
72
|
+
const useFactory = jest.fn().mockResolvedValue({
|
|
73
|
+
foo: 'bar'
|
|
74
|
+
});
|
|
75
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRootAsync({
|
|
76
|
+
useFactory,
|
|
77
|
+
inject: [
|
|
78
|
+
'SOME_TOKEN'
|
|
79
|
+
]
|
|
80
|
+
});
|
|
81
|
+
const provider = dynamicModule.providers.find((p)=>p.provide === _localizationconstants.LOCALIZATION_MODULE_OPTIONS);
|
|
82
|
+
expect(provider.inject).toEqual([
|
|
83
|
+
'SOME_TOKEN'
|
|
84
|
+
]);
|
|
85
|
+
const resolved = await provider.useFactory('injected');
|
|
86
|
+
expect(useFactory).toHaveBeenCalledWith('injected');
|
|
87
|
+
expect(resolved.config).toEqual({
|
|
88
|
+
foo: 'bar'
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it('useClass: registers both the class provider and an options provider calling createLocalizationOptions()', async ()=>{
|
|
92
|
+
let MyOptionsFactory = class MyOptionsFactory {
|
|
93
|
+
constructor(){
|
|
94
|
+
_define_property(this, "createLocalizationOptions", jest.fn().mockResolvedValue({
|
|
95
|
+
foo: 'from-class'
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRootAsync({
|
|
100
|
+
useClass: MyOptionsFactory
|
|
101
|
+
});
|
|
102
|
+
const classProvider = dynamicModule.providers.find((p)=>p.provide === MyOptionsFactory);
|
|
103
|
+
expect(classProvider.useClass).toBe(MyOptionsFactory);
|
|
104
|
+
const optionsProvider = dynamicModule.providers.find((p)=>p.provide === _localizationconstants.LOCALIZATION_MODULE_OPTIONS);
|
|
105
|
+
const instance = new MyOptionsFactory();
|
|
106
|
+
const resolved = await optionsProvider.useFactory(instance);
|
|
107
|
+
expect(instance.createLocalizationOptions).toHaveBeenCalled();
|
|
108
|
+
expect(resolved.config).toEqual({
|
|
109
|
+
foo: 'from-class'
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
it('useExisting: registers a single options provider without a duplicate class registration', ()=>{
|
|
113
|
+
let MyOptionsFactory = class MyOptionsFactory {
|
|
114
|
+
constructor(){
|
|
115
|
+
_define_property(this, "createLocalizationOptions", jest.fn());
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRootAsync({
|
|
119
|
+
useExisting: MyOptionsFactory
|
|
120
|
+
});
|
|
121
|
+
expect(dynamicModule.providers.filter((p)=>p.provide === MyOptionsFactory)).toHaveLength(0);
|
|
122
|
+
const optionsProvider = dynamicModule.providers.find((p)=>p.provide === _localizationconstants.LOCALIZATION_MODULE_OPTIONS);
|
|
123
|
+
expect(optionsProvider.inject).toEqual([
|
|
124
|
+
MyOptionsFactory
|
|
125
|
+
]);
|
|
126
|
+
});
|
|
127
|
+
it('should register no LOCALIZATION_MODULE_OPTIONS provider when neither useFactory, useClass, nor useExisting is given', ()=>{
|
|
128
|
+
const dynamicModule = _localizationmodule.LocalizationModule.forRootAsync({});
|
|
129
|
+
expect(providerTokens(dynamicModule.providers)).not.toContain(_localizationconstants.LOCALIZATION_MODULE_OPTIONS);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|