Skip to content

Commit

Permalink
BRS-1087: Add unit tests for components site-metrics and metrics-filt…
Browse files Browse the repository at this point in the history
…er (#258)

* BRS-1087: Add unit tests for components site-metrics and metrics-filter

* BRS-1087: Remove commented out line
  • Loading branch information
wilwong89 authored Mar 29, 2023
1 parent f0c7b26 commit 10763b1
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 13 deletions.
84 changes: 79 additions & 5 deletions src/app/metrics/metrics-filter/metrics-filter.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,55 @@
import { HttpClientModule } from '@angular/common/http';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Constants } from '../../shared/utils/constants';
import { ConfigService } from 'src/app/services/config.service';
import { DataService } from 'src/app/services/data.service';
import { MockData } from 'src/app/shared/utils/mock-data';
import { BehaviorSubject } from 'rxjs';

import { MetricsFilterComponent } from './metrics-filter.component';
import { SharedMetricsModule } from '../../shared/components/metrics/shared-metrics.module';
import { DsFormsModule } from '../../shared/components/ds-forms/ds-forms.module'

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

let mockData = MockData.mockParkFacility_1

let mockPark1 = MockData.mockPark_1;
let mockPark2 = MockData.mockPark_2;

let mockFacility1 = MockData.mockFacility_1
let mockFacility2 = MockData.mockFacility_2
let mockFacility3 = MockData.mockFacility_3

let mockDataService = {
watchItem: (id) => {
if (id === Constants.dataIds.PARK_AND_FACILITY_LIST) {
return new BehaviorSubject(mockData);
} else if (id === Constants.dataIds.METRICS_FILTERS_PARAMS) {
return new BehaviorSubject([mockFacility1,mockFacility2,mockFacility3])
}
return new BehaviorSubject(null);
},
};

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MetricsFilterComponent ],
imports: [ReactiveFormsModule, FormsModule, HttpClientModule],
providers: [ConfigService]
})
.compileComponents();
declarations: [MetricsFilterComponent],
imports: [
ReactiveFormsModule,
FormsModule,
HttpClientModule,
SharedMetricsModule,
DsFormsModule
],
providers: [
ConfigService,
{ provide: DataService, useValue: mockDataService },
],
}).compileComponents();

fixture = TestBed.createComponent(MetricsFilterComponent);
component = fixture.componentInstance;
Expand All @@ -25,4 +59,44 @@ describe('MetricsFilterComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

it('should have initial values', () => {
expect(component.timeSpanOptions).toEqual(['year', 'month', 'week']);
expect(component.timeSpanLabels).toEqual(['12M', '30D', '7D']);
expect(component.fileTypeOptions).toEqual([
{ value: 'pdf', display: 'PDF' },
{ value: 'csv', display: 'CSV' },
{ value: 'json', display: 'JSON' },
]);
});

it('should toggle outputs to true', () => {
component.selectAllExports(false);
component.selectAllExports(true);

expect(component.fields.exportBusiestDays.value).toBeTrue();
expect(component.fields.exportPassActivityByDay.value).toBeTrue();
expect(component.fields.exportPassTrendsByHour.value).toBeTrue();
expect(component.fields.exportPassBreakdownByStatus.value).toBeTrue();
expect(component.fields.exportReturningGuests.value).toBeTrue();
});

it('should toggle outputs to false', () => {
component.selectAllExports(true);
component.selectAllExports(false);

expect(component.fields.exportBusiestDays.value).toBeFalse();
expect(component.fields.exportPassActivityByDay.value).toBeFalse();
expect(component.fields.exportPassTrendsByHour.value).toBeFalse();
expect(component.fields.exportPassBreakdownByStatus.value).toBeFalse();
expect(component.fields.exportReturningGuests.value).toBeFalse();
});

it('should populate park list', () => {
let tempParkOptions = []
for (const park of Object.keys(component.parkFacilitiesList)) {
tempParkOptions.push({ value: park, display: component.parkFacilitiesList[park].name });
}
expect(component.parkOptions).toEqual(tempParkOptions)
})
});
1 change: 0 additions & 1 deletion src/app/metrics/metrics-filter/metrics-filter.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ export class MetricsFilterComponent extends BaseFormComponent {
}

selectAllExports(select: boolean) {
console.log('select:', select);
if (select) {
this.fields.exportBusiestDays.setValue(true);
this.fields.exportPassActivityByDay.setValue(true);
Expand Down
149 changes: 143 additions & 6 deletions src/app/metrics/site-metrics/site-metrics.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,164 @@
import { HttpClientModule } from '@angular/common/http';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {
ComponentFixture,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing';
import { ConfigService } from 'src/app/services/config.service';
import { Constants } from '../../shared/utils/constants';
import { BehaviorSubject } from 'rxjs';
import { DataService } from 'src/app/services/data.service';
import { MockData } from 'src/app/shared/utils/mock-data';

import { SiteMetricsComponent } from './site-metrics.component';
import { SharedMetricsModule } from '../../shared/components/metrics/shared-metrics.module';

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

let buildSpy;
const testSk = '37bbecdf38089efe13af862dc9d6f460'

let testMetricsData1 = MockData.metricsData1;
let testMetricsData2 = MockData.metricsData2;

let testSubject = new BehaviorSubject(testMetricsData1);

let fakeDataService = {
watchItem: () => {
return testSubject;
},
};

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SiteMetricsComponent ],
imports: [HttpClientModule],
providers: [ConfigService]
})
.compileComponents();
declarations: [SiteMetricsComponent],
imports: [HttpClientModule, SharedMetricsModule],
providers: [
ConfigService,
{ provide: DataService, useValue: fakeDataService },
],
}).compileComponents();

fixture = TestBed.createComponent(SiteMetricsComponent);
component = fixture.componentInstance;
buildSpy = spyOn(component, 'buildCharts').and.callThrough();
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
expect(component.isGenerating).toBeFalse();
expect(buildSpy).toHaveBeenCalledTimes(0);
});

it('should load metrics data into component', async () => {
let data = testMetricsData1;
expect(component.passActive).toEqual(data.active);
expect(component.passExpired).toEqual(data.expired);
expect(component.passReserved).toEqual(data.reserved);
expect(component.passExpired).toEqual(data.expired);
});

it('should update metrics with new data', async () => {
let data = testMetricsData2;

component.buildCharts(data);

await fixture.isStable();
expect(component.passActive).toEqual(data.active);
expect(component.passExpired).toEqual(data.expired);
expect(component.passReserved).toEqual(data.reserved);
expect(component.passExpired).toEqual(data.expired);
});

it('should handle generate export report click', fakeAsync(async () => {
let getPassExportSpy = spyOn(component, 'getPassExport');
let apiSpy = spyOn(component['apiService'], 'get').and.returnValue(
new BehaviorSubject({
status: 'Export job created',
sk: '37bbecdf38089efe13af862dc9d6f460',
})
);

const buttons =
fixture.debugElement.nativeElement.querySelectorAll('button');
buttons[0].click();
tick(1200);
await fixture.isStable();
fixture.detectChanges();

expect(getPassExportSpy).toHaveBeenCalledTimes(1);
expect(apiSpy).toHaveBeenCalledTimes(1);
expect(component.isGenerating).toBeTrue();
expect(component.signedURL).toBeNull();
expect(component.statusMessage).toBeTruthy();
}));

it('should test when API call finds no export report', async () => {
let toastService = spyOn(component['toastService'], 'addMessage')
let apiSpy = spyOn(component['apiService'], 'get').and.returnValue(
new BehaviorSubject({
status: 'Job not found',
sk: testSk
})
);

component.getPassExport(testSk)
await fixture.isStable();
fixture.detectChanges();

expect(apiSpy).toHaveBeenCalledTimes(1);
expect(component.isGenerating).toBeFalse();
expect(component.signedURL).toBeUndefined();
expect(component.buttonText).toBe('Export Pass Data');
expect(toastService).toHaveBeenCalledWith(
`Sorry, that didn't work. Please try again.`,
'Export Service',
Constants.ToastTypes.ERROR
)
})

it('should test when API call finds export report ready', fakeAsync(async () => {
let testSignedURL = 'www.google.ca'
let toastService = spyOn(component['toastService'], 'addMessage')
let apiSpy = spyOn(component['apiService'], 'get').and.returnValue(
new BehaviorSubject({
status: 'Job complete',
sk: testSk,
signedURL: testSignedURL,
jobObj: {
progressPercentage: 100
}
})
);
let windowSpy = spyOn(window, 'open')

component.getPassExport(testSk)
await fixture.isStable();
fixture.detectChanges();

expect(apiSpy).toHaveBeenCalledTimes(1);
expect(component.isGenerating).toBeFalse();
expect(component.signedURL).toEqual(testSignedURL);
expect(component.buttonText).toBe('Export Pass Data');
expect(toastService).toHaveBeenCalledWith(
`Your report is downloading.`,
'Export Service',
Constants.ToastTypes.SUCCESS
)

tick(5500)
expect(windowSpy).toHaveBeenCalledOnceWith(
testSignedURL, '_blank'
)
}))

it('should unsubscribe on destroy', async () => {
const subSpy = spyOn<any>(component['subscriptions'], 'unsubscribe');
component.ngOnDestroy();
expect(subSpy).toHaveBeenCalledTimes(1);
});
});
1 change: 0 additions & 1 deletion src/app/metrics/site-metrics/site-metrics.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export class SiteMetricsComponent implements OnDestroy {
labels.push(item);
data.push(res[item]);
passTotal += res[item];
console.log(item);
switch (item) {
case Constants.stateLabelDictionary.active.state:
this.passActive = res[item];
Expand Down
14 changes: 14 additions & 0 deletions src/app/shared/utils/mock-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,18 @@ export class MockData {
},
},
};

public static readonly metricsData1 = {
'active': 2,
'reserved': 30,
'cancelled': 400,
'expired': 5000
}

public static readonly metricsData2 = {
'active': 1,
'reserved': 20,
'cancelled': 300,
'expired': 4000
}
}

0 comments on commit 10763b1

Please sign in to comment.