import { renderHook, act } from '@testing-library/react'; import React, {ReactNode, createElement} from 'react'; import useCarouselThumbnailVideoLoading from '../useCarouselThumbnailVideoLoading'; import { StoreContext, initial, StoreState } from '../../services/store'; import { IMedia } from '../../types'; const makeMedia = (index: number, type: IMedia['type'] = 'video'): IMedia => ({ id: `post-${index}`, type, caption: `Caption ${index}`, source: 'instagram', post: `https://post.com/${index}`, image: `https://image.com/${index}.jpg`, thumbnail: `https://thumb.com/${index}.jpg`, video: `https://video.com/${index}.mp4`, postIndex: index, productsLinked: {}, }); const medias = [makeMedia(0), makeMedia(1), makeMedia(2)]; const makeStore = (overrides: Partial = {}): StoreState => ({ ...initial, isMobile: true, currentPosition: 1, data: { settings: { type: 'carousel', shop_this_look_display: 'default', } as any, content: { medias }, id: 'widget-1', }, setStoreState: jest.fn(), ...overrides, }); describe('useCarouselThumbnailVideoLoading', () => { let store: StoreState; const makeWrapper = () => ({ children }: { children: ReactNode }) => createElement(StoreContext.Provider, { value: store }, children); beforeEach(() => { store = makeStore(); jest.clearAllMocks(); }); it('loads the active carousel video immediately and keeps shoulders locked at first', () => { const { result: activeResult } = renderHook(() => useCarouselThumbnailVideoLoading(medias[1]), { wrapper: makeWrapper(), }); const { result: shoulderResult } = renderHook(() => useCarouselThumbnailVideoLoading(medias[0]), { wrapper: makeWrapper(), }); expect(activeResult.current.isCarouselThumbnailVideoEnabled).toBe(true); expect(activeResult.current.shouldLoadCarouselVideo).toBe(true); expect(shoulderResult.current.shouldLoadCarouselVideo).toBe(false); }); it('unlocks shoulder videos when the active carousel video becomes ready', () => { const { result } = renderHook(() => useCarouselThumbnailVideoLoading(medias[1]), { wrapper: makeWrapper(), }); act(() => { result.current.handleCarouselVideoReady(); }); expect(store.setStoreState).toHaveBeenCalledTimes(1); const update = (store.setStoreState as jest.Mock).mock.calls[0][0] as (state: StoreState) => StoreState; store = update(store); expect(store.unlockedShouldersForCarouselPostId).toBe('post-1'); }); it('loads shoulder videos after the active carousel video unlocks them', () => { const { result, rerender } = renderHook(() => useCarouselThumbnailVideoLoading(medias[0]), { wrapper: makeWrapper(), }); expect(result.current.shouldLoadCarouselVideo).toBe(false); store = makeStore({ unlockedShouldersForCarouselPostId: 'post-1' }); rerender(); expect(result.current.shouldLoadCarouselVideo).toBe(true); }); it('relocks shoulders when the active carousel slide changes', () => { store = makeStore({ unlockedShouldersForCarouselPostId: 'post-1' }); const { result, rerender } = renderHook(() => useCarouselThumbnailVideoLoading(medias[0]), { wrapper: makeWrapper(), }); expect(result.current.shouldLoadCarouselVideo).toBe(true); store = makeStore({ currentPosition: 2, unlockedShouldersForCarouselPostId: 'post-1', }); rerender(); expect(result.current.shouldLoadCarouselVideo).toBe(false); }); });