From 2e768fb49108ffe60f2552c17dda03feeb954196 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 25 Jul 2022 07:46:44 -0700 Subject: [PATCH] adding tests. Make sure that device status depends on the configured threshold. --- .../dashboard-device.component.spec.ts | 180 +++++++++++++++++- .../dashboard-device.component.ts | 10 +- 2 files changed, 178 insertions(+), 12 deletions(-) diff --git a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.spec.ts b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.spec.ts index 2c21c89..3c6cc67 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.spec.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.spec.ts @@ -10,6 +10,10 @@ import {TREO_APP_CONFIG} from '@treo/services/config/config.constants'; import {DeviceSummaryModel} from 'app/core/models/device-summary-model'; import * as moment from 'moment'; import {HttpClientTestingModule} from '@angular/common/http/testing'; +import {HttpClient} from '@angular/common/http'; +import {ScrutinyConfigService} from 'app/core/config/scrutiny-config.service'; +import {of} from 'rxjs'; +import {MetricsStatusThreshold} from 'app/core/config/app.config'; describe('DashboardDeviceComponent', () => { let component: DashboardDeviceComponent; @@ -17,9 +21,14 @@ describe('DashboardDeviceComponent', () => { const matDialogSpy = jasmine.createSpyObj('MatDialog', ['open']); // const configServiceSpy = jasmine.createSpyObj('ScrutinyConfigService', ['config$']); - + let configService: ScrutinyConfigService; + let httpClientSpy: jasmine.SpyObj; beforeEach(async(() => { + + httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']); + configService = new ScrutinyConfigService(httpClientSpy, {}); + TestBed.configureTestingModule({ imports: [ MatButtonModule, @@ -30,7 +39,8 @@ describe('DashboardDeviceComponent', () => { ], providers: [ {provide: MatDialog, useValue: matDialogSpy}, - {provide: TREO_APP_CONFIG, useValue: {dashboard_display: 'name'}} + {provide: TREO_APP_CONFIG, useValue: {dashboard_display: 'name', metrics: {status_threshold: 3}}}, + {provide: ScrutinyConfigService, useValue: configService} ], declarations: [DashboardDeviceComponent] }) @@ -50,25 +60,53 @@ describe('DashboardDeviceComponent', () => { describe('#classDeviceLastUpdatedOn()', () => { it('if non-zero device status, should be red', () => { + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() // component.deviceSummary = summary.data.summary['0x5000c500673e6b5f'] as DeviceSummaryModel expect(component.classDeviceLastUpdatedOn({ device: { - device_status: 2 - } + device_status: 2, + }, + smart: { + collector_date: moment().subtract(13, 'days').toISOString() + }, } as DeviceSummaryModel)).toBe('text-red') }); it('if non-zero device status, should be red', () => { - // component.deviceSummary = summary.data.summary['0x5000c500673e6b5f'] as DeviceSummaryModel + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() expect(component.classDeviceLastUpdatedOn({ device: { device_status: 2 - } + }, + smart: { + collector_date: moment().subtract(13, 'days').toISOString() + }, } as DeviceSummaryModel)).toBe('text-red') }); it('if healthy device status and updated in the last two weeks, should be green', () => { - // component.deviceSummary = summary.data.summary['0x5000c500673e6b5f'] as DeviceSummaryModel + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() expect(component.classDeviceLastUpdatedOn({ device: { device_status: 0 @@ -80,7 +118,14 @@ describe('DashboardDeviceComponent', () => { }); it('if healthy device status and updated more than two weeks ago, but less than 1 month, should be yellow', () => { - // component.deviceSummary = summary.data.summary['0x5000c500673e6b5f'] as DeviceSummaryModel + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() expect(component.classDeviceLastUpdatedOn({ device: { device_status: 0 @@ -92,7 +137,14 @@ describe('DashboardDeviceComponent', () => { }); it('if healthy device status and updated more 1 month ago, should be red', () => { - // component.deviceSummary = summary.data.summary['0x5000c500673e6b5f'] as DeviceSummaryModel + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() expect(component.classDeviceLastUpdatedOn({ device: { device_status: 0 @@ -104,4 +156,114 @@ describe('DashboardDeviceComponent', () => { }); }) + + describe('#deviceStatusString()', () => { + + it('if healthy device, should be passing', () => { + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() + expect(component.deviceStatusString({ + device: { + device_status: 0 + }, + smart: { + collector_date: moment().subtract(13, 'days').toISOString() + }, + } as DeviceSummaryModel)).toBe('passed') + }); + + it('if device with no smart data, should be unknown', () => { + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: MetricsStatusThreshold.Both, + } + } + })); + component.ngOnInit() + expect(component.deviceStatusString({ + device: { + device_status: 0 + }, + } as DeviceSummaryModel)).toBe('unknown') + }); + + const testCases = [ + { + 'deviceStatus': 1, + 'threshold': MetricsStatusThreshold.Smart, + 'result': 'failed' + }, + { + 'deviceStatus': 1, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'result': 'passed' + }, + { + 'deviceStatus': 1, + 'threshold': MetricsStatusThreshold.Both, + 'result': 'failed' + }, + + { + 'deviceStatus': 2, + 'threshold': MetricsStatusThreshold.Smart, + 'result': 'passed' + }, + { + 'deviceStatus': 2, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'result': 'failed' + }, + { + 'deviceStatus': 2, + 'threshold': MetricsStatusThreshold.Both, + 'result': 'failed' + }, + + { + 'deviceStatus': 3, + 'threshold': MetricsStatusThreshold.Smart, + 'result': 'failed' + }, + { + 'deviceStatus': 3, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'result': 'failed' + }, + { + 'deviceStatus': 3, + 'threshold': MetricsStatusThreshold.Both, + 'result': 'failed' + } + + ] + + testCases.forEach((test, index) => { + it(`if device with status (${test.deviceStatus}) and threshold (${test.threshold}), should be ${test.result}`, () => { + httpClientSpy.get.and.returnValue(of({ + settings: { + metrics: { + status_threshold: test.threshold, + } + } + })); + component.ngOnInit() + expect(component.deviceStatusString({ + device: { + device_status: test.deviceStatus + }, + smart: { + collector_date: moment().subtract(13, 'days').toISOString() + }, + } as DeviceSummaryModel)).toBe(test.result) + }); + }); + }) }); diff --git a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts index a8de9d5..254f8c1 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts @@ -10,6 +10,8 @@ import {DashboardDeviceDeleteDialogComponent} from 'app/layout/common/dashboard- import {DeviceTitlePipe} from 'app/shared/device-title.pipe'; import {DeviceSummaryModel} from 'app/core/models/device-summary-model'; +export type deviceStatusName = 'unknown' | 'passed' | 'failed' + @Component({ selector: 'app-dashboard-device', templateUrl: './dashboard-device.component.html', @@ -50,9 +52,10 @@ export class DashboardDeviceComponent implements OnInit { // ----------------------------------------------------------------------------------------------------- classDeviceLastUpdatedOn(deviceSummary: DeviceSummaryModel): string { - if (deviceSummary.device.device_status !== 0) { + const deviceStatus = this.deviceStatusString(deviceSummary) + if (deviceStatus === 'failed') { return 'text-red' // if the device has failed, always highlight in red - } else if (deviceSummary.device.device_status === 0 && deviceSummary.smart) { + } else if (deviceStatus === 'passed') { if (moment().subtract(14, 'days').isBefore(deviceSummary.smart.collector_date)) { // this device was updated in the last 2 weeks. return 'text-green' @@ -68,7 +71,8 @@ export class DashboardDeviceComponent implements OnInit { } } - deviceStatusString(deviceSummary: DeviceSummaryModel): string { + + deviceStatusString(deviceSummary: DeviceSummaryModel): deviceStatusName { // no smart data, so treat the device status as unknown if (!deviceSummary.smart) { return 'unknown'