[CST-2877] fix method for lang list & add reload after change lang

This commit is contained in:
Danilo Di Nuzzo
2020-06-24 10:55:13 +02:00
parent d66d5b6a46
commit ea5f727449
6 changed files with 95 additions and 40 deletions

View File

@@ -230,6 +230,12 @@ describe('AuthService test', () => {
expect(result).toBe(false); expect(result).toBe(false);
}); });
it('should return true when authentication is loaded', () => {
authService.isAuthenticationLoaded().subscribe((status: boolean) => {
expect(status).toBe(true);
});
});
}); });
describe('', () => { describe('', () => {

View File

@@ -21,7 +21,8 @@ import {
getAuthenticationToken, getAuthenticationToken,
getRedirectUrl, getRedirectUrl,
isAuthenticated, isAuthenticated,
isTokenRefreshing isTokenRefreshing,
isAuthenticatedLoaded
} from './selectors'; } from './selectors';
import { AppState, routerStateSelector } from '../../app.reducer'; import { AppState, routerStateSelector } from '../../app.reducer';
import { import {
@@ -148,6 +149,14 @@ export class AuthService {
return this.store.pipe(select(isAuthenticated)); return this.store.pipe(select(isAuthenticated));
} }
/**
* Determines if authentication is loaded
* @returns {Observable<boolean>}
*/
public isAuthenticationLoaded(): Observable<boolean> {
return this.store.pipe(select(isAuthenticatedLoaded));
}
/** /**
* Returns the href link to authenticated user * Returns the href link to authenticated user
* @returns {string} * @returns {string}
@@ -197,7 +206,7 @@ export class AuthService {
return this.store.pipe( return this.store.pipe(
select(getAuthenticatedUserId), select(getAuthenticatedUserId),
hasValueOperator(), hasValueOperator(),
switchMap((id: string) => this.epersonService.findById(id)), switchMap((id: string) => { console.log('ID: ', id); return this.epersonService.findById(id) }),
getAllSucceededRemoteDataPayload() getAllSucceededRemoteDataPayload()
) )
} }

View File

@@ -8,6 +8,7 @@ import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
import { LANG_COOKIE, LocaleService, LANG_ORIGIN } from './locale.service'; import { LANG_COOKIE, LocaleService, LANG_ORIGIN } from './locale.service';
import { AuthService } from '../auth/auth.service'; import { AuthService } from '../auth/auth.service';
import { AuthServiceMock } from 'src/app/shared/mocks/auth.service.mock'; import { AuthServiceMock } from 'src/app/shared/mocks/auth.service.mock';
import { NativeWindowRef } from '../services/window.service';
describe('LocaleService test suite', () => { describe('LocaleService test suite', () => {
let service: LocaleService; let service: LocaleService;
@@ -15,6 +16,7 @@ describe('LocaleService test suite', () => {
let cookieService: CookieService; let cookieService: CookieService;
let translateService: TranslateService; let translateService: TranslateService;
let authService: AuthService; let authService: AuthService;
let window;
let spyOnGet; let spyOnGet;
let spyOnSet; let spyOnSet;
@@ -41,7 +43,8 @@ describe('LocaleService test suite', () => {
cookieService = TestBed.get(CookieService); cookieService = TestBed.get(CookieService);
translateService = TestBed.get(TranslateService); translateService = TestBed.get(TranslateService);
authService = TestBed.get(TranslateService); authService = TestBed.get(TranslateService);
service = new LocaleService(cookieService, translateService, authService); window = new NativeWindowRef();
service = new LocaleService(window, cookieService, translateService, authService);
serviceAsAny = service; serviceAsAny = service;
spyOnGet = spyOn(cookieService, 'get'); spyOnGet = spyOn(cookieService, 'get');
spyOnSet = spyOn(cookieService, 'set'); spyOnSet = spyOn(cookieService, 'set');

View File

@@ -1,12 +1,14 @@
import { Injectable } from '@angular/core'; import { Injectable, Inject } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { isEmpty, hasValue } from '../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { CookieService } from '../services/cookie.service'; import { CookieService } from '../services/cookie.service';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { AuthService } from '../auth/auth.service'; import { AuthService } from '../auth/auth.service';
import { BehaviorSubject, Observable } from 'rxjs'; import { Observable, of as observableOf, combineLatest } from 'rxjs';
import { map, take, flatMap, tap } from 'rxjs/operators';
import { NativeWindowService, NativeWindowRef } from '../services/window.service';
export const LANG_COOKIE = 'language_cookie'; export const LANG_COOKIE = 'language_cookie';
@@ -33,6 +35,7 @@ const EPERSON_LANG_METADATA = 'eperson.language';
export class LocaleService { export class LocaleService {
constructor( constructor(
@Inject(NativeWindowService) protected _window: NativeWindowRef,
private cookie: CookieService, private cookie: CookieService,
private translate: TranslateService, private translate: TranslateService,
private authService: AuthService) { private authService: AuthService) {
@@ -58,39 +61,61 @@ export class LocaleService {
return lang; return lang;
} }
/**
* Get the languages list of the user in Accept-Language format
*
* @returns {Observable<string[]>}
*/
getLanguageCodeList(): Observable<string[]> { getLanguageCodeList(): Observable<string[]> {
const bs = new BehaviorSubject<string[]>([]); const obs$ = combineLatest([
// check if user has set preferred language in UI this.authService.isAuthenticated(),
if (this.translate.currentLang) { this.authService.isAuthenticationLoaded()
bs.next( ]);
this.setQuality(
[this.translate.currentLang], return obs$.pipe(
LANG_ORIGIN.UI, take(1),
false) flatMap(([isAuthenticated, isLoaded]) => {
); let epersonLang$: Observable<string[]> = observableOf([]);
} if (isAuthenticated && isLoaded) {
// check if user is loggedIn and has language associated epersonLang$ = this.authService.getAuthenticatedUserFromStore().pipe(
this.authService.getAuthenticatedUserFromStore().subscribe( take(1),
(eperson) => { map((eperson) => {
const languages: string[] = [];
const ePersonLang = eperson.firstMetadataValue(EPERSON_LANG_METADATA); const ePersonLang = eperson.firstMetadataValue(EPERSON_LANG_METADATA);
bs.next( if (ePersonLang) {
this.setQuality( languages.push(...this.setQuality(
[ePersonLang], [ePersonLang],
LANG_ORIGIN.EPERSON, LANG_ORIGIN.EPERSON,
!isEmpty(this.translate.currentLang)) !isEmpty(this.translate.currentLang)));
}
return languages;
})
); );
} }
); return epersonLang$.pipe(
// get the browser languages map((epersonLang: string[]) => {
const languages: string[] = [];
if (this.translate.currentLang) {
languages.push(...this.setQuality(
[this.translate.currentLang],
LANG_ORIGIN.UI,
false));
}
if (isNotEmpty(epersonLang)) {
languages.push(...epersonLang);
}
if (navigator.languages) { if (navigator.languages) {
bs.next( languages.push(...this.setQuality(
this.setQuality(
Object.assign([], navigator.languages), Object.assign([], navigator.languages),
LANG_ORIGIN.BROWSER, LANG_ORIGIN.BROWSER,
!isEmpty(this.translate.currentLang)) !isEmpty(this.translate.currentLang))
); );
} }
return bs; return languages;
})
)
})
);
} }
/** /**
@@ -129,8 +154,8 @@ export class LocaleService {
* Returns a new array that contains the languages list with the quality value. * Returns a new array that contains the languages list with the quality value.
* The quality factor indicate the relative degree of preference for the language * The quality factor indicate the relative degree of preference for the language
* @param languages the languages list * @param languages the languages list
* @param origin * @param origin origin of language list (UI, EPERSON, BROWSER)
* @param hasOther * @param hasOther true if contains other language, false otherwise
*/ */
setQuality(languages: string[], origin: LANG_ORIGIN, hasOther: boolean): string[] { setQuality(languages: string[], origin: LANG_ORIGIN, hasOther: boolean): string[] {
const langWithPrior = []; const langWithPrior = [];
@@ -155,4 +180,13 @@ export class LocaleService {
return langWithPrior; return langWithPrior;
} }
/**
* Refresh route navigated
*/
public refreshAfterChangeLanguage() {
// Hard redirect to the reload page with a unique number behind it
// so that all state is definitely lost
this._window.nativeWindow.location.href = `/reload/${new Date().getTime()}`;
}
} }

View File

@@ -34,11 +34,12 @@ class CustomLoader implements TranslateLoader {
let localService: any; let localService: any;
describe('LangSwitchComponent', () => { fdescribe('LangSwitchComponent', () => {
function getMockLocaleService(): LocaleService { function getMockLocaleService(): LocaleService {
return jasmine.createSpyObj('LocaleService', { return jasmine.createSpyObj('LocaleService', {
setCurrentLanguageCode: jasmine.createSpy('setCurrentLanguageCode') setCurrentLanguageCode: jasmine.createSpy('setCurrentLanguageCode'),
refreshAfterChangeLanguage: jasmine.createSpy('refreshAfterChangeLanguage')
}) })
} }
@@ -121,6 +122,7 @@ describe('LangSwitchComponent', () => {
it('should translate the app and set the client\'s language cookie', () => { it('should translate the app and set the client\'s language cookie', () => {
expect(localService.setCurrentLanguageCode).toHaveBeenCalled(); expect(localService.setCurrentLanguageCode).toHaveBeenCalled();
expect(localService.refreshAfterChangeLanguage).toHaveBeenCalled();
}); });
}); });

View File

@@ -55,6 +55,7 @@ export class LangSwitchComponent implements OnInit {
*/ */
useLang(lang: string) { useLang(lang: string) {
this.localeService.setCurrentLanguageCode(lang); this.localeService.setCurrentLanguageCode(lang);
this.localeService.refreshAfterChangeLanguage();
} }
} }