-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add mechanism to specify custom slot start/end times (#118)
See #100. If the start/end times of a meeting needs to be adjusted for some reason, the actual start/end times may now be specified in the `Meeting` field using `<HH:mm>` next to the time that needs to be modified. For example: - `9:00<8:30>` - `9:00-11:00<10:30>` - `11:00<11:15> - 13:00<12:45>` Validation will reject problematic custom times: - a custom start time that overlaps with a previous slot - a custom end time that overlaps with a next slot - custom times that do not change anything - custom times that make no sense (e.g., because custom start time is later than the custom end time) The custom start/end times are used in the calendar. If a group meets during contiguous slots and custom start/end times are set for the inner slots, the custom start/end times are ignored. For example, the custom times are ignored in `9:00; 11:00<11:15> - 13:00<12:45>; 14:00` because this will map to only one calendar entry from `9:00` to `16:00`.
- Loading branch information
Showing
2 changed files
with
350 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import * as assert from 'node:assert'; | ||
import { initTestEnv } from './init-test-env.mjs'; | ||
import { getEnvKey, setEnvKey } from '../tools/lib/envkeys.mjs'; | ||
import { fetchProject } from '../tools/lib/project.mjs'; | ||
import { groupSessionMeetings, | ||
computeSessionCalendarUpdates, | ||
parseSessionMeetings, | ||
serializeSessionMeetings, | ||
applyMeetingsChanges } from '../tools/lib/meetings.mjs'; | ||
|
||
async function fetchTestProject() { | ||
return fetchProject( | ||
await getEnvKey('PROJECT_OWNER'), | ||
await getEnvKey('PROJECT_NUMBER')); | ||
} | ||
|
||
describe('The meeting field parser', function () { | ||
before(function () { | ||
initTestEnv(); | ||
setEnvKey('PROJECT_NUMBER', 'group-meetings'); | ||
setEnvKey('ISSUE_TEMPLATE', 'test/data/template-group.yml'); | ||
}); | ||
|
||
it('parses a regular list of meetings', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { | ||
meeting: 'Tuesday, Room 1, 9:00; Room 1, 2020-02-11, 11:00 - 13:00' | ||
}; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ | ||
day: 'Tuesday (2042-02-11)', | ||
room: 'Room 1', | ||
slot: '9:00 - 11:00' | ||
}, | ||
{ | ||
day: '2020-02-11', | ||
room: 'Room 1', | ||
slot: '11:00 - 13:00' | ||
} | ||
]); | ||
}); | ||
|
||
it('serializes a regular list of meetings', async function () { | ||
const project = await fetchTestProject(); | ||
const meetings = [ | ||
{ | ||
day: 'Tuesday (2042-02-11)', | ||
room: 'Room 1', | ||
slot: '9:00 - 11:00' | ||
}, | ||
{ | ||
day: '2020-02-11', | ||
room: 'Room 2', | ||
slot: '11:00 - 13:00' | ||
} | ||
]; | ||
assert.deepStrictEqual(serializeSessionMeetings(meetings, project), { | ||
meeting: 'Tuesday, 9:00, Room 1; 2020-02-11, 11:00, Room 2' | ||
}); | ||
}); | ||
|
||
it('parses a list of meetings with custom start/end times', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '9:00<8:30> - 11:00<10:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ | ||
slot: '9:00 - 11:00', | ||
actualStart: '8:30', | ||
actualEnd: '10:30' | ||
} | ||
]); | ||
}); | ||
|
||
it('serializes a list of meetings with custom start/end times', async function () { | ||
const project = await fetchTestProject(); | ||
const meetings = [ | ||
{ | ||
slot: '9:00 - 11:00', | ||
actualStart: '8:30' | ||
}, | ||
{ | ||
slot: '11:00 - 13:00', | ||
actualEnd: '12:30' | ||
} | ||
]; | ||
assert.deepStrictEqual(serializeSessionMeetings(meetings, project), { | ||
meeting: '9:00<8:30>; 11:00 - 13:00<12:30>' | ||
}); | ||
}); | ||
|
||
it('validates a meeting with custom start/end times within the slot', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '11:00<11:15> - 13:00<12:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(serializeSessionMeetings(meetings, project), session); | ||
}); | ||
|
||
it('validates an early morning meeting', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '9:00<07:00>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(serializeSessionMeetings(meetings, project), session); | ||
}); | ||
|
||
it('validates a late evening meeting', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '16:00 - 18:00<19:00>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(serializeSessionMeetings(meetings, project), session); | ||
}); | ||
|
||
it('rejects a meeting with a custom start time that overlaps with former slot', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '11:00<10:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ invalid: '11:00<10:30>' } | ||
]); | ||
}); | ||
|
||
it('rejects a meeting with a custom end time that overlaps with next slot', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '11:00 - 13:00<16:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ invalid: '11:00 - 13:00<16:30>' } | ||
]); | ||
}); | ||
|
||
it('rejects a meeting with a custom start time that makes no sense', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '11:00<14:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ invalid: '11:00<14:30>' } | ||
]); | ||
}); | ||
|
||
it('rejects a meeting with a custom end time that makes no sense', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '9:00 - 11:00<8:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ invalid: '9:00 - 11:00<8:30>' } | ||
]); | ||
}); | ||
|
||
it('rejects a meeting with custom start/end times that make no sense', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '9:00<10:30> - 11:00<9:30>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ invalid: '9:00<10:30> - 11:00<9:30>' } | ||
]); | ||
}); | ||
|
||
it('rejects a meeting with custom start/end times that do not change anything', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { meeting: '9:00<9:00> - 11:00<11:00>' }; | ||
const meetings = parseSessionMeetings(session, project); | ||
assert.deepStrictEqual(meetings, [ | ||
{ invalid: '9:00<9:00> - 11:00<11:00>' } | ||
]); | ||
}); | ||
|
||
it('uses custom start/end times when it merges contiguous slots', async function () { | ||
const project = await fetchTestProject(); | ||
const session = { | ||
room: 'Room 1', | ||
day: 'Monday (2042-02-10)', | ||
meeting: '9:00<8:30>; 11:00; 14:00 - 16:00<15:30>' | ||
}; | ||
const merged = groupSessionMeetings(session, project); | ||
assert.deepStrictEqual(merged, [ | ||
{ | ||
room: 'Room 1', | ||
day: 'Monday (2042-02-10)', | ||
start: '8:30', | ||
end: '15:30' | ||
} | ||
]); | ||
}); | ||
}); |
Oops, something went wrong.