import { jest } from '@jest/globals'; import { act, renderHook } from '@testing-library/react-hooks'; import mockRouter from 'next-router-mock'; import { MemoryRouterProvider } from 'next-router-mock/MemoryRouterProvider'; import { PropsWithChildren } from 'react'; import { PageApiVersionProvider, usePageApiVersion, getVersionFromPath, replaceVersionInPath, } from './page-api-version'; jest.mock('next/router', () => mockRouter); function renderContext(initialUrl: string, onPush?: any) { return renderHook(usePageApiVersion, { wrapper: (props: PropsWithChildren) => ( {props.children} ), }); } describe('PageApiVersionContext', () => { it('defaults to latest version', () => { const { result } = renderHook(usePageApiVersion); expect(result.current).toMatchObject({ version: 'latest', hasVersion: false }); }); it('defaults to setVersion throwing error', () => { const { result } = renderHook(usePageApiVersion); expect(() => result.current.setVersion('v44.0.0')).toThrowError( 'PageApiVersionContext not found' ); }); }); describe(PageApiVersionProvider, () => { it('uses sdk version from pathname', () => { const { result } = renderContext('/versions/v44.0.0/sdk/notifications'); expect(result.current).toMatchObject({ version: 'v44.0.0', hasVersion: true }); }); it('uses unversioned version from pathname', () => { const { result } = renderContext('/versions/unversioned/react-native/view-props'); expect(result.current).toMatchObject({ version: 'unversioned', hasVersion: true }); }); it('uses latest version from pathname', () => { const { result } = renderContext('/versions/latest/sdk'); expect(result.current).toMatchObject({ version: 'latest', hasVersion: true }); }); it('updates router and version when setting version', () => { const onPush = jest.fn(); const { result, rerender } = renderContext('/versions/latest/sdk', onPush); expect(result.current).toMatchObject({ version: 'latest', hasVersion: true }); act(() => result.current.setVersion('unversioned')); rerender(); expect(onPush).toBeCalledWith('/versions/unversioned/sdk', { shallow: false }); }); }); describe(getVersionFromPath, () => { it('returns unversioned from pathname', () => { expect(getVersionFromPath('/versions/unversioned')).toBe('unversioned'); }); it('returns latest from sdk pathname', () => { expect(getVersionFromPath('/versions/latest/sdk/notifications')).toBe('latest'); }); it('returns v44.0.0 from react-native pathname', () => { expect(getVersionFromPath('/versions/v44.0.0/react-native/view-props')).toBe('v44.0.0'); }); it('returns null for non-versioned pathname', () => { expect(getVersionFromPath('/guides/monorepos/')).toBeNull(); }); }); describe(replaceVersionInPath, () => { it('returns same pathname for non-versioned pathname', () => { expect(replaceVersionInPath('/build-reference/how-tos/', 'latest')).toBe( '/build-reference/how-tos/' ); }); it('returns new pathname for unversioned pathname', () => { expect(replaceVersionInPath('/versions/unversioned', 'latest')).toBe('/versions/latest'); }); it('returns new pathname for sdk pathname', () => { expect(replaceVersionInPath('/versions/latest/sdk/notifications', 'v44.0.0')).toBe( '/versions/v44.0.0/sdk/notifications' ); }); it('returns new pathname for react-native pathname', () => { expect(replaceVersionInPath('/versions/v44.0.0/react-native/stylesheet/', 'v43.0.0')).toBe( '/versions/v43.0.0/react-native/stylesheet/' ); }); });