feat: prevent users from owning multiple teams in same league

This commit is contained in:
Chris Parsons 2025-10-21 22:27:14 -07:00
parent ee125565dd
commit 4ce71d05d2
3 changed files with 45 additions and 7 deletions

View file

@ -258,6 +258,14 @@ export async function action(args: Route.ActionArgs) {
return { error: "Only admins can assign team owners" };
}
// Check if user is already assigned to a team in this season
const teams = await findTeamsBySeasonId(season.id);
const userAlreadyHasTeam = teams.some(team => team.ownerId === userClerkId);
if (userAlreadyHasTeam) {
return { error: "This user is already assigned to a team in this league" };
}
try {
await assignTeamOwner(teamId, userClerkId);
return { success: true, message: "Owner assigned successfully" };
@ -934,11 +942,20 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone
<SelectValue placeholder="Select user" />
</SelectTrigger>
<SelectContent>
{allUsers.map((user: any) => (
<SelectItem key={user.id} value={user.clerkId}>
{user.displayName || user.username || user.email}
</SelectItem>
))}
{allUsers.map((user: any) => {
// Check if user already owns a team in this league
const userOwnsTeam = teams.some((t: any) => t.ownerId === user.clerkId);
return (
<SelectItem
key={user.id}
value={user.clerkId}
disabled={userOwnsTeam}
>
{user.username || user.email}
{userOwnsTeam && " (already in league)"}
</SelectItem>
);
})}
</SelectContent>
</Select>
<Button

View file

@ -74,7 +74,8 @@ The test suite covers:
- ✅ Reject assignment for non-admin users
- ✅ Allow commissioners to remove owners regardless of admin status
### 5. Edge Cases (5 tests)
### 5. Edge Cases (6 tests)
- ✅ Prevent assigning user who already owns a team in the league
- ✅ Handle removing owner from team with no owner
- ✅ Handle assigning owner to team that already has owner
- ✅ Handle invalid team ID gracefully
@ -86,7 +87,7 @@ The test suite covers:
- ✅ Reassigning owner from one user to another
- ✅ Handle multiple teams with different ownership states
**Total: 23 tests**
**Total: 24 tests**
## Key Features Tested

View file

@ -317,6 +317,26 @@ describe('Team Management - Edge Cases', () => {
vi.clearAllMocks();
});
it('should prevent assigning user who already owns a team in the league', async () => {
const userClerkId = 'user-clerk-1';
// Simulate that user already owns team-1
const existingTeams = [
createMockTeam({ id: 'team-1', ownerId: userClerkId, name: 'Team 1' }),
createMockTeam({ id: 'team-2', ownerId: null, name: 'Team 2' }),
];
// Check if user already has a team
const userAlreadyHasTeam = existingTeams.some(team => team.ownerId === userClerkId);
expect(userAlreadyHasTeam).toBe(true);
// Should not call assignTeamOwner if user already has a team
if (userAlreadyHasTeam) {
expect(assignTeamOwner).not.toHaveBeenCalled();
}
});
it('should handle removing owner from team that has no owner', async () => {
const teamId = 'team-1';
const mockTeam = createMockTeam({ id: teamId, ownerId: null, name: 'Team 1' });