Skip to content

Commit

Permalink
client part for deleting a user
Browse files Browse the repository at this point in the history
  • Loading branch information
clean-coder authored and peggimann committed Nov 6, 2024
1 parent 756dd72 commit 85e2def
Show file tree
Hide file tree
Showing 17 changed files with 541 additions and 10 deletions.
29 changes: 23 additions & 6 deletions frontend/src/app/services/user.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { fakeAsync, getTestBed, TestBed, tick } from '@angular/core/testing';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { UserService } from './user.service';
import { testUser, users } from '../shared/testData';

describe('UserService', () => {
let service: UserService;
let httpMock: HttpTestingController;
const URL = 'api/v1/users';

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
});
service = TestBed.inject(UserService);
const injector = getTestBed();
httpMock = injector.get(HttpTestingController);
httpMock = TestBed.inject(HttpTestingController);
});

afterEach(() => {
Expand All @@ -29,7 +26,7 @@ describe('UserService', () => {
const spy = jest.spyOn(service, 'reloadUsers');
service.getUsers().subscribe(() => {
expect(spy).toBeCalledTimes(1);
httpMock.expectOne(URL);
httpMock.expectOne('api/v1/users');
service.getUsers().subscribe((users) => {
expect(spy).toBeCalledTimes(1);
expect(users).toStrictEqual([]);
Expand Down Expand Up @@ -75,4 +72,24 @@ describe('UserService', () => {
const req2 = httpMock.expectOne(`api/v1/users`);
req2.flush({});
}));

it('getUserOkrData() should call userokrdata', fakeAsync(() => {
service.getUserOkrData(testUser).subscribe();
const req = httpMock.expectOne(`api/v1/users/${testUser.id}/userokrdata`);
expect(req.request.method).toBe('GET');
req.flush(testUser);
}));

it('deleteUser() should call deleteUser and reloadUsers', fakeAsync(() => {
service.deleteUser(testUser).subscribe();
const reqDeleteUser = httpMock.expectOne(`api/v1/users/${testUser.id}`);
expect(reqDeleteUser.request.method).toBe('DELETE');
reqDeleteUser.flush(testUser);

tick();

const reqReloadUsers = httpMock.expectOne(`api/v1/users`);
expect(reqReloadUsers.request.method).toBe('GET');
reqReloadUsers.flush({});
}));
});
13 changes: 13 additions & 0 deletions frontend/src/app/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BehaviorSubject, Observable, of, tap } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { User } from '../shared/types/model/User';
import { NewUser } from '../shared/types/model/NewUser';
import { UserOkrData } from '../shared/types/model/UserOkrData';

@Injectable({
providedIn: 'root',
Expand Down Expand Up @@ -62,4 +63,16 @@ export class UserService {
createUsers(userList: NewUser[]) {
return this.httpClient.post<User>(`${this.API_URL}/createall`, userList).pipe(tap(() => this.reloadUsers()));
}

isUserMemberOfTeams(user: User): Observable<Boolean> {
return this.httpClient.get<Boolean>(`${this.API_URL}/${user.id}/ismemberofteams`, {});
}

getUserOkrData(user: User): Observable<UserOkrData> {
return this.httpClient.get<UserOkrData>(`${this.API_URL}/${user.id}/userokrdata`, {});
}

deleteUser(user: User) {
return this.httpClient.delete<void>(`${this.API_URL}/${user.id}`, {}).pipe(tap(() => this.reloadUsers()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<section mat-dialog-title>
<app-dialog-header [dialogTitle]="this.data.dialogTitle"></app-dialog-header>
</section>

<mat-dialog-content>
@if (data.dialogText) {
<div class="mb-3">
<span class="dialog-text">{{ this.data.dialogText }}</span>
</div>
}

@if (data.dialogDetails) {
<ul>
@for (item of this.data.dialogDetails; track $index) {
<div class="mb-3">
<li>
<span class="dialog-text">{{ item }}</span>
</li>
</div>
}
</ul>
}
</mat-dialog-content>

<mat-dialog-actions class="m-0">
<button color="primary" [attr.data-testId]="'alertDialog-confirm'" (click)="closeDialog()" mat-flat-button>
Schliessen
</button>
</mat-dialog-actions>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatButtonHarness } from '@angular/material/button/testing';
import { AlertDialogComponent } from './alert-dialog.component';

const dialogMock = {
close: jest.fn(),
};

describe('AlertDialogComponent', () => {
let component: AlertDialogComponent;
let fixture: ComponentFixture<AlertDialogComponent>;
let loader: HarnessLoader;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AlertDialogComponent],
imports: [],
providers: [
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: MatDialogRef, useValue: dialogMock },
],
});
fixture = TestBed.createComponent(AlertDialogComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should have only one button', async () => {
let buttons = await loader.getAllHarnesses(MatButtonHarness);
expect(buttons.length).toBe(1);
});

it('should call close method with no parameter', async () => {
let buttons = await loader.getAllHarnesses(MatButtonHarness);
const submitButton = buttons[0];
await submitButton.click();

expect(dialogMock.close).toHaveBeenCalledWith();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';

export type AlertDialogData = {
dialogTitle: string;
dialogText?: string;
dialogDetails?: string[];
};

@Component({
selector: 'app-alert-dialog',
templateUrl: './alert-dialog.component.html',
styleUrl: './alert-dialog.component.scss',
})
export class AlertDialogComponent {
constructor(
@Inject(MAT_DIALOG_DATA) public data: AlertDialogData,
private dialogRef: MatDialogRef<AlertDialogComponent>,
) {}

closeDialog() {
this.dialogRef.close();
}
}
2 changes: 2 additions & 0 deletions frontend/src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { RouterOutlet } from '@angular/router';
import { SpinnerComponent } from './custom/spinner/spinner.component';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { CancelDialogComponent } from './dialog/cancel-dialog/cancel-dialog.component';
import { AlertDialogComponent } from './dialog/alert-dialog/alert-dialog.component';

@NgModule({
declarations: [
Expand All @@ -42,6 +43,7 @@ import { CancelDialogComponent } from './dialog/cancel-dialog/cancel-dialog.comp
SidepanelComponent,
SpinnerComponent,
CancelDialogComponent,
AlertDialogComponent,
],
imports: [
CommonModule,
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/app/shared/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,21 @@ export const testUser: User = {
email: '[email protected]',
};

export const testOkrChampionUser: User = {
id: 1,
firstname: 'Hans',
lastname: 'Muster',
isOkrChampion: true,
userTeamList: [
{
id: 1,
team: team1,
isTeamAdmin: false,
},
],
email: '[email protected]',
};

export const users: User[] = [
testUser,
{
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/app/shared/types/model/UserOkrData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface UserOkrData {
keyResults: UserKeyResultData[];
}

export interface UserKeyResultData {
keyResultId: number;
keyResultName: string;
objectiveId: number;
objectiveName: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<ng-container>
<button
(click)="deleteUser()"
[attr.data-testId]="'delete-user'"
class="mdc-button px-0 pe-2"
color="primary"
mat-button
>
<span class="d-flex align-items-center fw-bold add-text">
<img alt="Delete user button" class="add-cross-button" src="/assets/icons/delete-icon.svg" />
Member l&ouml;schen
</span>
</button>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.new-team {
display: flex;

> mat-form-field {
flex: 0 0 calc(35% + 1rem);
padding-right: 1rem;
box-sizing: border-box;
}
}
Loading

0 comments on commit 85e2def

Please sign in to comment.