From 19ff46b5a542dcbde516b80e1c6f2c388a5b4057 Mon Sep 17 00:00:00 2001 From: cmoinier Date: Fri, 20 Dec 2024 10:44:03 +0100 Subject: [PATCH] fix: fix unit tests --- .../publish-button.component.spec.ts | 71 ++++++++++++++----- .../publish-button.component.ts | 15 ++-- .../src/app/edit/edit-page.component.spec.ts | 8 +-- .../src/lib/+state/editor.facade.spec.ts | 4 +- 4 files changed, 70 insertions(+), 28 deletions(-) diff --git a/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.spec.ts b/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.spec.ts index ef0b38e18..5acecd8c6 100644 --- a/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.spec.ts +++ b/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.spec.ts @@ -1,7 +1,12 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing' +import { + ComponentFixture, + TestBed, + fakeAsync, + tick, +} from '@angular/core/testing' import { PublishButtonComponent } from './publish-button.component' import { EditorFacade } from '@geonetwork-ui/feature/editor' -import { BehaviorSubject, firstValueFrom, of } from 'rxjs' +import { BehaviorSubject, Subject, firstValueFrom, of } from 'rxjs' import { TranslateModule } from '@ngx-translate/core' import { HttpClientModule } from '@angular/common/http' import { PlatformServiceInterface } from '@geonetwork-ui/common/domain/platform.service.interface' @@ -10,6 +15,7 @@ import { RecordsApiService, } from '@geonetwork-ui/data-access/gn4' import { barbieUserFixture } from '@geonetwork-ui/common/fixtures' +import { OverlayRef } from '@angular/cdk/overlay' class EditorFacadeMock { changedSinceSave$ = new BehaviorSubject(false) @@ -18,9 +24,26 @@ class EditorFacadeMock { record$ = new BehaviorSubject({ ownerOrganization: { name: 'Group 1', id: 1 }, uniqueIdentifier: 304, + recordUpdated: new Date('2023-01-01'), + extras: { ownerInfo: '1|John|Doe' }, }) saveRecord = jest.fn() saveSuccess$ = new BehaviorSubject(true) + checkHasRecordChanged = jest.fn() + hasRecordChanged$ = new Subject() + isRecordNotYetSaved = jest.fn().mockReturnValue(false) + recordHasDraft = jest.fn().mockReturnValue(true) + getAllDrafts = jest + .fn() + .mockReturnValue( + of([{ uniqueIdentifier: 304, recordUpdated: new Date('2023-01-01') }]) + ) + getRecord = jest.fn().mockReturnValue( + of({ + recordUpdated: new Date('2023-02-01'), + extras: { ownerInfo: '1|John|Doe' }, + }) + ) } const user = barbieUserFixture() @@ -47,6 +70,7 @@ describe('PublishButtonComponent', () => { let fixture: ComponentFixture let facade: EditorFacadeMock let recordsApiService: RecordsApiService + let overlaySpy: any beforeEach(async () => { await TestBed.configureTestingModule({ @@ -79,6 +103,12 @@ describe('PublishButtonComponent', () => { facade = TestBed.inject(EditorFacade) as any fixture = TestBed.createComponent(PublishButtonComponent) component = fixture.componentInstance + overlaySpy = { + dispose: jest.fn(), + attach: jest.fn(), + backdropClick: jest.fn().mockReturnValue(of()), + } + component['overlayRef'] = overlaySpy fixture.detectChanges() }) @@ -137,41 +167,48 @@ describe('PublishButtonComponent', () => { describe('#cancelPublish', () => { it('should set isActionMenuOpen to false', () => { + component.isActionMenuOpen = true component.cancelPublish() expect(component.isActionMenuOpen).toBe(false) }) }) - describe('#openConfirmationMenu', () => { - it('should set isActionMenuOpen to true', () => { - component.openConfirmationMenu() - expect(component.isActionMenuOpen).toBe(true) - }) - }) - - describe('#publishRecord', () => { - it('should call openConfirmationMenu if publishWarning has length', () => { - component.publishWarning = ['Warning'] + describe('#verifyPublishConditions', () => { + it('should call openConfirmationMenu if hasRecordChanged emits with a date', () => { const openConfirmationMenuSpy = jest.spyOn( component, 'openConfirmationMenu' ) - component.publishRecord() + const saveRecordSpy = jest.spyOn(component, 'saveRecord') + + component.verifyPublishConditions() + facade.hasRecordChanged$.next(null) + facade.hasRecordChanged$.next({ date: new Date(), user: 'John Doe' }) + expect(openConfirmationMenuSpy).toHaveBeenCalled() + expect(saveRecordSpy).not.toHaveBeenCalled() }) - it('should call saveRecord if publishWarning is empty', () => { - component.publishWarning = [] + it('should call saveRecord if hasRecordChanged emits without a date', () => { + const openConfirmationMenuSpy = jest.spyOn( + component, + 'openConfirmationMenu' + ) const saveRecordSpy = jest.spyOn(component, 'saveRecord') - component.publishRecord() + + component.verifyPublishConditions() + facade.hasRecordChanged$.next(null) + facade.hasRecordChanged$.next({ date: undefined, user: undefined }) + expect(saveRecordSpy).toHaveBeenCalled() + expect(openConfirmationMenuSpy).not.toHaveBeenCalled() }) }) describe('formatDate', () => { it('should format date correctly based on current language', () => { const date = new Date('2024-01-01T10:00:00Z') const formattedDate = component.formatDate(date) - expect(formattedDate).toBe('1 janvier 2024 à 10:00') + expect(formattedDate).toBe('January 1, 2024 at 11:00 AM') }) it('should handle invalid date gracefully', () => { diff --git a/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.ts b/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.ts index d0423c8d7..3d79816fd 100644 --- a/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.ts +++ b/apps/metadata-editor/src/app/edit/components/publish-button/publish-button.component.ts @@ -14,8 +14,8 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner' import { EditorFacade } from '@geonetwork-ui/feature/editor' import { MatTooltipModule } from '@angular/material/tooltip' import { TranslateModule, TranslateService } from '@ngx-translate/core' -import { combineLatest, Observable, Subscription } from 'rxjs' -import { defaultIfEmpty, map, skip, switchMap, take } from 'rxjs/operators' +import { combineLatest, Observable, of, Subject, Subscription } from 'rxjs' +import { catchError, first, map, skip, switchMap, take } from 'rxjs/operators' import { RecordsApiService } from '@geonetwork-ui/data-access/gn4' import { PlatformServiceInterface } from '@geonetwork-ui/common/domain/platform.service.interface' import { @@ -154,11 +154,16 @@ export class PublishButtonComponent { .pipe( switchMap((record) => { this.facade.checkHasRecordChanged(record) - return this.facade.hasRecordChanged$.pipe(skip(1)) - }) + return this.facade.hasRecordChanged$.pipe( + skip(1), + take(1), + catchError(() => of(null)) + ) + }), + first() ) .subscribe((hasChanged) => { - if (hasChanged.date && hasChanged.user) { + if (hasChanged !== null && hasChanged.date) { this.publishWarning = hasChanged this.openConfirmationMenu() } else { diff --git a/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts b/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts index 364b7206e..575b46b94 100644 --- a/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts +++ b/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts @@ -215,18 +215,18 @@ describe('EditPageComponent', () => { }) describe('subscriptions', () => { - it('should add 3 subscriptions to component.subscription', () => { + it('should add 5 subscriptions to component.subscription', () => { const addSpy = jest.spyOn(component.subscription, 'add') component.ngOnInit() - expect(addSpy).toHaveBeenCalledTimes(3) + expect(addSpy).toHaveBeenCalledTimes(5) }) - it('should add 4 subscriptions to component.subscription when on /create route', () => { + it('should add 6 subscriptions to component.subscription when on /create route', () => { const activatedRoute = TestBed.inject(ActivatedRoute) activatedRoute.snapshot.routeConfig.path = '/create' fixture.detectChanges() const addSpy = jest.spyOn(component.subscription, 'add') component.ngOnInit() - expect(addSpy).toHaveBeenCalledTimes(4) + expect(addSpy).toHaveBeenCalledTimes(6) }) it('unsubscribes', () => { const unsubscribeSpy = jest.spyOn(component.subscription, 'unsubscribe') diff --git a/libs/feature/editor/src/lib/+state/editor.facade.spec.ts b/libs/feature/editor/src/lib/+state/editor.facade.spec.ts index dce20f906..e4e355056 100644 --- a/libs/feature/editor/src/lib/+state/editor.facade.spec.ts +++ b/libs/feature/editor/src/lib/+state/editor.facade.spec.ts @@ -78,10 +78,10 @@ describe('EditorFacade', () => { }) expect(spy).toHaveBeenCalledWith(action) }) - it('hasRecordChangedSinceDraft() should dispatch hasRecordChangedSinceDraft action', () => { + it('checkHasRecordChanged() should dispatch hasRecordChangedSinceDraft action', () => { const spy = jest.spyOn(store, 'dispatch') const record = datasetRecordsFixture()[0] - facade.hasRecordChangedSinceDraft(record) + facade.checkHasRecordChanged(record) const action = EditorActions.hasRecordChangedSinceDraft({ record }) expect(spy).toHaveBeenCalledWith(action) })