From 1c6e934b9cd78005f63000c0eee5b434b813b561 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Mon, 10 Jun 2024 16:56:11 +0200 Subject: fix(MessagesList): restore the state if context request was canceled, abort lookForNewMessages request if query param is missing Signed-off-by: Maksim Sukharev --- src/components/MessagesList/MessagesList.vue | 12 +++++++++++- src/store/messagesStore.js | 6 ++++++ src/store/messagesStore.spec.js | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/MessagesList/MessagesList.vue b/src/components/MessagesList/MessagesList.vue index 574e89f1c..22faf3674 100644 --- a/src/components/MessagesList/MessagesList.vue +++ b/src/components/MessagesList/MessagesList.vue @@ -643,7 +643,14 @@ export default { this.$store.dispatch('setLastKnownMessageId', { token, id: startingMessageId }) // Get chat messages before last read message and after it - await this.getMessageContext(token, startingMessageId) + try { + await this.getMessageContext(token, startingMessageId) + } catch (exception) { + // Request was cancelled, stop getting preconditions and restore initial state + this.$store.dispatch('setFirstKnownMessageId', { token, id: null }) + this.$store.dispatch('setLastKnownMessageId', { token, id: null }) + return + } } this.$nextTick(() => { @@ -686,9 +693,12 @@ export default { messageId, minimumVisible: CHAT.MINIMUM_VISIBLE, }) + this.loadingOldMessages = false } catch (exception) { if (Axios.isCancel(exception)) { console.debug('The request has been canceled', exception) + this.loadingOldMessages = false + throw exception } if (exception?.response?.status === 304 && exception?.response?.data === '') { diff --git a/src/store/messagesStore.js b/src/store/messagesStore.js index 120e9dc0b..72db09cbe 100644 --- a/src/store/messagesStore.js +++ b/src/store/messagesStore.js @@ -1110,6 +1110,12 @@ const actions = { async lookForNewMessages(context, { token, lastKnownMessageId, requestId, requestOptions }) { context.dispatch('cancelLookForNewMessages', { requestId }) + if (!lastKnownMessageId) { + // if param is null | undefined, it won't be included in the request query + console.warn('Trying to load messages without the required parameter') + return + } + // Get a new cancelable request function and cancel function pair const { request, cancel } = CancelableRequest(lookForNewMessages) diff --git a/src/store/messagesStore.spec.js b/src/store/messagesStore.spec.js index 91b301fd1..c2538b769 100644 --- a/src/store/messagesStore.spec.js +++ b/src/store/messagesStore.spec.js @@ -1300,6 +1300,10 @@ describe('messagesStore', () => { store = new Vuex.Store(testStoreConfig) }) + afterEach(() => { + jest.clearAllMocks() + }) + test('looks for new messages', async () => { const messages = [{ id: 1, @@ -1389,6 +1393,25 @@ describe('messagesStore', () => { expect(store.getters.getLastKnownMessageId(TOKEN)).toBe(null) }) + test('does not look for new messages if lastKnownMessageId is falsy', async () => { + // Arrange: prepare cancelable request from previous call of the function + const cancelFunctionMock = jest.fn() + cancelFunctionMocks.push(cancelFunctionMock) + store.commit('setCancelLookForNewMessages', { cancelFunction: cancelFunctionMock, requestId: 'request1' }) + console.warn = jest.fn() + + // Act + store.dispatch('lookForNewMessages', { + token: TOKEN, + requestId: 'request1', + lastKnownMessageId: null, + }) + + // Assert + expect(cancelFunctionMocks[0]).toHaveBeenCalledWith('canceled') + expect(lookForNewMessages).not.toHaveBeenCalled() + }) + test('cancels look for new messages', async () => { store.dispatch('lookForNewMessages', { token: TOKEN, -- cgit v1.2.3