diff --git a/api/src/helpers/timespan.ts b/api/src/helpers/timespan.ts index 7aa8e24..cf91cdd 100644 --- a/api/src/helpers/timespan.ts +++ b/api/src/helpers/timespan.ts @@ -34,12 +34,19 @@ export const getTimespanRange = ( ]; // FRIDAY 5pm - SUNDAY - case 'this-weekend': + case 'this-weekend': { + const friday5PM = now + .startOf('week') + .plus({ days: 4 }) + .plus({ hours: 17 }); + + const isNowWeekend = now > friday5PM; + return [ { range: { 'filter.times.startDateTime': { - gte: now.startOf('week').plus({ days: 4 }).plus({ hours: 17 }), // Friday 5pm + gte: isNowWeekend ? 'now' : friday5PM, // Friday 5pm or NOW lte: now.startOf('week').plus({ days: 6 }).endOf('day'), // Sunday }, }, @@ -52,6 +59,7 @@ export const getTimespanRange = ( }, }, ]; + } case 'this-week': return [ @@ -59,14 +67,14 @@ export const getTimespanRange = ( range: { 'filter.times.startDateTime': { gte: 'now', - lt: now.plus({ days: 7 }).endOf('day'), + lt: now.plus({ days: 6 }).endOf('day'), }, }, }, { range: { 'filter.times.endDateTime': { - gt: now, + gt: 'now', }, }, }, @@ -85,7 +93,7 @@ export const getTimespanRange = ( { range: { 'filter.times.endDateTime': { - gt: now, + gt: 'now', }, }, }, @@ -126,14 +134,22 @@ export const getTimespanRange = ( case 'november': case 'december': { const monthNumber = MONTHS.indexOf(timespan) + 1; - const startOfMonth = DateTime.local(now.year, monthNumber); + const isInPast = now.month > monthNumber; + const isCurrentMonth = now.month === monthNumber; + + const startOfMonth = DateTime.local( + now.year + (isInPast ? 1 : 0), + monthNumber + ); const endOfMonth = startOfMonth.endOf('month'); + console.log({ isCurrentMonth, now, startOfMonth }); + return [ { range: { 'filter.times.startDateTime': { - gte: startOfMonth, + gte: isCurrentMonth ? 'now' : startOfMonth, lte: endOfMonth, }, }, diff --git a/api/test/utils.test.ts b/api/test/utils.test.ts index 98352d4..d244afa 100644 --- a/api/test/utils.test.ts +++ b/api/test/utils.test.ts @@ -1,4 +1,5 @@ import { getNextOpeningDates } from '@weco/content-api/src/controllers/utils'; +import { getTimespanRange } from '@weco/content-api/src/helpers/timespan'; import { RegularOpeningDay } from '@weco/content-common/types/venue'; const regularOpeningDays = [ @@ -250,3 +251,274 @@ describe('getNextOpeningDates', () => { }); }); }); + +// +// September 2022 +// Su Mo Tu We Th Fr Sa +// 1 2 3 +// 4 5 6 7 8 9 10 +// 11 12 13 14 15 16 17 +// 18 19 20 21 22 23 24 +// +describe('getTimespanRange', () => { + describe('today', () => { + it('return events from today that are still ongoing or upcoming at the time of the request', () => { + mockDateNow('2022-09-05T14:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + lte: 'now/d', + }, + }, + }, + { range: { 'filter.times.endDateTime': { lt: 'now/d' } } }, + ]); + + expect(JSON.stringify(getTimespanRange('today'))).toEqual(expectedRange); + }); + }); + + describe('this-weekend', () => { + it("returns that weeks' weekend", () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: '2022-09-09T17:00:00.000+01:00', + lte: '2022-09-11T23:59:59.999+01:00', + }, + }, + }, + { range: { 'filter.times.endDateTime': { lt: 'now' } } }, + ]); + + expect(JSON.stringify(getTimespanRange('this-weekend'))).toEqual( + expectedRange + ); + }); + + it('if it is the weekend, it returns results that are upcoming at the time of the request', () => { + mockDateNow('2022-09-10T15:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + lte: '2022-09-11T23:59:59.999+01:00', + }, + }, + }, + { range: { 'filter.times.endDateTime': { lt: 'now' } } }, + ]); + + expect(JSON.stringify(getTimespanRange('this-weekend'))).toEqual( + expectedRange + ); + }); + + it("returns that weeks' weekend until the end of the Sunday", () => { + mockDateNow('2022-09-11T22:59:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + lte: '2022-09-11T23:59:59.999+01:00', + }, + }, + }, + { range: { 'filter.times.endDateTime': { lt: 'now' } } }, + ]); + + expect(JSON.stringify(getTimespanRange('this-weekend'))).toEqual( + expectedRange + ); + }); + }); + + describe('this-week', () => { + it('return events from the next seven days from the time of the request', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + lt: '2022-09-11T23:59:59.999+01:00', + }, + }, + }, + { + range: { + 'filter.times.endDateTime': { gt: 'now' }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('this-week'))).toEqual( + expectedRange + ); + }); + }); + + describe('this-month', () => { + it('return events from the time of the request to the end of the named month', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + lte: '2022-09-30T23:59:59.999+01:00', + }, + }, + }, + { + range: { + 'filter.times.endDateTime': { gt: 'now' }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('this-month'))).toEqual( + expectedRange + ); + }); + }); + + describe('future', () => { + it('return events from the time of the request to infinity', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('future'))).toEqual(expectedRange); + }); + }); + + describe('past', () => { + it('return events that ended before the time of the request', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.endDateTime': { + lt: 'now', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('past'))).toEqual(expectedRange); + }); + }); + + describe('monthly', () => { + it('returns events from an entire named month', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: '2022-10-01T00:00:00.000+01:00', + lte: '2022-10-31T23:59:59.999+00:00', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('october'))).toEqual( + expectedRange + ); + }); + + it('returns events from the future only, so the year changes if a past month is requested', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: '2023-08-01T00:00:00.000+01:00', + lte: '2023-08-31T23:59:59.999+01:00', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('august'))).toEqual(expectedRange); + }); + + it('returns events from the next year if requested around the end of it', () => { + mockDateNow('2022-11-30T10:00:00.000Z'); + + const expectedJanuaryRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: '2023-01-01T00:00:00.000+00:00', + lte: '2023-01-31T23:59:59.999+00:00', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('january'))).toEqual( + expectedJanuaryRange + ); + + const expectedDecemberRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: '2022-12-01T00:00:00.000+00:00', + lte: '2022-12-31T23:59:59.999+00:00', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('december'))).toEqual( + expectedDecemberRange + ); + }); + + it('if it is the current month, returns events starting at the time of the request until the end of the month', () => { + mockDateNow('2022-09-05T10:00:00.000Z'); + + const expectedRange = JSON.stringify([ + { + range: { + 'filter.times.startDateTime': { + gte: 'now', + lte: '2022-09-30T23:59:59.999+01:00', + }, + }, + }, + ]); + + expect(JSON.stringify(getTimespanRange('september'))).toEqual( + expectedRange + ); + }); + }); +});