feat: add CreateTeamDialog component
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { provideHttpClient } from '@angular/common/http';
|
||||||
|
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||||
|
import { MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { CreateTeamDialog } from './create-team-dialog';
|
||||||
|
import { environment } from '../../../../environments/environment';
|
||||||
|
|
||||||
|
describe('CreateTeamDialog', () => {
|
||||||
|
let dialogRef: { close: ReturnType<typeof vi.fn> };
|
||||||
|
let httpMock: HttpTestingController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
dialogRef = { close: vi.fn() };
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [CreateTeamDialog],
|
||||||
|
providers: [
|
||||||
|
provideHttpClient(),
|
||||||
|
provideHttpClientTesting(),
|
||||||
|
{ provide: MatDialogRef, useValue: dialogRef },
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
httpMock = TestBed.inject(HttpTestingController);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
httpMock.verify();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps the submit button disabled until a team name is entered', () => {
|
||||||
|
const fixture = TestBed.createComponent(CreateTeamDialog);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.componentInstance['form'].invalid).toBe(true);
|
||||||
|
|
||||||
|
fixture.componentInstance['form'].controls.name.setValue('1. Herren');
|
||||||
|
expect(fixture.componentInstance['form'].invalid).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates the team and closes the dialog with the created team', () => {
|
||||||
|
const fixture = TestBed.createComponent(CreateTeamDialog);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
fixture.componentInstance['form'].controls.name.setValue('1. Herren');
|
||||||
|
fixture.componentInstance['submit']();
|
||||||
|
|
||||||
|
const request = httpMock.expectOne(`${environment.apiUrl}teams`);
|
||||||
|
expect(request.request.body).toEqual({ name: '1. Herren' });
|
||||||
|
request.flush({ id: 9, name: '1. Herren', alias: 'a', balance: 0 });
|
||||||
|
|
||||||
|
expect(dialogRef.close).toHaveBeenCalledWith({
|
||||||
|
id: 9,
|
||||||
|
name: '1. Herren',
|
||||||
|
alias: 'a',
|
||||||
|
balance: 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('re-enables the form and keeps the dialog open when the request fails', () => {
|
||||||
|
const fixture = TestBed.createComponent(CreateTeamDialog);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
fixture.componentInstance['form'].controls.name.setValue('1. Herren');
|
||||||
|
fixture.componentInstance['submit']();
|
||||||
|
|
||||||
|
httpMock
|
||||||
|
.expectOne(`${environment.apiUrl}teams`)
|
||||||
|
.flush('error', { status: 500, statusText: 'Server Error' });
|
||||||
|
|
||||||
|
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||||
|
expect(fixture.componentInstance['saving']()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { Component, inject, signal } from '@angular/core';
|
||||||
|
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { Team } from '../../../models/team.model';
|
||||||
|
import { TeamsApi } from '../../../core/team/teams-api';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-create-team-dialog',
|
||||||
|
imports: [ReactiveFormsModule, MatButtonModule, MatDialogModule, MatFormFieldModule, MatInputModule],
|
||||||
|
template: `
|
||||||
|
<h2 mat-dialog-title>Team erstellen</h2>
|
||||||
|
<form [formGroup]="form" (ngSubmit)="submit()">
|
||||||
|
<mat-dialog-content>
|
||||||
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Teamname</mat-label>
|
||||||
|
<input matInput formControlName="name" />
|
||||||
|
</mat-form-field>
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions align="end">
|
||||||
|
<button mat-button type="button" (click)="dialogRef.close()">Abbrechen</button>
|
||||||
|
<button mat-flat-button type="submit" [disabled]="form.invalid || saving()">
|
||||||
|
Erstellen
|
||||||
|
</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
|
</form>
|
||||||
|
`,
|
||||||
|
styles: [
|
||||||
|
`
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class CreateTeamDialog {
|
||||||
|
protected readonly dialogRef = inject(MatDialogRef<CreateTeamDialog, Team | undefined>);
|
||||||
|
private readonly formBuilder = inject(FormBuilder);
|
||||||
|
private readonly teamsApi = inject(TeamsApi);
|
||||||
|
|
||||||
|
protected readonly saving = signal(false);
|
||||||
|
protected readonly form = this.formBuilder.nonNullable.group({
|
||||||
|
name: ['', Validators.required],
|
||||||
|
});
|
||||||
|
|
||||||
|
protected submit(): void {
|
||||||
|
if (this.form.invalid || this.saving()) return;
|
||||||
|
this.saving.set(true);
|
||||||
|
this.teamsApi.createTeam(this.form.getRawValue()).subscribe({
|
||||||
|
next: (team) => {
|
||||||
|
this.saving.set(false);
|
||||||
|
this.dialogRef.close(team);
|
||||||
|
},
|
||||||
|
error: () => this.saving.set(false),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user