AAE-40093 Support defining translations from code (#11442)

This commit is contained in:
Denys Vuika
2025-12-10 15:48:28 +00:00
committed by GitHub
parent 68ab5b1c16
commit 7eb2034008
2 changed files with 238 additions and 3 deletions
@@ -0,0 +1,217 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TestBed } from '@angular/core/testing';
import { ApplicationInitStatus } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { provideI18N } from './provide-i18n';
import { TranslateLoaderService } from './translate-loader.service';
import { TranslationService } from './translation.service';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { provideAppConfigTesting } from '../testing';
describe('provideI18N', () => {
describe('basic configuration', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [provideHttpClient(), provideHttpClientTesting(), provideAppConfigTesting(), provideI18N()]
});
});
it('should provide TranslateService', () => {
const translateService = TestBed.inject(TranslateService);
expect(translateService).toBeDefined();
});
it('should set default language to "en" when not specified', () => {
const translateService = TestBed.inject(TranslateService);
expect(translateService.defaultLang).toBe('en');
});
});
describe('with custom default language', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [provideHttpClient(), provideHttpClientTesting(), provideAppConfigTesting(), provideI18N({ defaultLanguage: 'fr' })]
});
});
it('should set custom default language', () => {
const translateService = TestBed.inject(TranslateService);
expect(translateService.defaultLang).toBe('fr');
});
});
describe('with assets configuration', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideAppConfigTesting(),
provideI18N({
assets: [
['my-app', 'assets/my-app'],
['custom-lib', 'assets/custom-lib']
]
})
]
});
});
it('should provide translation services with assets configuration', () => {
const translateService = TestBed.inject(TranslateService);
const translationService = TestBed.inject(TranslationService);
// Services should be properly configured
expect(translateService).toBeDefined();
expect(translationService).toBeDefined();
expect(translateService.defaultLang).toBe('en');
});
});
describe('with translations configuration', () => {
const mockTranslations = {
WELCOME_MESSAGE: 'Welcome!',
GOODBYE_MESSAGE: 'Goodbye!',
'NESTED.KEY': 'Nested value'
};
beforeEach(async () => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideAppConfigTesting(),
provideI18N({
translations: mockTranslations
})
]
});
// Wait for APP_INITIALIZER to complete
await TestBed.inject(ApplicationInitStatus).donePromise;
});
it('should set translations for default language', () => {
const translateService = TestBed.inject(TranslateService);
expect(translateService.instant('WELCOME_MESSAGE')).toBe('Welcome!');
expect(translateService.instant('GOODBYE_MESSAGE')).toBe('Goodbye!');
expect(translateService.instant('NESTED.KEY')).toBe('Nested value');
});
it('should merge translations with existing translations', async () => {
const translateService = TestBed.inject(TranslateService);
// Set some initial translations
translateService.setTranslation('en', { EXISTING_KEY: 'Existing value' });
// Set translations again to simulate the APP_INITIALIZER behavior
translateService.setTranslation('en', mockTranslations, true);
// The translations from config should be merged (merge flag is true)
expect(translateService.instant('WELCOME_MESSAGE')).toBe('Welcome!');
expect(translateService.instant('EXISTING_KEY')).toBe('Existing value');
});
});
describe('with translations and custom language', () => {
const mockTranslations = {
HELLO: 'Bonjour!'
};
beforeEach(async () => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideAppConfigTesting(),
provideI18N({
defaultLanguage: 'fr',
translations: mockTranslations
})
]
});
await TestBed.inject(ApplicationInitStatus).donePromise;
});
it('should set translations for custom default language', () => {
const translateService = TestBed.inject(TranslateService);
expect(translateService.defaultLang).toBe('fr');
expect(translateService.instant('HELLO')).toBe('Bonjour!');
});
});
describe('with combined configuration', () => {
const mockTranslations = {
'APP.TITLE': 'My Application'
};
beforeEach(async () => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideAppConfigTesting(),
provideI18N({
defaultLanguage: 'en',
assets: [['adf-core', 'assets/adf-core']],
translations: mockTranslations
})
]
});
await TestBed.inject(ApplicationInitStatus).donePromise;
});
it('should handle both assets and translations', () => {
const translateService = TestBed.inject(TranslateService);
const loader = translateService.currentLoader as TranslateLoaderService;
expect(translateService.defaultLang).toBe('en');
expect(loader).toBeDefined();
expect(loader.providerRegistered).toBeDefined();
expect(loader.providerRegistered('adf-core')).toBeTruthy();
expect(translateService.instant('APP.TITLE')).toBe('My Application');
});
});
describe('with empty translations', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideAppConfigTesting(),
provideI18N({
translations: {}
})
]
});
await TestBed.inject(ApplicationInitStatus).donePromise;
});
it('should handle empty translations object', () => {
const translateService = TestBed.inject(TranslateService);
expect(translateService).toBeDefined();
expect(translateService.defaultLang).toBe('en');
});
});
});
+21 -3
View File
@@ -15,8 +15,8 @@
* limitations under the License.
*/
import { EnvironmentProviders, Provider } from '@angular/core';
import { provideTranslateService, TranslateLoader } from '@ngx-translate/core';
import { EnvironmentProviders, inject, provideAppInitializer, Provider } from '@angular/core';
import { provideTranslateService, TranslateLoader, TranslateService } from '@ngx-translate/core';
import { TranslateLoaderService } from './translate-loader.service';
import { HttpClient } from '@angular/common/http';
import { provideTranslations } from './translation.service';
@@ -32,6 +32,12 @@ export interface ProvideI18NConfig {
* Example: [['adf-core', 'assets/adf-core'], ['my-translations', 'assets/my-translations']]
*/
assets?: [string, string][];
/**
* An object of translations to be used for i18n for the default language.
* Example: { 'WELCOME_MESSAGE': 'Welcome!' }
*/
translations?: Record<string, string>;
}
/**
@@ -44,6 +50,8 @@ export interface ProvideI18NConfig {
* @returns An array of providers for the i18n service.
*/
export function provideI18N(config?: ProvideI18NConfig): (Provider | EnvironmentProviders)[] {
const defaultLanguage = config?.defaultLanguage || 'en';
const result: (Provider | EnvironmentProviders)[] = [
provideTranslateService({
loader: {
@@ -51,7 +59,7 @@ export function provideI18N(config?: ProvideI18NConfig): (Provider | Environment
useExisting: TranslateLoaderService,
deps: [HttpClient]
},
defaultLanguage: config?.defaultLanguage || 'en'
defaultLanguage
})
];
@@ -61,5 +69,15 @@ export function provideI18N(config?: ProvideI18NConfig): (Provider | Environment
});
}
if (config?.translations) {
result.push(
provideAppInitializer(() => {
const translateService = inject(TranslateService);
translateService.setTranslation(defaultLanguage, config.translations, true);
return Promise.resolve();
})
);
}
return result;
}