Skip to content

Commit

Permalink
Merge pull request #95 from ClubInfoInsaT/fix-91
Browse files Browse the repository at this point in the history
feat(events): events spanning multiple days are shown on multiple days
  • Loading branch information
ignyx authored Sep 3, 2024
2 parents cf56e72 + 1af674b commit 776a4ec
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 15 deletions.
168 changes: 162 additions & 6 deletions __tests__/utils/PlanningEventManager.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,170 @@ test('dateToDateTimeString', () => {
expect(Planning.dateToDateTimeString(testDate)).toBe('2022-12-31 09:10');
});

test('generateEventAgenda empty agenda', () => {
const eventList = [];

jest
.spyOn(Date, 'now')
.mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());

const calendar = Planning.generateEventAgenda(eventList);
expect(Object.keys(calendar).length).toBe(1);
expect(calendar['2020-01-14'].length).toBe(0);
});

test('generateEventAgenda one event today', () => {
const eventList = [
{
start: new Date('2020-01-14T09:15:00.000Z'),
end: new Date('2020-01-14T10:15:00.000Z'),
},
].map((event) => ({
start: event.start.valueOf() / 1000,
end: event.end.valueOf() / 1000,
})); // convert to timestamp

jest
.spyOn(Date, 'now')
.mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());

const calendar = Planning.generateEventAgenda(eventList, 2);
expect(Object.keys(calendar).length).toBe(1);
expect(calendar['2020-01-14'].length).toBe(1);
expect(calendar['2020-01-14'][0]).toBe(eventList[0]);
});

test('generateEventAgenda two events today', () => {
const eventList = [
{
start: new Date('2020-01-14T11:15:00.000Z'),
end: new Date('2020-01-14T12:15:00.000Z'),
},
{
start: new Date('2020-01-14T09:15:00.000Z'),
end: new Date('2020-01-14T10:15:00.000Z'),
},
].map((event) => ({
start: event.start.valueOf() / 1000,
end: event.end.valueOf() / 1000,
})); // convert to timestamp

jest
.spyOn(Date, 'now')
.mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());

const calendar = Planning.generateEventAgenda(eventList, 2);
expect(Object.keys(calendar).length).toBe(1);
expect(calendar['2020-01-14'].length).toBe(2);
expect(calendar['2020-01-14'][0]).toBe(eventList[1]);
expect(calendar['2020-01-14'][1]).toBe(eventList[0]);
});

test('generateEventAgenda two events tomorrow', () => {
const eventList = [
{
start: new Date('2020-01-15T00:00:00.000Z'),
end: new Date('2020-01-15T12:15:00.000Z'),
},
{
start: new Date('2020-01-15T09:15:00.000Z'),
end: new Date('2020-01-15T10:15:00.000Z'),
},
].map((event) => ({
start: event.start.valueOf() / 1000,
end: event.end.valueOf() / 1000,
})); // convert to timestamp

jest
.spyOn(Date, 'now')
.mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());

const calendar = Planning.generateEventAgenda(eventList, 2);
expect(Object.keys(calendar).length).toBe(2);
expect(calendar['2020-01-14'].length).toBe(0);
expect(calendar['2020-01-15'][0]).toBe(eventList[0]);
expect(calendar['2020-01-15'][1]).toBe(eventList[1]);
});

test('generateEventAgenda future event spanning 3 days', () => {
const eventList = [
{
// length: 2 days
start: new Date('2020-01-16T00:00:00.000Z'),
end: new Date('2020-01-18T12:15:00.000Z'),
},
].map((event) => ({
start: event.start.valueOf() / 1000,
end: event.end.valueOf() / 1000,
})); // convert to timestamp

jest
.spyOn(Date, 'now')
.mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());

const calendar = Planning.generateEventAgenda(eventList, 2);
expect(Object.keys(calendar).length).toBe(4);
expect(calendar['2020-01-14'].length).toBe(0);
expect(calendar['2020-01-16'].length).toBe(1);
expect(calendar['2020-01-16'][0]).toBe(eventList[0]);
expect(calendar['2020-01-17'].length).toBe(1);
expect(calendar['2020-01-17'][0]).toBe(eventList[0]);
expect(calendar['2020-01-18'].length).toBe(1);
expect(calendar['2020-01-18'][0]).toBe(eventList[0]);
});

test('generateEventAgenda current event spanning 3 days', () => {
const eventList = [
{
// length: 2 days
start: new Date('2020-01-13T00:00:00.000Z'),
end: new Date('2020-01-15T12:15:00.000Z'),
},
].map((event) => ({
start: event.start.valueOf() / 1000,
end: event.end.valueOf() / 1000,
})); // convert to timestamp

jest
.spyOn(Date, 'now')
.mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());

const calendar = Planning.generateEventAgenda(eventList, 2);
expect(Object.keys(calendar).length).toBe(3);
expect(calendar['2020-01-13'].length).toBe(1);
expect(calendar['2020-01-13'][0]).toBe(eventList[0]);
expect(calendar['2020-01-14'].length).toBe(1);
expect(calendar['2020-01-14'][0]).toBe(eventList[0]);
expect(calendar['2020-01-15'].length).toBe(1);
expect(calendar['2020-01-15'][0]).toBe(eventList[0]);
});

test('generateEventAgenda', () => {
const eventList = [
{ start: new Date('2020-01-14T09:15:00.000Z') },
{ start: new Date('2020-02-01T09:15:00.000Z') },
{ start: new Date('2020-01-15T09:15:00.000Z') },
{ start: new Date('2020-02-01T09:30:00.000Z') },
{ start: new Date('2020-02-01T08:30:00.000Z') },
].map((event) => ({ start: event.start.valueOf() / 1000 })); // convert to timestamp
{
start: new Date('2020-01-14T09:15:00.000Z'),
end: new Date('2020-01-14T10:15:00.000Z'),
},
{
start: new Date('2020-02-01T09:15:00.000Z'),
end: new Date('2020-02-01T10:15:00.000Z'),
},
{
start: new Date('2020-01-15T09:15:00.000Z'),
end: new Date('2020-01-15T10:15:00.000Z'),
},
{
start: new Date('2020-02-01T09:30:00.000Z'),
end: new Date('2020-02-01T10:30:00.000Z'),
},
{
start: new Date('2020-02-01T08:30:00.000Z'),
end: new Date('2020-02-01T09:30:00.000Z'),
},
].map((event) => ({
start: event.start.valueOf() / 1000,
end: event.end.valueOf() / 1000,
})); // convert to timestamp

jest
.spyOn(Date, 'now')
Expand Down
31 changes: 22 additions & 9 deletions src/utils/Planning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,29 @@ export function generateEventAgenda(events: PlanningEventType[]): {
[key: string]: Array<PlanningEventType>;
} {
let eventsByDate: { [key: string]: Array<PlanningEventType> } = {};
eventsByDate[dateToDateString(new Date())] = [];

// Initialize today's date
// new Date(Date.now()) should be equivalent to new Date(), but the latter
// behaves unexpectedly in tests
eventsByDate[dateToDateString(new Date(Date.now()))] = [];

events.forEach((event) => {
// TODO events covering multiple days
const dateString = dateToDateString(new Date(event.start * 1000));
if (!eventsByDate[dateString]) {
eventsByDate[dateString] = [event];
} else {
eventsByDate[dateString].push(event);
// bad time complexity but we're dealing with small arrays
eventsByDate[dateString].sort((a, b) => a.start - b.start);
const dayLength = 24 * 60 * 60;
const lengthInDays = Math.floor((event.end - event.start) / dayLength);
console.log(lengthInDays, event.start, event.end, dayLength);

for (let i = 0; i <= lengthInDays; i++) {
const dateString = dateToDateString(
new Date((event.start + i * dayLength) * 1000)
);
if (!eventsByDate[dateString]) {
eventsByDate[dateString] = [event];
} else {
eventsByDate[dateString].push(event);
// Sort events, earlier events first
// bad time complexity but we're dealing with small arrays
eventsByDate[dateString].sort((a, b) => a.start - b.start);
}
}
});

Expand Down

0 comments on commit 776a4ec

Please sign in to comment.