feat: wire create-team dialog into team-select
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
<div class="team-select-toolbar">
|
||||
<button mat-stroked-button type="button" (click)="createTeam()">
|
||||
<mat-icon>add</mat-icon>
|
||||
Team erstellen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (loading()) {
|
||||
<div class="team-select-loading">
|
||||
<mat-spinner diameter="32" />
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
.team-select-toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 1rem 1rem 0;
|
||||
}
|
||||
|
||||
.team-select-loading,
|
||||
.team-select-empty {
|
||||
display: flex;
|
||||
|
||||
@@ -2,26 +2,42 @@ import { TestBed } from '@angular/core/testing';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { provideRouter, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { TeamSelect } from './team-select';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { AuthStore } from '../../core/auth/auth-store';
|
||||
import { Player } from '../../models/player.model';
|
||||
import { Team } from '../../models/team.model';
|
||||
import { MyTeamsStore } from '../../core/team/my-teams-store';
|
||||
import { CreateTeamDialog } from './create-team-dialog/create-team-dialog';
|
||||
|
||||
describe('TeamSelect', () => {
|
||||
let httpMock: HttpTestingController;
|
||||
let router: Router;
|
||||
let authStore: AuthStore;
|
||||
let myTeamsStore: MyTeamsStore;
|
||||
let dialogClosed: Subject<Team | undefined>;
|
||||
let dialog: { open: ReturnType<typeof vi.fn> };
|
||||
|
||||
beforeEach(async () => {
|
||||
localStorage.clear();
|
||||
dialogClosed = new Subject<Team | undefined>();
|
||||
dialog = { open: vi.fn(() => ({ afterClosed: () => dialogClosed.asObservable() })) };
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [TeamSelect],
|
||||
providers: [provideHttpClient(), provideHttpClientTesting(), provideRouter([])],
|
||||
providers: [
|
||||
provideHttpClient(),
|
||||
provideHttpClientTesting(),
|
||||
provideRouter([]),
|
||||
{ provide: MatDialog, useValue: dialog },
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
httpMock = TestBed.inject(HttpTestingController);
|
||||
router = TestBed.inject(Router);
|
||||
authStore = TestBed.inject(AuthStore);
|
||||
myTeamsStore = TestBed.inject(MyTeamsStore);
|
||||
authStore.setSession('token', { id: 42, email: 'a@b.de', firstName: 'A', lastName: 'B' });
|
||||
});
|
||||
|
||||
@@ -92,4 +108,41 @@ describe('TeamSelect', () => {
|
||||
|
||||
expect(fixture.nativeElement.textContent).toContain('Du bist noch keinem Team zugeordnet.');
|
||||
});
|
||||
|
||||
it('opens the create-team dialog and navigates into the newly created team on success', async () => {
|
||||
const navigateSpy = vi.spyOn(router, 'navigate');
|
||||
const refreshSpy = vi.spyOn(myTeamsStore, 'refresh');
|
||||
|
||||
const fixture = TestBed.createComponent(TeamSelect);
|
||||
fixture.detectChanges();
|
||||
httpMock.expectOne(`${environment.apiUrl}users/42/teams`).flush([]);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.componentInstance['createTeam']();
|
||||
expect(dialog.open).toHaveBeenCalledWith(CreateTeamDialog);
|
||||
|
||||
const created: Team = { id: 9, name: '1. Herren', alias: 'a', balance: 0 };
|
||||
dialogClosed.next(created);
|
||||
|
||||
expect(refreshSpy).toHaveBeenCalledWith(42);
|
||||
expect(navigateSpy).toHaveBeenCalledWith(['/team', 9, 'overview']);
|
||||
|
||||
httpMock.expectOne(`${environment.apiUrl}users/42/teams`).flush([]);
|
||||
});
|
||||
|
||||
it('does not navigate when the create-team dialog is dismissed without a team', async () => {
|
||||
const navigateSpy = vi.spyOn(router, 'navigate');
|
||||
|
||||
const fixture = TestBed.createComponent(TeamSelect);
|
||||
fixture.detectChanges();
|
||||
httpMock.expectOne(`${environment.apiUrl}users/42/teams`).flush([]);
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.componentInstance['createTeam']();
|
||||
dialogClosed.next(undefined);
|
||||
|
||||
expect(navigateSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { Component, effect, inject } from '@angular/core';
|
||||
import { Router, RouterLink } from '@angular/router';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { AuthStore } from '../../core/auth/auth-store';
|
||||
import { MyTeamsStore } from '../../core/team/my-teams-store';
|
||||
import { Team } from '../../models/team.model';
|
||||
import { CreateTeamDialog } from './create-team-dialog/create-team-dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'app-team-select',
|
||||
imports: [RouterLink, MatListModule, MatProgressSpinnerModule],
|
||||
imports: [RouterLink, MatButtonModule, MatIconModule, MatListModule, MatProgressSpinnerModule],
|
||||
templateUrl: './team-select.html',
|
||||
styleUrl: './team-select.scss',
|
||||
})
|
||||
@@ -15,6 +20,7 @@ export class TeamSelect {
|
||||
private readonly authStore = inject(AuthStore);
|
||||
private readonly myTeamsStore = inject(MyTeamsStore);
|
||||
private readonly router = inject(Router);
|
||||
private readonly dialog = inject(MatDialog);
|
||||
|
||||
protected readonly players = this.myTeamsStore.players;
|
||||
protected readonly loading = this.myTeamsStore.loading;
|
||||
@@ -34,4 +40,19 @@ export class TeamSelect {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected createTeam(): void {
|
||||
this.dialog
|
||||
.open(CreateTeamDialog)
|
||||
.afterClosed()
|
||||
.subscribe((team: Team | undefined) => {
|
||||
if (!team) return;
|
||||
|
||||
const userId = this.authStore.currentUser()?.id;
|
||||
if (userId) {
|
||||
this.myTeamsStore.refresh(userId);
|
||||
}
|
||||
void this.router.navigate(['/team', team.id, 'overview']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user