From df62600845a148052bb92b226ddd20fd640d482a Mon Sep 17 00:00:00 2001 From: Mathieu Meissonnier <173043140+mmeissonnier-pass@users.noreply.github.com> Date: Mon, 10 Feb 2025 19:08:28 +0100 Subject: [PATCH] fix: fixes from review --- .../useSearchVenueOffers.ts | 2 +- src/features/venue/api/useVenueOffers.test.ts | 83 ++++++++++++++++++- src/features/venue/api/useVenueOffers.ts | 2 + .../algolia/fetchAlgolia/transformOfferHit.ts | 2 +- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/api/useSearchVenuesOffer/useSearchVenueOffers.ts b/src/api/useSearchVenuesOffer/useSearchVenueOffers.ts index 19bef402d71..ceb67d41246 100644 --- a/src/api/useSearchVenuesOffer/useSearchVenueOffers.ts +++ b/src/api/useSearchVenuesOffer/useSearchVenueOffers.ts @@ -89,7 +89,7 @@ export function getVenueList(hits: Offer[], userLocation: Position) { } export const filterVenueOfferHit = ({ hit, offerId, venueId }: FilterVenueOfferType): boolean => - hit.objectID !== String(offerId) && hit.venue.id !== venueId + hit.offer.subcategoryId && hit.objectID !== String(offerId) && hit.venue.id !== venueId export const useSearchVenueOffers = ({ allocineId, diff --git a/src/features/venue/api/useVenueOffers.test.ts b/src/features/venue/api/useVenueOffers.test.ts index ad24207ea11..cad9e6e1f10 100644 --- a/src/features/venue/api/useVenueOffers.test.ts +++ b/src/features/venue/api/useVenueOffers.test.ts @@ -5,6 +5,8 @@ import { useVenueOffers } from 'features/venue/api/useVenueOffers' import * as useVenueSearchParameters from 'features/venue/helpers/useVenueSearchParameters' import mockVenueResponse from 'fixtures/venueResponse' import { fetchMultipleOffers } from 'libs/algolia/fetchAlgolia/fetchMultipleOffers/fetchMultipleOffers' +import { transformOfferHit, filterOfferHit } from 'libs/algolia/fetchAlgolia/transformOfferHit' +import { AlgoliaOffer, HitOffer } from 'libs/algolia/types' import { LocationMode, Position } from 'libs/location/types' import * as useNetInfoContextDefault from 'libs/network/NetInfoWrapper' import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC' @@ -166,11 +168,88 @@ const EXPECTED_CALL_PARAM = { } describe('useVenueOffers', () => { - it('should call multiple fetch offers algolia request', async () => { - renderHook(() => useVenueOffers(mockVenueResponse), { + it('should call multiple fetch offers algolia request and return correct response object', async () => { + const FETCH_MULTIPLE_OFFERS_RESPONSE = [ + { + hits: [ + { + offer: { + dates: [], + isDigital: false, + isDuo: false, + name: 'I want something more', + prices: [28.0], + subcategoryId: SubcategoryIdEnum.CONCERT, + thumbUrl: + 'https://storage.googleapis.com/passculture-metier-prod-production-assets-fine-grained/thumbs/mediations/CDZQ', + artist: 'CĂ©line Dion', + }, + _geoloc: { lat: 4.90339, lng: -52.31663 }, + objectID: '102310', + venue: { + id: 4, + name: 'Lieu 4', + publicName: 'Lieu 4', + address: '4 rue de la paix', + postalCode: '75000', + city: 'Paris', + }, + }, + ], + nbHits: 1, + }, + { + hits: [], + nbHits: 0, + }, + { + hits: [ + { + offer: { + dates: [], + isDigital: false, + isDuo: false, + name: 'Naruto T3', + prices: [28.0], + subcategoryId: SubcategoryIdEnum.LIVRE_PAPIER, + thumbUrl: + 'https://storage.googleapis.com/passculture-metier-prod-production-assets-fine-grained/thumbs/mediations/CDZQ', + artist: 'Masashi Kishimoto', + }, + _geoloc: { lat: 4.90339, lng: -52.31663 }, + objectID: '102310', + venue: { + id: 4, + name: 'Lieu 4', + publicName: 'Lieu 4', + address: '4 rue de la paix', + postalCode: '75000', + city: 'Paris', + }, + }, + ], + nbHits: 1, + }, + ] + mockFetchMultipleOffers.mockResolvedValueOnce(FETCH_MULTIPLE_OFFERS_RESPONSE) + + const { result } = renderHook(() => useVenueOffers(mockVenueResponse), { wrapper: ({ children }) => reactQueryProviderHOC(children), }) await waitFor(() => expect(mockFetchMultipleOffers).toHaveBeenCalledWith(EXPECTED_CALL_PARAM)) + + expect(result.current.data?.hits).toMatchObject( + FETCH_MULTIPLE_OFFERS_RESPONSE.slice(0, 2) + .flatMap((result) => result?.hits) + .filter(filterOfferHit) + .map(transformOfferHit()) + ) + + const headlineOffer = FETCH_MULTIPLE_OFFERS_RESPONSE.at(-1)?.hits[0] + + expect(result.current.data?.headlineOffer).toMatchObject( + transformOfferHit()(headlineOffer ?? ({} as AlgoliaOffer)) + ) }) it('should return empty artists when there are no offers', async () => { diff --git a/src/features/venue/api/useVenueOffers.ts b/src/features/venue/api/useVenueOffers.ts index 72b12d2bf39..bc21ae131e2 100644 --- a/src/features/venue/api/useVenueOffers.ts +++ b/src/features/venue/api/useVenueOffers.ts @@ -63,6 +63,8 @@ export const useVenueOffers = (venue?: VenueResponse): UseQueryResult // We don't want to display offers without image nor subcategoryId export const filterOfferHit = (hit?: AlgoliaOffer): hit is AlgoliaOffer => - !!hit && hit?.offer && !!hit.offer.thumbUrl && typeof hit.offer.subcategoryId !== 'undefined' + !!hit && hit.offer && !!hit.offer.thumbUrl && !!hit.offer.subcategoryId export const transformOfferHit = (urlPrefix?: string) =>