Skip to content
This repository has been archived by the owner on Oct 1, 2018. It is now read-only.

Commit

Permalink
Merge pull request #267 from IraErshova/feat-i18n-initialization
Browse files Browse the repository at this point in the history
feat(i18n): Setup ngx-translate in rxjs-docs
  • Loading branch information
ashwin-sureshkumar authored Feb 14, 2018
2 parents 621c41d + 584e008 commit f0ec397
Show file tree
Hide file tree
Showing 14 changed files with 269 additions and 47 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
"@angular/platform-browser-dynamic": "5.2.2",
"@angular/router": "5.2.2",
"@angular/service-worker": "5.2.2",
"@ngx-translate/core": "9.1.1",
"@ngx-translate/http-loader": "2.0.1",
"@types/hammerjs": "2.0.35",
"core-js": "2.4.1",
"hammerjs": "2.0.8",
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[routerLinkActiveOptions]="menu.options"
[routerLink]="menu.link"
(click)="shouldOpenChildMenu(menu.title)">
{{menu.title}}
{{menu.title | translate}}
</a>
</mat-nav-list>
</mat-sidenav>
Expand Down
46 changes: 26 additions & 20 deletions src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { MatSidenavModule, MatListModule } from '@angular/material';
import { TranslateModule } from '@ngx-translate/core';

import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
import { LanguageService } from './core/services/language.service';

describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;

beforeEach(
async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
BrowserAnimationsModule,
CoreModule.forRoot(),
MatSidenavModule,
MatListModule
],
declarations: [AppComponent]
}).compileComponents();
})
);
let languageService: LanguageService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
BrowserAnimationsModule,
CoreModule.forRoot(),
MatSidenavModule,
MatListModule,
TranslateModule.forRoot()
],
declarations: [AppComponent],
providers: [LanguageService]
});

fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
languageService = TestBed.get(LanguageService);
});

it('should create', () => {
expect(component).toBeTruthy();
it('should init supported languages on initialization', () => {
spyOn(languageService, 'init').and.stub();

fixture.detectChanges();

expect(languageService.init).toHaveBeenCalledWith(['en', 'ru']);
});
});
18 changes: 11 additions & 7 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { filter, map, mergeMap } from 'rxjs/operators';
import { SeoService, SeoData } from './core/services/seo.service';
import { OperatorMenuService } from './core/services/operator-menu.service';
import { LanguageService } from './core/services/language.service';

interface Menu {
title: string;
Expand All @@ -23,22 +24,22 @@ interface Menu {
export class AppComponent implements OnInit {
menus: Menu[] = [
{
title: 'Home',
title: 'MENU.HOME',
link: '/',
options: { exact: true }
},
{
title: 'Operators',
title: 'MENU.OPERATORS',
link: '/operators',
options: { exact: false }
},
{
title: 'Companies',
title: 'MENU.COMPANIES',
link: '/companies',
options: { exact: false }
},
{
title: 'Team',
title: 'MENU.TEAM',
link: '/team',
options: { exact: false }
}
Expand All @@ -48,7 +49,8 @@ export class AppComponent implements OnInit {
private _router: Router,
private _activatedRoute: ActivatedRoute,
private _seo: SeoService,
private _operatorMenuService: OperatorMenuService
private _operatorMenuService: OperatorMenuService,
private languageService: LanguageService
) {}

ngOnInit() {
Expand All @@ -67,11 +69,13 @@ export class AppComponent implements OnInit {
filter((data: SeoData) => data.title !== undefined)
)
.subscribe((data: SeoData) => this._seo.setHeaders(data));

this.languageService.init(['en', 'ru']);
}

shouldOpenChildMenu(title: string) {
shouldOpenChildMenu(title: string): void {
// for accessibility we need to ensure child menu is open when clicked
if (title === 'Operators') {
if (title === 'MENU.OPERATORS') {
this._operatorMenuService.openOperatorMenu();
}
}
Expand Down
22 changes: 19 additions & 3 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { ServiceWorkerModule } from '@angular/service-worker';
import { MatSidenavModule, MatListModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FlexLayoutModule } from '@angular/flex-layout';

import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

import { environment } from '../environments/environment';
import { CoreModule } from '../app/core/core.module';
import { MaterialModule } from './material/material.module';
import { AppRoutingModule } from './app-routing.module';

import { AppComponent } from './app.component';
import { LanguageService } from './core/services/language.service';

export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}

@NgModule({
declarations: [AppComponent],
Expand All @@ -23,8 +30,17 @@ import { AppComponent } from './app.component';
FlexLayoutModule,
MaterialModule,
AppRoutingModule,
CoreModule.forRoot()
HttpClientModule,
CoreModule.forRoot(),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
providers: [LanguageService],
bootstrap: [AppComponent]
})
export class AppModule {}
10 changes: 9 additions & 1 deletion src/app/core/components/toolbar/toolbar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
</button>
<span class="title" fxFlex> RxJS Docs </span>
<span class="title" fxFlex> WARNING: This is BETA site </span>
<a aria-label="GitHub Repository" class="mat-button" href="https://github.com/ReactiveX" aria-disabled="false">
<button mat-icon-button [matMenuTriggerFor]="appMenu">
<mat-icon>language</mat-icon>
</button>
<mat-menu #appMenu="matMenu" [overlapTrigger]="false" xPosition="before">
<button mat-menu-item *ngFor="let language of languagesList" (click)="onLangSwitch(language)">
{{language.nativeName}}
</button>
</mat-menu>
<a aria-label="GitHub Repository" target="_blank" class="mat-button" href="https://github.com/ReactiveX" aria-disabled="false">
<span class="mat-button-wrapper">
<img src="../../../assets/img/GitHub-Mark-Light-64px.png" alt="ReactiveX GitHub Repository"> GitHub
</span>
Expand Down
46 changes: 34 additions & 12 deletions src/app/core/components/toolbar/toolbar.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';

import { ToolbarComponent } from './toolbar.component';
import { MaterialModule } from '../../../material/material.module';
import { LanguageService } from '../../services/language.service';
import { TranslateModule } from '@ngx-translate/core';
import { languagesList } from '../../data/language.data';

describe('ToolbarComponent', () => {
const languages = languagesList;
let component: ToolbarComponent;
let fixture: ComponentFixture<ToolbarComponent>;

beforeEach(
async(() => {
TestBed.configureTestingModule({
imports: [MaterialModule, BrowserAnimationsModule, RouterTestingModule],
declarations: [ToolbarComponent]
}).compileComponents();
})
);
let languageService: LanguageService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
MaterialModule,
BrowserAnimationsModule,
RouterTestingModule,
TranslateModule.forRoot()
],
declarations: [ToolbarComponent],
providers: [LanguageService]
});

languageService = TestBed.get(LanguageService);
fixture = TestBed.createComponent(ToolbarComponent);
component = fixture.componentInstance;
});

it('should set languagesList and currentLang on initialization', () => {
spyOn(languageService, 'getLanguagesList').and.returnValue(languages);
spyOn(languageService, 'getCurrentLang').and.returnValue(languages[1]);

fixture.detectChanges();

expect(component.languagesList).toEqual(languages);
expect(component.currentLang).toEqual(languages[1]);
});

it('should create', () => {
expect(component).toBeTruthy();
it('should change current language on onLangSwitch', () => {
spyOn(languageService, 'saveLang').and.stub();

component.onLangSwitch(languages[1]);

expect(component.currentLang).toEqual(languages[1]);
expect(languageService.saveLang).toHaveBeenCalledWith(languages[1]);
});
});
19 changes: 16 additions & 3 deletions src/app/core/components/toolbar/toolbar.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Lang } from '../../models/language.model';
import { LanguageService } from '../../services/language.service';

@Component({
selector: 'app-toolbar',
Expand All @@ -7,11 +9,22 @@ import { Component, OnInit, Output, EventEmitter } from '@angular/core';
})
export class ToolbarComponent implements OnInit {
@Output() navToggle = new EventEmitter<boolean>();
currentLang: Lang;
languagesList: Lang[];

constructor(private languageService: LanguageService) {}

ngOnInit() {
this.languagesList = this.languageService.getLanguagesList();
this.currentLang = this.languageService.getCurrentLang();
}

navOpen() {
this.navToggle.emit(true);
}

constructor() {}

ngOnInit() {}
onLangSwitch(lang: Lang): void {
this.currentLang = lang;
this.languageService.saveLang(lang);
}
}
14 changes: 14 additions & 0 deletions src/app/core/data/language.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Lang } from '../models/language.model';

export const languagesList: Lang[] = [
{
code: 'en',
name: 'English',
nativeName: 'English'
},
{
code: 'ru',
name: 'Russian',
nativeName: 'Русский'
}
];
5 changes: 5 additions & 0 deletions src/app/core/models/language.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface Lang {
code: string;
name: string;
nativeName: string;
}
65 changes: 65 additions & 0 deletions src/app/core/services/language.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { TestBed } from '@angular/core/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

import { languagesList } from '../data/language.data';
import { LanguageService } from './language.service';

describe('LanguageService', () => {
const languages = languagesList;
let languageService: LanguageService;
let translateService: TranslateService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
providers: [LanguageService]
});

languageService = TestBed.get(LanguageService);
translateService = TestBed.get(TranslateService);

window.localStorage.removeItem('current_lang');
});

it('should set fullLangList on initialization', () => {
expect(languageService.fullLangList).toEqual(languages);
});

it('should set the using language and default language on init', () => {
spyOn(translateService, 'getBrowserLang').and.returnValue('en');
spyOn(translateService, 'use').and.stub();

languageService.init(['en', 'ru']);

expect(translateService.use).toHaveBeenCalledWith('en');
});

it('should get language list on getLanguagesList', () => {
spyOn(translateService, 'getLangs').and.returnValue(['en', 'ru']);

languageService.getLanguagesList();

expect(languageService.fullLangList).toEqual(languages);
});

it('should get current language on getCurrentLang', () => {
spyOn(languageService, 'getLanguagesList').and.returnValue(languages);
translateService.currentLang = 'ru';

const result = languageService.getCurrentLang();

expect(result).toEqual({
code: 'ru',
name: 'Russian',
nativeName: 'Русский'
});
});

it('should save language on saveLang', () => {
spyOn(translateService, 'use').and.stub();

languageService.saveLang(languages[1]);

expect(translateService.use).toHaveBeenCalledWith(languages[1].code);
});
});
Loading

0 comments on commit f0ec397

Please sign in to comment.