Skip to content

Commit

Permalink
Add mechanism to specify custom slot start/end times (#118)
Browse files Browse the repository at this point in the history
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
tidoust authored May 7, 2024
1 parent 9149ebf commit 59b351b
Show file tree
Hide file tree
Showing 2 changed files with 350 additions and 43 deletions.
185 changes: 185 additions & 0 deletions test/check-meeting-parsing.mjs
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'
}
]);
});
});
Loading

0 comments on commit 59b351b

Please sign in to comment.