From bb714bb2348eead69293cdb15ce67089e4869cb7 Mon Sep 17 00:00:00 2001 From: Xavier Le Cunff Date: Fri, 18 Oct 2024 18:50:43 +0200 Subject: [PATCH] fix: add review feedbacks --- .../MoviesScreeningCalendar/VenueCalendar.tsx | 32 +-------- .../useMoviesScreeningsList.native.test.ts | 69 +++++++++++++++++++ .../hook/useMoviesScreeningsList.ts | 32 +++++++++ .../useGetVenuesByDay.native.test.ts | 38 +++++----- 4 files changed, 122 insertions(+), 49 deletions(-) create mode 100644 src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.native.test.ts create mode 100644 src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.ts diff --git a/src/features/offer/components/MoviesScreeningCalendar/VenueCalendar.tsx b/src/features/offer/components/MoviesScreeningCalendar/VenueCalendar.tsx index 83412af6cf7..66e9fd4c883 100644 --- a/src/features/offer/components/MoviesScreeningCalendar/VenueCalendar.tsx +++ b/src/features/offer/components/MoviesScreeningCalendar/VenueCalendar.tsx @@ -1,15 +1,8 @@ -import React, { FunctionComponent, useMemo, useCallback } from 'react' +import React, { FunctionComponent, useCallback } from 'react' import { View } from 'react-native' import styled from 'styled-components/native' -import { SubcategoryIdEnum } from 'api/gen' -import { useOffersStocks } from 'features/offer/api/useOffersStocks' -import { filterOffersStocksByDate } from 'features/offer/components/MoviesScreeningCalendar/filterOffersStocksByDate' -import { - getNextMoviesByDate, - MovieOffer, -} from 'features/offer/components/MoviesScreeningCalendar/getNextMoviesByDate' -import { useMovieCalendar } from 'features/offer/components/MoviesScreeningCalendar/MovieCalendarContext' +import { useMoviesScreeningsList } from 'features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList' import { MovieOfferTile } from 'features/offer/components/MoviesScreeningCalendar/MovieOfferTile' import { VenueOffers } from 'features/venue/api/useVenueOffers' import { Spacer } from 'ui/theme' @@ -19,27 +12,6 @@ type Props = { offerIds: number[] } -const useMoviesScreeningsList = (offerIds: number[]) => { - const { selectedDate } = useMovieCalendar() - const { data: offersWithStocks } = useOffersStocks({ offerIds }) - - const moviesOffers: MovieOffer[] = useMemo(() => { - const filteredOffersWithStocks = filterOffersStocksByDate( - offersWithStocks?.offers || [], - selectedDate - ) - const nextScreeningOffers = getNextMoviesByDate(offersWithStocks?.offers || [], selectedDate) - - return [...filteredOffersWithStocks, ...nextScreeningOffers] - }, [offersWithStocks?.offers, selectedDate]).filter( - (offer) => offer.offer.subcategoryId === SubcategoryIdEnum.SEANCE_CINE - ) - - return { - moviesOffers, - } -} - export const VenueCalendar: FunctionComponent = ({ venueOffers, offerIds }) => { const { moviesOffers } = useMoviesScreeningsList(offerIds) diff --git a/src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.native.test.ts b/src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.native.test.ts new file mode 100644 index 00000000000..b3b5a40b0e9 --- /dev/null +++ b/src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.native.test.ts @@ -0,0 +1,69 @@ +import { SubcategoryIdEnum } from 'api/gen' +import * as getStocksByOfferIdsModule from 'features/offer/api/getStocksByOfferIds' +import * as useMovieCalendarModule from 'features/offer/components/MoviesScreeningCalendar/MovieCalendarContext' +import { + offerResponseBuilder, + stockBuilder, +} from 'features/offer/components/MoviesScreeningCalendar/offersStockResponse.builder' +import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC' +import { act, renderHook } from 'tests/utils' + +import { useMoviesScreeningsList } from './useMoviesScreeningsList' + +jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter') +jest.mock('libs/network/NetInfoWrapper') + +const getStocksByOfferIdsModuleSpy = jest.spyOn(getStocksByOfferIdsModule, 'getStocksByOfferIds') + +describe('useMoviesScreeningsList', () => { + const mockSelectedDate = new Date('2023-05-15') + const mockOfferIds = [1, 2, 3] + + beforeEach(() => { + jest + .spyOn(useMovieCalendarModule, 'useMovieCalendar') + .mockReturnValue({ selectedDate: mockSelectedDate, goToDate: jest.fn }) + }) + + it('should return filtered movie offers', async () => { + const mockOffers = [ + offerResponseBuilder() + .withId(1) + .withSubcategoryId(SubcategoryIdEnum.SEANCE_CINE) + .withStocks([stockBuilder().withBeginningDatetime('2023-05-15T10:00:00Z').build()]) + .build(), + offerResponseBuilder() + .withId(2) + .withSubcategoryId(SubcategoryIdEnum.SEANCE_CINE) + .withStocks([stockBuilder().withBeginningDatetime('2023-05-16T10:00:00Z').build()]) + .build(), + offerResponseBuilder() + .withId(3) + .withSubcategoryId(SubcategoryIdEnum.LIVRE_PAPIER) + .withStocks([stockBuilder().withBeginningDatetime('2023-05-15T10:00:00Z').build()]) + .build(), + ] + + getStocksByOfferIdsModuleSpy.mockResolvedValueOnce({ offers: mockOffers }) + + const { result } = renderHook(() => useMoviesScreeningsList(mockOfferIds), { + wrapper: ({ children }) => reactQueryProviderHOC(children), + }) + + await act(async () => {}) + + expect(result.current.moviesOffers).toStrictEqual([{ isUpcoming: false, offer: mockOffers[0] }]) + }) + + it('should return an empty array when no offers match the criteria', async () => { + getStocksByOfferIdsModuleSpy.mockResolvedValueOnce({ offers: [] }) + + const { result } = renderHook(() => useMoviesScreeningsList(mockOfferIds), { + wrapper: ({ children }) => reactQueryProviderHOC(children), + }) + + await act(async () => {}) + + expect(result.current.moviesOffers).toHaveLength(0) + }) +}) diff --git a/src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.ts b/src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.ts new file mode 100644 index 00000000000..9e23e6bcc63 --- /dev/null +++ b/src/features/offer/components/MoviesScreeningCalendar/hook/useMoviesScreeningsList.ts @@ -0,0 +1,32 @@ +import { useMemo } from 'react' + +import { SubcategoryIdEnum } from 'api/gen' +import { useOffersStocks } from 'features/offer/api/useOffersStocks' +import { filterOffersStocksByDate } from 'features/offer/components/MoviesScreeningCalendar/filterOffersStocksByDate' +import { + MovieOffer, + getNextMoviesByDate, +} from 'features/offer/components/MoviesScreeningCalendar/getNextMoviesByDate' +import { useMovieCalendar } from 'features/offer/components/MoviesScreeningCalendar/MovieCalendarContext' + +export const useMoviesScreeningsList = (offerIds: number[]) => { + const { selectedDate } = useMovieCalendar() + const { data: offersWithStocks } = useOffersStocks({ offerIds }) + + const moviesOffers: MovieOffer[] = useMemo(() => { + const filteredOffersWithStocks = filterOffersStocksByDate( + offersWithStocks?.offers || [], + selectedDate + ) + + const nextScreeningOffers = getNextMoviesByDate(offersWithStocks?.offers || [], selectedDate) + + return [...filteredOffersWithStocks, ...nextScreeningOffers] + }, [offersWithStocks?.offers, selectedDate]).filter( + (offer) => offer.offer.subcategoryId === SubcategoryIdEnum.SEANCE_CINE + ) + + return { + moviesOffers, + } +} diff --git a/src/features/offer/helpers/useGetVenueByDay/useGetVenuesByDay.native.test.ts b/src/features/offer/helpers/useGetVenueByDay/useGetVenuesByDay.native.test.ts index 8c9e7be0a25..9acd2b6e870 100644 --- a/src/features/offer/helpers/useGetVenueByDay/useGetVenuesByDay.native.test.ts +++ b/src/features/offer/helpers/useGetVenueByDay/useGetVenuesByDay.native.test.ts @@ -1,3 +1,4 @@ +import { addDays } from 'date-fns' import mockdate from 'mockdate' import * as getStocksByOfferIdsModule from 'features/offer/api/getStocksByOfferIds' @@ -14,14 +15,17 @@ import { act, renderHook } from 'tests/utils' const TODAY = dateBuilder().withDay(2).withHours(6) const TODAY_LATER = dateBuilder().withDay(2).withHours(10) const TODAY_DATE = TODAY.toDate() +const AFTER_15_DAYS = addDays(TODAY.toDate(), 16) const TOMORROW = dateBuilder().withDay(3) -const TODAY_STOCK = stockBuilder().withBeginningDatetime(TODAY_LATER.toString()) -const TOMORROW_STOCK = stockBuilder().withBeginningDatetime(TOMORROW.toString()) +const TODAY_STOCK = stockBuilder().withBeginningDatetime(TODAY_LATER.toString()).build() +const TOMORROW_STOCK = stockBuilder().withBeginningDatetime(TOMORROW.toString()).build() +const STOCK_AFTER_15_DAYS = stockBuilder().withBeginningDatetime(AFTER_15_DAYS.toString()).build() -const OFFER_WITH_STOCKS_TODAY = offerResponseBuilder().withStocks([TODAY_STOCK.build()]).build() -const OFFER_WITH_STOCKS_TOMORROW = offerResponseBuilder() - .withStocks([TOMORROW_STOCK.build()]) +const OFFER_WITH_STOCKS_TODAY = offerResponseBuilder().withStocks([TODAY_STOCK]).build() +const OFFER_WITH_STOCKS_TOMORROW = offerResponseBuilder().withStocks([TOMORROW_STOCK]).build() +const OFFER_WITH_STOCKS_AFTER_15_DAYS = offerResponseBuilder() + .withStocks([STOCK_AFTER_15_DAYS]) .build() mockdate.set(TODAY_DATE) @@ -70,11 +74,11 @@ describe('useGetVenueByDay', () => { expect(result.current.items).toHaveLength(initialNumberOfCinema) }) - it('should only return cinemas having stocks today', async () => { + it('should only return cinemas having stocks within 15 days', async () => { const offers = [ OFFER_WITH_STOCKS_TODAY, - OFFER_WITH_STOCKS_TOMORROW, - OFFER_WITH_STOCKS_TOMORROW, + OFFER_WITH_STOCKS_AFTER_15_DAYS, + OFFER_WITH_STOCKS_AFTER_15_DAYS, ] mockedGetStocksByOfferIds.mockResolvedValueOnce({ offers }) @@ -82,9 +86,7 @@ describe('useGetVenueByDay', () => { await act(async () => {}) - const filteredItems = result.current.items.filter((item) => !item.nextDate) - - expect(filteredItems).toHaveLength(1) + expect(result.current.items).toHaveLength(1) }) it('should return the specified initial number of cinema', async () => { @@ -167,11 +169,10 @@ describe('useGetVenueByDay', () => { describe('change date', () => { it('should return the list of cinema for a specified date', async () => { - const todaysOffers = generateOfferNumber(3, OFFER_WITH_STOCKS_TODAY) - const tomorrowOffers = generateOfferNumber(5, OFFER_WITH_STOCKS_TOMORROW) + const tomorrowOffers = generateOfferNumber(2, OFFER_WITH_STOCKS_TOMORROW) mockedGetStocksByOfferIds.mockResolvedValueOnce({ - offers: [...todaysOffers, ...tomorrowOffers], + offers: tomorrowOffers, }) const offer = offerResponseBuilder().build() @@ -182,14 +183,13 @@ describe('useGetVenueByDay', () => { const { result, rerender } = await renderUseGetVenueByDay(TODAY_DATE, offer, options) + expect(result.current.items).toHaveLength(0) + await act(async () => { - result.current.increaseCount() - rerender({ date: TOMORROW.toDate() }) + rerender({ date: dateBuilder().withDay(4).toDate() }) }) - const filteredItems = result.current.items.filter((item) => !item.nextDate) - - expect(filteredItems).toHaveLength(5) + expect(result.current.items).toHaveLength(2) }) it('should return the initial number of cinema after using increaseCount', async () => {