Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions cypress/e2e/fixtures/api/eventlog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,67 @@ const eventLogs = {
IDER: false
}
}
},
remotePlatformErase: {
notSupported: {
response: {
userConsent: 'none',
optInState: 0,
redirection: true,
KVM: true,
SOL: true,
IDER: false,
kvmAvailable: false,
ocr: false,
httpsBootSupported: false,
winREBootSupported: false,
localPBABootSupported: false,
remoteEraseEnabled: false,
remoteEraseSupported: false,
pbaBootFilesPath: [],
winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' }
}
},
supportedDisabled: {
response: {
userConsent: 'none',
optInState: 0,
redirection: true,
KVM: true,
SOL: true,
IDER: false,
kvmAvailable: false,
ocr: false,
httpsBootSupported: false,
winREBootSupported: false,
localPBABootSupported: false,
remoteEraseEnabled: false,
remoteEraseSupported: true,
platformEraseCaps: 0x05,
pbaBootFilesPath: [],
winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' }
}
},
supportedEnabled: {
response: {
userConsent: 'none',
optInState: 0,
redirection: true,
KVM: true,
SOL: true,
IDER: false,
kvmAvailable: false,
ocr: false,
httpsBootSupported: false,
winREBootSupported: false,
localPBABootSupported: false,
remoteEraseEnabled: true,
remoteEraseSupported: true,
platformEraseCaps: 0x05,
pbaBootFilesPath: [],
winREBootFilesPath: { instanceID: '', biosBootString: '', bootString: '' }
}
}
}
}

Expand Down
223 changes: 223 additions & 0 deletions cypress/e2e/integration/device/remote-platform-erase.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2022
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

import { httpCodes } from '../../fixtures/api/httpCodes'
import { eventLogs } from '../../fixtures/api/eventlog'

const navigateToRemotePlatformErase = (): void => {
cy.myIntercept('GET', 'devices?$top=25&$skip=0&$count=true', {
statusCode: httpCodes.SUCCESS,
body: eventLogs.devices.success.response
}).as('get-devices')

cy.myIntercept('GET', /devices\/.*$/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.devices.success.response
}).as('get-device-by-id')

cy.myIntercept('GET', /devices\/tags/, {
statusCode: httpCodes.SUCCESS,
body: []
}).as('get-tags')

cy.myIntercept('GET', /.*power.*/, {
statusCode: httpCodes.SUCCESS,
body: { powerstate: 2 }
}).as('get-powerstate')

cy.myIntercept('GET', /.*general.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.general.success.response
}).as('get-general')

cy.myIntercept('GET', /.*version.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.version.success.response
}).as('get-version')

cy.myIntercept('GET', /.*alarmOccurrences.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.alarmOccurrences.success.response
}).as('get-alarms')

cy.goToPage('Devices')
cy.wait('@get-devices').its('response.statusCode').should('eq', 200)

cy.get('mat-row').first().click()
cy.wait('@get-device-by-id').its('response.statusCode').should('eq', 200)

cy.get('.mat-mdc-list-item-title').contains('Remote Platform Erase').click()
}

describe('Remote Platform Erase', () => {
beforeEach(() => {
cy.setup()
})

it('should show "not supported" message when remoteEraseSupported is false', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.notSupported.response
}).as('get-features')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="remoteEraseCheckbox"]').should('not.exist')
cy.get('mat-icon').contains('info').should('exist')
})

it('should show checkbox when supported but not enabled', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedDisabled.response
}).as('get-features')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="remoteEraseCheckbox"]').should('exist')
cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').should('not.be.checked')
cy.get('[data-cy="initiateEraseButton"]').should('not.exist')
})

it('should show initiate erase button when feature is already enabled', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedEnabled.response
}).as('get-features')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').should('be.checked')
cy.get('[data-cy="initiateEraseButton"]').should('be.visible')
})

it('should enable the feature and show initiate erase button after toggling on', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedDisabled.response
}).as('get-features')

cy.myIntercept('POST', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedEnabled.response
}).as('post-features')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').check({ force: true })
cy.wait('@post-features').its('request.body.enablePlatformErase').should('eq', true)

cy.get('[data-cy="initiateEraseButton"]').should('be.visible')
})

it('should disable the feature after toggling off', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedEnabled.response
}).as('get-features')

cy.myIntercept('POST', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedDisabled.response
}).as('post-features')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').uncheck({ force: true })
cy.wait('@post-features').its('request.body.enablePlatformErase').should('eq', false)

cy.get('[data-cy="initiateEraseButton"]').should('not.exist')
})

it('should call the remoteErase API when erase is confirmed in the dialog', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedEnabled.response
}).as('get-features')

cy.myIntercept('POST', /.*amt\/remoteErase.*/, {
statusCode: httpCodes.SUCCESS,
body: {}
}).as('post-erase')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="initiateEraseButton"]').click()

cy.get('mat-dialog-container').should('be.visible')
cy.get('mat-dialog-container').contains('button', 'Yes').click()

cy.wait('@post-erase').its('response.statusCode').should('eq', 200)
})

it('should not call the remoteErase API when erase is cancelled', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedEnabled.response
}).as('get-features')

cy.myIntercept('POST', /.*amt\/remoteErase.*/, {
statusCode: httpCodes.SUCCESS,
body: {}
}).as('post-erase')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="initiateEraseButton"]').click()

cy.get('mat-dialog-container').should('be.visible')
cy.get('mat-dialog-container').contains('button', 'No').click()

cy.get('@post-erase.all').should('have.length', 0)
})

it('should show error snackbar when toggling feature fails', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedDisabled.response
}).as('get-features')

cy.myIntercept('POST', /.*amt\/features.*/, {
statusCode: httpCodes.INTERNAL_SERVER_ERROR,
body: {}
}).as('post-features-error')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="remoteEraseCheckbox"] input[type="checkbox"]').check({ force: true })
cy.wait('@post-features-error')

cy.get('mat-snack-bar-container').should('be.visible')
})

it('should show error snackbar when erase API fails', () => {
cy.myIntercept('GET', /.*amt\/features.*/, {
statusCode: httpCodes.SUCCESS,
body: eventLogs.remotePlatformErase.supportedEnabled.response
}).as('get-features')

cy.myIntercept('POST', /.*amt\/remoteErase.*/, {
statusCode: httpCodes.INTERNAL_SERVER_ERROR,
body: {}
}).as('post-erase-error')

navigateToRemotePlatformErase()
cy.wait('@get-features')

cy.get('[data-cy="initiateEraseButton"]').click()
cy.get('mat-dialog-container').contains('button', 'Yes').click()

cy.wait('@post-erase-error')
cy.get('mat-snack-bar-container').should('be.visible')
})
})
3 changes: 3 additions & 0 deletions src/app/devices/device-detail/device-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ <h3 matListItemTitle>{{ item.name | translate }}</h3>
@case ('tls') {
<app-tls [deviceId]="deviceId"></app-tls>
}
@case ('remote-platform-erase') {
<app-remote-platform-erase [deviceId]="deviceId"></app-remote-platform-erase>
}
}
</mat-sidenav-content>
</mat-sidenav-container>
8 changes: 8 additions & 0 deletions src/app/devices/device-detail/device-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { GeneralComponent } from '../general/general.component'
import { NetworkSettingsComponent } from '../network-settings/network-settings.component'
import { environment } from 'src/environments/environment'
import { TLSComponent } from '../tls/tls.component'
import { RemotePlatformEraseComponent } from '../remote-platform-erase/remote-platform-erase.component'
import { TranslateModule } from '@ngx-translate/core'

@Component({
Expand Down Expand Up @@ -57,6 +58,7 @@ import { TranslateModule } from '@ngx-translate/core'
RouterLinkActive,
NetworkSettingsComponent,
TLSComponent,
RemotePlatformEraseComponent,
TranslateModule
]
})
Expand Down Expand Up @@ -115,6 +117,12 @@ export class DeviceDetailComponent implements OnInit {
description: 'deviceDetail.certificatesDescription.value',
component: 'certificates',
icon: 'verified'
},
{
name: 'deviceDetail.remotePlatformErase.value',
description: 'deviceDetail.remotePlatformEraseDescription.value',
component: 'remote-platform-erase',
icon: 'phonelink_erase'
}
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('DeviceToolbarComponent', () => {
kvmAvailable: true,
winREBootSupported: true,
localPBABootSupported: true,
remoteErase: true,
remoteEraseEnabled: true,
pbaBootFilesPath: [],
winREBootFilesPath: {
instanceID: '',
Expand Down
6 changes: 3 additions & 3 deletions src/app/devices/devices.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe('DevicesService', () => {
httpsBootSupported: false,
winREBootSupported: false,
localPBABootSupported: false,
remoteErase: false,
remoteEraseEnabled: false,
pbaBootFilesPath: [],
winREBootFilesPath: {
instanceID: '',
Expand Down Expand Up @@ -516,7 +516,7 @@ describe('DevicesService', () => {
httpsBootSupported: false,
winREBootSupported: false,
localPBABootSupported: false,
remoteErase: false,
remoteEraseEnabled: false,
pbaBootFilesPath: [],
winREBootFilesPath: {
instanceID: '',
Expand All @@ -533,7 +533,7 @@ describe('DevicesService', () => {
ocr: true,
winREBootSupported: true,
localPBABootSupported: true,
remoteErase: true
enablePlatformErase: true
}

service.setAmtFeatures('device1', payload).subscribe((response) => {
Expand Down
10 changes: 9 additions & 1 deletion src/app/devices/devices.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,14 @@ export class DevicesService {
}
}

sendRemotePlatformErase(deviceId: string, eraseMask: number): Observable<any> {
return this.http.post<any>(`${environment.mpsServer}/api/v1/amt/remoteErase/${deviceId}`, { eraseMask }).pipe(
catchError((err) => {
throw err
})
)
}

getTags(): Observable<string[]> {
return this.http.get<string[]>(`${environment.mpsServer}/api/v1/devices/tags`).pipe(
map((tags) => tags.sort(caseInsensitiveCompare)),
Expand Down Expand Up @@ -425,7 +433,7 @@ export class DevicesService {
enableSOL: true,
enableIDER: true,
ocr: true,
remoteErase: true
enablePlatformErase: true
}
): Observable<AMTFeaturesResponse> {
return this.http
Expand Down
Loading
Loading