diff --git a/server/src/data-layer/services/BookingHistoryService.test.ts b/server/src/data-layer/services/BookingHistoryService.test.ts index bafc582f6..2c564961a 100644 --- a/server/src/data-layer/services/BookingHistoryService.test.ts +++ b/server/src/data-layer/services/BookingHistoryService.test.ts @@ -15,17 +15,19 @@ describe("BookingHistoryService integration tests", () => { const endDate = dateToFirestoreTimeStamp(new Date(2002, 10, 10)) const currentTime = dateToFirestoreTimeStamp(new Date()) - const newEvent = await bookingHistoryService.addBookingDeletedEvent({ + const event = { uid: "user-removed-from-booking", start_date: startDate as Timestamp, end_date: endDate as Timestamp, event_type: "removed_user_from_booking", timestamp: currentTime - }) + } as const + + const newEvent = await bookingHistoryService.addBookingDeletedEvent(event) - const result = db.bookingHistory.doc("user-removed-from-booking").get() + const result = (await db.bookingHistory.doc(newEvent.id).get()).data() - expect(result).toEqual(newEvent) + expect(result).toEqual(event) }) it("Should be able to add an event for created bookings", async () => { @@ -33,17 +35,19 @@ describe("BookingHistoryService integration tests", () => { const endDate = dateToFirestoreTimeStamp(new Date(2002, 10, 10)) const currentTime = dateToFirestoreTimeStamp(new Date()) - const newEvent = await bookingHistoryService.addBookingAddedEvent({ + const event = { uid: "user-added-to-booking", start_date: startDate as Timestamp, end_date: endDate as Timestamp, event_type: "added_user_to_booking", timestamp: currentTime - }) + } as const + + const newEvent = await bookingHistoryService.addBookingAddedEvent(event) - const result = db.bookingHistory.doc("user-added-to-booking").get() + const result = (await db.bookingHistory.doc(newEvent.id).get()).data() - expect(result).toEqual(newEvent) + expect(result).toEqual(event) }) it("Should be able to add an event for availability changes", async () => { @@ -51,72 +55,130 @@ describe("BookingHistoryService integration tests", () => { const endDate = dateToFirestoreTimeStamp(new Date(2002, 10, 10)) const currentTime = dateToFirestoreTimeStamp(new Date()) - const newEvent = await bookingHistoryService.addAvailibilityChangeEvent({ + const event = { start_date: startDate as Timestamp, end_date: endDate as Timestamp, event_type: "changed_date_availability", timestamp: currentTime, change: -69 - }) + } as const - const result = db.bookingHistory.doc(newEvent.id).get() + const newEvent = + await bookingHistoryService.addAvailibilityChangeEvent(event) - expect(result).toEqual(newEvent) - }) + const result = await (await db.bookingHistory.doc(newEvent.id).get()).data() - it("Should be able to fetch history in between a range of dates", async () => { + expect(result).toEqual(event) + }) + describe("Fetching events", () => { /** * In these tests we don't care about these */ const startDate = dateToFirestoreTimeStamp(new Date(2002, 10, 8)) const endDate = dateToFirestoreTimeStamp(new Date(2002, 10, 10)) - const searchStartDate = dateToFirestoreTimeStamp(new Date(2001, 10, 6)) - const searchEndDate = dateToFirestoreTimeStamp(new Date(2001, 10, 9)) - - const availabilityEvent = - await bookingHistoryService.addAvailibilityChangeEvent({ - timestamp: dateToFirestoreTimeStamp(new Date(2001, 10, 9)), - change: 69, - start_date: startDate, - end_date: endDate, - event_type: "changed_date_availability" - }) + const availabilityEvent = { + timestamp: Timestamp.fromDate(new Date(2001, 10, 9)), + change: 69, + start_date: startDate, + end_date: endDate, + event_type: "changed_date_availability" + } as const - const deletedEvent = await bookingHistoryService.addBookingDeletedEvent({ - timestamp: dateToFirestoreTimeStamp(new Date(2001, 10, 9)), + const deletedEvent = { + timestamp: Timestamp.fromDate(new Date(2001, 10, 9)), start_date: startDate, end_date: endDate, event_type: "removed_user_from_booking", uid: "deleted-user" - }) + } as const - const addedEvent = await bookingHistoryService.addBookingAddedEvent({ - timestamp: dateToFirestoreTimeStamp(new Date(2001, 10, 9)), + const addedEvent = { + timestamp: Timestamp.fromDate(new Date(2001, 10, 9)), start_date: startDate, end_date: endDate, event_type: "added_user_to_booking", uid: "added-user" - }) + } as const - const notIncludedEvent = await bookingHistoryService.addBookingAddedEvent({ - timestamp: dateToFirestoreTimeStamp(new Date(2001, 10, 10)), + const notIncludedEvent = { + timestamp: Timestamp.fromDate(new Date(2001, 10, 10)), start_date: startDate, end_date: endDate, event_type: "added_user_to_booking", uid: "unincluded-user" + } as const + + it("Should be able to fetch history in between a range of dates", async () => { + const searchStartDate = dateToFirestoreTimeStamp(new Date(2001, 10, 6)) + const searchEndDate = dateToFirestoreTimeStamp(new Date(2001, 10, 9)) + + const { id: availabilityId } = + await bookingHistoryService.addAvailibilityChangeEvent( + availabilityEvent + ) + + const { id: deletedId } = + await bookingHistoryService.addBookingDeletedEvent(deletedEvent) + + const { id: addedId } = + await bookingHistoryService.addBookingAddedEvent(addedEvent) + + const { id: notIncludedId } = + await bookingHistoryService.addBookingAddedEvent(notIncludedEvent) + + const foundEvents = + await bookingHistoryService.getAllHistoryBetweenDateRange( + searchStartDate, + searchEndDate + ) + + expect(foundEvents).toContainEqual({ ...addedEvent, id: addedId }) + expect(foundEvents).toContainEqual({ ...deletedEvent, id: deletedId }) + expect(foundEvents).toContainEqual({ + ...availabilityEvent, + id: availabilityId + }) + expect(foundEvents).not.toContainEqual({ + ...notIncludedEvent, + id: notIncludedId + }) }) - const foundEvents = - await bookingHistoryService.getAllHistoryBetweenDateRange( - searchStartDate, - searchEndDate - ) + it("Should be able to fetch the latest X events", async () => { + // Ordering matters! Earlier addition means it should be the first out + const { id: notIncludedId } = + await bookingHistoryService.addBookingAddedEvent(notIncludedEvent) + + const { id: availabilityId } = + await bookingHistoryService.addAvailibilityChangeEvent( + availabilityEvent + ) + + const { id: deletedId } = + await bookingHistoryService.addBookingDeletedEvent(deletedEvent) - expect(foundEvents).toContainEqual(availabilityEvent) - expect(foundEvents).toContainEqual(addedEvent) - expect(foundEvents).toContainEqual(deletedEvent) - expect(foundEvents).not.toContainEqual(notIncludedEvent) + const { id: addedId } = + await bookingHistoryService.addBookingAddedEvent(addedEvent) + + const PAGE_LENGTH = 3 as const + + const { data: foundEvents, nextCursor } = + await bookingHistoryService.getLatestHistory(PAGE_LENGTH) + + expect(nextCursor).not.toBeUndefined() + expect(foundEvents).toHaveLength(PAGE_LENGTH) + + expect(foundEvents).toContainEqual({ ...addedEvent, id: addedId }) + expect(foundEvents).toContainEqual({ ...deletedEvent, id: deletedId }) + expect(foundEvents).toContainEqual({ + ...availabilityEvent, + id: availabilityId + }) + expect(foundEvents).not.toContainEqual({ + ...notIncludedEvent, + id: notIncludedId + }) + }) }) - it("Should be able to fetch the latest X events") }) diff --git a/server/src/data-layer/services/BookingHistoryService.ts b/server/src/data-layer/services/BookingHistoryService.ts index 084efdc93..8eadb7ebe 100644 --- a/server/src/data-layer/services/BookingHistoryService.ts +++ b/server/src/data-layer/services/BookingHistoryService.ts @@ -17,7 +17,7 @@ class BookingHistoryService { * Stores a manual deletion of a booking (by admin) into the booking history collection * * @param event the required parameters defined by {@link BookingDeletedEvent} - * @returns the created document + * @returns the created document reference */ public async addBookingDeletedEvent(event: BookingDeletedEvent) { return await db.bookingHistory.add(event) @@ -27,7 +27,7 @@ class BookingHistoryService { * Stores a manual creation of a booking (by admin) into the booking history collection * * @param event the required parameters defined by {@link BookingAddedEvent} - * @returns the created document + * @returns the created document reference */ public async addBookingAddedEvent(event: BookingAddedEvent) { return await db.bookingHistory.add(event) @@ -37,7 +37,7 @@ class BookingHistoryService { * Stores a modification to the booking availability into the booking history collection * * @param event the required parameters defined by {@link BookingAvailabilityChangeEvent} - * @returns the created document + * @returns the created document reference */ public async addAvailibilityChangeEvent( event: BookingAvailabilityChangeEvent @@ -74,7 +74,7 @@ class BookingHistoryService { * @returns the page of booking history items and a cursor pointing to the * last `id` to use for pagination */ - public async getAllHistory( + public async getLatestHistory( limit: number = 100, startAfter?: FirebaseFirestore.DocumentSnapshot< BookingHistoryEvent,