X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=webapp-frontend%2Fsrc%2Fapp%2Fei-coordinator%2Fjobs-list%2Fjobs-list.component.spec.ts;h=7ccb80d02777f55753b0bbe06b8d411afa10b191;hb=199867d823a88d154b1dcfe5faed8713c76d5880;hp=24750ebeb0bb3748e96bcbcd055f1dfc90399272;hpb=f8f8ed0d00fb9c8ba0ca88f180cad5f13381db2a;p=portal%2Fnonrtric-controlpanel.git diff --git a/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.spec.ts b/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.spec.ts index 24750eb..7ccb80d 100644 --- a/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.spec.ts +++ b/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.spec.ts @@ -17,145 +17,527 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { HarnessLoader } from '@angular/cdk/testing'; -import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, FormBuilder } from '@angular/forms'; -import { MatInputHarness } from '@angular/material/input/testing'; -import { MatTableModule } from '@angular/material/table'; -import { MatTableHarness } from '@angular/material/table/testing'; -import { of } from 'rxjs/observable/of'; -import { EIJob } from 'src/app/interfaces/ei.types'; -import { UiService } from 'src/app/services/ui/ui.service'; -import { EIJobDataSource } from '../ei-job.datasource'; - -import { JobsListComponent } from './jobs-list.component'; - -describe('JobsListComponent', () => { - let component: JobsListComponent; - let fixture: ComponentFixture; +import { HarnessLoader } from "@angular/cdk/testing"; +import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; +import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { + async, + ComponentFixture, + discardPeriodicTasks, + fakeAsync, + TestBed, + tick, +} from "@angular/core/testing"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { MatFormFieldModule } from "@angular/material/form-field"; +import { MatInputModule } from "@angular/material/input"; +import { MatInputHarness } from "@angular/material/input/testing"; +import { MatPaginatorModule } from "@angular/material/paginator"; +import { MatSortModule } from "@angular/material/sort"; +import { MatSortHarness } from "@angular/material/sort/testing"; +import { MatPaginatorHarness } from "@angular/material/paginator/testing"; +import { MatTableModule } from "@angular/material/table"; +import { MatTableHarness } from "@angular/material/table/testing"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { of } from "rxjs/observable/of"; +import { EIJob } from "@interfaces/ei.types"; +import { EIService } from "@services/ei/ei.service"; +import { UiService } from "@services/ui/ui.service"; + +import { Job, JobsListComponent } from "./jobs-list.component"; +import { Subscription } from "rxjs"; + +let component: JobsListComponent; +let fixture: ComponentFixture; + +const eijob1 = { + ei_job_identity: "job1", + ei_type_identity: "type1", + owner: "owner1", + target_uri: "http://one", +} as EIJob; +const eijob2 = { + ei_job_identity: "job2", + ei_type_identity: "type2", + owner: "owner2", + target_uri: "http://two", +} as EIJob; + +const job1 = { + jobId: "job1", + typeId: "type1", + owner: "owner1", + targetUri: "http://one", + prodId: "producer1", +} as Job; +const job2 = { + jobId: "job2", + typeId: "type2", + owner: "owner2", + targetUri: "http://two", + prodId: "producer1", +} as Job; +const job3 = { + jobId: "job1", + typeId: "type1", + owner: "owner1", + targetUri: "http://one", + prodId: "producer2", +} as Job; +const job4 = { + jobId: "job2", + typeId: "type2", + owner: "owner2", + targetUri: "http://two", + prodId: "producer2", +} as Job; + +describe("JobsListComponent", () => { let loader: HarnessLoader; - let eiJobComponent: jasmine.SpyObj; - let jobDataSourceSpy: jasmine.SpyObj; - - const job1 = { - ei_job_identity: 'job1', - ei_type_identity: 'type1', - owner: 'owner1', - target_uri: 'http://one' - } as EIJob; - const job2 = { - ei_job_identity: 'job2', - ei_type_identity: 'type2', - owner: 'owner2', - target_uri: 'http://two' - } as EIJob; beforeEach(async(() => { - eiJobComponent = jasmine.createSpyObj('producersListSpy', ['refresh']); - jobDataSourceSpy = jasmine.createSpyObj('EIJobDataSource', ['loadJobs', 'eiJobs', 'eiJobsSubject']); - - jobDataSourceSpy.eiJobsSubject.and.returnValue(of([job1, job2])); + const spy = jasmine.createSpyObj("EIService", [ + "getProducerIds", + "getJobsForProducer", + ]); TestBed.configureTestingModule({ imports: [ MatTableModule, - ReactiveFormsModule - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA + MatPaginatorModule, + FormsModule, + MatSortModule, + ReactiveFormsModule, + BrowserAnimationsModule, + MatFormFieldModule, + MatInputModule, ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [JobsListComponent], - providers: [ - { provide: EIJobDataSource, useValue: jobDataSourceSpy }, - UiService, - FormBuilder, - ] + providers: [{ provide: EIService, useValue: spy }, UiService], }) - .compileComponents(); + .compileComponents() + .then(() => { + fixture = TestBed.createComponent(JobsListComponent); + component = fixture.componentInstance; + loader = TestbedHarnessEnvironment.loader(fixture); + }); })); - const expectedJob1Row = { id: 'job1', typeId: 'type1', owner: 'owner1', targetUri: 'http://one' }; - - beforeEach(() => { - fixture = TestBed.createComponent(JobsListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - loader = TestbedHarnessEnvironment.loader(fixture); - }); + const expectedJob1Row = { + jobId: "job1", + prodId: "producer1", + typeId: "type1", + owner: "owner1", + targetUri: "http://one", + }; - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - it('should contain job table with correct columns', async () => { - let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' })); - let headerRow = (await producersTable.getHeaderRows())[0]; - let headers = await headerRow.getCellTextByColumnName(); + describe("#content", () => { + it("should loadJobs", fakeAsync(() => { + setServiceSpy(); + const newSub: Subscription = component.dataSubscription(); + tick(0); - expect(headers).toEqual({ id: 'Job ID', typeId: 'Type ID', owner: 'Owner', targetUri: 'Target URI' }); + const actualJobs: Job[] = component.jobs(); + expect(actualJobs.length).toEqual(4); + expect(actualJobs).toEqual([job1, job2, job3, job4]); + newSub.unsubscribe(); + })); + + it("should contain job table with correct columns", fakeAsync(() => { + setServiceSpy(); + component.ngOnInit(); + tick(0); + + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + loadTable.getHeaderRows().then((headerRow) => { + headerRow[0].getCellTextByColumnName().then((header) => { + expect(header).toEqual({ + jobId: "Job ID", + prodId: "Producer ID", + typeId: "Type ID", + owner: "Owner", + targetUri: "Target URI", + }); + }); + }); + }); + + discardPeriodicTasks(); + })); + + it("should set correct dark mode from UIService", fakeAsync(() => { + setServiceSpy(); + component.ngOnInit(); + tick(0); + + const uiService: UiService = TestBed.inject(UiService); + expect(component.darkMode).toBeTruthy(); + + uiService.darkModeState.next(false); + fixture.detectChanges(); + expect(component.darkMode).toBeFalsy(); + discardPeriodicTasks(); + })); }); - it('should contain data after initialization', async () => { - component.ngOnInit(); - const expectedJobRows = [ - expectedJob1Row, - { id: 'job2', typeId: 'type2', owner: 'owner2', targetUri: 'http://two' } - ]; - let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' })); - let jobRows = await jobsTable.getRows(); - expect(jobRows.length).toEqual(2); - jobRows.forEach(row => { - row.getCellTextByColumnName().then(values => { - expect(expectedJobRows).toContain(jasmine.objectContaining(values)); - }); + describe("#jobsTable", () => { + it("should contain data after initialization", fakeAsync(() => { + setServiceSpy(); + component.ngOnInit(); + tick(0); + + const expectedJobRows = [ + expectedJob1Row, + { + jobId: "job2", + prodId: "producer1", + typeId: "type2", + owner: "owner2", + targetUri: "http://two", + }, + { + jobId: "job1", + prodId: "producer2", + typeId: "type1", + owner: "owner1", + targetUri: "http://one", + }, + { + jobId: "job2", + prodId: "producer2", + typeId: "type2", + owner: "owner2", + targetUri: "http://two", + }, + ]; + + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(4); + jobRows.forEach((row) => { + row.getCellTextByColumnName().then((values) => { + expect(expectedJobRows).toContain( + jasmine.objectContaining(values) + ); + }); + }); + }); + }); + discardPeriodicTasks(); + })); + + it("should display default values for non required properties ", fakeAsync(() => { + const jobMissingProperties = { + ei_job_identity: "job1", + ei_job_data: { + jobparam2: "value2_job2", + jobparam3: "value3_job2", + jobparam1: "value1_job2", + }, + target_uri: "http://one", + } as EIJob; + + let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj; + eiServiceSpy.getProducerIds.and.returnValue(of(["producer1"])); + eiServiceSpy.getJobsForProducer.and.returnValue( + of([jobMissingProperties]) + ); + + component.ngOnInit(); + tick(0); + const expectedJobRow = { + jobId: "job1", + prodId: "producer1", + typeId: "< No type >", + owner: "< No owner >", + targetUri: "http://one", + }; + + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + loadTable.getRows().then((jobRows) => { + jobRows[0].getCellTextByColumnName().then((value) => { + expect(expectedJobRow).toContain(jasmine.objectContaining(value)); + }); + }); + }); + discardPeriodicTasks(); + })); + + it("filtering", fakeAsync(() => { + setServiceSpy(); + component.ngOnInit(); + tick(0); + + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + loader + .getHarness(MatInputHarness.with({ selector: "#jobIdFilter" })) + .then((idFilter) => { + idFilter.setValue("1"); + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(2); + jobRows[0].getCellTextByColumnName().then((value) => { + expect(expectedJob1Row).toContain( + jasmine.objectContaining(value) + ); + }); + }); + idFilter.setValue(""); + }); + loader + .getHarness(MatInputHarness.with({ selector: "#jobTypeIdFilter" })) + .then((typeIdFilter) => { + typeIdFilter.setValue("1"); + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(2); + jobRows[0].getCellTextByColumnName().then((value) => { + expect(expectedJob1Row).toContain( + jasmine.objectContaining(value) + ); + }); + }); + typeIdFilter.setValue(""); + }); + loader + .getHarness(MatInputHarness.with({ selector: "#jobOwnerFilter" })) + .then((ownerFilter) => { + ownerFilter.setValue("1"); + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(2); + jobRows[0].getCellTextByColumnName().then((value) => { + expect(expectedJob1Row).toContain( + jasmine.objectContaining(value) + ); + }); + }); + ownerFilter.setValue(""); + }); + loader + .getHarness( + MatInputHarness.with({ selector: "#jobTargetUriFilter" }) + ) + .then((targetUriFilter) => { + targetUriFilter.setValue("1"); + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(2); + jobRows[0].getCellTextByColumnName().then((value) => { + expect(expectedJob1Row).toContain( + jasmine.objectContaining(value) + ); + }); + }); + targetUriFilter.setValue(""); + }); + }); + + discardPeriodicTasks(); + })); + + describe("#sorting", () => { + it("should verify sort functionality on the table", fakeAsync(() => { + setServiceSpy(); + tick(0); + + loader.getHarness(MatSortHarness).then((sort) => { + sort.getSortHeaders({ sortDirection: "" }).then((headers) => { + expect(headers.length).toBe(5); + + headers[0].click().then((_) => { + headers[0].isActive().then((active) => { + expect(active).toBe(true); + }); + headers[0].getSortDirection().then((direction) => { + expect(direction).toBe("asc"); + }); + }); + headers[0].click().then((_) => { + headers[0].getSortDirection().then((direction) => { + expect(direction).toBe("desc"); + }); + }); + }); + }); + discardPeriodicTasks(); + })); + + it("should sort table asc and desc by first header", fakeAsync(() => { + setServiceSpy(); + tick(0); + + loader.getHarness(MatSortHarness).then((sort) => { + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + sort.getSortHeaders().then((headers) => { + headers[0].click().then((_) => { + headers[0].getSortDirection().then((direction) => { + expect(direction).toBe(""); + }); + }); + headers[0].click().then((_) => { + headers[0].getSortDirection().then((direction) => { + expect(direction).toBe("asc"); + }); + }); + loadTable.getRows().then((jobRows) => { + jobRows[0].getCellTextByColumnName().then((value) => { + expect(expectedJob1Row).toContain( + jasmine.objectContaining(value) + ); + }); + }); + headers[0].click().then((_) => { + headers[0].getSortDirection().then((direction) => { + expect(direction).toBe("desc"); + }); + }); + loadTable.getRows().then((jobRows) => { + jobRows[jobRows.length - 1] + .getCellTextByColumnName() + .then((value) => { + expect(expectedJob1Row).toContain( + jasmine.objectContaining(value) + ); + }); + }); + }); + }); + }); + discardPeriodicTasks(); + })); + + it("should not sort when clicking on filtering box", fakeAsync(() => { + setServiceSpy(); + component.ngOnInit(); + tick(0); + + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + loadTable.getRows().then((jobRows) => { + let jobIds, jobTypeIds, jobOwner, jobTargetUri: String[]; + for (let i = 0; i < jobRows.length; i++) { + jobRows[i].getCellTextByColumnName().then((value) => { + jobIds.push(value[0]); + jobTypeIds.push(value[2]); + jobOwner.push(value[3]); + jobTargetUri.push(value[4]); + }); + }; + loader + .getHarness(MatInputHarness.with({ selector: "#jobIdFilter"})) + .then((idFilter) => { + let unfilteredJobIds: String[]; + idFilter.setValue(""); + for (let i = 0; i < jobRows.length; i++) { + jobRows[i].getCellTextByColumnName().then((value) => { + unfilteredJobIds.push(value[0]); + }); + }; + expect(unfilteredJobIds).toBe(jobIds); + }); + loader + .getHarness(MatInputHarness.with({ selector: "#jobTypeIdFilter"})) + .then((idFilter) => { + let unfilteredJobTypeIds: String[]; + idFilter.setValue(""); + for (let i = 0; i < jobRows.length; i++) { + jobRows[i].getCellTextByColumnName().then((value) => { + unfilteredJobTypeIds.push(value[2]); + }); + }; + expect(unfilteredJobTypeIds).toBe(jobTypeIds); + }); + loader + .getHarness(MatInputHarness.with({ selector: "#jobOwnerFilter"})) + .then((idFilter) => { + let unfilteredJobOwner: String[]; + idFilter.setValue(""); + for (let i = 0; i < jobRows.length; i++) { + jobRows[i].getCellTextByColumnName().then((value) => { + unfilteredJobOwner.push(value[3]); + }); + }; + expect(unfilteredJobOwner).toBe(jobOwner); + }); + loader + .getHarness(MatInputHarness.with({ selector: "#jobTargetUriFilter"})) + .then((idFilter) => { + let unfilteredJobTargetUri: String[]; + idFilter.setValue(""); + for (let i = 0; i < jobRows.length; i++) { + jobRows[i].getCellTextByColumnName().then((value) => { + unfilteredJobTargetUri.push(value[4]); + }); + }; + expect(unfilteredJobTargetUri).toBe(jobTargetUri); + }); + }); + }); + discardPeriodicTasks(); + })); }); - }); - it('should display default values for non required properties ', async () => { - const jobMissingProperties = { - ei_job_identity: 'job1', - target_uri: 'http://one' - } as EIJob; - const jobs: EIJob[] = [jobMissingProperties]; - jobDataSourceSpy.eiJobsSubject.and.returnValue(of(jobs)); - component.ngOnInit(); - - const expectedJobRow = { id: 'job1', typeId: '< No type >', owner: '< No owner >', targetUri: 'http://one' }; - let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' })); - let jobRows = await jobsTable.getRows(); - expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJobRow); - }); + describe("#paging", () => { + it("should work properly on the table", fakeAsync(() => { + let eiServiceSpy = TestBed.inject( + EIService + ) as jasmine.SpyObj; + eiServiceSpy.getProducerIds.and.returnValue( + of(["producer1", "producer2"]) + ); + eiServiceSpy.getJobsForProducer.and.returnValue( + of([eijob1, eijob2, eijob1]) + ); + tick(0); + + loader.getHarness(MatPaginatorHarness).then((paging) => { + paging.setPageSize(5); - it('filtering', async () => { - component.ngOnInit(); - let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' })); - - let idFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobIdFilter' })); - await idFilterInput.setValue("1"); - let jobRows = await jobsTable.getRows(); - expect(jobRows.length).toEqual(1); - expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row); - - idFilterInput.setValue(''); - let typeIdFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobTypeIdFilter' })); - await typeIdFilterInput.setValue("1"); - jobRows = await jobsTable.getRows(); - expect(jobRows.length).toEqual(1); - - typeIdFilterInput.setValue(''); - let ownerFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobOwnerFilter' })); - await ownerFilterInput.setValue("1"); - jobRows = await jobsTable.getRows(); - expect(jobRows.length).toEqual(1); - expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row); - - ownerFilterInput.setValue(''); - let targetUriFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobTargetUriFilter' })); - await targetUriFilterInput.setValue("one"); - jobRows = await jobsTable.getRows(); - expect(jobRows.length).toEqual(1); - expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row); + loader + .getHarness(MatTableHarness.with({ selector: "#jobsTable" })) + .then((loadTable) => { + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(5); + }); + paging.goToNextPage(); + loadTable.getRows().then((jobRows) => { + expect(jobRows.length).toEqual(1); + jobRows[0].getCellTextByColumnName().then((value) => { + const expectedRow = { + jobId: "job1", + prodId: "producer2", + typeId: "type1", + owner: "owner1", + targetUri: "http://one", + }; + expect(expectedRow).toContain( + jasmine.objectContaining(value) + ); + }); + }); + }); + }); + discardPeriodicTasks(); + })); + }); }); }); + +function setServiceSpy() { + let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj; + eiServiceSpy.getProducerIds.and.returnValue(of(["producer1", "producer2"])); + eiServiceSpy.getJobsForProducer.and.returnValue(of([eijob1, eijob2])); +}