Commit c78eb35a authored by Vitali Stupin's avatar Vitali Stupin

Pull request #24: Ng11

Merge in XTSS/xtss-catalogue from ng11 to develop

* commit '3efdd5ce':
  Fixing tests
  Migrating to eslint
  Upgrading to angular 11
parents 1955ad26 3efdd5ce
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"tsconfig.json"
],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@typescript-eslint/explicit-member-accessibility": [
"off",
{
"accessibility": "explicit"
}
],
"arrow-parens": [
"off",
"always"
],
"import/order": "off"
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
}
]
}
......@@ -26,7 +26,7 @@
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [],
"es5BrowserSupport": true
"aot": true
},
"configurations": {
"production": {
......@@ -38,8 +38,6 @@
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
......@@ -50,6 +48,10 @@
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
]
}
......@@ -91,42 +93,11 @@
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"xtss-catalogue-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "xtss-catalogue:serve"
},
"configurations": {
"production": {
"devServerTarget": "xtss-catalogue:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"builder": "@angular-eslint/builder:lint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
......@@ -134,4 +105,4 @@
}
},
"defaultProject": "xtss-catalogue"
}
\ No newline at end of file
}
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
\ No newline at end of file
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getTitleText()).toEqual('Welcome to xtss-catalogue!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get(browser.baseUrl) as Promise<any>;
}
getTitleText() {
return element(by.css('app-root h1')).getText() as Promise<string>;
}
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -9,47 +9,55 @@
"test-headless": "ng test --watch=false --browsers=ChromiumHeadless",
"test-docker": "ng test --watch=false --browsers=ChromiumDocker",
"lint": "ng lint",
"e2e": "ng e2e",
"sonar": "sonar-scanner"
},
"private": true,
"dependencies": {
"@angular/animations": "^8.2.14",
"@angular/common": "^8.2.14",
"@angular/compiler": "^8.2.14",
"@angular/core": "^8.2.14",
"@angular/forms": "^8.2.14",
"@angular/platform-browser": "^8.2.14",
"@angular/platform-browser-dynamic": "^8.2.14",
"@angular/router": "^8.2.14",
"@angular/animations": "^11.0.2",
"@angular/common": "^11.0.2",
"@angular/compiler": "^11.0.2",
"@angular/core": "^11.0.2",
"@angular/forms": "^11.0.2",
"@angular/platform-browser": "^11.0.2",
"@angular/platform-browser-dynamic": "^11.0.2",
"@angular/router": "^11.0.2",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0",
"bootstrap": "^4.4.1",
"bootstrap": "^4.5.3",
"core-js": "^2.6.11",
"rxjs": "~6.5.3",
"tslib": "^1.10.0",
"zone.js": "~0.9.1"
"rxjs": "^6.5.5",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.803.20",
"@angular/cli": "~8.3.20",
"@angular/compiler-cli": "^8.2.14",
"@angular/language-service": "^8.2.14",
"@types/jasmine": "~2.8.8",
"@angular-devkit/build-angular": "~0.1100.2",
"@angular-eslint/builder": "0.8.0-beta.1",
"@angular-eslint/eslint-plugin": "0.8.0-beta.1",
"@angular-eslint/eslint-plugin-template": "0.8.0-beta.1",
"@angular-eslint/template-parser": "0.8.0-beta.1",
"@angular/cli": "~11.0.2",
"@angular/compiler-cli": "^11.0.2",
"@angular/language-service": "^11.0.2",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "^2.0.8",
"@types/node": "~8.9.4",
"codelyzer": "^5.2.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "^4.4.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^2.1.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"@types/node": "^12.11.1",
"@typescript-eslint/eslint-plugin": "4.3.0",
"@typescript-eslint/parser": "4.3.0",
"codelyzer": "^6.0.0",
"eslint": "^7.6.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.6",
"eslint-plugin-prefer-arrow": "1.2.2",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "^2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"sonar-scanner": "^3.1.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.5.3"
"typescript": "~4.0.5"
}
}
......@@ -12,7 +12,7 @@ const routes: Routes = [
];
@NgModule({
imports: [ RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled'}) ],
imports: [ RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled', relativeLinkResolution: 'legacy' }) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
import { TestBed, async } from '@angular/core/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
......
// We mock configuration file that has different naming convention
/* eslint-disable @typescript-eslint/naming-convention */
import { Injectable } from '@angular/core';
import { AppConfig } from './app.config';
......
......@@ -15,12 +15,14 @@ describe('AppConfig', () => {
});
it('should load configuration', async () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
httpClientSpy.get.and.returnValue(of({TEST: 'OK'}));
await config.load();
expect(httpClientSpy.get).toHaveBeenCalledWith('./assets/config.json');
});
it('getConfig should work', async () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
httpClientSpy.get.and.returnValue(of({TEST: 'OK'}));
await config.load();
expect(config.getConfig('TEST')).toBe('OK');
......
import { AppModule, HttpLoaderFactory } from './app.module';
import { AppModule, httpLoaderFactory } from './app.module';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AppConfig } from './app.config';
import { TestBed } from '@angular/core/testing';
......@@ -19,7 +19,7 @@ describe('AppModule', () => {
});
it('HttpLoaderFactory should work', () => {
expect(HttpLoaderFactory(httpClientSpy as any) instanceof TranslateHttpLoader).toBeTruthy();
expect(httpLoaderFactory(httpClientSpy as any) instanceof TranslateHttpLoader).toBeTruthy();
});
it('AppConfig should be initialized', async () => {
......@@ -29,7 +29,7 @@ describe('AppModule', () => {
{ provide: AppConfig, useValue: appConfigSpy }
]
});
expect(TestBed.get(AppConfig)).toBeTruthy();
expect(TestBed.inject(AppConfig)).toBeTruthy();
expect(appConfigSpy.load).toHaveBeenCalledTimes(1);
});
});
......@@ -15,6 +15,9 @@ import { APP_INITIALIZER } from '@angular/core';
import { AppConfig } from './app.config';
import { MessagesComponent } from './messages/messages.component';
// Providing path as a workaround for ngx-translate bug with --base-href option
export const httpLoaderFactory = (http: HttpClient) => new TranslateHttpLoader(http, './assets/i18n/');
@NgModule({
declarations: [
AppComponent,
......@@ -33,7 +36,7 @@ import { MessagesComponent } from './messages/messages.component';
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
useFactory: httpLoaderFactory,
deps: [HttpClient]
}
})
......@@ -45,8 +48,3 @@ import { MessagesComponent } from './messages/messages.component';
bootstrap: [AppComponent]
})
export class AppModule { }
export function HttpLoaderFactory(http: HttpClient) {
// Providing path as a workaround for ngx-translate bug with --base-href option
return new TranslateHttpLoader(http, './assets/i18n/');
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { HeaderComponent } from './header.component';
import { HttpClientModule } from '@angular/common/http';
......@@ -10,7 +10,7 @@ describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ HeaderComponent ],
imports: [
......@@ -35,7 +35,7 @@ describe('HeaderComponent', () => {
});
it('should set language', () => {
const languagesService: LanguagesService = TestBed.get(LanguagesService);
const languagesService: LanguagesService = TestBed.inject(LanguagesService);
spyOn(languagesService, 'setLang').and.returnValue(null);
component.setLang('xxx');
expect(languagesService.setLang).toHaveBeenCalledWith('xxx');
......
......@@ -17,30 +17,30 @@ describe('LanguagesService', () => {
}));
it('should be created', () => {
const service: LanguagesService = TestBed.get(LanguagesService);
const service: LanguagesService = TestBed.inject(LanguagesService);
expect(service).toBeTruthy();
});
it('should set default lang with empty localStorage', () => {
const translateService: TranslateService = TestBed.get(TranslateService);
const translateService: TranslateService = TestBed.inject(TranslateService);
spyOn(translateService, 'setDefaultLang');
spyOn(window.localStorage, 'getItem').and.returnValue(undefined);
TestBed.get(LanguagesService);
TestBed.inject(LanguagesService);
expect(translateService.setDefaultLang).toHaveBeenCalledWith('est');
});
it('should set default lang from localStorage', () => {
const translateService: TranslateService = TestBed.get(TranslateService);
const translateService: TranslateService = TestBed.inject(TranslateService);
spyOn(translateService, 'setDefaultLang');
spyOn(window.localStorage, 'getItem').and.returnValue('ENG');
TestBed.get(LanguagesService);
TestBed.inject(LanguagesService);
expect(translateService.setDefaultLang).toHaveBeenCalledWith('eng');
});
it('should set language', () => {
const translateService: TranslateService = TestBed.get(TranslateService);
const translateService: TranslateService = TestBed.inject(TranslateService);
spyOn(translateService, 'use');
const service = TestBed.get(LanguagesService);
const service = TestBed.inject(LanguagesService);
service.setLang('ENG');
expect(translateService.use).toHaveBeenCalledWith('eng');
});
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';
import { MessagesComponent } from './messages.component';
......@@ -7,7 +7,7 @@ describe('MessagesComponent', () => {
let component: MessagesComponent;
let fixture: ComponentFixture<MessagesComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
MessagesComponent
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
......@@ -12,7 +12,7 @@ describe('SearchComponent', () => {
let fixture: ComponentFixture<SearchComponent>;
let subsystemsService: SubsystemsService;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ SearchComponent ],
imports: [
......@@ -28,7 +28,7 @@ describe('SearchComponent', () => {
}));
beforeEach(() => {
subsystemsService = TestBed.get(SubsystemsService);
subsystemsService = TestBed.inject(SubsystemsService);
spyOn(subsystemsService, 'getLimits').and.returnValue({10: 10, 20: 20});
spyOn(subsystemsService, 'setNonEmpty').and.returnValue(null);
spyOn(subsystemsService, 'setLimit').and.returnValue(null);
......
......@@ -7,7 +7,7 @@ import { SubsystemsService } from '../../subsystems.service';
})
export class SearchComponent implements OnInit {
limit: string;
limits: object;
limits: Record<string, number>;
nonEmpty: boolean;
filter: string;
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';
import { SubsystemItemComponent } from './subsystem-item.component';
......@@ -17,7 +17,7 @@ describe('SubsystemItemComponent', () => {
let fixture: ComponentFixture<SubsystemItemComponent>;
let subsystemsService: SubsystemsService;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
SubsystemItemComponent
......@@ -38,7 +38,7 @@ describe('SubsystemItemComponent', () => {
}));
beforeEach(() => {
subsystemsService = TestBed.get(SubsystemsService);
subsystemsService = TestBed.inject(SubsystemsService);
spyOn(subsystemsService, 'getApiUrlBase').and.returnValue(null);
fixture = TestBed.createComponent(SubsystemItemComponent);
......@@ -99,7 +99,8 @@ describe('SubsystemItemComponent', () => {
});
it('should go to detail view', () => {
const spy = TestBed.get(Router).navigateByUrl;
const injected = TestBed.inject(Router) as jasmine.SpyObj<Router>;
const spy = injected.navigateByUrl;
component.showDetail();
expect(spy).toHaveBeenCalledWith('/INST/CLASS/CODE/SUB');
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';
import { SubsystemListComponent } from './subsystem-list.component';
......@@ -32,7 +32,7 @@ describe('SubsystemListComponent', () => {
let getInstancesSpy;
let subsystemsService: SubsystemsService;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
SubsystemListComponent,
......@@ -63,13 +63,13 @@ describe('SubsystemListComponent', () => {
}));
beforeEach(() => {
subsystemsService = TestBed.get(SubsystemsService);
subsystemsService = TestBed.inject(SubsystemsService);
getInstanceSpy = spyOn(subsystemsService, 'getInstance').and.returnValue('INST');
getInstancesSpy = spyOn(subsystemsService, 'getInstances').and.returnValue(['INST']);
spyOn(TestBed.get(ViewportScroller), 'scrollToPosition');
spyOn(TestBed.inject(ViewportScroller), 'scrollToPosition');
spyOn(subsystemsService, 'setInstance').and.returnValue(null);
spyOn(subsystemsService, 'getDefaultInstance').and.returnValue('DEFINST');
spyOn(TestBed.get(SubsystemsService), 'getApiUrlBase').and.returnValue('base');
spyOn(TestBed.inject(SubsystemsService), 'getApiUrlBase').and.returnValue('base');
});
it('should create', () => {
......@@ -84,7 +84,7 @@ describe('SubsystemListComponent', () => {
fixture = TestBed.createComponent(SubsystemListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
expect(TestBed.get(Router).navigateByUrl).toHaveBeenCalledWith('/DEFINST', Object({ replaceUrl: true }));
expect(TestBed.inject(Router).navigateByUrl).toHaveBeenCalledWith('/DEFINST', Object({ replaceUrl: true }));
});
it('should detect when instance is not selected', () => {
......@@ -108,14 +108,15 @@ describe('SubsystemListComponent', () => {
fixture = TestBed.createComponent(SubsystemListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
expect(TestBed.get(ViewportScroller).scrollToPosition).toHaveBeenCalledWith([11, 12]);
expect(TestBed.inject(ViewportScroller).scrollToPosition).toHaveBeenCalledWith([11, 12]);
});
it('switchInstance should work', () => {
fixture = TestBed.createComponent(SubsystemListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
const spy = TestBed.get(Router).navigateByUrl;
const injected = TestBed.inject(Router) as jasmine.SpyObj<Router>;
const spy = injected.navigateByUrl;
component.switchInstance('NEWINST');
expect(spy).toHaveBeenCalledWith('/NEWINST');
......@@ -137,7 +138,8 @@ describe('SubsystemListComponent', () => {
fixture = TestBed.createComponent(SubsystemListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
const spy = TestBed.get(ViewportScroller).scrollToPosition;
const injected = TestBed.inject(ViewportScroller) as jasmine.SpyObj<ViewportScroller>;
const spy = injected.scrollToPosition;
spy.calls.reset();
component.scrollToTop();
expect(spy).toHaveBeenCalledWith([0, 0]);
......@@ -150,13 +152,13 @@ describe('SubsystemListComponent', () => {
subsystemsService.filteredSubsystemsSubject.next([new Subsystem(), new Subsystem()]);
const getLimitSpy = spyOn(subsystemsService, 'getLimit').and.returnValue(['all']);
const getLimitSpy = spyOn(subsystemsService, 'getLimit').and.returnValue('all');
expect(component.isPartialList()).toBeFalsy();