@@ -9,7 +9,8 @@ import { useChatContext } from '../../../contexts/chatContext/ChatContext';
99import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext' ;
1010import dispatchConnectionChangedEvent from '../../../mock-builders/event/connectionChanged' ;
1111import dispatchConnectionRecoveredEvent from '../../../mock-builders/event/connectionRecovered' ;
12- import { getTestClient } from '../../../mock-builders/mock' ;
12+ import { getTestClient , getTestClientWithUser , setUser } from '../../../mock-builders/mock' ;
13+ import { DBSyncManager } from '../../../utils/DBSyncManager' ;
1314import { Streami18n } from '../../../utils/i18n/Streami18n' ;
1415import { Chat } from '../Chat' ;
1516
@@ -24,7 +25,10 @@ const TranslationContextConsumer = ({ fn }) => {
2425} ;
2526
2627describe ( 'Chat' , ( ) => {
27- afterEach ( cleanup ) ;
28+ afterEach ( ( ) => {
29+ cleanup ( ) ;
30+ jest . clearAllMocks ( ) ;
31+ } ) ;
2832 const chatClient = getTestClient ( ) ;
2933
3034 it ( 'renders children without crashing' , async ( ) => {
@@ -215,5 +219,79 @@ describe('Chat', () => {
215219 expect ( context . tDateTimeParser ) . toBe ( newI18nInstance . tDateTimeParser ) ;
216220 } ) ;
217221 } ) ;
222+
223+ it ( 'makes sure DBSyncManager listeners are cleaned up after Chat remount' , async ( ) => {
224+ const chatClientWithUser = await getTestClientWithUser ( { id : 'testID' } ) ;
225+ jest . spyOn ( DBSyncManager , 'init' ) ;
226+
227+ // initial mount and render
228+ const { rerender } = render (
229+ < Chat client = { chatClientWithUser } enableOfflineSupport key = { 1 } /> ,
230+ ) ;
231+
232+ // the unsubscribe fn changes during init(), so we keep a reference to the spy
233+ const unsubscribeSpy = jest . spyOn ( DBSyncManager . connectionChangedListener , 'unsubscribe' ) ;
234+ const listenersAfterInitialMount = chatClientWithUser . listeners [ 'connection.changed' ] ;
235+
236+ // remount
237+ rerender ( < Chat client = { chatClientWithUser } enableOfflineSupport key = { 2 } /> ) ;
238+
239+ await waitFor ( ( ) => {
240+ expect ( DBSyncManager . init ) . toHaveBeenCalledTimes ( 2 ) ;
241+ expect ( unsubscribeSpy ) . toHaveBeenCalledTimes ( 2 ) ;
242+ expect ( chatClientWithUser . listeners [ 'connection.changed' ] . length ) . toBe (
243+ listenersAfterInitialMount . length ,
244+ ) ;
245+ } ) ;
246+ } ) ;
247+
248+ it ( 'makes sure DBSyncManager listeners are cleaned up if the user changes' , async ( ) => {
249+ const chatClientWithUser = await getTestClientWithUser ( { id : 'testID1' } ) ;
250+ jest . spyOn ( DBSyncManager , 'init' ) ;
251+
252+ // initial render
253+ const { rerender } = render ( < Chat client = { chatClientWithUser } enableOfflineSupport /> ) ;
254+
255+ // the unsubscribe fn changes during init(), so we keep a reference to the spy
256+ const unsubscribeSpy = jest . spyOn ( DBSyncManager . connectionChangedListener , 'unsubscribe' ) ;
257+ await act ( async ( ) => {
258+ await setUser ( chatClientWithUser , { id : 'testID2' } ) ;
259+ } ) ;
260+ const listenersAfterInitialMount = chatClientWithUser . listeners [ 'connection.changed' ] ;
261+
262+ // rerender with different user ID
263+ rerender ( < Chat client = { chatClientWithUser } enableOfflineSupport /> ) ;
264+
265+ await waitFor ( ( ) => {
266+ expect ( DBSyncManager . init ) . toHaveBeenCalledTimes ( 2 ) ;
267+ expect ( unsubscribeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
268+ expect ( chatClientWithUser . listeners [ 'connection.changed' ] . length ) . toBe (
269+ listenersAfterInitialMount . length ,
270+ ) ;
271+ } ) ;
272+ } ) ;
273+
274+ it ( 'makes sure DBSyncManager state stays intact during normal rerenders' , async ( ) => {
275+ const chatClientWithUser = await getTestClientWithUser ( { id : 'testID' } ) ;
276+ jest . spyOn ( DBSyncManager , 'init' ) ;
277+
278+ // initial render
279+ const { rerender } = render ( < Chat client = { chatClientWithUser } enableOfflineSupport /> ) ;
280+
281+ // the unsubscribe fn changes during init(), so we keep a reference to the spy
282+ const unsubscribeSpy = jest . spyOn ( DBSyncManager . connectionChangedListener , 'unsubscribe' ) ;
283+ const listenersAfterInitialMount = chatClientWithUser . listeners [ 'connection.changed' ] ;
284+
285+ // rerender
286+ rerender ( < Chat client = { chatClientWithUser } enableOfflineSupport /> ) ;
287+
288+ await waitFor ( ( ) => {
289+ expect ( DBSyncManager . init ) . toHaveBeenCalledTimes ( 1 ) ;
290+ expect ( unsubscribeSpy ) . toHaveBeenCalledTimes ( 0 ) ;
291+ expect ( chatClientWithUser . listeners [ 'connection.changed' ] . length ) . toBe (
292+ listenersAfterInitialMount . length ,
293+ ) ;
294+ } ) ;
295+ } ) ;
218296 } ) ;
219297} ) ;
0 commit comments