mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ADF-3784] support for browser cultures (i18n) (#4066)
* support language cultures * update docs * fix typo * fix tests * correctly replace fallback translations * login dialog fixes * fix error component * [denys-i18n-cultures] Fix error content unit tests
This commit is contained in:
parent
d6df5bc862
commit
b5f9036545
@ -249,6 +249,9 @@ The table below illustrates how the selection is made:
|
|||||||
| X | fr | jp | en | fr |
|
| X | fr | jp | en | fr |
|
||||||
| it | fr | jp | en | it |
|
| it | fr | jp | en | it |
|
||||||
|
|
||||||
|
The translation service probes the browser culture first, for example `en-GB`.
|
||||||
|
If the `en-GB.json` file does not exist, the service falls back to the language id: `en`.
|
||||||
|
|
||||||
Once the locale language is determined, it is saved to the user preferences and this saved value
|
Once the locale language is determined, it is saved to the user preferences and this saved value
|
||||||
will be used from that point on, regardless of the `app.config.json` and browser settings.
|
will be used from that point on, regardless of the `app.config.json` and browser settings.
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
tabindex="1">
|
tabindex="1">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<span class="adf-login-validation" for="username" *ngIf="formError.username">
|
<span class="adf-login-validation" for="username" *ngIf="formError['username']">
|
||||||
<span id="username-error" class="adf-login-error" data-automation-id="username-error">{{formError.username | translate }}</span>
|
<span id="username-error" class="adf-login-error" data-automation-id="username-error">{{formError['username'] | translate }}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -55,7 +55,7 @@
|
|||||||
<div class="adf-login__field">
|
<div class="adf-login__field">
|
||||||
<mat-form-field class="adf-full-width" floatPlaceholder="never" color="primary">
|
<mat-form-field class="adf-full-width" floatPlaceholder="never" color="primary">
|
||||||
<input matInput placeholder="{{'LOGIN.LABEL.PASSWORD' | translate }}"
|
<input matInput placeholder="{{'LOGIN.LABEL.PASSWORD' | translate }}"
|
||||||
type="password"
|
[type]="isPasswordShow ? 'text' : 'password'"
|
||||||
[formControl]="form.controls['password']"
|
[formControl]="form.controls['password']"
|
||||||
id="password"
|
id="password"
|
||||||
data-automation-id="password"
|
data-automation-id="password"
|
||||||
@ -69,9 +69,9 @@
|
|||||||
visibility_off
|
visibility_off
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<span class="adf-login-validation" for="password" *ngIf="formError.password">
|
<span class="adf-login-validation" for="password" *ngIf="formError['password']">
|
||||||
<span id="password-required" class="adf-login-error"
|
<span id="password-required" class="adf-login-error"
|
||||||
data-automation-id="password-required">{{formError.password | translate }}</span>
|
data-automation-id="password-required">{{formError['password'] | translate }}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, ElementRef, EventEmitter,
|
import { Component, EventEmitter,
|
||||||
Input, OnInit, Output, TemplateRef, ViewEncapsulation
|
Input, OnInit, Output, TemplateRef, ViewEncapsulation
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
@ -42,6 +42,11 @@ enum LoginSteps {
|
|||||||
Welcome = 2
|
Welcome = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ValidationMessage {
|
||||||
|
value: string;
|
||||||
|
params?: any;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-login',
|
selector: 'adf-login',
|
||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
@ -134,7 +139,7 @@ export class LoginComponent implements OnInit {
|
|||||||
headerTemplate: TemplateRef<any>;
|
headerTemplate: TemplateRef<any>;
|
||||||
data: any;
|
data: any;
|
||||||
|
|
||||||
private _message: { [id: string]: { [id: string]: string } };
|
private _message: { [id: string]: { [id: string]: ValidationMessage } };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -147,7 +152,6 @@ export class LoginComponent implements OnInit {
|
|||||||
private authService: AuthenticationService,
|
private authService: AuthenticationService,
|
||||||
private translateService: TranslationService,
|
private translateService: TranslationService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private elementRef: ElementRef,
|
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private appConfig: AppConfigService,
|
private appConfig: AppConfigService,
|
||||||
private userPreferences: UserPreferencesService,
|
private userPreferences: UserPreferencesService,
|
||||||
@ -220,8 +224,11 @@ export class LoginComponent implements OnInit {
|
|||||||
if (hasError) {
|
if (hasError) {
|
||||||
for (let key in this.form.controls[field].errors) {
|
for (let key in this.form.controls[field].errors) {
|
||||||
if (key) {
|
if (key) {
|
||||||
this.formError[field] +=
|
const message = this._message[field][key];
|
||||||
this._message[field][key] + '';
|
if (message && message.value) {
|
||||||
|
const translated = this.translateService.instant(message.value, message.params);
|
||||||
|
this.formError[field] += translated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,7 +263,7 @@ export class LoginComponent implements OnInit {
|
|||||||
(err: any) => {
|
(err: any) => {
|
||||||
this.actualLoginStep = LoginSteps.Landing;
|
this.actualLoginStep = LoginSteps.Landing;
|
||||||
this.displayErrorMessage(err);
|
this.displayErrorMessage(err);
|
||||||
this.enableError();
|
this.isError = true;
|
||||||
this.error.emit(new LoginErrorEvent(err));
|
this.error.emit(new LoginErrorEvent(err));
|
||||||
},
|
},
|
||||||
() => this.logService.info('Login done')
|
() => this.logService.info('Login done')
|
||||||
@ -310,13 +317,10 @@ export class LoginComponent implements OnInit {
|
|||||||
msg: string,
|
msg: string,
|
||||||
params?: any
|
params?: any
|
||||||
) {
|
) {
|
||||||
if (params) {
|
this._message[field][ruleId] = {
|
||||||
this.translateService.get(msg, params).subscribe((res: string) => {
|
value: msg,
|
||||||
this._message[field][ruleId] = res;
|
params
|
||||||
});
|
};
|
||||||
} else {
|
|
||||||
this._message[field][ruleId] = msg;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,10 +328,6 @@ export class LoginComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
toggleShowPassword() {
|
toggleShowPassword() {
|
||||||
this.isPasswordShow = !this.isPasswordShow;
|
this.isPasswordShow = !this.isPasswordShow;
|
||||||
this.elementRef.nativeElement.querySelector('#password').type = this
|
|
||||||
.isPasswordShow
|
|
||||||
? 'text'
|
|
||||||
: 'password';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -371,18 +371,25 @@ export class LoginComponent implements OnInit {
|
|||||||
private initFormFieldsMessagesDefault() {
|
private initFormFieldsMessagesDefault() {
|
||||||
this._message = {
|
this._message = {
|
||||||
username: {
|
username: {
|
||||||
required: 'LOGIN.MESSAGES.USERNAME-REQUIRED'
|
required: {
|
||||||
|
value: 'LOGIN.MESSAGES.USERNAME-REQUIRED'
|
||||||
|
},
|
||||||
|
minLength: {
|
||||||
|
value: 'LOGIN.MESSAGES.USERNAME-MIN',
|
||||||
|
params: {
|
||||||
|
get minLength() {
|
||||||
|
return this.minLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
required: 'LOGIN.MESSAGES.PASSWORD-REQUIRED'
|
required: {
|
||||||
|
value: 'LOGIN.MESSAGES.PASSWORD-REQUIRED'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.translateService
|
|
||||||
.get('LOGIN.MESSAGES.USERNAME-MIN', { minLength: this.minLength })
|
|
||||||
.subscribe((res: string) => {
|
|
||||||
this._message['username']['minlength'] = res;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initFormFieldsDefault() {
|
private initFormFieldsDefault() {
|
||||||
@ -400,13 +407,6 @@ export class LoginComponent implements OnInit {
|
|||||||
this.initFormError();
|
this.initFormError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable the error flag
|
|
||||||
*/
|
|
||||||
private enableError() {
|
|
||||||
this.isError = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private hasCustomFieldsValidation(): boolean {
|
private hasCustomFieldsValidation(): boolean {
|
||||||
return this.fieldsValidation !== undefined;
|
return this.fieldsValidation !== undefined;
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,15 @@ export class TranslateLoaderService implements TranslateLoader {
|
|||||||
private suffix: string = '.json';
|
private suffix: string = '.json';
|
||||||
private providers: ComponentTranslationModel[] = [];
|
private providers: ComponentTranslationModel[] = [];
|
||||||
private queue: string [][] = [];
|
private queue: string [][] = [];
|
||||||
|
private defaultLang: string = 'en';
|
||||||
|
|
||||||
constructor(private http: HttpClient) {
|
constructor(private http: HttpClient) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDefaultLang(value: string) {
|
||||||
|
this.defaultLang = value || 'en';
|
||||||
|
}
|
||||||
|
|
||||||
registerProvider(name: string, path: string) {
|
registerProvider(name: string, path: string) {
|
||||||
let registered = this.providers.find((provider) => provider.name === name);
|
let registered = this.providers.find((provider) => provider.name === name);
|
||||||
if (registered) {
|
if (registered) {
|
||||||
@ -50,6 +55,29 @@ export class TranslateLoaderService implements TranslateLoader {
|
|||||||
return this.providers.find((x) => x.name === name) ? true : false;
|
return this.providers.find((x) => x.name === name) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchLanguageFile(lang: string, component: ComponentTranslationModel, fallbackUrl?: string): Observable<void> {
|
||||||
|
const translationUrl = fallbackUrl || `${component.path}/${this.prefix}/${lang}${this.suffix}?v=${Date.now()}`;
|
||||||
|
|
||||||
|
return this.http.get(translationUrl).pipe(
|
||||||
|
map((res: Response) => {
|
||||||
|
component.json[lang] = res;
|
||||||
|
}),
|
||||||
|
retry(3),
|
||||||
|
catchError(() => {
|
||||||
|
if (!fallbackUrl && lang.includes('-')) {
|
||||||
|
const [langId] = lang.split('-');
|
||||||
|
|
||||||
|
if (langId && langId !== this.defaultLang) {
|
||||||
|
const url = `${component.path}/${this.prefix}/${langId}${this.suffix}?v=${Date.now()}`;
|
||||||
|
|
||||||
|
return this.fetchLanguageFile(lang, component, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return throwError(`Failed to load ${translationUrl}`);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
getComponentToFetch(lang: string): Array<Observable<any>> {
|
getComponentToFetch(lang: string): Array<Observable<any>> {
|
||||||
const observableBatch = [];
|
const observableBatch = [];
|
||||||
if (!this.queue[lang]) {
|
if (!this.queue[lang]) {
|
||||||
@ -59,16 +87,8 @@ export class TranslateLoaderService implements TranslateLoader {
|
|||||||
if (!this.isComponentInQueue(lang, component.name)) {
|
if (!this.isComponentInQueue(lang, component.name)) {
|
||||||
this.queue[lang].push(component.name);
|
this.queue[lang].push(component.name);
|
||||||
|
|
||||||
const translationUrl = `${component.path}/${this.prefix}/${lang}${this.suffix}?v=${Date.now()}`;
|
|
||||||
|
|
||||||
observableBatch.push(
|
observableBatch.push(
|
||||||
this.http.get(translationUrl).pipe(
|
this.fetchLanguageFile(lang, component)
|
||||||
map((res: Response) => {
|
|
||||||
component.json[lang] = res;
|
|
||||||
}),
|
|
||||||
retry(3),
|
|
||||||
catchError(() => throwError(`Failed to load ${translationUrl}`))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -43,6 +43,7 @@ export class TranslationService {
|
|||||||
|
|
||||||
this.defaultLang = 'en';
|
this.defaultLang = 'en';
|
||||||
translate.setDefaultLang(this.defaultLang);
|
translate.setDefaultLang(this.defaultLang);
|
||||||
|
this.customLoader.setDefaultLang(this.defaultLang);
|
||||||
|
|
||||||
if (providers && providers.length > 0) {
|
if (providers && providers.length > 0) {
|
||||||
for (let provider of providers) {
|
for (let provider of providers) {
|
||||||
|
@ -117,24 +117,24 @@ describe('UserPreferencesService', () => {
|
|||||||
|
|
||||||
it('should return as default locale the app.config locate as first', () => {
|
it('should return as default locale the app.config locate as first', () => {
|
||||||
appConfig.config.locale = 'fake-locate-config';
|
appConfig.config.locale = 'fake-locate-config';
|
||||||
spyOn(translate, 'getBrowserLang').and.returnValue('fake-locate-browser');
|
spyOn(translate, 'getBrowserCultureLang').and.returnValue('fake-locate-browser');
|
||||||
expect(preferences.getDefaultLocale()).toBe('fake-locate-config');
|
expect(preferences.getDefaultLocale()).toBe('fake-locate-config');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return as default locale the browser locale as second', () => {
|
it('should return as default locale the browser locale as second', () => {
|
||||||
spyOn(translate, 'getBrowserLang').and.returnValue('fake-locate-browser');
|
spyOn(translate, 'getBrowserCultureLang').and.returnValue('fake-locate-browser');
|
||||||
expect(preferences.getDefaultLocale()).toBe('fake-locate-browser');
|
expect(preferences.getDefaultLocale()).toBe('fake-locate-browser');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return as default locale the component property as third ', () => {
|
it('should return as default locale the component property as third ', () => {
|
||||||
spyOn(translate, 'getBrowserLang').and.stub();
|
spyOn(translate, 'getBrowserCultureLang').and.stub();
|
||||||
expect(preferences.getDefaultLocale()).toBe('en');
|
expect(preferences.getDefaultLocale()).toBe('en');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return as locale the store locate', () => {
|
it('should return as locale the store locate', () => {
|
||||||
preferences.locale = 'fake-store-locate';
|
preferences.locale = 'fake-store-locate';
|
||||||
appConfig.config.locale = 'fake-locate-config';
|
appConfig.config.locale = 'fake-locate-config';
|
||||||
spyOn(translate, 'getBrowserLang').and.returnValue('fake-locate-browser');
|
spyOn(translate, 'getBrowserCultureLang').and.returnValue('fake-locate-browser');
|
||||||
expect(preferences.locale).toBe('fake-store-locate');
|
expect(preferences.locale).toBe('fake-store-locate');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ export class UserPreferencesService {
|
|||||||
* @returns Default locale language code
|
* @returns Default locale language code
|
||||||
*/
|
*/
|
||||||
public getDefaultLocale(): string {
|
public getDefaultLocale(): string {
|
||||||
return this.appConfig.get<string>('locale') || this.translate.getBrowserLang() || 'en';
|
return this.appConfig.get<string>('locale') || this.translate.getBrowserCultureLang() || 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,16 +31,6 @@ describe('ErrorContentComponent', () => {
|
|||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
let translateService: TranslationService;
|
let translateService: TranslationService;
|
||||||
|
|
||||||
setupTestBed({
|
|
||||||
imports: [
|
|
||||||
CoreTestingModule
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
{ provide: TranslationService, useClass: TranslationMock },
|
|
||||||
{ provide: ActivatedRoute, useValue: { params: of({id: '404'})}}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ErrorContentComponent);
|
fixture = TestBed.createComponent(ErrorContentComponent);
|
||||||
element = fixture.nativeElement;
|
element = fixture.nativeElement;
|
||||||
@ -53,84 +43,109 @@ describe('ErrorContentComponent', () => {
|
|||||||
TestBed.resetTestingModule();
|
TestBed.resetTestingModule();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create error component', async(() => {
|
describe(' with an undefined error', () => {
|
||||||
fixture.detectChanges();
|
|
||||||
expect(errorContentComponent).toBeTruthy();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should render error code', async(() => {
|
setupTestBed({
|
||||||
fixture.detectChanges();
|
imports: [
|
||||||
const errorContentElement = element.querySelector('.adf-error-content-code');
|
CoreTestingModule
|
||||||
expect(errorContentElement).not.toBeNull();
|
],
|
||||||
expect(errorContentElement).toBeDefined();
|
providers: [
|
||||||
}));
|
{ provide: TranslationService, useClass: TranslationMock },
|
||||||
|
{ provide: ActivatedRoute, useValue: { params: of() } }
|
||||||
it('should render error title', async(() => {
|
]
|
||||||
fixture.detectChanges();
|
|
||||||
const errorContentElement = element.querySelector('.adf-error-content-title');
|
|
||||||
expect(errorContentElement).not.toBeNull();
|
|
||||||
expect(errorContentElement).toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should render error description', async(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
const errorContentElement = element.querySelector('.adf-error-content-description');
|
|
||||||
expect(errorContentElement).not.toBeNull();
|
|
||||||
expect(errorContentElement).toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should render error description', async(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
const errorContentElement = element.querySelector('.adf-error-content-description');
|
|
||||||
expect(errorContentElement).not.toBeNull();
|
|
||||||
expect(errorContentElement).toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should hide secondary button if this one has no value', async(() => {
|
|
||||||
spyOn(translateService, 'instant').and.callFake((inputString) => {
|
|
||||||
return '';
|
|
||||||
});
|
});
|
||||||
fixture.detectChanges();
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
const errorContentElement = element.querySelector('.adf-error-content-description-link');
|
|
||||||
expect(errorContentElement).toBeNull();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should render secondary button with its value from the translate file', async(() => {
|
it('should create error component', async(() => {
|
||||||
spyOn(translateService, 'instant').and.callFake((inputString) => {
|
fixture.detectChanges();
|
||||||
return 'Secondary Button';
|
expect(errorContentComponent).toBeTruthy();
|
||||||
});
|
}));
|
||||||
fixture.detectChanges();
|
|
||||||
fixture.whenStable().then(() => {
|
it('should render error code', async(() => {
|
||||||
const errorContentElement = element.querySelector('#adf-secondary-button');
|
fixture.detectChanges();
|
||||||
|
const errorContentElement = element.querySelector('.adf-error-content-code');
|
||||||
expect(errorContentElement).not.toBeNull();
|
expect(errorContentElement).not.toBeNull();
|
||||||
expect(errorContentElement).toBeDefined();
|
expect(errorContentElement).toBeDefined();
|
||||||
expect(errorContentElement.textContent).toContain('ERROR_CONTENT.UNKNOWN.SECONDARY_BUTTON.TEXT');
|
}));
|
||||||
|
|
||||||
|
it('should render error title', async(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
const errorContentElement = element.querySelector('.adf-error-content-title');
|
||||||
|
expect(errorContentElement).not.toBeNull();
|
||||||
|
expect(errorContentElement).toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should render error description', async(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
const errorContentElement = element.querySelector('.adf-error-content-description');
|
||||||
|
expect(errorContentElement).not.toBeNull();
|
||||||
|
expect(errorContentElement).toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should render error description', async(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
const errorContentElement = element.querySelector('.adf-error-content-description');
|
||||||
|
expect(errorContentElement).not.toBeNull();
|
||||||
|
expect(errorContentElement).toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should hide secondary button if this one has no value', async(() => {
|
||||||
|
spyOn(translateService, 'instant').and.callFake((inputString) => {
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
const errorContentElement = element.querySelector('.adf-error-content-description-link');
|
||||||
|
expect(errorContentElement).toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should render secondary button with its value from the translate file', async(() => {
|
||||||
|
spyOn(translateService, 'instant').and.callFake((inputString) => {
|
||||||
|
return 'Secondary Button';
|
||||||
|
});
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
const errorContentElement = element.querySelector('#adf-secondary-button');
|
||||||
|
expect(errorContentElement).not.toBeNull();
|
||||||
|
expect(errorContentElement).toBeDefined();
|
||||||
|
expect(errorContentElement.textContent).toContain('ERROR_CONTENT.UNKNOWN.SECONDARY_BUTTON.TEXT');
|
||||||
|
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should the default value of return button be /', async(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(errorContentComponent.returnButtonUrl).toBe('/');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should navigate to the default error UNKNOWN if it does not find the error', async(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(errorContentComponent.errorCode).toBe('UNKNOWN');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(' with a specific error', () => {
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [
|
||||||
|
CoreTestingModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: TranslationService, useClass: TranslationMock },
|
||||||
|
{ provide: ActivatedRoute, useValue: { params: of({ id: '404' }) } }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
|
|
||||||
it('should the default value of return button be /', async(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(errorContentComponent.returnButtonUrl).toBe('/');
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should navigate to an error given by the route params', async(() => {
|
|
||||||
spyOn(translateService, 'get').and.returnValue(of('404'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(errorContentComponent.errorCode).toBe('404');
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should navigate to the default error UNKNOWN if it does not find the error', async(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(errorContentComponent.errorCode).toBe('UNKNOWN');
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
it('should navigate to an error given by the route params', async(() => {
|
||||||
|
spyOn(translateService, 'get').and.returnValue(of('404'));
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(errorContentComponent.errorCode).toBe('404');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,7 @@ export class ErrorContentComponent implements OnInit, AfterContentChecked {
|
|||||||
|
|
||||||
/** Error code associated with this error. */
|
/** Error code associated with this error. */
|
||||||
@Input()
|
@Input()
|
||||||
errorCode: string;
|
errorCode: string = 'UNKNOWN';
|
||||||
|
|
||||||
hasSecondButton: boolean;
|
hasSecondButton: boolean;
|
||||||
|
|
||||||
@ -58,15 +58,8 @@ export class ErrorContentComponent implements OnInit, AfterContentChecked {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.route) {
|
if (this.route) {
|
||||||
this.route.params.forEach((params: Params) => {
|
this.route.params.forEach((params: Params) => {
|
||||||
if (params['id'] && !this.errorCode) {
|
if (params['id']) {
|
||||||
this.errorCode = params['id'];
|
this.errorCode = params['id'];
|
||||||
let unknown = '';
|
|
||||||
this.translateService.get('ERROR_CONTENT.' + this.errorCode + '.TITLE').subscribe((errorTranslation: string) => {
|
|
||||||
unknown = errorTranslation;
|
|
||||||
});
|
|
||||||
if (unknown === 'ERROR_CONTENT.' + this.errorCode + '.TITLE') {
|
|
||||||
this.errorCode = 'UNKNOWN';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user