diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml new file mode 100644 index 0000000..125aead --- /dev/null +++ b/.github/workflows/testing.yaml @@ -0,0 +1,25 @@ +name: Testing + +env: + NODE_VERSION: 20.18 + +on: 'push' +jobs: + testing: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm run test:ci diff --git a/package.json b/package.json index 887cbb9..8229193 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", + "test:ci": "ng test --no-watch --no-progress --browsers=ChromeHeadless", "lint": "ng lint" }, "private": true, diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index d5ed01b..d3be6ce 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,11 +1,13 @@ import { TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; +import {TestingModule} from "./testing.module"; +import {MatToolbarModule} from "@angular/material/toolbar"; +import {AppModule} from "./app.module"; describe('AppComponent', () => { beforeEach(() => TestBed.configureTestingModule({ - imports: [RouterTestingModule], + imports: [TestingModule, MatToolbarModule, AppModule], declarations: [AppComponent], }), ); @@ -15,19 +17,4 @@ describe('AppComponent', () => { const app = fixture.componentInstance; expect(app).toBeTruthy(); }); - - it(`should have as title 'federated-catalog-viewer-ui'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('federated-catalog-viewer-ui'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('.content span')?.textContent).toContain( - 'federated-catalog-viewer-ui app is running!', - ); - }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 6b6378e..b9076eb 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; import { AuthService } from './services/auth.service'; import { Subscription } from 'rxjs'; @@ -10,9 +9,9 @@ import { Subscription } from 'rxjs'; }) export class AppComponent implements OnInit, OnDestroy { username: string | null = null; - private usernameSubscription!: Subscription; + private usernameSubscription?: Subscription; - constructor(private router: Router, private authService: AuthService) {} + constructor( private authService: AuthService) {} ngOnInit(): void { this.usernameSubscription = this.authService.username$.subscribe((username) => { @@ -25,7 +24,7 @@ export class AppComponent implements OnInit, OnDestroy { } ngOnDestroy(): void { - this.usernameSubscription.unsubscribe(); + this.usernameSubscription?.unsubscribe(); } isLoggedIn(): boolean { return this.authService.isLoggedIn(); diff --git a/src/app/components/authentication/authentication.component.spec.ts b/src/app/components/authentication/authentication.component.spec.ts index 5aad49a..6bebe10 100644 --- a/src/app/components/authentication/authentication.component.spec.ts +++ b/src/app/components/authentication/authentication.component.spec.ts @@ -1,6 +1,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AuthenticationComponent } from './authentication.component'; +import {TestingModule} from "../../testing.module"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {NO_ERRORS_SCHEMA} from "@angular/core"; +import {MatInputModule} from "@angular/material/input"; +import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; describe('AuthenticationComponent', () => { let component: AuthenticationComponent; @@ -8,7 +13,9 @@ describe('AuthenticationComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AuthenticationComponent], + imports: [TestingModule, MatFormFieldModule, MatInputModule, BrowserAnimationsModule], + declarations: [AuthenticationComponent], + schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); fixture = TestBed.createComponent(AuthenticationComponent); diff --git a/src/app/components/catalog-browser/catalog-browser.component.html b/src/app/components/catalog-browser/catalog-browser.component.html index 0e8839e..2bf2cb3 100644 --- a/src/app/components/catalog-browser/catalog-browser.component.html +++ b/src/app/components/catalog-browser/catalog-browser.component.html @@ -1,9 +1,6 @@ - - {{ '"' + (label | async) + '" Entries' }} - - Browse Catalog Contents + Browse Catalog Contents diff --git a/src/app/components/catalog-browser/catalog-browser.component.spec.ts b/src/app/components/catalog-browser/catalog-browser.component.spec.ts index 5b4cf2c..6347f31 100644 --- a/src/app/components/catalog-browser/catalog-browser.component.spec.ts +++ b/src/app/components/catalog-browser/catalog-browser.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CatalogBrowserComponent } from './catalog-browser.component'; +import {TestingModule} from "../../testing.module"; +import {MatCardModule} from "@angular/material/card"; describe('CatalogBrowserComponent', () => { let component: CatalogBrowserComponent; @@ -8,6 +10,7 @@ describe('CatalogBrowserComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [TestingModule, MatCardModule], declarations: [CatalogBrowserComponent], }); fixture = TestBed.createComponent(CatalogBrowserComponent); diff --git a/src/app/components/catalog-browser/catalog-browser.component.ts b/src/app/components/catalog-browser/catalog-browser.component.ts index be9e722..43024ba 100644 --- a/src/app/components/catalog-browser/catalog-browser.component.ts +++ b/src/app/components/catalog-browser/catalog-browser.component.ts @@ -1,7 +1,7 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, } from '@angular/core'; import { NodeQueryResult } from '../../types/dtos'; import { QueryService } from '../../services/query.service'; -import { ActivatedRoute } from '@angular/router'; + import { BehaviorSubject, combineLatest, Observable, Subject } from 'rxjs'; import { map, switchMap, scan, startWith, concatMap } from 'rxjs/operators'; @@ -10,7 +10,7 @@ import { map, switchMap, scan, startWith, concatMap } from 'rxjs/operators'; templateUrl: './catalog-browser.component.html', styleUrls: ['./catalog-browser.component.scss'], }) -export class CatalogBrowserComponent implements OnInit { +export class CatalogBrowserComponent{ public readonly data$: Observable<{ totalCount: number; nodes: NodeQueryResult[] }>; public readonly selectedTab$ = new BehaviorSubject(0); public readonly limit$ = new BehaviorSubject(30); @@ -18,7 +18,7 @@ export class CatalogBrowserComponent implements OnInit { public readonly tabs = ['Legal Participant', 'Service Offering', 'Resource']; - constructor(private _queryService: QueryService, private _activatedRoute: ActivatedRoute) { + constructor(private _queryService: QueryService) { const selectedKey$ = this.selectedTab$.pipe( map((selectedTab) => ['LegalParticipant', 'ServiceOffering', 'Resource'][selectedTab]), ); @@ -48,13 +48,6 @@ export class CatalogBrowserComponent implements OnInit { ); } - pageSizes = [30, 50, 100, 200]; - label?: Observable; - - ngOnInit(): void { - this.label = this._activatedRoute.queryParams.pipe(map((params) => params['label'])); - } - protected fetchNodesAndCount( key: string, limit: number, @@ -66,10 +59,6 @@ export class CatalogBrowserComponent implements OnInit { ]).pipe(map(([nodes, totalCount]) => ({ nodes, totalCount }))); } - onPageSizeChange(newSize: number): void { - this.limit$.next(newSize); - } - onTabChange(index: number): void { this.selectedTab$.next(index); } diff --git a/src/app/components/node-details/node-details.component.spec.ts b/src/app/components/node-details/node-details.component.spec.ts index 3b2f495..2a32af5 100644 --- a/src/app/components/node-details/node-details.component.spec.ts +++ b/src/app/components/node-details/node-details.component.spec.ts @@ -1,6 +1,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NodeDetailsComponent } from './node-details.component'; +import {TestingModule} from "../../testing.module"; +import {ActivatedRoute} from "@angular/router"; +import {of} from "rxjs"; describe('NodeDetailsComponent', () => { let component: NodeDetailsComponent; @@ -8,7 +11,16 @@ describe('NodeDetailsComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [TestingModule], declarations: [NodeDetailsComponent], + providers: [ + { + provide: ActivatedRoute, + useValue: { + params: of({ id: 123 }), + }, + }, + ] }); fixture = TestBed.createComponent(NodeDetailsComponent); component = fixture.componentInstance; diff --git a/src/app/components/node-labels/node-labels.component.spec.ts b/src/app/components/node-labels/node-labels.component.spec.ts index 4825eb3..20b7225 100644 --- a/src/app/components/node-labels/node-labels.component.spec.ts +++ b/src/app/components/node-labels/node-labels.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NodeLabelsComponent } from './node-labels.component'; +import {TestingModule} from "../../testing.module"; +import {MatChipsModule} from "@angular/material/chips"; describe('NodeLabelsComponent', () => { let component: NodeLabelsComponent; @@ -8,6 +10,7 @@ describe('NodeLabelsComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [TestingModule, MatChipsModule], declarations: [NodeLabelsComponent], }); fixture = TestBed.createComponent(NodeLabelsComponent); diff --git a/src/app/components/node-table/node-table.component.spec.ts b/src/app/components/node-table/node-table.component.spec.ts index 77850d2..a2ac331 100644 --- a/src/app/components/node-table/node-table.component.spec.ts +++ b/src/app/components/node-table/node-table.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NodeTableComponent } from './node-table.component'; +import {TestingModule} from "../../testing.module"; +import {MatTableModule} from "@angular/material/table"; describe('NodeTableComponent', () => { let component: NodeTableComponent; @@ -8,6 +10,7 @@ describe('NodeTableComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [TestingModule, MatTableModule], declarations: [NodeTableComponent], }); fixture = TestBed.createComponent(NodeTableComponent); diff --git a/src/app/components/query/query.component.spec.ts b/src/app/components/query/query.component.spec.ts index 2f9eab2..3aa588e 100644 --- a/src/app/components/query/query.component.spec.ts +++ b/src/app/components/query/query.component.spec.ts @@ -1,6 +1,14 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { QueryComponent } from './query.component'; +import {TestingModule} from "../../testing.module"; +import {of} from "rxjs"; +import {ActivatedRoute} from "@angular/router"; +import {MatCardModule} from "@angular/material/card"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {MatInputModule} from "@angular/material/input"; +import {ReactiveFormsModule} from "@angular/forms"; +import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; describe('QueryComponent', () => { let component: QueryComponent; @@ -8,7 +16,17 @@ describe('QueryComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [TestingModule, MatCardModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, BrowserAnimationsModule + ], declarations: [QueryComponent], + providers: [ + { + provide: ActivatedRoute, + useValue: { + queryParams: of({ query: "test" }), + }, + }, + ] }); fixture = TestBed.createComponent(QueryComponent); component = fixture.componentInstance; diff --git a/src/app/services/query.service.spec.ts b/src/app/services/query.service.spec.ts index aee81ad..f740dc5 100644 --- a/src/app/services/query.service.spec.ts +++ b/src/app/services/query.service.spec.ts @@ -1,12 +1,15 @@ import { TestBed } from '@angular/core/testing'; import { QueryService } from './query.service'; +import {TestingModule} from "../testing.module"; describe('QueryService', () => { let service: QueryService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + imports: [TestingModule] + }); service = TestBed.inject(QueryService); }); diff --git a/src/app/testing.module.ts b/src/app/testing.module.ts index e69de29..b8cd7eb 100644 --- a/src/app/testing.module.ts +++ b/src/app/testing.module.ts @@ -0,0 +1,12 @@ +import {provideHttpClientTesting} from "@angular/common/http/testing"; +import {provideHttpClient} from "@angular/common/http"; +import {NgModule} from "@angular/core"; + +@NgModule({ + imports: [], + providers: [ + provideHttpClient(), + provideHttpClientTesting(), + ], +}) +export class TestingModule {}