From 730585cd14aab19fbaefc73e23923ba375e69677 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Wed, 21 Aug 2024 12:39:29 -0400 Subject: [PATCH] Fix front-end unit tests (#2529) This doesn't really add any tests, and we'll require many more additions if we actually want to have full unit testing, but this at least makes the tests pass when running `npm test`. --- console-webapp/build.gradle | 2 + console-webapp/karma.conf.js | 11 ++ .../app/domains/domainList.component.spec.ts | 3 +- .../registrarSelector.component.spec.ts | 3 +- .../security/security.component.spec.ts | 104 ++++++++---------- .../settings/security/security.component.ts | 1 + .../security/security.service.spec.ts | 6 +- .../security/securityEdit.component.html | 1 + .../settings/whois/whois.component.spec.ts | 9 +- .../registrar/registrar.service.mock.ts | 21 ++++ console-webapp/tsconfig.json | 3 +- 11 files changed, 97 insertions(+), 67 deletions(-) create mode 100644 console-webapp/src/testdata/registrar/registrar.service.mock.ts diff --git a/console-webapp/build.gradle b/console-webapp/build.gradle index 575e883fb..90aab8eb7 100644 --- a/console-webapp/build.gradle +++ b/console-webapp/build.gradle @@ -69,7 +69,9 @@ task deploy(type: Exec) { } tasks.buildConsoleWebappProd.dependsOn(tasks.npmInstallDeps) +tasks.runConsoleWebappUnitTests.dependsOn(tasks.npmInstallDeps) tasks.applyFormatting.dependsOn(tasks.npmInstallDeps) tasks.checkFormatting.dependsOn(tasks.npmInstallDeps) tasks.build.dependsOn(tasks.checkFormatting) +tasks.build.dependsOn(tasks.runConsoleWebappUnitTests) tasks.deploy.dependsOn(tasks.buildConsoleWebappProd) diff --git a/console-webapp/karma.conf.js b/console-webapp/karma.conf.js index 7a1e4db56..d293722c4 100644 --- a/console-webapp/karma.conf.js +++ b/console-webapp/karma.conf.js @@ -3,6 +3,17 @@ module.exports = function (config) { config.set({ + customLaunchers: { + ChromeHeadless: { + base: 'Chrome', + flags: [ + '--no-sandbox', + '--disable-gpu', + '--headless', + '--remote-debugging-port=9222' + ] + } + }, basePath: '', frameworks: ['jasmine', '@angular-devkit/build-angular'], plugins: [ diff --git a/console-webapp/src/app/domains/domainList.component.spec.ts b/console-webapp/src/app/domains/domainList.component.spec.ts index 96f165a16..93037332b 100644 --- a/console-webapp/src/app/domains/domainList.component.spec.ts +++ b/console-webapp/src/app/domains/domainList.component.spec.ts @@ -20,6 +20,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MaterialModule } from '../material.module'; import { BackendService } from '../shared/services/backend.service'; import { DomainListComponent } from './domainList.component'; +import { FormsModule } from '@angular/forms'; describe('DomainListComponent', () => { let component: DomainListComponent; @@ -28,7 +29,7 @@ describe('DomainListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [DomainListComponent], - imports: [MaterialModule, BrowserAnimationsModule], + imports: [MaterialModule, BrowserAnimationsModule, FormsModule], providers: [ BackendService, provideHttpClient(), diff --git a/console-webapp/src/app/registrar/registrarSelector.component.spec.ts b/console-webapp/src/app/registrar/registrarSelector.component.spec.ts index eae8ffd4d..fc600912b 100644 --- a/console-webapp/src/app/registrar/registrarSelector.component.spec.ts +++ b/console-webapp/src/app/registrar/registrarSelector.component.spec.ts @@ -20,6 +20,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MaterialModule } from '../material.module'; import { BackendService } from '../shared/services/backend.service'; import { RegistrarSelectorComponent } from './registrarSelector.component'; +import { FormsModule } from '@angular/forms'; describe('RegistrarSelectorComponent', () => { let component: RegistrarSelectorComponent; @@ -28,7 +29,7 @@ describe('RegistrarSelectorComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [RegistrarSelectorComponent], - imports: [MaterialModule, BrowserAnimationsModule], + imports: [MaterialModule, BrowserAnimationsModule, FormsModule], providers: [ BackendService, provideHttpClient(), diff --git a/console-webapp/src/app/settings/security/security.component.spec.ts b/console-webapp/src/app/settings/security/security.component.spec.ts index d0bc72de6..36a48b9d6 100644 --- a/console-webapp/src/app/settings/security/security.component.spec.ts +++ b/console-webapp/src/app/settings/security/security.component.spec.ts @@ -20,20 +20,18 @@ import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; import { MaterialModule } from 'src/app/material.module'; -import { - Registrar, - RegistrarService, -} from 'src/app/registrar/registrar.service'; +import { RegistrarService } from 'src/app/registrar/registrar.service'; import { BackendService } from 'src/app/shared/services/backend.service'; import SecurityComponent from './security.component'; -import { SecurityService, apiToUiConverter } from './security.service'; +import { SecurityService } from './security.service'; +import SecurityEditComponent from './securityEdit.component'; +import { MOCK_REGISTRAR_SERVICE } from 'src/testdata/registrar/registrar.service.mock'; describe('SecurityComponent', () => { let component: SecurityComponent; let fixture: ComponentFixture; let fetchSecurityDetailsSpy: Function; let saveSpy: Function; - let dummyRegistrarService: RegistrarService; beforeEach(async () => { const securityServiceSpy = jasmine.createSpyObj(SecurityService, [ @@ -46,16 +44,13 @@ describe('SecurityComponent', () => { saveSpy = securityServiceSpy.saveChanges; - dummyRegistrarService = { - registrar: { ipAddressAllowList: ['123.123.123.123'] }, - } as RegistrarService; - await TestBed.configureTestingModule({ - declarations: [SecurityComponent], + declarations: [SecurityEditComponent, SecurityComponent], imports: [MaterialModule, BrowserAnimationsModule, FormsModule], providers: [ BackendService, - { provide: RegistrarService, useValue: dummyRegistrarService }, + SecurityService, + { provide: RegistrarService, useValue: MOCK_REGISTRAR_SERVICE }, provideHttpClient(), provideHttpClientTesting(), ], @@ -78,78 +73,65 @@ describe('SecurityComponent', () => { expect(component).toBeTruthy(); }); - it('should render ip allow list', waitForAsync(() => { - component.enableEdit(); + it('should render security elements', waitForAsync(() => { + fixture.detectChanges(); fixture.whenStable().then(() => { - expect( - Array.from( - fixture.nativeElement.querySelectorAll( - '.settings-security__ip-allowlist' - ) - ) - ).toHaveSize(1); - expect( - fixture.nativeElement.querySelector('.settings-security__ip-allowlist') - .value - ).toBe('123.123.123.123'); + let listElems: Array = Array.from( + fixture.nativeElement.querySelectorAll('span.console-app__list-value') + ); + expect(listElems).toHaveSize(8); + expect(listElems.map((e) => e.textContent)).toEqual([ + 'Change the password used for EPP logins', + '••••••••••••••', + 'Restrict access to EPP production servers to the following IP/IPv6 addresses, or ranges like 1.1.1.0/24', + '123.123.123.123', + 'X.509 PEM certificate for EPP production access', + 'No client certificate on file.', + 'X.509 PEM backup certificate for EPP production access', + 'No failover certificate on file.', + ]); }); })); it('should remove ip', waitForAsync(() => { - expect( - Array.from( - fixture.nativeElement.querySelectorAll( - '.settings-security__ip-allowlist' - ) - ) - ).toHaveSize(1); - component.removeIpEntry(0); + component.dataSource.ipAddressAllowList = + component.dataSource.ipAddressAllowList?.splice(1); fixture.whenStable().then(() => { fixture.detectChanges(); - expect( - Array.from( - fixture.nativeElement.querySelectorAll( - '.settings-security__ip-allowlist' - ) - ) - ).toHaveSize(0); + let listElems: Array = Array.from( + fixture.nativeElement.querySelectorAll('span.console-app__list-value') + ); + expect(listElems.map((e) => e.textContent)).toContain( + 'No IP addresses on file.' + ); }); })); - it('should toggle inEdit', () => { - expect(component.inEdit).toBeFalse(); - component.enableEdit(); - expect(component.inEdit).toBeTrue(); + it('should toggle isEditingSecurity', () => { + expect(component.securityService.isEditingSecurity).toBeFalse(); + component.editSecurity(); + expect(component.securityService.isEditingSecurity).toBeTrue(); }); - it('should create temporary data structure', () => { - expect(component.dataSource).toEqual( - apiToUiConverter(dummyRegistrarService.registrar) - ); - component.removeIpEntry(0); - expect(component.dataSource).toEqual({ ipAddressAllowList: [] }); - expect(dummyRegistrarService.registrar).toEqual({ - ipAddressAllowList: ['123.123.123.123'], - } as Registrar); - component.cancel(); - expect(component.dataSource).toEqual( - apiToUiConverter(dummyRegistrarService.registrar) - ); + it('should toggle isEditingPassword', () => { + expect(component.securityService.isEditingPassword).toBeFalse(); + component.editEppPassword(); + expect(component.securityService.isEditingPassword).toBeTrue(); }); it('should call save', waitForAsync(async () => { - component.enableEdit(); - fixture.detectChanges(); + component.editSecurity(); await fixture.whenStable(); + fixture.detectChanges(); const el = fixture.nativeElement.querySelector( - '.settings-security__clientCertificate' + '.console-app__clientCertificateValue' ); el.value = 'test'; el.dispatchEvent(new Event('input')); fixture.detectChanges(); await fixture.whenStable(); fixture.nativeElement - .querySelector('.settings-security__actions-save') + .querySelector('.settings-security__edit-save') .click(); expect(saveSpy).toHaveBeenCalledOnceWith({ ipAddressAllowList: [{ value: '123.123.123.123' }], diff --git a/console-webapp/src/app/settings/security/security.component.ts b/console-webapp/src/app/settings/security/security.component.ts index 55d73660e..d4da674e3 100644 --- a/console-webapp/src/app/settings/security/security.component.ts +++ b/console-webapp/src/app/settings/security/security.component.ts @@ -35,6 +35,7 @@ export default class SecurityComponent { if (this.registrarService.registrar()) { this.dataSource = apiToUiConverter(this.registrarService.registrar()); this.securityService.isEditingSecurity = false; + this.securityService.isEditingPassword = false; } }); } diff --git a/console-webapp/src/app/settings/security/security.service.spec.ts b/console-webapp/src/app/settings/security/security.service.spec.ts index 565773752..80347c48a 100644 --- a/console-webapp/src/app/settings/security/security.service.spec.ts +++ b/console-webapp/src/app/settings/security/security.service.spec.ts @@ -21,11 +21,13 @@ import { BackendService } from 'src/app/shared/services/backend.service'; import SecurityComponent from './security.component'; import { SecurityService, - SecuritySettings, - SecuritySettingsBackendModel, apiToUiConverter, uiToApiConverter, } from './security.service'; +import { + SecuritySettings, + SecuritySettingsBackendModel, +} from 'src/app/registrar/registrar.service'; describe('SecurityService', () => { const uiMockData: SecuritySettings = { diff --git a/console-webapp/src/app/settings/security/securityEdit.component.html b/console-webapp/src/app/settings/security/securityEdit.component.html index 95140db28..d1c836059 100644 --- a/console-webapp/src/app/settings/security/securityEdit.component.html +++ b/console-webapp/src/app/settings/security/securityEdit.component.html @@ -33,6 +33,7 @@

X.509 PEM certificate for EPP production access.