Skip to content

Commit 1a93af7

Browse files
committed
Fixed issue with assigning judges for 1 group rounds
1 parent f2d7627 commit 1a93af7

File tree

3 files changed

+200
-10
lines changed

3 files changed

+200
-10
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { generateJudgeAssignmentsFromCompetingAssignments } from './generateJudgeAssignmentsFromCompetingAssignments';
2+
import type { Activity, Competition, Person, Round } from '@wca/helpers';
3+
import { describe, expect, it } from 'vitest';
4+
5+
const roundActivity: Activity = {
6+
id: 1,
7+
name: '3x3x3 Round 1',
8+
activityCode: '333-r1',
9+
startTime: '2024-01-01T10:00:00Z',
10+
endTime: '2024-01-01T11:00:00Z',
11+
childActivities: [],
12+
extensions: [],
13+
};
14+
15+
const round: Round = {
16+
id: '333-r1',
17+
format: 'a',
18+
timeLimit: null,
19+
cutoff: null,
20+
advancementCondition: null,
21+
scrambleSetCount: 1,
22+
results: [],
23+
extensions: [],
24+
};
25+
26+
const createGroupActivities = (count: number): Activity[] =>
27+
Array.from({ length: count }, (_, idx) => ({
28+
id: idx + 2,
29+
name: `Group ${idx + 1}`,
30+
activityCode: `333-r1-g${idx + 1}`,
31+
startTime: '2024-01-01T10:00:00Z',
32+
endTime: '2024-01-01T11:00:00Z',
33+
childActivities: [],
34+
extensions: [],
35+
}));
36+
37+
const competitor = (registrantId: number, competingActivityId: number): Person => ({
38+
registrantId,
39+
name: `Competitor ${registrantId}`,
40+
assignments: [{ assignmentCode: 'competitor', activityId: competingActivityId }],
41+
registration: { status: 'accepted', eventIds: ['333'] },
42+
});
43+
44+
const buildCompetition = (groupCount: number, persons: Person[]): Competition => {
45+
const groups = createGroupActivities(groupCount);
46+
47+
return {
48+
formatVersion: 'v1.0',
49+
id: 'test-comp',
50+
name: 'Test Competition',
51+
shortName: 'Test',
52+
persons,
53+
events: [
54+
{
55+
id: '333',
56+
rounds: [round],
57+
competitorLimit: null,
58+
qualification: null,
59+
extensions: [],
60+
},
61+
],
62+
schedule: {
63+
startDate: '2024-01-01',
64+
numberOfDays: 1,
65+
venues: [
66+
{
67+
id: 1,
68+
name: 'Main Venue',
69+
latitudeMicrodegrees: 0,
70+
longitudeMicrodegrees: 0,
71+
countryIso2: 'US',
72+
timezone: 'America/New_York',
73+
extensions: [],
74+
rooms: [
75+
{
76+
id: 10,
77+
name: 'Main Room',
78+
color: '#000',
79+
extensions: [],
80+
activities: [{ ...roundActivity, childActivities: groups }],
81+
},
82+
],
83+
},
84+
],
85+
},
86+
competitorLimit: null,
87+
extensions: [],
88+
};
89+
};
90+
91+
describe('generateJudgeAssignmentsFromCompetingAssignments', () => {
92+
it('does not generate judge assignments when only one group exists', () => {
93+
const wcif = buildCompetition(1, [competitor(1, 2)]);
94+
const generator = generateJudgeAssignmentsFromCompetingAssignments(wcif, '333-r1');
95+
96+
const generatedAssignments = generator ? generator([]) : [];
97+
98+
expect(generatedAssignments).toEqual([]);
99+
});
100+
101+
it('assigns judging duties to the next group when multiple groups exist', () => {
102+
const persons = [competitor(1, 2), competitor(2, 3)];
103+
const wcif = buildCompetition(2, persons);
104+
const generator = generateJudgeAssignmentsFromCompetingAssignments(wcif, '333-r1');
105+
106+
const generatedAssignments = generator ? generator([]) : [];
107+
108+
expect(generatedAssignments).toEqual([
109+
{
110+
registrantId: 1,
111+
assignment: { assignmentCode: 'staff-judge', activityId: 3, stationNumber: null },
112+
},
113+
{
114+
registrantId: 2,
115+
assignment: { assignmentCode: 'staff-judge', activityId: 2, stationNumber: null },
116+
},
117+
]);
118+
});
119+
});

src/lib/assignmentGenerators/generateJudgeAssignmentsFromCompetingAssignments.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const generateJudgeAssignmentsFromCompetingAssignments = (
1818
const round = event.rounds?.find((r) => r.id === roundActivityCode);
1919
const groups = findGroupActivitiesByRound(wcif, roundActivityCode);
2020
const groupIds = groups.map((g) => g.id);
21+
const hasMultipleGroups = groupIds.length > 1;
2122

2223
if (!event || !round || !roundNumber) {
2324
console.error('Error finding round', roundActivityCode);
@@ -26,6 +27,10 @@ export const generateJudgeAssignmentsFromCompetingAssignments = (
2627
}
2728

2829
return (assignments: InProgressAssignmment[]): InProgressAssignmment[] => {
30+
if (!hasMultipleGroups) {
31+
return [];
32+
}
33+
2934
const personFilterContext = { assignments, groupIds };
3035

3136
const persons = personsShouldBeInRound(round)(wcif.persons)

src/lib/wcif/groups.test.ts

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,18 @@ const baseRound: Activity = {
2020
extensions: [],
2121
};
2222

23-
const buildWcif = (roundActivities: Activity[]): Competition => ({
23+
const laterRound: Activity = {
24+
...baseRound,
25+
id: 2,
26+
name: '333 Round 2',
27+
activityCode: '333-r2',
28+
startTime: '2024-01-01T11:00:00Z',
29+
endTime: '2024-01-01T12:00:00Z',
30+
};
31+
32+
const buildWcifWithRooms = (
33+
rooms: Array<{ id: number; name?: string; activities: Activity[] }>
34+
): Competition => ({
2435
schedule: {
2536
startDate: '2024-01-01',
2637
numberOfDays: 1,
@@ -33,15 +44,13 @@ const buildWcif = (roundActivities: Activity[]): Competition => ({
3344
countryIso2: 'US',
3445
timezone: 'America/New_York',
3546
extensions: [],
36-
rooms: [
37-
{
38-
id: 10,
39-
name: 'Main Room',
40-
activities: roundActivities,
41-
color: '#000',
42-
extensions: [],
43-
},
44-
],
47+
rooms: rooms.map(({ id, name, activities }) => ({
48+
id,
49+
name: name ?? `Room ${id}`,
50+
activities,
51+
color: '#000',
52+
extensions: [],
53+
})),
4554
},
4655
],
4756
},
@@ -55,6 +64,9 @@ const buildWcif = (roundActivities: Activity[]): Competition => ({
5564
extensions: [],
5665
});
5766

67+
const buildWcif = (roundActivities: Activity[]): Competition =>
68+
buildWcifWithRooms([{ id: 10, name: 'Main Room', activities: roundActivities }]);
69+
5870
describe('group helpers', () => {
5971
it('creates group assignments', () => {
6072
expect(createGroupAssignment(1, 2, 'competitor', 5)).toEqual({
@@ -106,6 +118,27 @@ describe('group helpers', () => {
106118
expect(roundWithGroups.childActivities?.[1].startTime).toBe('2024-01-01T10:30:00.000Z');
107119
});
108120

121+
it('splits round durations evenly and increments activity ids across multiple stages', () => {
122+
const wcif = buildWcif([baseRound, laterRound]);
123+
const [firstRound, secondRound] = createGroupsAcrossStages(wcif, [baseRound, laterRound], {
124+
spreadGroupsAcrossAllStages: true,
125+
groups: 3,
126+
});
127+
128+
expect(firstRound.childActivities?.map((a) => a.id)).toEqual([3, 4, 5]);
129+
expect(secondRound.childActivities?.map((a) => a.id)).toEqual([6, 7, 8]);
130+
expect(firstRound.childActivities?.map((a) => a.startTime)).toEqual([
131+
'2024-01-01T10:00:00.000Z',
132+
'2024-01-01T10:20:00.000Z',
133+
'2024-01-01T10:40:00.000Z',
134+
]);
135+
expect(firstRound.childActivities?.map((a) => a.endTime)).toEqual([
136+
'2024-01-01T10:20:00.000Z',
137+
'2024-01-01T10:40:00.000Z',
138+
'2024-01-01T11:00:00.000Z',
139+
]);
140+
});
141+
109142
it('creates groups per room when not spreading across stages', () => {
110143
const wcif = buildWcif([baseRound]);
111144
const [roundWithGroups] = createGroupsAcrossStages(wcif, [baseRound], {
@@ -119,6 +152,39 @@ describe('group helpers', () => {
119152
]);
120153
});
121154

155+
it('uses per-room group counts when not spreading across stages', () => {
156+
const roomOneRound = { ...baseRound };
157+
const roomTwoRound: Activity = {
158+
...baseRound,
159+
id: 3,
160+
name: '444 Round 1',
161+
activityCode: '444-r1',
162+
};
163+
164+
const wcif = buildWcifWithRooms([
165+
{ id: 10, activities: [roomOneRound] },
166+
{ id: 11, activities: [roomTwoRound] },
167+
]);
168+
169+
const [mainRoomRound, sideRoomRound] = createGroupsAcrossStages(
170+
wcif,
171+
[roomOneRound, roomTwoRound],
172+
{
173+
spreadGroupsAcrossAllStages: false,
174+
groups: { 10: 1, 11: 3 },
175+
}
176+
);
177+
178+
expect(mainRoomRound.childActivities?.map((a) => a.activityCode)).toEqual(['333-r1-g1']);
179+
expect(sideRoomRound.childActivities?.map((a) => a.activityCode)).toEqual([
180+
'444-r1-g1',
181+
'444-r1-g2',
182+
'444-r1-g3',
183+
]);
184+
expect(sideRoomRound.childActivities?.[1].startTime).toBe('2024-01-01T10:20:00.000Z');
185+
expect(sideRoomRound.childActivities?.[2].endTime).toBe('2024-01-01T11:00:00.000Z');
186+
});
187+
122188
it('calculates group sizes for a round id', () => {
123189
const group1 = {
124190
id: 2,

0 commit comments

Comments
 (0)