From a29515f58fbf9181f6cb4ee4e699044d17269708 Mon Sep 17 00:00:00 2001 From: Anton Barysau Date: Mon, 4 Mar 2024 14:52:58 +0300 Subject: [PATCH] use initComponent pattern --- .../tests/contracts.component.spec.ts | 19 ++++-- .../home/tests/home.component.spec.ts | 17 +++-- .../login/test/login.component.spec.ts | 68 +++++++++++++------ .../tests/not-found.component.spec.ts | 26 +++++-- src/app/tests/app.component.spec.ts | 52 ++++++++++---- .../foundation/tests/test.component.spec.ts | 8 --- 6 files changed, 130 insertions(+), 60 deletions(-) diff --git a/src/app/components/contracts/tests/contracts.component.spec.ts b/src/app/components/contracts/tests/contracts.component.spec.ts index 34c7752..a823ecb 100644 --- a/src/app/components/contracts/tests/contracts.component.spec.ts +++ b/src/app/components/contracts/tests/contracts.component.spec.ts @@ -32,9 +32,10 @@ import { describe('ContractsComponent', () => { let contractServiceMock: jasmine.SpyObj let messageBoxServiceMock: jasmine.SpyObj - let contractsHarness: ContractsHarness - async function initComponent(contracts?: Contract[]): Promise { + async function initComponent(contracts?: Contract[]): Promise<{ + contractsHarness: ContractsHarness + }> { if (contracts) { contractServiceMock.getContracts.and.returnValue(of(contracts)) } @@ -62,8 +63,10 @@ describe('ContractsComponent', () => { }).compileComponents() const fixture = TestBed.createComponent(ContractsComponent) - contractsHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, ContractsHarness) - return contractsHarness + const contractsHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, ContractsHarness) + return { + contractsHarness + } } beforeEach(async () => { @@ -84,7 +87,9 @@ describe('ContractsComponent', () => { conditions: 'test contract b' } ] - await initComponent(CONTRACTS) + const { + contractsHarness + } = await initComponent(CONTRACTS) expect(await contractsHarness.elementChildCount('contractList')).toBe(CONTRACTS.length) expect(await contractsHarness.elementVisible('noContractsMessage')).toBe(false) @@ -95,7 +100,9 @@ describe('ContractsComponent', () => { }) it('display no contract message if there are no contracts', async () => { - await initComponent([]) + const { + contractsHarness: contractsHarness + } = await initComponent([]) expect(await contractsHarness.elementChildCount('contractList')).toBe(0) expect(await contractsHarness.elementVisible('noContractsMessage')).toBe(true) diff --git a/src/app/components/home/tests/home.component.spec.ts b/src/app/components/home/tests/home.component.spec.ts index e31d713..1349aa6 100644 --- a/src/app/components/home/tests/home.component.spec.ts +++ b/src/app/components/home/tests/home.component.spec.ts @@ -17,9 +17,9 @@ import { } from '@angular/cdk/testing/testbed' describe('HomeComponent', () => { - let homeHarness: HomeHarness - - beforeEach(async () => { + async function initComponent(): Promise<{ + homeHarness: HomeHarness + }> { await TestBed.configureTestingModule({ imports: [ HomeComponent, @@ -29,10 +29,17 @@ describe('HomeComponent', () => { }).compileComponents() const fixture = TestBed.createComponent(HomeComponent) - homeHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, HomeHarness) - }) + const homeHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, HomeHarness) + return { + homeHarness + } + } it('display welcome message', async () => { + const { + homeHarness + } = await initComponent() + expect(await homeHarness.elementVisible('welcomeMessage')).toBe(true) }) }) diff --git a/src/app/components/login/test/login.component.spec.ts b/src/app/components/login/test/login.component.spec.ts index ae3b106..ce588ae 100644 --- a/src/app/components/login/test/login.component.spec.ts +++ b/src/app/components/login/test/login.component.spec.ts @@ -38,28 +38,15 @@ import { describe('LoginComponent', () => { let authServiceMock: jasmine.SpyObj let messageBoxServiceMock: jasmine.SpyObj - let loginHarness: LoginHarness - let router: Router const VALID_CREDS = { login: 'my_login', password: 'my_password' } - beforeEach(async () => { - authServiceMock = jasmine.createSpyObj('authService', ['login']) - authServiceMock.login.and.callFake((login: string, password: string) => { - if (login === VALID_CREDS.login && password === VALID_CREDS.password) { - return of(undefined) - } - else { - return throwError(() => new HttpErrorResponse({ - status: 403 - })) - } - }) - - messageBoxServiceMock = jasmine.createSpyObj('messageBoxService', ['error']) - + async function initComponent(): Promise<{ + loginHarness: LoginHarness + router: Router + }> { await TestBed.configureTestingModule({ imports: [ LoginComponent, @@ -78,12 +65,37 @@ describe('LoginComponent', () => { ] }).compileComponents() + const router = TestBed.inject(Router) + const fixture = TestBed.createComponent(LoginComponent) - loginHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, LoginHarness) - router = TestBed.inject(Router) + const loginHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, LoginHarness) + return { + loginHarness, + router + } + } + + beforeEach(async () => { + authServiceMock = jasmine.createSpyObj('authService', ['login']) + authServiceMock.login.and.callFake((login: string, password: string) => { + if (login === VALID_CREDS.login && password === VALID_CREDS.password) { + return of(undefined) + } + else { + return throwError(() => new HttpErrorResponse({ + status: 403 + })) + } + }) + + messageBoxServiceMock = jasmine.createSpyObj('messageBoxService', ['error']) }) it('enable/disable login button based on form validity', async () => { + const { + loginHarness + } = await initComponent() + // initial state // invalid form: login missing, password missing expect(await loginHarness.buttonEnabled('loginButton')).toBe(false) @@ -110,6 +122,10 @@ describe('LoginComponent', () => { }) it('display/hide error message based on login validity', async () => { + const { + loginHarness + } = await initComponent() + // initial state: no validation done expect(await loginHarness.elementVisible('loginErrorEmpty')).toBe(false) @@ -129,6 +145,10 @@ describe('LoginComponent', () => { }) it('display/hide error message based on password validity', async () => { + const { + loginHarness + } = await initComponent() + // initial state: no validation done expect(await loginHarness.elementVisible('passwordErrorEmpty')).toBe(false) @@ -148,6 +168,10 @@ describe('LoginComponent', () => { }) it('display error message in case of invalid credentials', async () => { + const { + loginHarness + } = await initComponent() + expect(await loginHarness.elementVisible('incorrectCreds')).toBe(false) await loginHarness.enterValue('loginInput', `${VALID_CREDS.login}_invalid`) @@ -157,6 +181,9 @@ describe('LoginComponent', () => { }) it('navigate to home on successful login', async () => { + const { + loginHarness, router + } = await initComponent() const navigateSpy = spyOn(router, 'navigate') await loginHarness.enterValue('loginInput', VALID_CREDS.login) @@ -171,6 +198,9 @@ describe('LoginComponent', () => { status: 500 })) }) + const { + loginHarness + } = await initComponent() await loginHarness.enterValue('loginInput', VALID_CREDS.login) await loginHarness.enterValue('passwordInput', VALID_CREDS.password) diff --git a/src/app/components/not-found/tests/not-found.component.spec.ts b/src/app/components/not-found/tests/not-found.component.spec.ts index 53a0816..6d7c649 100644 --- a/src/app/components/not-found/tests/not-found.component.spec.ts +++ b/src/app/components/not-found/tests/not-found.component.spec.ts @@ -23,10 +23,10 @@ import { } from '@angular/router' describe('NotFoundComponent', () => { - let notFoundHarness: NotFoundHarness - let router: Router - - beforeEach(async () => { + async function initComponent(): Promise<{ + notFoundHarness: NotFoundHarness + router: Router + }> { await TestBed.configureTestingModule({ imports: [ NotFoundComponent, @@ -36,16 +36,28 @@ describe('NotFoundComponent', () => { providers: [] }).compileComponents() + const router = TestBed.inject(Router) + const fixture = TestBed.createComponent(NotFoundComponent) - notFoundHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, NotFoundHarness) - router = TestBed.inject(Router) - }) + const notFoundHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, NotFoundHarness) + return { + notFoundHarness, + router + } + } it('display "not found" message', async () => { + const { + notFoundHarness + } = await initComponent() + expect(await notFoundHarness.elementVisible('notFoundMessage')).toBe(true) }) it('navigate to home page on link click', async () => { + const { + notFoundHarness, router + } = await initComponent() const navigateByUrlSpy = spyOn(router, 'navigateByUrl') await notFoundHarness.clickLink('navToHomeLink') diff --git a/src/app/tests/app.component.spec.ts b/src/app/tests/app.component.spec.ts index 9290afa..8985c19 100644 --- a/src/app/tests/app.component.spec.ts +++ b/src/app/tests/app.component.spec.ts @@ -36,20 +36,11 @@ describe('AppComponent', () => { let isAuthMock: BehaviorSubject let authServiceMock: jasmine.SpyObj let messageBoxServiceMock: jasmine.SpyObj - let appHarness: AppHarness - let router: Router - - beforeEach(async () => { - isAuthMock = new BehaviorSubject(true) - authServiceMock = jasmine.createSpyObj('authService', [ - 'logout', - 'isAuth' - ]) - authServiceMock.isAuth.and.returnValue(isAuthMock) - authServiceMock.logout.and.returnValue(of(undefined)) - - messageBoxServiceMock = jasmine.createSpyObj('messageBoxService', ['error']) + async function initComponent(): Promise<{ + appHarness: AppHarness + router: Router + }> { await TestBed.configureTestingModule({ imports: [ AppComponent, @@ -68,16 +59,40 @@ describe('AppComponent', () => { ] }).compileComponents() + const router = TestBed.inject(Router) + const fixture = TestBed.createComponent(AppComponent) - appHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, AppHarness) - router = TestBed.inject(Router) + const appHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, AppHarness) + return { + appHarness, + router + } + } + + beforeEach(async () => { + isAuthMock = new BehaviorSubject(true) + authServiceMock = jasmine.createSpyObj('authService', [ + 'logout', + 'isAuth' + ]) + authServiceMock.isAuth.and.returnValue(isAuthMock) + authServiceMock.logout.and.returnValue(of(undefined)) + + messageBoxServiceMock = jasmine.createSpyObj('messageBoxService', ['error']) }) it('display translated welcome message', async () => { + const { + appHarness + } = await initComponent() + expect(await appHarness.elementText('welcomeMessage')).toBe('Hello, contracts-angular component en') }) it('navigate to login on successful logout', async () => { + const { + appHarness, router + } = await initComponent() const navigateSpy = spyOn(router, 'navigate') await appHarness.clickButton('logoutButton') @@ -88,12 +103,19 @@ describe('AppComponent', () => { authServiceMock.logout.and.returnValue(throwError(() => { return new Error('some error') })) + const { + appHarness + } = await initComponent() await appHarness.clickButton('logoutButton') expect(messageBoxServiceMock.error).toHaveBeenCalledWith('Failed to logout.') }) it('display welcome message and logout button only to authenticated user', async () => { + const { + appHarness + } = await initComponent() + expect(await appHarness.elementVisible('welcomeMessage')).toBe(true) expect(await appHarness.elementVisible('logoutButton')).toBe(true) diff --git a/src/app/tests/foundation/tests/test.component.spec.ts b/src/app/tests/foundation/tests/test.component.spec.ts index 953a7bc..68e574a 100644 --- a/src/app/tests/foundation/tests/test.component.spec.ts +++ b/src/app/tests/foundation/tests/test.component.spec.ts @@ -121,14 +121,6 @@ describe('Base harness', () => { await expectAsync(baseHarness.elementChildCount('div-child-count-grandchild-present-non-existent')).toBeRejected() }) - it('elementChildCount', async () => { - await expectAsync(baseHarness.elementChildCount('div-child-count-no-grandchild-present')).toBeResolvedTo(2) - await expectAsync(baseHarness.elementChildCount('div-child-count-grandchild-present')).toBeResolvedTo(2) - - await expectAsync(baseHarness.elementChildCount('div-child-count-no-grandchild-present-non-existent')).toBeRejected() - await expectAsync(baseHarness.elementChildCount('div-child-count-grandchild-present-non-existent')).toBeRejected() - }) - it('enterValue - updateOn: change', async () => { let formValuesOnChange: string[] = [] testComponent.formControlUpdateOnChange.valueChanges.subscribe((value: string) => {