diff --git a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts index 7b9027ffdc33f6f5cef1980aac392859a457237d..12140f8351c958ba5388638076727ef41bee5053 100644 --- a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts @@ -24,14 +24,20 @@ import 'cypress-real-events'; import { convertToDataTestId } from '../../support/tech-util'; +//TODO BenutzerListPage erstellen welche den Button und die Liste enthaelt. export class BenutzerListE2EComponent { private readonly headline: string = 'user-list-headline'; + private readonly list: string = 'user-list'; private readonly benutzerHinzufuegenButton: string = 'add-user-button'; public getHeadline(): Cypress.Chainable<Element> { return cy.getTestElement(this.headline); } + public getList(): Cypress.Chainable<Element> { + return cy.getTestElement(this.list); + } + public getHinzufuegenButton(): Cypress.Chainable<Element> { return cy.getTestElement(this.benutzerHinzufuegenButton); } @@ -98,10 +104,16 @@ export class BenutzerE2EComponent { private readonly loeschenCheckbox: string = 'Loschen-checkbox-editor'; private readonly userCheckbox: string = 'User-checkbox-editor'; private readonly postCheckbox: string = 'Poststelle-checkbox-editor'; + private readonly datenbeauftragungCheckbox: string = 'Datenbeauftragung-checkbox-editor'; private readonly organisationsEinheitCheckboxSuffix: string = '-checkbox-editor'; private readonly saveButton: string = 'save-button'; + private readonly deleteButton: string = 'delete-button'; + + public getHeadline(): Cypress.Chainable<Element> { + return cy.getTestElement(this.headline); + } public getVornameInput(): Cypress.Chainable<Element> { return cy.getTestElement(this.userVorname); @@ -135,15 +147,32 @@ export class BenutzerE2EComponent { return cy.getTestElement(this.postCheckbox); } - public getSaveButton(): Cypress.Chainable<Element> { - return cy.getTestElement(this.saveButton); + public getDatenbeauftragungCheckbox(): Cypress.Chainable<Element> { + return cy.getTestElement(this.datenbeauftragungCheckbox); } public getOrganisationsEinheitCheckbox(einheit: string): Cypress.Chainable<Element> { return cy.getTestElement(einheit + this.organisationsEinheitCheckboxSuffix); } - public getHeadline(): Cypress.Chainable<Element> { - return cy.getTestElement(this.headline); + public getSaveButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.saveButton); + } + + public getDeleteButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.deleteButton); + } +} + +export class BenutzerDeleteDialogE2EComponent { + private readonly deleteButton: string = 'dialog-delete'; + private readonly cancelButton: string = 'cancel-dialog'; + + public getCancelButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.cancelButton); + } + + public getDeleteButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.deleteButton); } } diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-loesche.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-loesche.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd494a41834116ef96c2ed992e026fba95bb53ef --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-loesche.cy.ts @@ -0,0 +1,33 @@ +import { faker } from '@faker-js/faker'; +import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; +import { E2EBenutzerVerifier } from 'apps/admin-e2e/src/helper/benutzer/benutzer.verifier'; +import { AdminUserE2E } from 'apps/admin-e2e/src/model/util'; +import { loginAsAriane } from 'apps/admin-e2e/src/support/user-util'; + +describe('Benutzer Löschen', () => { + const benutzerVerifier: E2EBenutzerVerifier = new E2EBenutzerVerifier(); + const benutzerHelper: E2EBenutzerHelper = new E2EBenutzerHelper(); + + const userName: string = 'testtheo' + faker.string.uuid(); + const user: AdminUserE2E = { + vorname: 'Theo', + nachname: 'Testuser', + username: userName, + email: 'theo' + faker.string.uuid() + '@ozg-sh.de', + isUser: true, + organisationseinheiten: [], + }; + + before(() => { + loginAsAriane(); + }); + + it('should delete user', () => { + benutzerHelper.openNewBenutzerPage(); + benutzerHelper.addBenutzerAndSave(user); + + benutzerHelper.deleteBenutzer(userName); + + benutzerVerifier.verifyUserNotInList(userName); + }); +}); diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts index 9c8898bc0fcddef20b538919cc20bde8bc6e1993..320db78e13e0fee0cae8dad0cd94969ad7b0e2de 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts @@ -1,4 +1,8 @@ -import { BenutzerE2EComponent } from '../../components/benutzer/benutzer.e2e.component'; +import { + BenutzerDeleteDialogE2EComponent, + BenutzerE2EComponent, + BenutzerListE2EComponent, +} from '../../components/benutzer/benutzer.e2e.component'; import { SnackBarE2EComponent } from '../../components/ui/snackbar.e2e.component'; import { OrganisationsEinheitE2E } from '../../model/organisations-einheit'; import { AdminUserE2E } from '../../model/util'; @@ -7,6 +11,8 @@ import { exist, notExist } from '../../support/cypress.util'; export class E2EBenutzerExecutor { private benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); private snackBar: SnackBarE2EComponent = new SnackBarE2EComponent(); + private benutzerDeleteDialog: BenutzerDeleteDialogE2EComponent = new BenutzerDeleteDialogE2EComponent(); + private benutzerListPage: BenutzerListE2EComponent = new BenutzerListE2EComponent(); public modifyBenutzer(user: AdminUserE2E): void { this.benutzerPage.getVornameInput().type(user.vorname); @@ -39,9 +45,17 @@ export class E2EBenutzerExecutor { exist(this.snackBar.getMessage()); this.snackBar.getCloseButton().click(); notExist(this.snackBar.getMessage()); + exist(this.benutzerListPage.getList()); } public saveBenutzer(): void { this.benutzerPage.getSaveButton().click(); } + + public deleteBenutzer(): void { + this.benutzerPage.getDeleteButton().click(); + exist(this.benutzerDeleteDialog.getDeleteButton()); + this.benutzerDeleteDialog.getDeleteButton().click(); + exist(this.benutzerListPage.getList()); + } } diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts index 3f2b6be7847116296225a8c28d81fb86e37f9cf9..2b06766322f460cdb12f6ec065e19b9e79e756f0 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts @@ -17,32 +17,45 @@ export class E2EBenutzerHelper { public addBenutzerAndSave(user: AdminUserE2E): void { this.addBenutzer(user); - this.executer.saveAndCloseSnackbar(); + this.saveAndCloseSnackbar(); } public addBenutzer(user: AdminUserE2E): void { - this.executer.modifyBenutzer(user); - } - - public openBenutzerPage(userName: string): void { - this.navigator.openBenutzerPage(userName); + this.modifyBenutzer(user); } public editBenutzerAndSave(user: AdminUserE2E): void { this.editBenutzer(user); - this.executer.saveAndCloseSnackbar(); + this.saveAndCloseSnackbar(); } public editBenutzer(user: AdminUserE2E): void { + this.modifyBenutzer(user); + } + + private modifyBenutzer(user: AdminUserE2E): void { this.executer.modifyBenutzer(user); } public editOrganisationsEinheitenAndSave(organisationsEinheiten: OrganisationsEinheitE2E[]): void { this.executer.modifyOrganisationsEinheiten(organisationsEinheiten); + this.saveAndCloseSnackbar(); + } + + private saveAndCloseSnackbar(): void { this.executer.saveAndCloseSnackbar(); } public saveBenutzer(): void { this.executer.saveBenutzer(); } + + public deleteBenutzer(userName: string): void { + this.openBenutzerPage(userName); + this.executer.deleteBenutzer(); + } + + public openBenutzerPage(userName: string): void { + this.navigator.openBenutzerPage(userName); + } } diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts index d0c33452341f51de81cefee2d0f7f0e610532c7b..be750e3dfbfe90c3821451932ecb475bd31cbbe5 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts @@ -4,7 +4,7 @@ import { BenutzerListItemE2EComponent, } from '../../components/benutzer/benutzer.e2e.component'; import { AdminUserE2E } from '../../model/util'; -import { contains, exist } from '../../support/cypress.util'; +import { contains, exist, notExist } from '../../support/cypress.util'; import { AlfaRollen } from '../../support/user-util'; export class E2EBenutzerVerifier { @@ -41,6 +41,10 @@ export class E2EBenutzerVerifier { if (user.isAdmin) contains(benutzer.getRoles(), AlfaRollen.ADMIN); } + public verifyUserNotInList(userName: string): void { + notExist(this.getBenutzerItem(userName).getRoot()); + } + private getBenutzerItem(userName: string): BenutzerListItemE2EComponent { return this.benutzerListPage.getItem(userName); } diff --git a/alfa-client/apps/admin/package.json b/alfa-client/apps/admin/package.json index 924f232583709ebf8224d6a8301cd00d84cb1307..ea02e8712086f17ab1ed610cd07352cd0918d4b0 100644 --- a/alfa-client/apps/admin/package.json +++ b/alfa-client/apps/admin/package.json @@ -1,4 +1,4 @@ { "name": "admin", - "version": "1.6.0-SNAPSHOT" + "version": "null" } diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts index ea3ca2d74ffe1eb2b6fb903a300d5b1b7b36e455..5a91a0813ffbe8dec5a89c9f526382168481bdcd 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts @@ -49,15 +49,16 @@ describe('KeycloakResourceService', () => { }); describe('getAll', () => { + const stateResource: StateResource<unknown> = createStateResource([]); + beforeEach(() => { - service.handleChanges = jest.fn(); + service.handleChanges = jest.fn().mockReturnValue(singleCold(stateResource)); }); - it('should return stateResource as observable', (done) => { - service.getAll().subscribe((stateResource) => { - expect(stateResource).toBe(service.stateResource.value); - done(); - }); + it('should return stateResource', () => { + const stateResource$: Observable<StateResource<unknown[]>> = service.getAll(); + + expect(stateResource$).toBeObservable(singleCold(stateResource)); }); it('should call handleChanges ', fakeAsync(() => { @@ -68,12 +69,25 @@ describe('KeycloakResourceService', () => { }); describe('handleChanges', () => { - it('should call doIfLoadingRequired', () => { - const doIfLoadingRequired: jest.SpyInstance<boolean> = jest.spyOn(ResourceUtil, 'doIfLoadingRequired'); + let doIfLoadingRequiredSpy: jest.SpyInstance<boolean>; + + beforeEach(() => { + doIfLoadingRequiredSpy = jest.spyOn(ResourceUtil, 'doIfLoadingRequired').mockImplementation(); + }); + it('should call doIfLoadingRequired', () => { service.handleChanges(emptyStateResource); - expect(doIfLoadingRequired).toHaveBeenCalled(); + expect(doIfLoadingRequiredSpy).toHaveBeenCalled(); + }); + + it('should return stateResource', (done) => { + service.stateResource.next(createStateResource([])); + + service.handleChanges(emptyStateResource).subscribe((stateResource: StateResource<[]>) => { + expect(stateResource).toEqual(createStateResource([])); + done(); + }); }); }); diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts index 572761923b93f3d3a21719659416b268fb17076f..dd680a850d96b5fb67f292c86e5e41f31207e094 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts @@ -22,22 +22,20 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { createEmptyStateResource, createStateResource, doIfLoadingRequired, StateResource } from '@alfa-client/tech-shared'; -import { BehaviorSubject, first, map, Observable, startWith, tap } from 'rxjs'; +import { BehaviorSubject, first, map, Observable, startWith, switchMap, tap } from 'rxjs'; export abstract class KeycloakResourceService<T> { - readonly stateResource: BehaviorSubject<StateResource<T[]>> = new BehaviorSubject({ - ...createStateResource<T[]>([]), - loaded: false, - }); + readonly stateResource: BehaviorSubject<StateResource<T[]>> = new BehaviorSubject(createEmptyStateResource()); public getAll(): Observable<StateResource<T[]>> { return this.stateResource .asObservable() - .pipe(tap((stateResource: StateResource<T[]>): void => this.handleChanges(stateResource))); + .pipe(switchMap((stateResource: StateResource<T[]>) => this.handleChanges(stateResource))); } - handleChanges(stateResource: StateResource<T[]>): void { + handleChanges(stateResource: StateResource<T[]>): Observable<StateResource<T[]>> { doIfLoadingRequired(stateResource, (): void => this.loadResource()); + return this.stateResource.asObservable(); } loadResource(): void { diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts index 3be33cbcdfd5b941af8ce9ef4a51c63160419bb5..724564f208c9f26cb6265da1bbad81b52ad92b13 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts @@ -26,8 +26,13 @@ import { ROUTES } from '@admin-client/shared'; import { User, UserService } from '@admin-client/user-shared'; import { PatchConfig } from '@admin/keycloak-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { createEmptyStateResource, createStateResource, StateResource } from '@alfa-client/tech-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; +import { + createEmptyStateResource, + createLoadingStateResource, + createStateResource, + StateResource, +} from '@alfa-client/tech-shared'; +import { Mock, mock, mockWindowError } from '@alfa-client/test-utils'; import { SnackBarService } from '@alfa-client/ui'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { AbstractControl, FormControl, FormGroup, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; @@ -159,7 +164,13 @@ describe('UserFormService', () => { }); describe('initOrganisationsEinheiten', () => { + beforeEach(() => { + formService._addOrganisationsEinheitenToForm = jest.fn(); + }); + it('should call adminOrganisationsEinheitService getAll', () => { + formService._initOrganisationsEinheiten(); + expect(adminOrganisationsEinheitService.getAll).toHaveBeenCalled(); }); @@ -170,8 +181,6 @@ describe('UserFormService', () => { }); it('should call addOrganisationsEinheitenToForm ', fakeAsync(() => { - formService._addOrganisationsEinheitenToForm = jest.fn(); - formService._initOrganisationsEinheiten().subscribe(); tick(); @@ -189,6 +198,15 @@ describe('UserFormService', () => { it('should set initOrganisationsEinheiten$', () => { expect(formService['_initOrganisationsEinheiten$']).toBeDefined(); }); + + it('should not throw any exception on loading state resource', () => { + adminOrganisationsEinheitService.getAll.mockReturnValue(of(createLoadingStateResource())); + const errorMock: any = mockWindowError(); + + formService._initOrganisationsEinheiten(); + + expect(errorMock).not.toHaveBeenCalled(); + }); }); describe('addOrganisationsEinheitenToForm', () => { diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts index a456872659a6b1ebd15a0bb570080b5834069fdd..3d0960b1d363fe87688c1c9fd07f7b61ddefc67c 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts @@ -26,7 +26,7 @@ import { ROUTES } from '@admin-client/shared'; import { User, UserService } from '@admin-client/user-shared'; import { KeycloakFormService, PatchConfig } from '@admin/keycloak-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { createEmptyStateResource, EMPTY_STRING, mapToResource, StateResource } from '@alfa-client/tech-shared'; +import { createEmptyStateResource, EMPTY_STRING, isLoaded, mapToResource, StateResource } from '@alfa-client/tech-shared'; import { SnackBarService } from '@alfa-client/ui'; import { Injectable, OnDestroy } from '@angular/core'; import { @@ -39,7 +39,7 @@ import { Validators, } from '@angular/forms'; import { UrlSegment } from '@angular/router'; -import { catchError, Observable, of, Subscription, tap } from 'rxjs'; +import { catchError, filter, Observable, of, Subscription, tap } from 'rxjs'; @Injectable() export class UserFormService extends KeycloakFormService<User> implements OnDestroy { @@ -137,6 +137,7 @@ export class UserFormService extends KeycloakFormService<User> implements OnDest _initOrganisationsEinheiten(): Observable<AdminOrganisationsEinheit[]> { const organisationsEinheitenGroup: UntypedFormGroup = this.getOrganisationsEinheitenGroup(); return this.adminOrganisationsEinheitService.getAll().pipe( + filter(isLoaded), mapToResource<AdminOrganisationsEinheit[]>(), tap((organisationsEinheiten: AdminOrganisationsEinheit[]): void => { this.setOrganisationsEinheitenIdsInMap(organisationsEinheiten); diff --git a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.spec.ts index e3b7bcedafc499a5bf7187d096e9bcb1eb9d6105..e03fe86039ad5c895d6be78eb173a56e78aa445e 100644 --- a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.spec.ts @@ -20,6 +20,7 @@ describe('UserListContainerComponent', () => { userService = { ...mock(UserService), getAll: jest.fn().mockReturnValue(usersStateResource$), + refresh: jest.fn(), }; await TestBed.configureTestingModule({ @@ -55,4 +56,12 @@ describe('UserListContainerComponent', () => { expect(userList.usersStateResource).toBe(usersStateResource); }); }); + + describe('on destroy', () => { + it('should call service to refresh list', () => { + component.ngOnDestroy(); + + expect(userService.refresh).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.ts b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.ts index 371df8b2664808b39e524439d4ae45d63016f177..ac2e37357acff04c7849031dec3d2cefe30f6a44 100644 --- a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.ts +++ b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list-container.component.ts @@ -1,8 +1,8 @@ import { User, UserService } from '@admin-client/user-shared'; -import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared'; +import { StateResource } from '@alfa-client/tech-shared'; import { AsyncPipe } from '@angular/common'; -import { Component, inject, OnInit } from '@angular/core'; -import { Observable, of } from 'rxjs'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; import { UserListComponent } from './user-list/user-list.component'; @Component({ @@ -11,12 +11,16 @@ import { UserListComponent } from './user-list/user-list.component'; imports: [UserListComponent, AsyncPipe], templateUrl: './user-list-container.component.html', }) -export class UserListContainerComponent implements OnInit { +export class UserListContainerComponent implements OnInit, OnDestroy { private userService = inject(UserService); - public usersStateResource$: Observable<StateResource<User[]>> = of(createEmptyStateResource<User[]>()); + public usersStateResource$: Observable<StateResource<User[]>>; ngOnInit(): void { this.usersStateResource$ = this.userService.getAll(); } + + ngOnDestroy(): void { + this.userService.refresh(); + } } diff --git a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html index c131614ac1e604fb3afc63765f97d57ad73e9c17..e2db54f1168e688391e37bd141c058e60dd45022 100644 --- a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html @@ -25,8 +25,10 @@ --> <h1 class="heading-1 mb-4" data-test-id="user-list-headline">Benutzer & Rollen</h1> <ods-routing-button [linkPath]="ROUTES.BENUTZER_NEU" text="Benutzer hinzufügen" class="mb-4 w-fit" dataTestId="add-user-button" /> -<ods-list> - @for (user of usersStateResource.resource; track $index) { - <admin-user [user]="user" class="block w-full" /> - } -</ods-list> +<ods-spinner [stateResource]="usersStateResource"> + <ods-list data-test-id="user-list"> + @for (user of usersStateResource.resource; track $index) { + <admin-user [user]="user" class="block w-full" /> + } + </ods-list> +</ods-spinner> diff --git a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.spec.ts index 23bc4e3efe65add8ea04eaff6d4324b907190dc8..fe161b5c1fc09a5a9b2def8a5a500b261358a9fe 100644 --- a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.spec.ts @@ -26,7 +26,7 @@ import { User } from '@admin-client/user-shared'; import { createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; import { getMockComponent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RoutingButtonComponent } from '@ods/component'; +import { RoutingButtonComponent, SpinnerComponent } from '@ods/component'; import { MockComponent } from 'ng-mocks'; import { createUser } from '../../../../../user-shared/test/user'; import { UserListComponent } from './user-list.component'; @@ -38,8 +38,10 @@ describe('UsersListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [UserListComponent], - declarations: [MockComponent(RoutingButtonComponent), MockComponent(UserComponent)], + imports: [ + UserListComponent, + [MockComponent(RoutingButtonComponent), MockComponent(UserComponent), MockComponent(SpinnerComponent)], + ], }).compileComponents(); fixture = TestBed.createComponent(UserListComponent); diff --git a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.ts b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.ts index 984d6540945e2739b3b89e66eb9fc03ebc7264d6..61df6b59bfa24732237a7837e9a0d67e7f2f90cc 100644 --- a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.ts +++ b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.ts @@ -26,7 +26,7 @@ import { User } from '@admin-client/user-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { AsyncPipe } from '@angular/common'; import { Component, Input } from '@angular/core'; -import { ButtonWithSpinnerComponent, RoutingButtonComponent } from '@ods/component'; +import { ButtonWithSpinnerComponent, RoutingButtonComponent, SpinnerComponent } from '@ods/component'; import { ListComponent, ListItemComponent } from '@ods/system'; import { UserComponent } from './user/user.component'; @@ -34,7 +34,15 @@ import { UserComponent } from './user/user.component'; selector: 'admin-user-list', templateUrl: './user-list.component.html', standalone: true, - imports: [ButtonWithSpinnerComponent, ListComponent, UserComponent, AsyncPipe, ListItemComponent, RoutingButtonComponent], + imports: [ + ButtonWithSpinnerComponent, + ListComponent, + UserComponent, + AsyncPipe, + ListItemComponent, + RoutingButtonComponent, + SpinnerComponent, + ], }) export class UserListComponent { @Input() usersStateResource: StateResource<User[]>; diff --git a/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.spec.ts b/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.spec.ts index 8cbe8c1ae06eabaea31340ddd8eb31f710cab503..4bb01a272a95332484183637cc71de58207548e3 100644 --- a/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.spec.ts +++ b/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.spec.ts @@ -80,20 +80,6 @@ describe('OpenDialogButtonComponent', () => { }); }); - describe('open', () => { - beforeEach(() => { - component._createComponent = jest.fn().mockReturnValue(componentRef); - }); - - it('should emit close emitter on dialog close', () => { - component.close.emit = jest.fn(); - - component.open(); - - expect(component.close.emit).toHaveBeenCalled(); - }); - }); - describe('create component', () => { it('should call component factory to create component', () => { component._createComponent(); diff --git a/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.ts b/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.ts index 2815aab6fd3ed8601930bfe061fecc23fc0e4704..66f08331d70aec3b84830d1650d38a4011d912f8 100644 --- a/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.ts +++ b/alfa-client/libs/design-component/src/lib/open-dialog-button/open-dialog-button.component.ts @@ -1,9 +1,8 @@ import { OzgCloudComponentFactory } from '@alfa-client/tech-shared'; import { DIALOG_COMPONENT, OzgcloudDialogService } from '@alfa-client/ui'; import { ComponentType } from '@angular/cdk/portal'; -import { Component, ComponentRef, EventEmitter, inject, Injector, Input, Output, ViewContainerRef } from '@angular/core'; +import { Component, ComponentRef, inject, Injector, Input, ViewContainerRef } from '@angular/core'; import { ButtonComponent, ButtonVariants } from '@ods/system'; -import { first } from 'rxjs'; @Component({ selector: 'ods-open-dialog-button', @@ -34,13 +33,8 @@ export class OpenDialogButtonComponent { @Input() dataTestId: string; @Input() variant: ButtonVariants['variant'] = 'primary'; - @Output() close: EventEmitter<void> = new EventEmitter(); - public open(): void { - this.dialogService - .openInContext(this._createComponent().instance.constructor, this.viewContainerRef) - .closed.pipe(first()) - .subscribe(this.close.emit); + this.dialogService.openInContext(this._createComponent().instance.constructor, this.viewContainerRef); } _createComponent(): ComponentRef<any> { diff --git a/alfa-client/libs/test-utils/src/lib/mocking.ts b/alfa-client/libs/test-utils/src/lib/mocking.ts index 0fb616db60420994880e9acfddec1d0d37e10486..20ac6152a4230849892a5f6e5599670b24e05165 100644 --- a/alfa-client/libs/test-utils/src/lib/mocking.ts +++ b/alfa-client/libs/test-utils/src/lib/mocking.ts @@ -53,3 +53,9 @@ export function mockGetValue(object: any, name: string, returnValue: any): void get: jest.fn(() => returnValue), }); } + +export function mockWindowError(): any { + const errorHandler = jest.fn(); + window.onerror = errorHandler; + return errorHandler; +}