Skip to content

Commit

Permalink
fix(store): migrate getters, actions and tests
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <[email protected]>
  • Loading branch information
Antreesy committed Dec 12, 2023
1 parent eb7c319 commit 6eb0968
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 2 deletions.
67 changes: 65 additions & 2 deletions src/stores/__tests__/chatExtras.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,72 @@ describe('chatExtrasStore', () => {
chatExtrasStore.removeUserAbsence(token2)

// Assert
expect(chatExtrasStore.absence[token]).toEqual(undefined)
expect(chatExtrasStore.absence[token2]).toEqual(undefined)
expect(chatExtrasStore.absence[token]).not.toBeDefined()
expect(chatExtrasStore.absence[token2]).not.toBeDefined()
})

})

describe('reply message', () => {
it('adds reply message id to the store', () => {
// Act
chatExtrasStore.addMessageToBeReplied({ token, id: 101 })

// Assert
expect(chatExtrasStore.getMessageToBeReplied(token)).toBe(101)
})

it('clears reply message', () => {
// Arrange
chatExtrasStore.addMessageToBeReplied({ token, id: 101 })

// Act
chatExtrasStore.removeMessageToBeReplied(token)

// Assert
expect(chatExtrasStore.getMessageToBeReplied(token)).not.toBeDefined()
})
})

describe('current input message', () => {
it('sets current input message', () => {
// Act
chatExtrasStore.setCurrentMessageInput({ token: 'token-1', text: 'message-1' })

// Assert
expect(chatExtrasStore.getCurrentMessageInput('token-1')).toStrictEqual('message-1')
})

it('clears current input message', () => {
// Arrange
chatExtrasStore.setCurrentMessageInput({ token: 'token-1', text: 'message-1' })

// Act
chatExtrasStore.removeCurrentMessageInput('token-1')

// Assert
expect(chatExtrasStore.currentMessageInput['token-1']).not.toBeDefined()
expect(chatExtrasStore.getCurrentMessageInput('token-1')).toBe('')
})
})

describe('purge store', () => {
it('clears store for provided token', async () => {
// Arrange
const response = generateOCSResponse({ payload })
getUserAbsence.mockResolvedValueOnce(response)

await chatExtrasStore.getUserAbsence({ token: 'token-1', userId })
chatExtrasStore.addMessageToBeReplied({ token: 'token-1', id: 101 })
chatExtrasStore.setCurrentMessageInput({ token: 'token-1', text: 'message-1' })

// Act
chatExtrasStore.purgeChatExtras('token-1')

// Assert
expect(chatExtrasStore.absence['token-1']).not.toBeDefined()
expect(chatExtrasStore.messagesToBeReplied['token-1']).not.toBeDefined()
expect(chatExtrasStore.currentMessageInput['token-1']).not.toBeDefined()
})
})
})
90 changes: 90 additions & 0 deletions src/stores/chatExtras.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* @copyright Copyright (c) 2023 Maksim Sukharev <[email protected]>
*
* @author Maksim Sukharev <[email protected]>
* @author Marco Ambrosini <[email protected]>
*
* @license AGPL-3.0-or-later
*
Expand All @@ -25,11 +26,42 @@ import Vue from 'vue'

import { getUserAbsence } from '../services/participantsService.js'

/**
* @typedef {string} Token
*/

/**
* @typedef {object} State
* @property {{[key: Token]: object}} absence - The absence status per conversation.
* @property {{[key: Token]: number}} messagesToBeReplied - The parent message id to reply per conversation.
* @property {{[key: Token]: string}} currentMessageInput -The input value per conversation.
*/

/**
* Store for conversation extra chat features apart from messages
*
* @param {string} id store name
* @param {State} options.state store state structure
*/
export const useChatExtrasStore = defineStore('chatExtras', {
state: () => ({
absence: {},
messagesToBeReplied: {},
currentMessageInput: {},
}),

getters: {
getMessageToBeReplied: (state) => (token) => {
if (state.messagesToBeReplied[token]) {
return state.messagesToBeReplied[token]
}
},

getCurrentMessageInput: (state) => (token) => {
return state.currentMessageInput[token] ?? ''
},
},

actions: {
/**
* Fetch an absence status for user and save to store
Expand Down Expand Up @@ -64,5 +96,63 @@ export const useChatExtrasStore = defineStore('chatExtras', {
Vue.delete(this.absence, token)
}
},

/**
* Add a reply message id to the store
*
* @param {object} payload action payload
* @param {string} payload.token The conversation token
* @param {number} payload.id The id of message
*/
addMessageToBeReplied({ token, id }) {
Vue.set(this.messagesToBeReplied, token, id)
},

/**
* Removes a reply message id from the store
* (after posting message or dismissing the operation)
*
* @param {string} token The conversation token
*/
removeMessageToBeReplied(token) {
Vue.delete(this.messagesToBeReplied, token)
},

/**
* Add a current input value to the store for a given conversation token
*
* @param {object} payload action payload
* @param {string} payload.token The conversation token
* @param {string} payload.text The string to store
*/
setCurrentMessageInput({ token, text }) {
// FIXME upstream: https://github.com/nextcloud-libraries/nextcloud-vue/issues/4492
const temp = document.createElement('textarea')
temp.innerHTML = text.replace(/&/gmi, '&amp;')
const parsedText = temp.value.replace(/&amp;/gmi, '&').replace(/&lt;/gmi, '<')
.replace(/&gt;/gmi, '>').replace(/&sect;/gmi, '§')

Vue.set(this.currentMessageInput, token, parsedText)
},

/**
* Remove a current input value from the store for a given conversation token
*
* @param {string} token The conversation token
*/
removeCurrentMessageInput(token) {
Vue.delete(this.currentMessageInput, token)
},

/**
* Clears store for a deleted conversation
*
* @param {string} token the token of the conversation to be deleted
*/
purgeChatExtras(token) {
this.removeMessageToBeReplied(token)
this.removeUserAbsence(token)
this.removeCurrentMessageInput(token)
},
},
})

0 comments on commit 6eb0968

Please sign in to comment.