-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
271 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<div ngbDropdown class="navbar-nav" *ngIf="moreThanOneLanguage"> | ||
<a href="#" id="dropdownLang" role="button" class="nav-link" (click)="$event.preventDefault()" data-toggle="dropdown" ngbDropdownToggle> | ||
<i class="fa fa-language fa-fw" aria-hidden="true"></i> | ||
{{ currentLangLabel() }} | ||
</a> | ||
<ul ngbDropdownMenu class="dropdown-menu" aria-labelledby="dropdownLang"> | ||
<li class="dropdown-item" #langSelect *ngFor="let lang of translate.getLangs()" | ||
(click)="translate.use(lang)" | ||
[class.active]="lang === translate.currentLang"> | ||
{{ langLabel(lang) }} | ||
</li> | ||
</ul> | ||
</div> |
Empty file.
163 changes: 163 additions & 0 deletions
163
src/app/shared/lang-switch/lang-switch.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import {LangSwitchComponent} from './lang-switch.component'; | ||
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; | ||
import {DebugElement, NO_ERRORS_SCHEMA} from '@angular/core'; | ||
import {TranslateLoader, TranslateModule, TranslateService} from '@ngx-translate/core'; | ||
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; | ||
import { GLOBAL_CONFIG } from '../../../config'; | ||
import {LangConfig} from '../../../config/lang-config.interface'; | ||
import {Observable, of} from 'rxjs'; | ||
|
||
// This test is completely independent from any message catalogs or keys in the codebase | ||
// The translation module is instantiated with these bogus messages that we aren't using anyway. | ||
|
||
// Double quotes are mandatory in JSON, so de-activating the tslint rule checking for single quotes here. | ||
/* tslint:disable:quotemark */ | ||
// JSON for the language files has double quotes around all literals | ||
/* tslint:disable:object-literal-key-quotes */ | ||
class CustomLoader implements TranslateLoader { | ||
getTranslation(lang: string): Observable<any> { | ||
return of({ | ||
"footer": { | ||
"copyright": "copyright © 2002-{{ year }}", | ||
"link.dspace": "DSpace software", | ||
"link.duraspace": "DuraSpace" | ||
} | ||
}); | ||
} | ||
} | ||
/* tslint:enable:quotemark */ | ||
/* tslint:enable:object-literal-key-quotes */ | ||
|
||
describe('LangSwitchComponent', () => { | ||
|
||
describe('with English and Deutsch activated, English as default', () => { | ||
let component: LangSwitchComponent; | ||
let fixture: ComponentFixture<LangSwitchComponent>; | ||
let de: DebugElement; | ||
let langSwitchElement: HTMLElement; | ||
|
||
let translate: TranslateService; | ||
let http: HttpTestingController; | ||
|
||
beforeEach(async(() => { | ||
|
||
const mockConfig = { | ||
languages: [{ | ||
code: 'en', | ||
label: 'English', | ||
active: true, | ||
}, { | ||
code: 'de', | ||
label: 'Deutsch', | ||
active: true, | ||
}] | ||
}; | ||
|
||
TestBed.configureTestingModule({ | ||
imports: [HttpClientTestingModule, TranslateModule.forRoot( | ||
{ | ||
loader: {provide: TranslateLoader, useClass: CustomLoader} | ||
} | ||
)], | ||
declarations: [LangSwitchComponent], | ||
schemas: [NO_ERRORS_SCHEMA], | ||
providers: [TranslateService, {provide: GLOBAL_CONFIG, useValue: mockConfig}] | ||
}).compileComponents() | ||
.then(() => { | ||
translate = TestBed.get(TranslateService); | ||
translate.addLangs(mockConfig.languages.filter((langConfig:LangConfig) => langConfig.active === true).map((a) => a.code)); | ||
translate.setDefaultLang('en'); | ||
translate.use('en'); | ||
http = TestBed.get(HttpTestingController); | ||
fixture = TestBed.createComponent(LangSwitchComponent); | ||
component = fixture.componentInstance; | ||
de = fixture.debugElement; | ||
langSwitchElement = de.nativeElement; | ||
}); | ||
})); | ||
|
||
it('should create', () => { | ||
expect(component).toBeDefined(); | ||
}); | ||
|
||
it('should identify English as the label for the current active language in the component', async(() => { | ||
fixture.detectChanges(); | ||
expect(component.currentLangLabel()).toEqual('English'); | ||
})); | ||
|
||
it('should be initialized with more than one language active', async(() => { | ||
fixture.detectChanges(); | ||
expect(component.moreThanOneLanguage).toBeTruthy(); | ||
})); | ||
|
||
it('should define the main A HREF in the UI', (() => { | ||
expect(langSwitchElement.querySelector('a')).toBeDefined(); | ||
})); | ||
|
||
it('should show English in the UI as the label for the language dropdown', async(() => { | ||
spyOn(translate, 'getBrowserLang').and.returnValue('en'); | ||
fixture.detectChanges(); | ||
// the main link to open up the dropdown should now say English | ||
expect(langSwitchElement.querySelector('a').textContent.trim()).toEqual('English'); | ||
})); | ||
}); | ||
|
||
describe('with English as the only active and also default language', () => { | ||
|
||
let component: LangSwitchComponent; | ||
let fixture: ComponentFixture<LangSwitchComponent>; | ||
let de: DebugElement; | ||
let langSwitchElement: HTMLElement; | ||
|
||
let translate: TranslateService; | ||
let http: HttpTestingController; | ||
|
||
beforeEach(async(() => { | ||
|
||
const mockConfig = { | ||
languages: [{ | ||
code: 'en', | ||
label: 'English', | ||
active: true, | ||
}, { | ||
code: 'de', | ||
label: 'Deutsch', | ||
active: false | ||
}] | ||
}; | ||
|
||
TestBed.configureTestingModule({ | ||
imports: [HttpClientTestingModule, TranslateModule.forRoot( | ||
{ | ||
loader: {provide: TranslateLoader, useClass: CustomLoader} | ||
} | ||
)], | ||
declarations: [LangSwitchComponent], | ||
schemas: [NO_ERRORS_SCHEMA], | ||
providers: [TranslateService, {provide: GLOBAL_CONFIG, useValue: mockConfig}] | ||
}).compileComponents(); | ||
translate = TestBed.get(TranslateService); | ||
translate.addLangs(mockConfig.languages.filter((MyLangConfig) => MyLangConfig.active === true).map((a) => a.code)); | ||
translate.setDefaultLang('en'); | ||
translate.use('en'); | ||
http = TestBed.get(HttpTestingController); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(LangSwitchComponent); | ||
component = fixture.componentInstance; | ||
de = fixture.debugElement; | ||
langSwitchElement = de.nativeElement; | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeDefined(); | ||
}); | ||
|
||
it('should not define the main header for the language switch, as it should be invisible', (() => { | ||
expect(langSwitchElement.querySelector('a')).toBeNull(); | ||
})); | ||
|
||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import {Component, Inject, OnInit} from '@angular/core'; | ||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; | ||
import {TranslateService} from '@ngx-translate/core'; | ||
import {LangConfig} from '../../../config/lang-config.interface'; | ||
|
||
@Component({ | ||
selector: 'ds-lang-switch', | ||
styleUrls: ['lang-switch.component.scss'], | ||
templateUrl: 'lang-switch.component.html', | ||
}) | ||
|
||
/** | ||
* Component representing a switch for changing the interface language throughout the application | ||
* If only one language is active, the component will disappear as there are no languages to switch to. | ||
*/ | ||
export class LangSwitchComponent implements OnInit { | ||
|
||
// All of the languages that are active, meaning that a user can switch between them. | ||
activeLangs: LangConfig[]; | ||
|
||
// A language switch only makes sense if there is more than one active language to switch between. | ||
moreThanOneLanguage: boolean; | ||
|
||
constructor( | ||
@Inject(GLOBAL_CONFIG) public config: GlobalConfig, | ||
public translate: TranslateService | ||
) { | ||
} | ||
|
||
ngOnInit(): void { | ||
this.activeLangs = this.config.languages.filter((MyLangConfig) => MyLangConfig.active === true); | ||
this.moreThanOneLanguage = (this.activeLangs.length > 1); | ||
} | ||
|
||
/** | ||
* Returns the label for the current language | ||
*/ | ||
currentLangLabel(): string { | ||
return this.activeLangs.find((MyLangConfig) => MyLangConfig.code === this.translate.currentLang).label; | ||
} | ||
|
||
/** | ||
* Returns the label for a specific language code | ||
*/ | ||
langLabel(langcode: string): string { | ||
return this.activeLangs.find((MyLangConfig) => MyLangConfig.code === langcode).label; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Config } from './config.interface'; | ||
|
||
export interface LangConfig extends Config { | ||
code: string; | ||
label: string; | ||
active: boolean; | ||
} |