@@ -7,8 +7,9 @@ import { render, act, queryAllByAttribute, cleanup, RenderResult } from '@testin
77import { configMocks , mockIntersectionObserver } from 'jsdom-testing-mocks' ;
88import { pdfScaleAtom } from 'V2/atoms' ;
99import { TestAtomStoreProvider } from 'V2/testing' ;
10- import PDF , { PDFProps } from '../PDF' ;
10+ import { PDF , PDFProps } from '../PDF' ;
1111import * as helpers from '../functions/helpers' ;
12+ import { pdfEventBus } from '../events' ;
1213
1314configMocks ( { act } ) ;
1415const oberserverMock = mockIntersectionObserver ( ) ;
@@ -65,8 +66,9 @@ jest.mock('../pdfjs.ts', () => ({
6566 return {
6667 promise : Promise . resolve ( {
6768 numPages : 5 ,
68- getPage : jest . fn ( async ( ) =>
69+ getPage : jest . fn ( async ( pageNum : number ) =>
6970 Promise . resolve ( {
71+ pageNumber : pageNum ,
7072 getViewport : ( ) => ( { width : 100 , height : 300 } ) ,
7173 } )
7274 ) ,
@@ -104,10 +106,10 @@ jest.mock('../pdfjs.ts', () => ({
104106describe ( 'PDF' , ( ) => {
105107 let renderResult : RenderResult ;
106108
107- const renderComponet = ( scrollToPage ?: PDFProps [ 'scrollToPage' ] ) => {
109+ const renderComponet = ( ) => {
108110 renderResult = render (
109111 < TestAtomStoreProvider initialValues = { [ [ pdfScaleAtom , 1.5 ] ] } >
110- < PDF fileUrl = "url/of/file.pdf" scrollToPage = { scrollToPage } highlights = { highlights } />
112+ < PDF fileUrl = "url/of/file.pdf" highlights = { highlights } />
111113 </ TestAtomStoreProvider >
112114 ) ;
113115 } ;
@@ -167,15 +169,99 @@ describe('PDF', () => {
167169 expect ( container ) . toMatchSnapshot ( ) ;
168170 } ) ;
169171
170- it ( 'should scroll to page' , async ( ) => {
171- jest . useFakeTimers ( ) ;
172- await act ( ( ) => {
173- renderComponet ( '2' ) ;
172+ describe ( 'pdfEventBus' , ( ) => {
173+ beforeEach ( ( ) => {
174+ jest . spyOn ( pdfEventBus , 'dispatch' ) ;
175+ } ) ;
176+
177+ it ( 'should dispatch pdfReady event when PDF and containerWidth are ready' , async ( ) => {
178+ await act ( ( ) => {
179+ renderComponet ( ) ;
180+ } ) ;
181+
182+ expect ( pdfEventBus . dispatch ) . toHaveBeenCalledWith ( 'pdfReady' ) ;
174183 } ) ;
175- jest . advanceTimersByTime ( 200 ) ;
176184
177- expect ( helpers . triggerScroll ) . toHaveBeenCalledTimes ( 1 ) ;
178- jest . useRealTimers ( ) ;
185+ it ( 'should dispatch onPageChange event when a page is rendered' , async ( ) => {
186+ const dispatchSpy = jest . spyOn ( pdfEventBus , 'dispatch' ) ;
187+
188+ await act ( ( ) => {
189+ renderComponet ( ) ;
190+ } ) ;
191+
192+ const { container } = renderResult ;
193+ const page1 = queryAllByAttribute ( 'class' , container , 'pdf-page' ) [ 0 ] ;
194+
195+ await act ( ( ) => {
196+ oberserverMock . enterNode ( page1 ) ;
197+ } ) ;
198+
199+ expect ( mockPageRender ) . toHaveBeenCalled ( ) ;
200+ expect ( dispatchSpy ) . toHaveBeenCalledWith ( 'onPageChange' , 1 ) ;
201+ } ) ;
202+
203+ it ( 'should scroll to page when goToPage event is dispatched' , async ( ) => {
204+ await act ( ( ) => {
205+ renderComponet ( ) ;
206+ } ) ;
207+
208+ const { container } = renderResult ;
209+ const page3Container = container . querySelector ( '#page-3-container' ) as HTMLDivElement ;
210+
211+ act ( ( ) => {
212+ pdfEventBus . dispatch ( 'goToPage' , 3 ) ;
213+ } ) ;
214+
215+ expect ( helpers . triggerScroll ) . toHaveBeenCalledWith ( { current : page3Container } , 0 ) ;
216+ } ) ;
217+
218+ it ( 'should unsubscribe from goToPage event on unmount' , async ( ) => {
219+ const mockCallback = jest . fn ( ) ;
220+
221+ await act ( ( ) => {
222+ renderComponet ( ) ;
223+ } ) ;
224+
225+ pdfEventBus . on ( 'goToPage' , mockCallback ) ;
226+
227+ cleanup ( ) ;
228+
229+ act ( ( ) => {
230+ pdfEventBus . dispatch ( 'goToPage' , 1 ) ;
231+ } ) ;
232+
233+ expect ( mockCallback ) . toHaveBeenCalledTimes ( 1 ) ;
234+ expect ( helpers . triggerScroll ) . not . toHaveBeenCalled ( ) ;
235+ } ) ;
236+
237+ it ( 'should handle multiple PDF instances without listener accumulation' , async ( ) => {
238+ let unmountInstanceOne : RenderResult [ 'unmount' ] ;
239+
240+ await act ( async ( ) => {
241+ const result = render (
242+ < TestAtomStoreProvider initialValues = { [ [ pdfScaleAtom , 1.5 ] ] } >
243+ < PDF fileUrl = "url/of/file1.pdf" highlights = { highlights } />
244+ </ TestAtomStoreProvider >
245+ ) ;
246+ unmountInstanceOne = result . unmount ;
247+ } ) ;
248+
249+ await act ( async ( ) => {
250+ render (
251+ < TestAtomStoreProvider initialValues = { [ [ pdfScaleAtom , 1.5 ] ] } >
252+ < PDF fileUrl = "url/of/file2.pdf" highlights = { highlights } />
253+ </ TestAtomStoreProvider >
254+ ) ;
255+ } ) ;
256+
257+ unmountInstanceOne ! ( ) ;
258+
259+ act ( ( ) => {
260+ pdfEventBus . dispatch ( 'goToPage' , 1 ) ;
261+ } ) ;
262+
263+ expect ( helpers . triggerScroll ) . toHaveBeenCalledTimes ( 1 ) ;
264+ } ) ;
179265 } ) ;
180266
181267 describe ( 'intersection observer' , ( ) => {
0 commit comments