UNPKG

@amityco/ts-sdk-react-native

Version:

Amity Social Cloud Typescript SDK

467 lines (377 loc) 14.4 kB
import { disableCache, enableCache } from '~/cache/api'; import { client, connectClient, disconnectClient, messages, generateRawMessage, convertRawMessage, pause, messagesDesc, } from '~/utils/tests'; import { getMessages } from '../getMessages'; import * as getMessageMarkers from '../../../marker/api/getMessageMarkers'; describe('getMessages by aroundMessageId (Jump to message)', () => { beforeAll(() => { connectClient(); jest.spyOn(getMessageMarkers, 'getMessageMarkers').mockImplementation(() => Promise.resolve({ data: [], cachedAt: undefined, }), ); }); afterAll(disconnectClient); beforeEach(enableCache); afterEach(disableCache); const { subChannelId } = messages; const returnValue: Amity.RawMessage[] = [generateRawMessage({ messageId: messages.page1[0] })]; const rawMessage = generateRawMessage({ messageId: returnValue[0].messageId, messageFeedId: subChannelId, }); const message = convertRawMessage(rawMessage); it('should return messages collection when jumping to a message and pagination works correctly', async () => { /** * descending order * [100,99,98,97,96,95,94,93,92] * << Previous | Next >> */ const returnValuePage1: Amity.RawMessage[] = [ generateRawMessage({ messageId: messagesDesc.page2[0], segment: 97 }), generateRawMessage({ messageId: messagesDesc.page2[1], segment: 96 }), // aroundMessageId generateRawMessage({ messageId: messagesDesc.page2[2], segment: 95 }), ]; const returnValuePage2Previous: Amity.RawMessage[] = [ generateRawMessage({ messageId: messagesDesc.page1[0], segment: 100 }), generateRawMessage({ messageId: messagesDesc.page1[1], segment: 99 }), generateRawMessage({ messageId: messagesDesc.page1[2], segment: 98 }), ]; const returnValuePage2Next: Amity.RawMessage[] = [ generateRawMessage({ messageId: messagesDesc.page3[0], segment: 94 }), generateRawMessage({ messageId: messagesDesc.page3[1], segment: 93 }), generateRawMessage({ messageId: messagesDesc.page3[2], segment: 92 }), ]; const aroundMessageId = messagesDesc.page2[1]; const callback = jest.fn(); const spyGet = jest.spyOn(client.http, 'get').mockImplementation((url: string, params) => { if (url !== '/api/v5/messages') return Promise.resolve(); // segmentDesc nextPage#2 if (params?.params?.options?.token === 'eyJsaW1pdCI6MywiYmVmb3JlIjoibWVzc2FnZUlkMTAxIn0=') { return Promise.resolve({ data: { messages: returnValuePage2Next, paging: { previous: 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDM5MTExMTAwMDAwMH0', }, }, }); } // segmentDesc previousPage#2 if ( params?.params?.options?.token === 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDM5MTExMTAwMDAwMH0' ) { return Promise.resolve({ data: { messages: returnValuePage2Previous, paging: { previous: 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDM5MTExMTAwMDAwMH0', next: 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDQ5MTExMTAwMDAwMH0=', }, }, }); } // segmentDesc page#1 return Promise.resolve({ data: { messages: returnValuePage1, paging: { previous: 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDM5MTExMTAwMDAwMH0', next: 'eyJsaW1pdCI6MywiYmVmb3JlIjoibWVzc2FnZUlkMTAxIn0=', }, }, }); }); getMessages({ subChannelId, sortBy: 'segmentDesc', aroundMessageId, limit: 3 }, callback); expect(spyGet).toHaveBeenCalledWith('/api/v5/messages', { params: { isDeleted: false, messageFeedId: 'message-feed-id', options: { sortBy: 'segmentDesc', limit: 3, around: aroundMessageId }, }, }); expect(callback).toHaveBeenCalledTimes(1); expect(callback).toHaveBeenCalledWith( expect.objectContaining({ data: [], error: undefined, loading: true, }), ); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(1); expect(callback).lastCalledWith( expect.objectContaining({ data: returnValuePage1.map(convertRawMessage), error: undefined, loading: false, }), ); const { onNextPage, hasNextPage, onPrevPage, hasPrevPage } = callback.mock.lastCall[0]; expect(hasNextPage).toBe(true); expect(onNextPage).toBeTruthy(); expect(hasPrevPage).toBe(true); expect(onPrevPage).toBeTruthy(); onNextPage(); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(3); expect(callback).lastCalledWith( expect.objectContaining({ data: [...returnValuePage1, ...returnValuePage2Next].map(convertRawMessage), error: undefined, loading: false, }), ); const { onNextPage: newOnNextPage, hasNextPage: newHasNextPage, onPrevPage: newOnPrevPage, hasPrevPage: newHasPrevPage, } = callback.mock.lastCall[0]; expect(newHasNextPage).toBe(false); // TODO: check if onNextPage should be undefined or not // expect(newOnNextPage).toBeFalsy(); expect(newHasPrevPage).toBe(true); expect(newOnPrevPage).toBeTruthy(); newOnPrevPage(); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(5); expect(callback).lastCalledWith( expect.objectContaining({ data: [...returnValuePage2Previous, ...returnValuePage1, ...returnValuePage2Next].map( convertRawMessage, ), error: undefined, loading: false, }), ); }); it('should return erorr if target messageId is not found', async () => { const error = new Error('Amity SDK (400400): Target jump message not found!'); const aroundMessageId = messagesDesc.page2[1]; const callback = jest.fn(); const spyGet = jest.spyOn(client.http, 'get').mockImplementation(() => { return Promise.reject(error); }); getMessages({ subChannelId, sortBy: 'segmentDesc', aroundMessageId, limit: 3 }, callback); expect(spyGet).toHaveBeenCalledWith('/api/v5/messages', { params: { isDeleted: false, messageFeedId: 'message-feed-id', options: { sortBy: 'segmentDesc', limit: 3, around: aroundMessageId }, }, }); expect(callback).toHaveBeenCalledTimes(1); expect(callback).toHaveBeenCalledWith( expect.objectContaining({ data: [], error: undefined, loading: true, }), ); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(1); expect(callback).lastCalledWith( expect.objectContaining({ data: [], error, loading: false, }), ); }); describe('Event', () => { it('should prepend new message if sortBy segmentDsc and hasPrevPage = false', async () => { const returnValue: Amity.RawMessage[] = [ generateRawMessage({ messageId: messagesDesc.page1[0], segment: 100 }), generateRawMessage({ messageId: messagesDesc.page1[1], segment: 99 }), // aroundMessageId generateRawMessage({ messageId: messagesDesc.page1[2], segment: 98 }), ]; const newMessage = generateRawMessage({ messageId: 'newMessageId', segment: 101 }); const aroundMessageId = messagesDesc.page1[1]; const callback = jest.fn(); const spyGet = jest.spyOn(client.http, 'get').mockImplementation((url: string, params) => { if (url !== '/api/v5/messages') return Promise.resolve(); return Promise.resolve({ data: { messages: returnValue, paging: { next: 'eyJsaW1pdCI6MywiYmVmb3JlIjoibWVzc2FnZUlkMTAxIn0=', }, }, }); }); getMessages({ subChannelId, sortBy: 'segmentDesc', aroundMessageId, limit: 3 }, callback); expect(spyGet).toHaveBeenCalledWith('/api/v5/messages', { params: { isDeleted: false, messageFeedId: 'message-feed-id', options: { sortBy: 'segmentDesc', limit: 3, around: aroundMessageId }, }, }); await pause(100); client.emitter.emit('message.created', { messages: [newMessage], users: [], files: [], reactions: [], }); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(2); expect(callback).lastCalledWith( expect.objectContaining({ data: [newMessage, ...returnValue].map(convertRawMessage), error: undefined, loading: false, }), ); }); it('should not prepend new message if sortBy segmentDsc and hasPrevPage = true', async () => { const returnValue: Amity.RawMessage[] = [ generateRawMessage({ messageId: messagesDesc.page3[0], segment: 100 }), generateRawMessage({ messageId: messagesDesc.page3[1], segment: 99 }), // aroundMessageId generateRawMessage({ messageId: messagesDesc.page3[2], segment: 98 }), ]; const newMessage = generateRawMessage({ messageId: 'newMessageId-105', segment: 102 }); const aroundMessageId = messagesDesc.page3[1]; const callback = jest.fn(); const spyGet = jest.spyOn(client.http, 'get').mockImplementation((url: string, params) => { if (url !== '/api/v5/messages') return Promise.resolve(); return Promise.resolve({ data: { messages: returnValue, paging: { previous: 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDM5MTExMTAwMDAwMH0', next: 'eyJsaW1pdCI6MywiYmVmb3JlIjoibWVzc2FnZUlkMTAxIn0=', }, }, }); }); getMessages({ subChannelId, sortBy: 'segmentDesc', aroundMessageId, limit: 3 }, callback); expect(spyGet).toHaveBeenCalledWith('/api/v5/messages', { params: { isDeleted: false, messageFeedId: 'message-feed-id', options: { sortBy: 'segmentDesc', limit: 3, around: aroundMessageId }, }, }); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(1); client.emitter.emit('message.created', { messages: [newMessage], users: [], files: [], reactions: [], }); await pause(100); expect(callback).toBeCalledTimes(2); expect(callback).lastCalledWith( expect.objectContaining({ data: returnValue.map(convertRawMessage), error: undefined, loading: false, }), ); }); it('should append new message if sortBy segmentAsc and hasNextPage = false', async () => { const returnValue: Amity.RawMessage[] = [ generateRawMessage({ messageId: messages.page1[0], segment: 1 }), generateRawMessage({ messageId: messages.page1[1], segment: 2 }), // aroundMessageId generateRawMessage({ messageId: messages.page1[2], segment: 3 }), ]; const newMessage = generateRawMessage({ messageId: 'newMessageId', segment: 4 }); const aroundMessageId = messages.page1[1]; const callback = jest.fn(); const spyGet = jest.spyOn(client.http, 'get').mockImplementation((url: string, params) => { if (url !== '/api/v5/messages') return Promise.resolve(); return Promise.resolve({ data: { messages: returnValue, paging: { prev: 'eyJsaW1pdCI6MywiYmVmb3JlIjoibWVzc2FnZUlkMTAxIn0=', }, }, }); }); getMessages({ subChannelId, sortBy: 'segmentAsc', aroundMessageId, limit: 3 }, callback); expect(spyGet).toHaveBeenCalledWith('/api/v5/messages', { params: { isDeleted: false, messageFeedId: 'message-feed-id', options: { sortBy: 'segmentAsc', limit: 3, around: aroundMessageId }, }, }); await pause(100); client.emitter.emit('message.created', { messages: [newMessage], users: [], files: [], reactions: [], }); await pause(100); expect(callback.mock.calls.length).toBeGreaterThan(2); expect(callback).lastCalledWith( expect.objectContaining({ data: [...returnValue, newMessage].map(convertRawMessage), error: undefined, loading: false, }), ); }); it('should not append new message if sortBy segmentAsc and hasNextPage = true', async () => { const returnValue: Amity.RawMessage[] = [ generateRawMessage({ messageId: messages.page2[0], segment: 1 }), generateRawMessage({ messageId: messages.page2[1], segment: 2 }), // aroundMessageId generateRawMessage({ messageId: messages.page2[2], segment: 3 }), ]; const newMessage = generateRawMessage({ messageId: 'newMessageId', segment: 4 }); const aroundMessageId = messages.page2[1]; const callback = jest.fn(); const spyGet = jest.spyOn(client.http, 'get').mockImplementation((url: string, params) => { if (url !== '/api/v5/messages') return Promise.resolve(); return Promise.resolve({ data: { messages: returnValue, paging: { previous: 'eyJsaW1pdCI6MiwiYmVmb3JlIjo2MzQ3MTYxNDM5MTExMTAwMDAwMH0', next: 'eyJsaW1pdCI6MywiYmVmb3JlIjoibWVzc2FnZUlkMTAxIn0=', }, }, }); }); getMessages({ subChannelId, sortBy: 'segmentAsc', aroundMessageId, limit: 3 }, callback); expect(spyGet).toHaveBeenCalledWith('/api/v5/messages', { params: { isDeleted: false, messageFeedId: 'message-feed-id', options: { sortBy: 'segmentAsc', limit: 3, around: aroundMessageId }, }, }); await pause(100); client.emitter.emit('message.created', { messages: [newMessage], users: [], files: [], reactions: [], }); await pause(100); expect(callback).toBeCalledTimes(2); expect(callback).lastCalledWith( expect.objectContaining({ data: returnValue.map(convertRawMessage), error: undefined, loading: false, }), ); }); }); });