From 2e768fb49108ffe60f2552c17dda03feeb954196 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 25 Jul 2022 07:46:44 -0700 Subject: [PATCH 1/2] 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' From ce2f990eb1b112f4f816c91dbcf4e849ab4b44d4 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Fri, 29 Jul 2022 07:11:57 -0700 Subject: [PATCH 2/2] consolidate device status to string logic in DeviceStatusPipe. Ensure device status takes into account new settings. --- .../dashboard-device.component.html | 12 +- .../dashboard-device.component.spec.ts | 111 ------------- .../dashboard-device.component.ts | 25 +-- .../app/modules/detail/detail.component.html | 5 +- .../app/modules/detail/detail.component.ts | 2 + .../src/app/shared/device-status.pipe.spec.ts | 148 +++++++++++++++++- .../src/app/shared/device-status.pipe.ts | 78 +++++++-- 7 files changed, 222 insertions(+), 159 deletions(-) diff --git a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.html b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.html index bd7b4a1..7dfe40c 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.html +++ b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.html @@ -1,15 +1,15 @@ -
@@ -47,7 +47,7 @@
Status
{{ deviceStatusString(deviceSummary) | titlecase}}
+ *ngIf="deviceSummary.smart?.collector_date; else unknownStatus">{{ deviceStatusForModelWithThreshold(deviceSummary.device, !!deviceSummary.smart, config.metrics.status_threshold) | titlecase}}
No Data
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 3c6cc67..6e578a1 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 @@ -155,115 +155,4 @@ describe('DashboardDeviceComponent', () => { } as DeviceSummaryModel)).toBe('text-red') }); }) - - - 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 254f8c1..e29957e 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 @@ -9,8 +9,7 @@ import {MatDialog} from '@angular/material/dialog'; import {DashboardDeviceDeleteDialogComponent} from 'app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component'; import {DeviceTitlePipe} from 'app/shared/device-title.pipe'; import {DeviceSummaryModel} from 'app/core/models/device-summary-model'; - -export type deviceStatusName = 'unknown' | 'passed' | 'failed' +import {DeviceStatusPipe} from 'app/shared/device-status.pipe'; @Component({ selector: 'app-dashboard-device', @@ -37,6 +36,8 @@ export class DashboardDeviceComponent implements OnInit { readonly humanizeDuration = humanizeDuration; + deviceStatusForModelWithThreshold = DeviceStatusPipe.deviceStatusForModelWithThreshold + ngOnInit(): void { // Subscribe to config changes this._configService.config$ @@ -52,7 +53,7 @@ export class DashboardDeviceComponent implements OnInit { // ----------------------------------------------------------------------------------------------------- classDeviceLastUpdatedOn(deviceSummary: DeviceSummaryModel): string { - const deviceStatus = this.deviceStatusString(deviceSummary) + const deviceStatus = DeviceStatusPipe.deviceStatusForModelWithThreshold(deviceSummary.device, !!deviceSummary.smart, this.config.metrics.status_threshold) if (deviceStatus === 'failed') { return 'text-red' // if the device has failed, always highlight in red } else if (deviceStatus === 'passed') { @@ -71,24 +72,6 @@ export class DashboardDeviceComponent implements OnInit { } } - - deviceStatusString(deviceSummary: DeviceSummaryModel): deviceStatusName { - // no smart data, so treat the device status as unknown - if (!deviceSummary.smart) { - return 'unknown' - } - - // determine the device status, by comparing it against the allowed threshold - // tslint:disable-next-line:no-bitwise - const deviceStatus = deviceSummary.device.device_status & this.config.metrics.status_threshold - if (deviceStatus === 0) { - return 'passed' - } else { - return 'failed' - } - } - - openDeleteDialog(): void { const dialogRef = this.dialog.open(DashboardDeviceDeleteDialogComponent, { // width: '250px', diff --git a/webapp/frontend/src/app/modules/detail/detail.component.html b/webapp/frontend/src/app/modules/detail/detail.component.html index e96a493..d2ff848 100644 --- a/webapp/frontend/src/app/modules/detail/detail.component.html +++ b/webapp/frontend/src/app/modules/detail/detail.component.html @@ -56,12 +56,13 @@
- {{device?.device_status | deviceStatus}} + {{device | deviceStatus:!!smart_results:config.metrics.status_threshold:true}}
Status
diff --git a/webapp/frontend/src/app/modules/detail/detail.component.ts b/webapp/frontend/src/app/modules/detail/detail.component.ts index 1353c51..ce21642 100644 --- a/webapp/frontend/src/app/modules/detail/detail.component.ts +++ b/webapp/frontend/src/app/modules/detail/detail.component.ts @@ -16,6 +16,7 @@ import {DeviceModel} from 'app/core/models/device-model'; import {SmartModel} from 'app/core/models/measurements/smart-model'; import {SmartAttributeModel} from 'app/core/models/measurements/smart-attribute-model'; import {AttributeMetadataModel} from 'app/core/models/thresholds/attribute-metadata-model'; +import {DeviceStatusPipe} from 'app/shared/device-status.pipe'; // from Constants.go - these must match const AttributeStatusPassed = 0 @@ -89,6 +90,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { readonly humanizeDuration = humanizeDuration; + deviceStatusForModelWithThreshold = DeviceStatusPipe.deviceStatusForModelWithThreshold // ----------------------------------------------------------------------------------------------------- // @ Lifecycle hooks // ----------------------------------------------------------------------------------------------------- diff --git a/webapp/frontend/src/app/shared/device-status.pipe.spec.ts b/webapp/frontend/src/app/shared/device-status.pipe.spec.ts index 23bc958..57d9e7c 100644 --- a/webapp/frontend/src/app/shared/device-status.pipe.spec.ts +++ b/webapp/frontend/src/app/shared/device-status.pipe.spec.ts @@ -1,8 +1,146 @@ -import { DeviceStatusPipe } from './device-status.pipe'; +import {DeviceStatusPipe} from './device-status.pipe'; +import {MetricsStatusThreshold} from '../core/config/app.config'; +import {DeviceModel} from '../core/models/device-model'; describe('DeviceStatusPipe', () => { - it('create an instance', () => { - const pipe = new DeviceStatusPipe(); - expect(pipe).toBeTruthy(); - }); + it('create an instance', () => { + const pipe = new DeviceStatusPipe(); + expect(pipe).toBeTruthy(); + }); + + describe('#deviceStatusForModelWithThreshold', () => { + it('if healthy device, should be passing', () => { + expect(DeviceStatusPipe.deviceStatusForModelWithThreshold( + {device_status: 0} as DeviceModel, + true, + MetricsStatusThreshold.Both + )).toBe('passed') + }); + + it('if device with no smart data, should be unknown', () => { + expect(DeviceStatusPipe.deviceStatusForModelWithThreshold( + {device_status: 0} as DeviceModel, + false, + MetricsStatusThreshold.Both + )).toBe('unknown') + }); + + const testCases = [ + { + 'deviceStatus': 10000, // invalid status + 'hasSmartResults': false, + 'threshold': MetricsStatusThreshold.Smart, + 'includeReason': false, + 'result': 'unknown' + }, + + { + 'deviceStatus': 1, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Smart, + 'includeReason': false, + 'result': 'failed' + }, + { + 'deviceStatus': 1, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'includeReason': false, + 'result': 'passed' + }, + { + 'deviceStatus': 1, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Both, + 'includeReason': false, + 'result': 'failed' + }, + + { + 'deviceStatus': 2, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Smart, + 'includeReason': false, + 'result': 'passed' + }, + { + 'deviceStatus': 2, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'includeReason': false, + 'result': 'failed' + }, + { + 'deviceStatus': 2, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Both, + 'includeReason': false, + 'result': 'failed' + }, + + { + 'deviceStatus': 3, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Smart, + 'includeReason': false, + 'result': 'failed' + }, + { + 'deviceStatus': 3, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'includeReason': false, + 'result': 'failed' + }, + { + 'deviceStatus': 3, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Both, + 'includeReason': false, + 'result': 'failed' + }, + + { + 'deviceStatus': 3, + 'hasSmartResults': false, + 'threshold': MetricsStatusThreshold.Smart, + 'includeReason': true, + 'result': 'unknown' + }, + { + 'deviceStatus': 3, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Smart, + 'includeReason': true, + 'result': 'failed: smart' + }, + { + 'deviceStatus': 3, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Scrutiny, + 'includeReason': true, + 'result': 'failed: scrutiny' + }, + { + 'deviceStatus': 3, + 'hasSmartResults': true, + 'threshold': MetricsStatusThreshold.Both, + 'includeReason': true, + 'result': 'failed: both' + } + + + ] + + testCases.forEach((test, index) => { + it(`if device with status (${test.deviceStatus}), hasSmartResults(${test.hasSmartResults}) and threshold (${test.threshold}), should be ${test.result}`, () => { + expect(DeviceStatusPipe.deviceStatusForModelWithThreshold( + {device_status: test.deviceStatus} as DeviceModel, + test.hasSmartResults, + test.threshold, + test.includeReason + )).toBe(test.result) + }); + }); + }); }); diff --git a/webapp/frontend/src/app/shared/device-status.pipe.ts b/webapp/frontend/src/app/shared/device-status.pipe.ts index 42261c6..68a692d 100644 --- a/webapp/frontend/src/app/shared/device-status.pipe.ts +++ b/webapp/frontend/src/app/shared/device-status.pipe.ts @@ -1,21 +1,71 @@ -import { Pipe, PipeTransform } from '@angular/core'; +import {Pipe, PipeTransform} from '@angular/core'; +import {MetricsStatusThreshold} from '../core/config/app.config'; +import {DeviceModel} from '../core/models/device-model'; + +const DEVICE_STATUS_NAMES: { [key: number]: string } = { + 0: 'passed', + 1: 'failed', + 2: 'failed', + 3: 'failed' +}; + +const DEVICE_STATUS_NAMES_WITH_REASON: { [key: number]: string } = { + 0: 'passed', + 1: 'failed: smart', + 2: 'failed: scrutiny', + 3: 'failed: both' +}; + @Pipe({ - name: 'deviceStatus' + name: 'deviceStatus' }) export class DeviceStatusPipe implements PipeTransform { - transform(deviceStatusFlag: number): string { - if(deviceStatusFlag === 0){ - return 'passed' - } else if(deviceStatusFlag === 3){ - return 'failed: both' - } else if(deviceStatusFlag === 2) { - return 'failed: scrutiny' - } else if(deviceStatusFlag === 1) { - return 'failed: smart' - } - return 'unknown' - } + + static deviceStatusForModelWithThreshold( + deviceModel: DeviceModel, + hasSmartResults: boolean = true, + threshold: MetricsStatusThreshold = MetricsStatusThreshold.Both, + includeReason: boolean = false + ): string { + // no smart data, so treat the device status as unknown + if (!hasSmartResults) { + return 'unknown' + } + + let statusNameLookup = DEVICE_STATUS_NAMES + if (includeReason) { + statusNameLookup = DEVICE_STATUS_NAMES_WITH_REASON + } + // determine the device status, by comparing it against the allowed threshold + // tslint:disable-next-line:no-bitwise + const deviceStatus = deviceModel.device_status & threshold + return statusNameLookup[deviceStatus] + } + + // static deviceStatusForModelWithThreshold(deviceModel: DeviceModel | any, threshold: MetricsStatusThreshold): string { + // // tslint:disable-next-line:no-bitwise + // const deviceStatus = deviceModel?.device_status & threshold + // if(deviceStatus === 0){ + // return 'passed' + // } else if(deviceStatus === 3){ + // return 'failed: both' + // } else if(deviceStatus === 2) { + // return 'failed: scrutiny' + // } else if(deviceStatus === 1) { + // return 'failed: smart' + // } + // return 'unknown' + // } + + transform( + deviceModel: DeviceModel, + hasSmartResults: boolean = true, + threshold: MetricsStatusThreshold = MetricsStatusThreshold.Both, + includeReason: boolean = false + ): string { + return DeviceStatusPipe.deviceStatusForModelWithThreshold(deviceModel, hasSmartResults, threshold, includeReason) + } }