wip
This commit is contained in:
@@ -35,11 +35,27 @@ import { GetTeamJoinRequestsUseCase } from '@gridpilot/racing/application/use-ca
|
||||
import { GetDriverTeamUseCase } from '@gridpilot/racing/application/use-cases/GetDriverTeamUseCase';
|
||||
import type { IDriverRegistrationStatusPresenter } from '@gridpilot/racing/application/presenters/IDriverRegistrationStatusPresenter';
|
||||
import type { IRaceRegistrationsPresenter } from '@gridpilot/racing/application/presenters/IRaceRegistrationsPresenter';
|
||||
import type { IAllTeamsPresenter } from '@gridpilot/racing/application/presenters/IAllTeamsPresenter';
|
||||
import type {
|
||||
IAllTeamsPresenter,
|
||||
AllTeamsResultDTO,
|
||||
AllTeamsViewModel,
|
||||
} from '@gridpilot/racing/application/presenters/IAllTeamsPresenter';
|
||||
import type { ITeamDetailsPresenter } from '@gridpilot/racing/application/presenters/ITeamDetailsPresenter';
|
||||
import type { ITeamMembersPresenter } from '@gridpilot/racing/application/presenters/ITeamMembersPresenter';
|
||||
import type { ITeamJoinRequestsPresenter } from '@gridpilot/racing/application/presenters/ITeamJoinRequestsPresenter';
|
||||
import type { IDriverTeamPresenter } from '@gridpilot/racing/application/presenters/IDriverTeamPresenter';
|
||||
import type {
|
||||
ITeamMembersPresenter,
|
||||
TeamMembersResultDTO,
|
||||
TeamMembersViewModel,
|
||||
} from '@gridpilot/racing/application/presenters/ITeamMembersPresenter';
|
||||
import type {
|
||||
ITeamJoinRequestsPresenter,
|
||||
TeamJoinRequestsResultDTO,
|
||||
TeamJoinRequestsViewModel,
|
||||
} from '@gridpilot/racing/application/presenters/ITeamJoinRequestsPresenter';
|
||||
import type {
|
||||
IDriverTeamPresenter,
|
||||
DriverTeamResultDTO,
|
||||
DriverTeamViewModel,
|
||||
} from '@gridpilot/racing/application/presenters/IDriverTeamPresenter';
|
||||
|
||||
/**
|
||||
* Simple in-memory fakes mirroring current alpha behavior.
|
||||
@@ -407,10 +423,35 @@ describe('Racing application use-cases - teams', () => {
|
||||
}
|
||||
|
||||
class TestAllTeamsPresenter implements IAllTeamsPresenter {
|
||||
teams: any[] = [];
|
||||
private viewModel: AllTeamsViewModel | null = null;
|
||||
|
||||
present(teams: any[]): void {
|
||||
this.teams = teams;
|
||||
reset(): void {
|
||||
this.viewModel = null;
|
||||
}
|
||||
|
||||
present(input: AllTeamsResultDTO): void {
|
||||
this.viewModel = {
|
||||
teams: input.teams.map((team) => ({
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
tag: team.tag,
|
||||
description: team.description,
|
||||
memberCount: team.memberCount,
|
||||
leagues: team.leagues,
|
||||
specialization: team.specialization,
|
||||
region: team.region,
|
||||
languages: team.languages,
|
||||
})),
|
||||
totalCount: input.teams.length,
|
||||
};
|
||||
}
|
||||
|
||||
getViewModel(): AllTeamsViewModel | null {
|
||||
return this.viewModel;
|
||||
}
|
||||
|
||||
get teams(): any[] {
|
||||
return this.viewModel?.teams ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,26 +464,129 @@ describe('Racing application use-cases - teams', () => {
|
||||
}
|
||||
|
||||
class TestTeamMembersPresenter implements ITeamMembersPresenter {
|
||||
members: any[] = [];
|
||||
private viewModel: TeamMembersViewModel | null = null;
|
||||
|
||||
present(members: any[]): void {
|
||||
this.members = members;
|
||||
reset(): void {
|
||||
this.viewModel = null;
|
||||
}
|
||||
|
||||
present(input: TeamMembersResultDTO): void {
|
||||
const members = input.memberships.map((membership) => {
|
||||
const driverId = membership.driverId;
|
||||
const driverName = input.driverNames[driverId] ?? driverId;
|
||||
const avatarUrl = input.avatarUrls[driverId] ?? '';
|
||||
|
||||
return {
|
||||
driverId,
|
||||
driverName,
|
||||
role: membership.role,
|
||||
joinedAt: membership.joinedAt.toISOString(),
|
||||
isActive: membership.status === 'active',
|
||||
avatarUrl,
|
||||
};
|
||||
});
|
||||
|
||||
const ownerCount = members.filter((m) => m.role === 'owner').length;
|
||||
const managerCount = members.filter((m) => m.role === 'manager').length;
|
||||
const memberCount = members.filter((m) => m.role === 'member').length;
|
||||
|
||||
this.viewModel = {
|
||||
members,
|
||||
totalCount: members.length,
|
||||
ownerCount,
|
||||
managerCount,
|
||||
memberCount,
|
||||
};
|
||||
}
|
||||
|
||||
getViewModel(): TeamMembersViewModel | null {
|
||||
return this.viewModel;
|
||||
}
|
||||
|
||||
get members(): any[] {
|
||||
return this.viewModel?.members ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
class TestTeamJoinRequestsPresenter implements ITeamJoinRequestsPresenter {
|
||||
requests: any[] = [];
|
||||
private viewModel: TeamJoinRequestsViewModel | null = null;
|
||||
|
||||
present(requests: any[]): void {
|
||||
this.requests = requests;
|
||||
reset(): void {
|
||||
this.viewModel = null;
|
||||
}
|
||||
|
||||
present(input: TeamJoinRequestsResultDTO): void {
|
||||
const requests = input.requests.map((request) => {
|
||||
const driverId = request.driverId;
|
||||
const driverName = input.driverNames[driverId] ?? driverId;
|
||||
const avatarUrl = input.avatarUrls[driverId] ?? '';
|
||||
|
||||
return {
|
||||
requestId: request.id,
|
||||
driverId,
|
||||
driverName,
|
||||
teamId: request.teamId,
|
||||
status: 'pending',
|
||||
requestedAt: request.requestedAt.toISOString(),
|
||||
avatarUrl,
|
||||
};
|
||||
});
|
||||
|
||||
const pendingCount = requests.filter((r) => r.status === 'pending').length;
|
||||
|
||||
this.viewModel = {
|
||||
requests,
|
||||
pendingCount,
|
||||
totalCount: requests.length,
|
||||
};
|
||||
}
|
||||
|
||||
getViewModel(): TeamJoinRequestsViewModel | null {
|
||||
return this.viewModel;
|
||||
}
|
||||
|
||||
get requests(): any[] {
|
||||
return this.viewModel?.requests ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
class TestDriverTeamPresenter implements IDriverTeamPresenter {
|
||||
viewModel: any = null;
|
||||
private viewModel: DriverTeamViewModel | null = null;
|
||||
|
||||
present(team: any, membership: any, driverId: string): void {
|
||||
this.viewModel = { team, membership, driverId };
|
||||
reset(): void {
|
||||
this.viewModel = null;
|
||||
}
|
||||
|
||||
present(input: DriverTeamResultDTO): void {
|
||||
const { team, membership, driverId } = input;
|
||||
|
||||
const isOwner = team.ownerId === driverId;
|
||||
const canManage = membership.role === 'owner' || membership.role === 'manager';
|
||||
|
||||
this.viewModel = {
|
||||
team: {
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
tag: team.tag,
|
||||
description: team.description,
|
||||
ownerId: team.ownerId,
|
||||
leagues: team.leagues,
|
||||
specialization: team.specialization,
|
||||
region: team.region,
|
||||
languages: team.languages,
|
||||
},
|
||||
membership: {
|
||||
role: membership.role,
|
||||
joinedAt: membership.joinedAt.toISOString(),
|
||||
isActive: membership.status === 'active',
|
||||
},
|
||||
isOwner,
|
||||
canManage,
|
||||
};
|
||||
}
|
||||
|
||||
getViewModel(): DriverTeamViewModel | null {
|
||||
return this.viewModel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,19 +621,22 @@ describe('Racing application use-cases - teams', () => {
|
||||
teamDetailsPresenter,
|
||||
);
|
||||
|
||||
const driverRepository = new FakeDriverRepository();
|
||||
const imageService = new FakeImageService();
|
||||
|
||||
teamMembersPresenter = new TestTeamMembersPresenter();
|
||||
getTeamMembersUseCase = new GetTeamMembersUseCase(
|
||||
membershipRepo,
|
||||
new FakeDriverRepository() as any,
|
||||
new FakeImageService() as any,
|
||||
driverRepository,
|
||||
imageService,
|
||||
teamMembersPresenter,
|
||||
);
|
||||
|
||||
|
||||
teamJoinRequestsPresenter = new TestTeamJoinRequestsPresenter();
|
||||
getTeamJoinRequestsUseCase = new GetTeamJoinRequestsUseCase(
|
||||
membershipRepo,
|
||||
new FakeDriverRepository() as any,
|
||||
new FakeImageService() as any,
|
||||
driverRepository,
|
||||
imageService,
|
||||
teamJoinRequestsPresenter,
|
||||
);
|
||||
|
||||
@@ -614,11 +761,12 @@ describe('Racing application use-cases - teams', () => {
|
||||
leagues: [],
|
||||
});
|
||||
|
||||
await getDriverTeamUseCase.execute(ownerId);
|
||||
await getDriverTeamUseCase.execute({ driverId: ownerId }, driverTeamPresenter);
|
||||
const result = driverTeamPresenter.viewModel;
|
||||
expect(result).not.toBeNull();
|
||||
expect(result?.team.id).toBe(team.id);
|
||||
expect(result?.membership.driverId).toBe(ownerId);
|
||||
expect(result?.membership.isActive).toBe(true);
|
||||
expect(result?.isOwner).toBe(true);
|
||||
});
|
||||
|
||||
it('lists all teams and members via queries after multiple operations', async () => {
|
||||
@@ -635,10 +783,10 @@ describe('Racing application use-cases - teams', () => {
|
||||
|
||||
await joinTeam.execute({ teamId: team.id, driverId: otherDriverId });
|
||||
|
||||
await getAllTeamsUseCase.execute();
|
||||
await getAllTeamsUseCase.execute(undefined as void, allTeamsPresenter);
|
||||
expect(allTeamsPresenter.teams.length).toBe(1);
|
||||
|
||||
await getTeamMembersUseCase.execute(team.id);
|
||||
await getTeamMembersUseCase.execute({ teamId: team.id }, teamMembersPresenter);
|
||||
const memberIds = teamMembersPresenter.members.map((m) => m.driverId).sort();
|
||||
expect(memberIds).toEqual([ownerId, otherDriverId].sort());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user