@@ -7,11 +7,12 @@ import { v4 as uuidv4 } from 'uuid';
77
88import { Channel } from '../../components/Channel/Channel' ;
99import { Chat } from '../../components/Chat/Chat' ;
10- import { MessagesContext } from '../../contexts' ;
10+ import { ChannelContext , ChatContext , MessageInputContext , MessagesContext } from '../../contexts' ;
1111import { deleteMessageApi } from '../../mock-builders/api/deleteMessage' ;
1212import { deleteReactionApi } from '../../mock-builders/api/deleteReaction' ;
1313import { erroredDeleteApi , erroredPostApi } from '../../mock-builders/api/error' ;
1414import { getOrCreateChannelApi } from '../../mock-builders/api/getOrCreateChannel' ;
15+ import { sendMessageApi } from '../../mock-builders/api/sendMessage' ;
1516import { sendReactionApi } from '../../mock-builders/api/sendReaction' ;
1617import { useMockedApis } from '../../mock-builders/api/useMockedApis' ;
1718import dispatchConnectionChangedEvent from '../../mock-builders/event/connectionChanged' ;
@@ -100,7 +101,6 @@ export const OptimisticUpdates = () => {
100101 const channelResponse = createChannel ( ) ;
101102 useMockedApis ( chatClient , [ getOrCreateChannelApi ( channelResponse ) ] ) ;
102103 channel = chatClient . channel ( 'messaging' , channelResponse . id ) ;
103- console . log ( 'BEFORE HERE' ) ;
104104 await channel . watch ( ) ;
105105
106106 channel . cid = channelResponse . channel . cid ;
@@ -178,7 +178,7 @@ export const OptimisticUpdates = () => {
178178 } ) ;
179179 } ) ;
180180
181- it ( 'pending task should be cleared if deleteMessage request is succesful ' , async ( ) => {
181+ it ( 'pending task should be cleared if deleteMessage request is successful ' , async ( ) => {
182182 const message = generateMessage ( ) ;
183183 render (
184184 < Chat client = { chatClient } enableOfflineSupport >
@@ -238,7 +238,7 @@ export const OptimisticUpdates = () => {
238238 } ) ;
239239 } ) ;
240240
241- it ( 'pending task should be cleared if sendReaction request is succesful ' , async ( ) => {
241+ it ( 'pending task should be cleared if sendReaction request is successful ' , async ( ) => {
242242 const reaction = generateReaction ( ) ;
243243 const targetMessage = channel . state . messages [ 0 ] ;
244244
@@ -265,6 +265,69 @@ export const OptimisticUpdates = () => {
265265 } ) ;
266266 } ) ;
267267
268+ describe ( 'send message' , ( ) => {
269+ it ( 'pending task should exist if sendMessage request fails' , async ( ) => {
270+ const newMessage = generateMessage ( ) ;
271+
272+ render (
273+ < Chat client = { chatClient } enableOfflineSupport >
274+ < Channel channel = { channel } initialValue = { newMessage . text } >
275+ < CallbackEffectWithContext
276+ callback = { async ( { sendMessage } ) => {
277+ useMockedApis ( chatClient , [ erroredPostApi ( ) ] ) ;
278+ try {
279+ await sendMessage ( { customMessageData : newMessage } ) ;
280+ } catch ( e ) {
281+ // do nothing
282+ }
283+ } }
284+ context = { MessageInputContext }
285+ >
286+ < View testID = 'children' />
287+ </ CallbackEffectWithContext >
288+ </ Channel >
289+ </ Chat > ,
290+ ) ;
291+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'children' ) ) . toBeTruthy ( ) ) ;
292+ await waitFor ( async ( ) => {
293+ const pendingTasksRows = await BetterSqlite . selectFromTable ( 'pendingTasks' ) ;
294+ const pendingTaskType = pendingTasksRows ?. [ 0 ] ?. type ;
295+ const pendingTaskPayload = JSON . parse ( pendingTasksRows ?. [ 0 ] ?. payload || '{}' ) ;
296+ expect ( pendingTaskType ) . toBe ( 'send-message' ) ;
297+ expect ( pendingTaskPayload [ 0 ] . id ) . toEqual ( newMessage . id ) ;
298+ expect ( pendingTaskPayload [ 0 ] . text ) . toEqual ( newMessage . text ) ;
299+ } ) ;
300+ } ) ;
301+
302+ it ( 'pending task should be cleared if sendMessage request is successful' , async ( ) => {
303+ const newMessage = generateMessage ( ) ;
304+
305+ // initialValue is needed as a prop to trick the message input ctx into thinking
306+ // we are sending a message.
307+ render (
308+ < Chat client = { chatClient } enableOfflineSupport >
309+ < Channel channel = { channel } initialValue = { newMessage . text } >
310+ < CallbackEffectWithContext
311+ callback = { async ( { sendMessage } ) => {
312+ useMockedApis ( chatClient , [ sendMessageApi ( newMessage ) ] ) ;
313+ await sendMessage ( { customMessageData : newMessage } ) ;
314+ } }
315+ context = { MessageInputContext }
316+ >
317+ < View testID = 'children' />
318+ </ CallbackEffectWithContext >
319+ </ Channel >
320+ </ Chat > ,
321+ ) ;
322+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'children' ) ) . toBeTruthy ( ) ) ;
323+
324+ await waitFor ( async ( ) => {
325+ const pendingTasksRows = await BetterSqlite . selectFromTable ( 'pendingTasks' ) ;
326+ expect ( pendingTasksRows . length ) . toBe ( 0 ) ;
327+ } ) ;
328+ } ) ;
329+ } ) ;
330+
268331 describe ( 'delete reaction' , ( ) => {
269332 it ( 'pending task should exist if deleteReaction request fails' , async ( ) => {
270333 const reaction = generateReaction ( ) ;
@@ -299,7 +362,7 @@ export const OptimisticUpdates = () => {
299362 } ) ;
300363 } ) ;
301364
302- it ( 'pending task should be cleared if deleteReaction request is succesful ' , async ( ) => {
365+ it ( 'pending task should be cleared if deleteReaction request is successful ' , async ( ) => {
303366 const reaction = generateReaction ( ) ;
304367 const targetMessage = channel . state . messages [ 0 ] ;
305368
@@ -327,52 +390,98 @@ export const OptimisticUpdates = () => {
327390 } ) ;
328391 } ) ;
329392
330- it ( 'pending task should be executed after connection is recovered' , async ( ) => {
331- const message = channel . state . messages [ 0 ] ;
332- const reaction = generateReaction ( ) ;
333-
334- render (
335- < Chat client = { chatClient } enableOfflineSupport >
336- < Channel channel = { channel } initialValue = { message . text } >
337- < CallbackEffectWithContext
338- callback = { async ( { deleteMessage, sendReaction } ) => {
339- useMockedApis ( chatClient , [ erroredDeleteApi ( ) ] ) ;
340- try {
341- await deleteMessage ( reaction ) ;
342- } catch ( e ) {
343- // do nothing
344- }
345-
346- useMockedApis ( chatClient , [ erroredPostApi ( ) ] ) ;
347- try {
348- await sendReaction ( reaction . type , message . id ) ;
349- } catch ( e ) {
350- // do nothing
351- }
352- } }
353- context = { MessagesContext }
354- >
355- < View testID = 'children' />
356- </ CallbackEffectWithContext >
357- </ Channel >
358- </ Chat > ,
359- ) ;
360- await waitFor ( ( ) => expect ( screen . getByTestId ( 'children' ) ) . toBeTruthy ( ) ) ;
393+ describe ( 'pending task execution' , ( ) => {
394+ it ( 'pending task should be executed after connection is recovered' , async ( ) => {
395+ const message = channel . state . messages [ 0 ] ;
396+ const reaction = generateReaction ( ) ;
397+
398+ render (
399+ < Chat client = { chatClient } enableOfflineSupport >
400+ < Channel channel = { channel } initialValue = { message . text } >
401+ < CallbackEffectWithContext
402+ callback = { async ( { deleteMessage, sendReaction } ) => {
403+ useMockedApis ( chatClient , [ erroredDeleteApi ( ) ] ) ;
404+ try {
405+ await deleteMessage ( message ) ;
406+ } catch ( e ) {
407+ // do nothing
408+ }
409+
410+ useMockedApis ( chatClient , [ erroredPostApi ( ) ] ) ;
411+ try {
412+ await sendReaction ( reaction . type , message . id ) ;
413+ } catch ( e ) {
414+ // do nothing
415+ }
416+ } }
417+ context = { MessagesContext }
418+ >
419+ < View testID = 'children' />
420+ </ CallbackEffectWithContext >
421+ </ Channel >
422+ </ Chat > ,
423+ ) ;
424+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'children' ) ) . toBeTruthy ( ) ) ;
425+
426+ await waitFor ( async ( ) => {
427+ const pendingTasksRows = await BetterSqlite . selectFromTable ( 'pendingTasks' ) ;
428+
429+ expect ( pendingTasksRows . length ) . toBe ( 2 ) ;
430+ } ) ;
431+
432+ const deleteMessageSpy = jest . spyOn ( chatClient , '_deleteMessage' ) . mockImplementation ( ) ;
433+ const sendReactionSpy = jest . spyOn ( channel , '_sendReaction' ) . mockImplementation ( ) ;
361434
362- await waitFor ( async ( ) => {
363- const pendingTasksRows = await BetterSqlite . selectFromTable ( 'pendingTasks' ) ;
435+ act ( ( ) => dispatchConnectionChangedEvent ( chatClient , true ) ) ;
364436
365- expect ( pendingTasksRows . length ) . toBe ( 2 ) ;
437+ await waitFor ( ( ) => {
438+ expect ( deleteMessageSpy ) . toHaveBeenCalled ( ) ;
439+ expect ( sendReactionSpy ) . toHaveBeenCalled ( ) ;
440+ } ) ;
366441 } ) ;
367442
368- const deleteMessageSpy = jest . spyOn ( chatClient , '_deleteMessage' ) . mockImplementation ( ) ;
369- const sendReactionSpy = jest . spyOn ( channel , '_sendReaction' ) . mockImplementation ( ) ;
443+ // This is a separate test so CallbackEffectWithContext does not need to be modified in order
444+ // to accept multiple contexts. It can be improved in the future.
445+ it ( 'send message pending task should be executed after connection is recovered' , async ( ) => {
446+ const newMessage = generateMessage ( ) ;
370447
371- act ( ( ) => dispatchConnectionChangedEvent ( chatClient , true ) ) ;
448+ // initialValue is needed as a prop to trick the message input ctx into thinking
449+ // we are sending a message.
450+ render (
451+ < Chat client = { chatClient } enableOfflineSupport >
452+ < Channel channel = { channel } initialValue = { newMessage . text } >
453+ < CallbackEffectWithContext
454+ callback = { async ( { sendMessage } ) => {
455+ useMockedApis ( chatClient , [ erroredPostApi ( ) ] ) ;
456+ try {
457+ await sendMessage ( { customMessageData : newMessage } ) ;
458+ } catch ( e ) {
459+ // do nothing
460+ }
461+ } }
462+ context = { MessageInputContext }
463+ >
464+ < View testID = 'children' />
465+ </ CallbackEffectWithContext >
466+ </ Channel >
467+ </ Chat > ,
468+ ) ;
469+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'children' ) ) . toBeTruthy ( ) ) ;
470+
471+ await waitFor ( async ( ) => {
472+ const pendingTasksRows = await BetterSqlite . selectFromTable ( 'pendingTasks' ) ;
473+ console . log ( 'TESTINGROWS: ' , pendingTasksRows ) ;
474+
475+ expect ( pendingTasksRows . length ) . toBe ( 1 ) ;
476+ } ) ;
372477
373- await waitFor ( ( ) => {
374- expect ( deleteMessageSpy ) . toHaveBeenCalled ( ) ;
375- expect ( sendReactionSpy ) . toHaveBeenCalled ( ) ;
478+ const sendMessageSpy = jest . spyOn ( channel , '_sendMessage' ) . mockImplementation ( ) ;
479+
480+ act ( ( ) => dispatchConnectionChangedEvent ( chatClient , true ) ) ;
481+
482+ await waitFor ( ( ) => {
483+ expect ( sendMessageSpy ) . toHaveBeenCalled ( ) ;
484+ } ) ;
376485 } ) ;
377486 } ) ;
378487 } ) ;
0 commit comments