diff options
Diffstat (limited to 'src/components')
25 files changed, 313 insertions, 175 deletions
diff --git a/src/components/CallView/shared/VideoBackground.vue b/src/components/CallView/shared/VideoBackground.vue index 4be58f58d..9667e35a7 100644 --- a/src/components/CallView/shared/VideoBackground.vue +++ b/src/components/CallView/shared/VideoBackground.vue @@ -40,6 +40,9 @@ import { getBuilder } from '@nextcloud/browser-storage' const browserStorage = getBuilder('nextcloud').persist().build() // note: this info is shared with the Avatar component +/** + * @param userId + */ function getUserHasAvatar(userId) { const flag = browserStorage.getItem('user-has-avatar.' + userId) if (typeof flag === 'string') { @@ -48,6 +51,10 @@ function getUserHasAvatar(userId) { return null } +/** + * @param userId + * @param flag + */ function setUserHasAvatar(userId, flag) { browserStorage.setItem('user-has-avatar.' + userId, flag) } diff --git a/src/components/ConversationSettings/NotificationsSettings.vue b/src/components/ConversationSettings/NotificationsSettings.vue index 52cd07278..2accbbeff 100644 --- a/src/components/ConversationSettings/NotificationsSettings.vue +++ b/src/components/ConversationSettings/NotificationsSettings.vue @@ -133,6 +133,7 @@ export default { methods: { /** * Set the notification level for the conversation + * * @param {int} notificationLevel The notification level to set. */ async setNotificationLevel(notificationLevel) { diff --git a/src/components/LeftSidebar/ConversationsList/Conversation.spec.js b/src/components/LeftSidebar/ConversationsList/Conversation.spec.js index 9a6b41090..7c52ed820 100644 --- a/src/components/LeftSidebar/ConversationsList/Conversation.spec.js +++ b/src/components/LeftSidebar/ConversationsList/Conversation.spec.js @@ -96,6 +96,11 @@ describe('Conversation.vue', () => { }) describe('displayed subtitle', () => { + /** + * @param item + * @param expectedText + * @param isSearchResult + */ function testConversationLabel(item, expectedText, isSearchResult = false) { const wrapper = mount(Conversation, { localVue, @@ -268,6 +273,11 @@ describe('Conversation.vue', () => { }) describe('unread messages counter', () => { + /** + * @param item + * @param expectedCounterText + * @param expectedHighlighted + */ function testCounter(item, expectedCounterText, expectedHighlighted) { const wrapper = mount(Conversation, { localVue, @@ -331,6 +341,10 @@ describe('Conversation.vue', () => { $router = { push: jest.fn() } }) + /** + * @param wrapper + * @param text + */ function findActionButton(wrapper, text) { const actionButtons = wrapper.findAllComponents(ActionButton) const items = actionButtons.filter(actionButton => { @@ -342,6 +356,9 @@ describe('Conversation.vue', () => { return items.at(0) } + /** + * @param actionName + */ function shallowMountAndGetAction(actionName) { const wrapper = shallowMount(Conversation, { localVue, @@ -364,7 +381,7 @@ describe('Conversation.vue', () => { return findActionButton(el, actionName) } - test('forwards click event on list item', async() => { + test('forwards click event on list item', async () => { const wrapper = mount(Conversation, { localVue, store, @@ -386,6 +403,10 @@ describe('Conversation.vue', () => { }) describe('notification level', () => { + /** + * @param actionName + * @param level + */ async function testSetNotificationLevel(actionName, level) { const setNotificationLevelAction = jest.fn().mockResolvedValueOnce() testStoreConfig.modules.conversationsStore.actions.setNotificationLevel = setNotificationLevelAction @@ -398,21 +419,21 @@ describe('Conversation.vue', () => { expect(setNotificationLevelAction).toHaveBeenCalledWith(expect.anything(), { token: TOKEN, notificationLevel: level }) } - test('sets notification to all messages', async() => { + test('sets notification to all messages', async () => { await testSetNotificationLevel('All messages', 1) }) - test('sets notification to at-mentions only', async() => { + test('sets notification to at-mentions only', async () => { await testSetNotificationLevel('@-mentions only', 2) }) - test('sets notification to off', async() => { + test('sets notification to off', async () => { await testSetNotificationLevel('Off', 3) }) }) describe('leaving conversation', () => { - test('leaves conversation', async() => { + test('leaves conversation', async () => { const actionHandler = jest.fn() testStoreConfig.modules.participantsStore.actions.removeCurrentUserFromConversation = actionHandler @@ -424,14 +445,14 @@ describe('Conversation.vue', () => { expect(actionHandler).toHaveBeenCalledWith(expect.anything(), { token: TOKEN }) }) - test('hides "leave conversation" action when not allowed', async() => { + test('hides "leave conversation" action when not allowed', async () => { item.canLeaveConversation = false const action = shallowMountAndGetAction('Leave conversation') expect(action.exists()).toBe(false) }) - test('errors with notification when a new moderator is required before leaving', async() => { + test('errors with notification when a new moderator is required before leaving', async () => { const actionHandler = jest.fn().mockRejectedValueOnce({ response: { status: 400, @@ -450,7 +471,7 @@ describe('Conversation.vue', () => { }) describe('deleting conversation', () => { - test('deletes conversation when confirmed', async() => { + test('deletes conversation when confirmed', async () => { const actionHandler = jest.fn().mockResolvedValueOnce() const updateTokenAction = jest.fn() testStoreConfig.modules.conversationsStore.actions.deleteConversationFromServer = actionHandler @@ -474,7 +495,7 @@ describe('Conversation.vue', () => { expect(updateTokenAction).not.toHaveBeenCalled() }) - test('does not delete conversation when not confirmed', async() => { + test('does not delete conversation when not confirmed', async () => { const actionHandler = jest.fn().mockResolvedValueOnce() const updateTokenAction = jest.fn() testStoreConfig.modules.conversationsStore.actions.deleteConversationFromServer = actionHandler @@ -498,7 +519,7 @@ describe('Conversation.vue', () => { expect(updateTokenAction).not.toHaveBeenCalled() }) - test('hides "delete conversation" action when not allowed', async() => { + test('hides "delete conversation" action when not allowed', async () => { item.canDeleteConversation = false const action = shallowMountAndGetAction('Delete conversation') @@ -506,7 +527,7 @@ describe('Conversation.vue', () => { }) }) - test('copies link conversation', async() => { + test('copies link conversation', async () => { const copyTextMock = jest.fn().mockResolvedValueOnce() const wrapper = shallowMount(Conversation, { localVue, @@ -536,7 +557,7 @@ describe('Conversation.vue', () => { expect(copyTextMock).toHaveBeenCalledWith('http://localhost/nc-webroot/call/XXTOKENXX') expect(showSuccess).toHaveBeenCalled() }) - test('sets favorite', async() => { + test('sets favorite', async () => { const toggleFavoriteAction = jest.fn().mockResolvedValueOnce() testStoreConfig.modules.conversationsStore.actions.toggleFavorite = toggleFavoriteAction @@ -565,7 +586,7 @@ describe('Conversation.vue', () => { expect(toggleFavoriteAction).toHaveBeenCalledWith(expect.anything(), item) }) - test('unsets favorite', async() => { + test('unsets favorite', async () => { const toggleFavoriteAction = jest.fn().mockResolvedValueOnce() testStoreConfig.modules.conversationsStore.actions.toggleFavorite = toggleFavoriteAction @@ -595,7 +616,7 @@ describe('Conversation.vue', () => { expect(toggleFavoriteAction).toHaveBeenCalledWith(expect.anything(), item) }) - test('marks conversation as read', async() => { + test('marks conversation as read', async () => { const clearLastReadMessageAction = jest.fn().mockResolvedValueOnce() testStoreConfig.modules.conversationsStore.actions.clearLastReadMessage = clearLastReadMessageAction diff --git a/src/components/LeftSidebar/ConversationsList/Conversation.vue b/src/components/LeftSidebar/ConversationsList/Conversation.vue index 4f4e79276..a26177fb1 100644 --- a/src/components/LeftSidebar/ConversationsList/Conversation.vue +++ b/src/components/LeftSidebar/ConversationsList/Conversation.vue @@ -281,7 +281,8 @@ export default { * This is a simplified version of the last chat message. * Parameters are parsed without markup (just replaced with the name), * e.g. no avatars on mentions. - * @returns {string} A simple message to show below the conversation name + * + * @return {string} A simple message to show below the conversation name */ simpleLastChatMessage() { if (!Object.keys(this.lastChatMessage).length) { @@ -300,7 +301,7 @@ export default { }, /** - * @returns {string} Part of the name until the first space + * @return {string} Part of the name until the first space */ shortLastChatMessageAuthor() { if (!Object.keys(this.lastChatMessage).length @@ -390,6 +391,7 @@ export default { /** * Set the notification level for the conversation + * * @param {int} level The notification level to set. */ async setNotificationLevel(level) { diff --git a/src/components/LeftSidebar/LeftSidebar.spec.js b/src/components/LeftSidebar/LeftSidebar.spec.js index 99ff95127..366377715 100644 --- a/src/components/LeftSidebar/LeftSidebar.spec.js +++ b/src/components/LeftSidebar/LeftSidebar.spec.js @@ -35,6 +35,9 @@ describe('LeftSidebar.vue', () => { let addConversationAction let createOneToOneConversationAction + /** + * + */ function mountComponent() { return mount(LeftSidebar, { localVue, @@ -117,7 +120,7 @@ describe('LeftSidebar.vue', () => { conversationsListMock.mockImplementation(() => cloneDeep(conversationsList)) }) - test('fetches and renders conversation list initially', async() => { + test('fetches and renders conversation list initially', async () => { const conversationsReceivedEvent = jest.fn() EventBus.$once('conversationsReceived', conversationsReceivedEvent) fetchConversationsAction.mockResolvedValueOnce() @@ -152,7 +155,7 @@ describe('LeftSidebar.vue', () => { }) }) - test('re-fetches conversations every 30 seconds', async() => { + test('re-fetches conversations every 30 seconds', async () => { const wrapper = mountComponent() expect(fetchConversationsAction).toHaveBeenCalled() @@ -174,7 +177,7 @@ describe('LeftSidebar.vue', () => { expect(fetchConversationsAction).toHaveBeenCalled() }) - test('re-fetches conversations when receiving bus event', async() => { + test('re-fetches conversations when receiving bus event', async () => { const wrapper = mountComponent() expect(fetchConversationsAction).toHaveBeenCalled() @@ -275,6 +278,12 @@ describe('LeftSidebar.vue', () => { fetchConversationsAction.mockResolvedValue() }) + /** + * @param searchTerm + * @param possibleResults + * @param listedResults + * @param loadStateSettingsOverride + */ async function testSearch(searchTerm, possibleResults, listedResults, loadStateSettingsOverride) { searchPossibleConversations.mockResolvedValueOnce({ data: { @@ -318,7 +327,7 @@ describe('LeftSidebar.vue', () => { } describe('displaying search results', () => { - test('displays search results when search is active', async() => { + test('displays search results when search is active', async () => { const wrapper = await testSearch( 'search', [...usersResults, ...groupsResults, ...circlesResults], @@ -364,7 +373,7 @@ describe('LeftSidebar.vue', () => { expect(optionsEls.at(1).props('items')).toStrictEqual([groupsResults[0], groupsResults[1]]) expect(optionsEls.at(2).props('items')).toStrictEqual([circlesResults[0], circlesResults[1]]) }) - test('only shows user search results when cannot create conversations', async() => { + test('only shows user search results when cannot create conversations', async () => { const wrapper = await testSearch( 'search', [...usersResults, ...groupsResults, ...circlesResults], @@ -406,7 +415,7 @@ describe('LeftSidebar.vue', () => { expect(optionsEls.at(0).props('items')).toStrictEqual([usersResults[1], usersResults[2]]) expect(optionsEls.length).toBe(1) }) - test('does not show circles results when circles are disabled', async() => { + test('does not show circles results when circles are disabled', async () => { const wrapper = await testSearch( 'search', [...usersResults, ...groupsResults], @@ -453,6 +462,13 @@ describe('LeftSidebar.vue', () => { }) describe('not found caption', () => { + /** + * @param searchTerm + * @param possibleResults + * @param listedResults + * @param loadStateSettingsOverride + * @param expectedCaption + */ async function testSearchNotFound(searchTerm, possibleResults, listedResults, loadStateSettingsOverride, expectedCaption) { const wrapper = await testSearch(searchTerm, possibleResults, listedResults, loadStateSettingsOverride) @@ -482,7 +498,7 @@ describe('LeftSidebar.vue', () => { return wrapper } - test('displays all types in caption when nothing was found', async() => { + test('displays all types in caption when nothing was found', async () => { await testSearchNotFound( 'search', [], @@ -495,7 +511,7 @@ describe('LeftSidebar.vue', () => { ) }) - test('displays all types in caption when only listed conversations were found', async() => { + test('displays all types in caption when only listed conversations were found', async () => { await testSearchNotFound( 'search', [], @@ -508,7 +524,7 @@ describe('LeftSidebar.vue', () => { ) }) - test('displays all types minus circles when nothing was found but circles is disabled', async() => { + test('displays all types minus circles when nothing was found but circles is disabled', async () => { await testSearchNotFound( 'search', [], @@ -521,7 +537,7 @@ describe('LeftSidebar.vue', () => { ) }) - test('displays caption for users and groups not found', async() => { + test('displays caption for users and groups not found', async () => { await testSearchNotFound( 'search', [...circlesResults], @@ -533,7 +549,7 @@ describe('LeftSidebar.vue', () => { 'Users and groups' ) }) - test('displays caption for users not found', async() => { + test('displays caption for users not found', async () => { await testSearchNotFound( 'search', [...circlesResults, ...groupsResults], @@ -545,7 +561,7 @@ describe('LeftSidebar.vue', () => { 'Users' ) }) - test('displays caption for groups not found', async() => { + test('displays caption for groups not found', async () => { await testSearchNotFound( 'search', [...usersResults, ...circlesResults], @@ -557,7 +573,7 @@ describe('LeftSidebar.vue', () => { 'Groups' ) }) - test('displays caption for groups and circles not found', async() => { + test('displays caption for groups and circles not found', async () => { await testSearchNotFound( 'search', [...usersResults], @@ -569,7 +585,7 @@ describe('LeftSidebar.vue', () => { 'Groups and circles' ) }) - test('displays caption for users and circles not found', async() => { + test('displays caption for users and circles not found', async () => { await testSearchNotFound( 'search', [...groupsResults], @@ -584,7 +600,7 @@ describe('LeftSidebar.vue', () => { }) describe('clicking search results', () => { - test('joins listed conversation from search result', async() => { + test('joins listed conversation from search result', async () => { const wrapper = await testSearch('search', [], listedResults) const appNavEl = wrapper.findComponent({ name: 'AppNavigation' }) @@ -597,7 +613,7 @@ describe('LeftSidebar.vue', () => { expect(wrapper.vm.$route.name).toBe('conversation') expect(wrapper.vm.$route.params).toStrictEqual({ token: 'listed-token-2' }) }) - test('creates one to one conversation from user search result', async() => { + test('creates one to one conversation from user search result', async () => { createOneToOneConversationAction.mockResolvedValue({ id: 9999, token: 'new-conversation', @@ -614,7 +630,7 @@ describe('LeftSidebar.vue', () => { expect(wrapper.vm.$route.name).toBe('conversation') expect(wrapper.vm.$route.params).toStrictEqual({ token: 'new-conversation' }) }) - test('shows group conversation dialog when clicking search result', async() => { + test('shows group conversation dialog when clicking search result', async () => { const eventHandler = jest.fn() EventBus.$once('NewGroupConversationDialog', eventHandler) @@ -631,7 +647,7 @@ describe('LeftSidebar.vue', () => { expect(createOneToOneConversationAction).not.toHaveBeenCalled() expect(addConversationAction).not.toHaveBeenCalled() }) - test('shows circles conversation dialog when clicking search result', async() => { + test('shows circles conversation dialog when clicking search result', async () => { const eventHandler = jest.fn() EventBus.$once('NewGroupConversationDialog', eventHandler) @@ -647,7 +663,7 @@ describe('LeftSidebar.vue', () => { // nothing created yet expect(createOneToOneConversationAction).not.toHaveBeenCalled() }) - test('clears search results when joining user chat', async() => { + test('clears search results when joining user chat', async () => { createOneToOneConversationAction.mockResolvedValue({ id: 9999, token: 'new-conversation', @@ -669,7 +685,7 @@ describe('LeftSidebar.vue', () => { expect(searchBoxEl.exists()).toBe(true) expect(input.element.value).toBe('') }) - test('does not clear search results when clicking group chat', async() => { + test('does not clear search results when clicking group chat', async () => { const wrapper = await testSearch('search', [...groupsResults], []) const appNavEl = wrapper.findComponent({ name: 'AppNavigation' }) @@ -710,7 +726,7 @@ describe('LeftSidebar.vue', () => { }) }) - test('shows settings when clicking the settings button', async() => { + test('shows settings when clicking the settings button', async () => { conversationsListMock.mockImplementation(() => []) const eventHandler = jest.fn() subscribe('show-settings', eventHandler) diff --git a/src/components/LeftSidebar/LeftSidebar.vue b/src/components/LeftSidebar/LeftSidebar.vue index 69131e761..00a79d432 100644 --- a/src/components/LeftSidebar/LeftSidebar.vue +++ b/src/components/LeftSidebar/LeftSidebar.vue @@ -358,7 +358,7 @@ export default { * Create a new conversation with the selected user * or bring up the dialog to create a new group/circle conversation * - * @param {Object} item The autocomplete suggestion to start a conversation with + * @param {object} item The autocomplete suggestion to start a conversation with * @param {string} item.id The ID of the target * @param {string} item.label The displayname of the target * @param {string} item.source The source of the target (e.g. users, groups, circle) diff --git a/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue b/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue index df32e225c..c8878799f 100644 --- a/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue +++ b/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue @@ -226,9 +226,11 @@ export default { this.showModal() }, - /** Reinitialise the component to it's initial state. This is necessary + /** + * Reinitialise the component to it's initial state. This is necessary * because once the component is mounted it's data would persist even if - * the modal closes */ + * the modal closes + */ closeModal() { this.modal = false this.page = 0 @@ -251,8 +253,10 @@ export default { handleClickBack() { this.page = 0 }, - /** Handles the creation of the group conversation, adds the seleced - * participants to it and routes to it */ + /** + * Handles the creation of the group conversation, adds the seleced + * participants to it and routes to it + */ async handleCreateConversation() { this.page = 2 @@ -320,16 +324,20 @@ export default { this.closeModal() } }, - /** Creates a new private conversation, adds it to the store and sets - * the local token value to the newly created conversation's token */ + /** + * Creates a new private conversation, adds it to the store and sets + * the local token value to the newly created conversation's token + */ async createPrivateConversation() { const response = await createPrivateConversation(this.conversationName) const conversation = response.data.ocs.data this.$store.dispatch('addConversation', conversation) this.token = conversation.token }, - /** Creates a new public conversation, adds it to the store and sets - * the local token value to the newly created conversation's token */ + /** + * Creates a new public conversation, adds it to the store and sets + * the local token value to the newly created conversation's token + */ async createPublicConversation() { const response = await createPublicConversation(this.conversationName) const conversation = response.data.ocs.data diff --git a/src/components/LeftSidebar/NewGroupConversation/SetContacts/SetContacts.vue b/src/components/LeftSidebar/NewGroupConversation/SetContacts/SetContacts.vue index dfd8f38be..bbb30898c 100644 --- a/src/components/LeftSidebar/NewGroupConversation/SetContacts/SetContacts.vue +++ b/src/components/LeftSidebar/NewGroupConversation/SetContacts/SetContacts.vue @@ -97,8 +97,9 @@ export default { /** * Search hint at the bottom of the participants list, displayed only if * the user is not searching - * @returns {boolean} - **/ + * + * @return {boolean} + */ displaySearchHint() { return !this.contactsLoading && this.searchText === '' }, diff --git a/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue b/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue index 953151383..efc8fcd86 100644 --- a/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue +++ b/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue @@ -43,7 +43,9 @@ export default { }, }, methods: { - /** Emits the input event with the checked bulean as a value + /** + * Emits the input event with the checked bulean as a value + * * @param {object} event The checkbox click event object. */ handleInput(event) { diff --git a/src/components/MessagesList/MessagesGroup/Message/Message.spec.js b/src/components/MessagesList/MessagesGroup/Message/Message.spec.js index 0d8547759..7a656eb2f 100644 --- a/src/components/MessagesList/MessagesGroup/Message/Message.spec.js +++ b/src/components/MessagesList/MessagesGroup/Message/Message.spec.js @@ -86,7 +86,7 @@ describe('Message.vue', () => { store = new Vuex.Store(testStoreConfig) }) - test('renders rich text message', async() => { + test('renders rich text message', async () => { const wrapper = shallowMount(Message, { localVue, store, @@ -97,7 +97,7 @@ describe('Message.vue', () => { expect(message.attributes('text')).toBe('test message') }) - test('renders emoji as single plain text', async() => { + test('renders emoji as single plain text', async () => { messageProps.isSingleEmoji = true messageProps.message = '🌧️' const wrapper = shallowMount(Message, { @@ -268,6 +268,11 @@ describe('Message.vue', () => { }) describe('rich objects', () => { + /** + * @param message + * @param messageParameters + * @param expectedRichParameters + */ function renderRichObject(message, messageParameters, expectedRichParameters) { messageProps.message = message messageProps.messageParameters = messageParameters @@ -480,7 +485,7 @@ describe('Message.vue', () => { store = new Vuex.Store(testStoreConfig) }) - test('renders author if first message', async() => { + test('renders author if first message', async () => { messageProps.isFirstMessage = true const wrapper = shallowMount(Message, { localVue, @@ -492,7 +497,7 @@ describe('Message.vue', () => { expect(displayName.text()).toBe('user-display-name-1') }) - test('does not render author if not first message', async() => { + test('does not render author if not first message', async () => { messageProps.isFirstMessage = false const wrapper = shallowMount(Message, { localVue, @@ -512,7 +517,7 @@ describe('Message.vue', () => { store = new Vuex.Store(testStoreConfig) }) - test('does not render actions for system messages are available', async() => { + test('does not render actions for system messages are available', async () => { messageProps.systemMessage = 'this is a system message' const wrapper = shallowMount(Message, { @@ -527,7 +532,7 @@ describe('Message.vue', () => { expect(actionsEl.exists()).toBe(false) }) - test('does not render actions for temporary messages', async() => { + test('does not render actions for temporary messages', async () => { messageProps.isTemporary = true const wrapper = shallowMount(Message, { @@ -542,7 +547,7 @@ describe('Message.vue', () => { expect(actionsEl.exists()).toBe(false) }) - test('actions become visible on mouse over', async() => { + test('actions become visible on mouse over', async () => { messageProps.sendingFailure = 'timeout' const wrapper = shallowMount(Message, { localVue, @@ -573,7 +578,7 @@ describe('Message.vue', () => { }) describe('reply action', () => { - test('replies to message', async() => { + test('replies to message', async () => { const replyAction = jest.fn() testStoreConfig.modules.quoteReplyStore.actions.addMessageToBeReplied = replyAction store = new Vuex.Store(testStoreConfig) @@ -607,7 +612,7 @@ describe('Message.vue', () => { }) }) - test('hides reply button when not replyable', async() => { + test('hides reply button when not replyable', async () => { messageProps.isReplyable = false store = new Vuex.Store(testStoreConfig) @@ -626,7 +631,7 @@ describe('Message.vue', () => { }) describe('private reply action', () => { - test('creates a new conversation when replying to message privately', async() => { + test('creates a new conversation when replying to message privately', async () => { const routerPushMock = jest.fn().mockResolvedValue() const createOneToOneConversation = jest.fn() testStoreConfig.modules.conversationsStore.actions.createOneToOneConversation = createOneToOneConversation @@ -667,6 +672,9 @@ describe('Message.vue', () => { }) }) + /** + * @param visible + */ function testPrivateReplyActionVisible(visible) { store = new Vuex.Store(testStoreConfig) @@ -683,25 +691,25 @@ describe('Message.vue', () => { expect(actionButton.exists()).toBe(visible) } - test('hides private reply action for own messages', async() => { + test('hides private reply action for own messages', async () => { // using default message props which have the // actor id set to the current user testPrivateReplyActionVisible(false) }) - test('hides private reply action for one to one conversation type', async() => { + test('hides private reply action for one to one conversation type', async () => { messageProps.actorId = 'another-user' conversationProps.type = CONVERSATION.TYPE.ONE_TO_ONE testPrivateReplyActionVisible(false) }) - test('hides private reply action for guest messages', async() => { + test('hides private reply action for guest messages', async () => { messageProps.actorId = 'guest-user' messageProps.actorType = ATTENDEE.ACTOR_TYPE.GUESTS testPrivateReplyActionVisible(false) }) - test('hides private reply action when current user is a guest', async() => { + test('hides private reply action when current user is a guest', async () => { messageProps.actorId = 'another-user' getActorTypeMock.mockClear().mockReturnValue(() => ATTENDEE.ACTOR_TYPE.GUESTS) testPrivateReplyActionVisible(false) @@ -709,7 +717,7 @@ describe('Message.vue', () => { }) describe('delete action', () => { - test('deletes message', async() => { + test('deletes message', async () => { let resolveDeleteMessage const deleteMessage = jest.fn().mockReturnValue(new Promise((resolve, reject) => { resolveDeleteMessage = resolve })) testStoreConfig.modules.messagesStore.actions.deleteMessage = deleteMessage @@ -755,6 +763,11 @@ describe('Message.vue', () => { expect(wrapper.find('.icon-loading-small').exists()).toBe(false) }) + /** + * @param visible + * @param mockDate + * @param participantType + */ function testDeleteMessageVisible(visible, mockDate, participantType = PARTICIPANT.TYPE.USER) { store = new Vuex.Store(testStoreConfig) @@ -836,7 +849,7 @@ describe('Message.vue', () => { }) }) - test('marks message as unread', async() => { + test('marks message as unread', async () => { const updateLastReadMessageAction = jest.fn().mockResolvedValueOnce() const fetchConversationAction = jest.fn().mockResolvedValueOnce() testStoreConfig.modules.conversationsStore.actions.updateLastReadMessage = updateLastReadMessageAction @@ -888,7 +901,7 @@ describe('Message.vue', () => { }) }) - test('copies message link', async() => { + test('copies message link', async () => { const copyTextMock = jest.fn() // appears even with more restrictive conditions @@ -926,7 +939,7 @@ describe('Message.vue', () => { expect(copyTextMock).toHaveBeenCalledWith('http://localhost/nc-webroot/call/XXTOKENXX#message_123') }) - test('renders clickable custom actions', async() => { + test('renders clickable custom actions', async () => { const handler = jest.fn() const handler2 = jest.fn() const actionsGetterMock = jest.fn().mockReturnValue([{ @@ -977,7 +990,7 @@ describe('Message.vue', () => { store = new Vuex.Store(testStoreConfig) }) - test('lets user retry sending a timed out message', async() => { + test('lets user retry sending a timed out message', async () => { messageProps.sendingFailure = 'timeout' const wrapper = shallowMount(Message, { localVue, diff --git a/src/components/MessagesList/MessagesGroup/Message/MessagePart/FilePreview.spec.js b/src/components/MessagesList/MessagesGroup/Message/MessagePart/FilePreview.spec.js index b0bf9ba99..cee2cb2ca 100644 --- a/src/components/MessagesList/MessagesGroup/Message/MessagePart/FilePreview.spec.js +++ b/src/components/MessagesList/MessagesGroup/Message/MessagePart/FilePreview.spec.js @@ -57,12 +57,15 @@ describe('FilePreview.vue', () => { window.devicePixelRatio = oldPixelRatio }) + /** + * @param url + */ function parseRelativeUrl(url) { return new URL('https://localhost' + url) } describe('file preview rendering', () => { - test('renders file preview', async() => { + test('renders file preview', async () => { const wrapper = shallowMount(FilePreview, { localVue, store, @@ -82,7 +85,7 @@ describe('FilePreview.vue', () => { expect(wrapper.find('.loading').exists()).toBe(false) }) - test('renders file preview for guests', async() => { + test('renders file preview for guests', async () => { propsData.link = 'https://localhost/nc-webroot/s/xtokenx' getUserIdMock.mockClear().mockReturnValue(null) @@ -105,7 +108,7 @@ describe('FilePreview.vue', () => { expect(wrapper.find('.loading').exists()).toBe(false) }) - test('calculates preview size based on window pixel ratio', async() => { + test('calculates preview size based on window pixel ratio', async () => { window.devicePixelRatio = 1.5 const wrapper = shallowMount(FilePreview, { @@ -121,7 +124,7 @@ describe('FilePreview.vue', () => { expect(imageUrl.searchParams.get('y')).toBe('576') }) - test('renders small previews when requested', async() => { + test('renders small previews when requested', async () => { propsData.smallPreview = true const wrapper = shallowMount(FilePreview, { @@ -146,7 +149,7 @@ describe('FilePreview.vue', () => { store = new Vuex.Store(testStoreConfig) }) - test('renders progress bar while uploading', async() => { + test('renders progress bar while uploading', async () => { propsData.id = 'temp-123' propsData.index = 'index-1' propsData.uploadId = 1000 @@ -185,7 +188,7 @@ describe('FilePreview.vue', () => { expect(wrapper.find('.loading').exists()).toBe(true) }) - test('renders default mime icon on load error', async() => { + test('renders default mime icon on load error', async () => { const wrapper = shallowMount(FilePreview, { localVue, store, @@ -199,7 +202,7 @@ describe('FilePreview.vue', () => { expect(imageUrl).toBe(imagePath('core', 'filetypes/file')) }) - test('renders generic mime type icon for unknown mime types', async() => { + test('renders generic mime type icon for unknown mime types', async () => { propsData.previewAvailable = 'no' OC.MimeType.getIconUrl.mockReturnValueOnce(imagePath('core', 'image/jpeg')) @@ -239,7 +242,7 @@ describe('FilePreview.vue', () => { return null }) }) - test('directly renders small GIF files', async() => { + test('directly renders small GIF files', async () => { propsData.size = 128 const wrapper = shallowMount(FilePreview, { @@ -255,7 +258,7 @@ describe('FilePreview.vue', () => { .toBe(generateRemoteUrl('dav/files/current-user-id') + '/path/to/test%20%2520.gif') }) - test('directly renders small GIF files (absolute path)', async() => { + test('directly renders small GIF files (absolute path)', async () => { propsData.size = 128 propsData.path = '/path/to/test %20.gif' @@ -272,7 +275,7 @@ describe('FilePreview.vue', () => { .toBe(generateRemoteUrl('dav/files/current-user-id') + '/path/to/test%20%2520.gif') }) - test('directly renders small GIF files for guests', async() => { + test('directly renders small GIF files for guests', async () => { propsData.size = 128 propsData.link = 'https://localhost/nc-webroot/s/xtokenx' getUserIdMock.mockClear().mockReturnValue(null) @@ -290,7 +293,7 @@ describe('FilePreview.vue', () => { .toBe(propsData.link + '/download/test%20%2520.gif') }) - test('renders static preview for big GIF files', async() => { + test('renders static preview for big GIF files', async () => { // bigger than max from capability propsData.size = 2048 @@ -345,7 +348,7 @@ describe('FilePreview.vue', () => { } }) - test('opens viewer when clicking if viewer available', async() => { + test('opens viewer when clicking if viewer available', async () => { OCA.Viewer = { open: jest.fn(), availableHandlers: [{ @@ -377,7 +380,7 @@ describe('FilePreview.vue', () => { expect(OCA.Files.Sidebar.state.file).toBe('/path/to/test.jpg') }) - test('does not open viewer when clicking if no mime handler available', async() => { + test('does not open viewer when clicking if no mime handler available', async () => { OCA.Viewer = { open: jest.fn(), availableHandlers: [{ @@ -398,7 +401,7 @@ describe('FilePreview.vue', () => { expect(OCA.Viewer.open).not.toHaveBeenCalled() }) - test('does not open viewer when clicking if viewer is not available', async() => { + test('does not open viewer when clicking if viewer is not available', async () => { delete OCA.Viewer const wrapper = shallowMount(FilePreview, { localVue, @@ -427,6 +430,9 @@ describe('FilePreview.vue', () => { } }) + /** + * @param visible + */ async function testPlayButtonVisible(visible) { const wrapper = shallowMount(FilePreview, { localVue, @@ -440,11 +446,11 @@ describe('FilePreview.vue', () => { expect(buttonEl.exists()).toBe(visible) } - test('renders play icon for video previews', async() => { + test('renders play icon for video previews', async () => { await testPlayButtonVisible(true) }) - test('does not render play icon for direct renders', async() => { + test('does not render play icon for direct renders', async () => { // gif is directly rendered propsData.mimetype = 'image/gif' propsData.name = 'test.gif' @@ -453,7 +459,7 @@ describe('FilePreview.vue', () => { await testPlayButtonVisible(false) }) - test('render play icon gif previews with big size', async() => { + test('render play icon gif previews with big size', async () => { // gif is directly rendered propsData.mimetype = 'image/gif' propsData.name = 'test.gif' @@ -463,12 +469,12 @@ describe('FilePreview.vue', () => { await testPlayButtonVisible(true) }) - test('does not render play icon for small previews', async() => { + test('does not render play icon for small previews', async () => { propsData.smallPreview = true await testPlayButtonVisible(false) }) - test('does not render play icon for failed videos', async() => { + test('does not render play icon for failed videos', async () => { const wrapper = shallowMount(FilePreview, { localVue, store, @@ -481,12 +487,12 @@ describe('FilePreview.vue', () => { expect(buttonEl.exists()).toBe(false) }) - test('does not render play icon if viewer not available', async() => { + test('does not render play icon if viewer not available', async () => { delete OCA.Viewer await testPlayButtonVisible(false) }) - test('does not render play icon for non-videos', async() => { + test('does not render play icon for non-videos', async () => { // viewer supported, but not a video propsData.mimetype = 'image/png' propsData.name = 'test.png' @@ -501,7 +507,7 @@ describe('FilePreview.vue', () => { beforeEach(() => { propsData.isUploadEditor = true }) - test('emits event when clicking remove button when inside upload editor', async() => { + test('emits event when clicking remove button when inside upload editor', async () => { const wrapper = shallowMount(FilePreview, { localVue, store, diff --git a/src/components/MessagesList/MessagesGroup/Message/MessagePart/Forwarder.vue b/src/components/MessagesList/MessagesGroup/Message/MessagePart/Forwarder.vue index ffd8daea6..e62a1539c 100644 --- a/src/components/MessagesList/MessagesGroup/Message/MessagePart/Forwarder.vue +++ b/src/components/MessagesList/MessagesGroup/Message/MessagePart/Forwarder.vue @@ -103,7 +103,8 @@ export default { /** * Object containing all the mentions in the message that will be forwarded - * @returns {Object} mentions. + * + * @return {object} mentions. */ mentions() { const mentions = {} diff --git a/src/components/MessagesList/MessagesGroup/MessagesGroup.vue b/src/components/MessagesList/MessagesGroup/MessagesGroup.vue index 9c77b34e8..64492cdc8 100644 --- a/src/components/MessagesList/MessagesGroup/MessagesGroup.vue +++ b/src/components/MessagesList/MessagesGroup/MessagesGroup.vue @@ -112,28 +112,32 @@ export default { computed: { /** * The message actor type. - * @returns {string} + * + * @return {string} */ actorType() { return this.messages[0].actorType }, /** * The message actor id. - * @returns {string} + * + * @return {string} */ actorId() { return this.messages[0].actorId }, /** * The message date. - * @returns {string} + * + * @return {string} */ dateSeparator() { return this.messages[0].dateSeparator || '' }, /** * The message actor display name. - * @returns {string} + * + * @return {string} */ actorDisplayName() { const displayName = this.messages[0].actorDisplayName.trim() @@ -150,7 +154,8 @@ export default { }, /** * Whether the given message is a system message - * @returns {bool} + * + * @return {bool} */ isSystemMessage() { return this.messages[0].systemMessage.length !== 0 diff --git a/src/components/MessagesList/MessagesList.spec.js b/src/components/MessagesList/MessagesList.spec.js index d9f0f2fa5..22d6a3e53 100644 --- a/src/components/MessagesList/MessagesList.spec.js +++ b/src/components/MessagesList/MessagesList.spec.js @@ -286,6 +286,9 @@ describe('MessagesList.vue', () => { expect(messagesListMock).toHaveBeenCalledWith(TOKEN) }) + /** + * @param messages + */ function testNotGrouped(messages) { messagesListMock.mockReturnValue(messages) diff --git a/src/components/MessagesList/MessagesList.vue b/src/components/MessagesList/MessagesList.vue index cfafc4a07..62143728a 100644 --- a/src/components/MessagesList/MessagesList.vue +++ b/src/components/MessagesList/MessagesList.vue @@ -147,7 +147,7 @@ export default { /** * Finds the first visual unread message element * - * @returns {object} DOM element of the first unread message + * @return {object} DOM element of the first unread message */ unreadMessageElement() { let el = document.getElementById('message_' + this.visualLastReadMessageId) @@ -162,7 +162,7 @@ export default { * Gets the messages array. We need this because the DynamicScroller needs an array to * loop through. * - * @returns {array} + * @return {Array} */ messagesList() { return this.$store.getters.messagesList(this.token) @@ -172,7 +172,7 @@ export default { * corresponds to the id of the message, and makes it easy and efficient to access the * individual message object. * - * @returns {object} + * @return {object} */ messages() { // FIXME: remove if unused ? @@ -180,7 +180,8 @@ export default { }, /** * Creates an array of messages grouped in nested arrays by same autor. - * @returns {array} + * + * @return {Array} */ messagesGroupedByAuthor() { const groups = [] @@ -211,7 +212,8 @@ export default { * When isSticky is true, as new messages are appended to the list, the div .scroller * automatically scrolls down to the last message, if it's false, new messages are * appended but the scrolling position is not altered. - * @returns {boolean} + * + * @return {boolean} */ isSticky() { return this.isChatScrolledToBottom @@ -221,7 +223,7 @@ export default { * Returns whether the current participant is a participant of the * current conversation or not. * - * @returns {Boolean} true if it is already a participant, false + * @return {boolean} true if it is already a participant, false * otherwise. */ isParticipant() { @@ -314,7 +316,7 @@ export default { * @param {string} message2.actorDisplayName Actor display name of previous message * @param {string} message2.systemMessage System message content of the previous message * @param {int} message2.timestamp Timestamp of the second message - * @returns {boolean} Boolean if the messages should be grouped or not + * @return {boolean} Boolean if the messages should be grouped or not */ messagesShouldBeGrouped(message1, message2) { if (!message2) { @@ -354,7 +356,7 @@ export default { * @param {null|object} message2 The previous message * @param {string} message2.id The ID of the second message * @param {int} message2.timestamp Timestamp of the second message - * @returns {boolean} Boolean if the messages have the same date + * @return {boolean} Boolean if the messages have the same date */ messagesHaveDifferentDate(message1, message2) { return !message2 // There is no previous message @@ -367,7 +369,7 @@ export default { * @param {object} message The message object * @param {string} message.id The ID of the message * @param {int} message.timestamp Timestamp of the message - * @returns {string} Translated string of "<Today>, <November 11th, 2019>", "<3 days ago>, <November 8th, 2019>" + * @return {string} Translated string of "<Today>, <November 11th, 2019>", "<3 days ago>, <November 8th, 2019>" */ generateDateSeparator(message) { const date = this.getDateOfMessage(message) @@ -402,7 +404,7 @@ export default { * @param {object} message The message object * @param {string} message.id The ID of the message * @param {int} message.timestamp Timestamp of the message - * @returns {object} MomentJS object + * @return {object} MomentJS object */ getDateOfMessage(message) { if (message.id.toString().startsWith('temp-')) { @@ -512,6 +514,7 @@ export default { /** * Get messages history. + * * @param {boolean} includeLastKnown Include or exclude the last known message in the response */ async getOldMessages(includeLastKnown) { @@ -535,6 +538,7 @@ export default { /** * Creates a long polling request for a new message. + * * @param {boolean} scrollToBottom Whether we should try to automatically scroll to the bottom */ async getNewMessages(scrollToBottom = true) { @@ -634,7 +638,7 @@ export default { * the bottom of the viewport. * * @param {object} messageEl message element after which to start searching - * @returns {object} DOM element for the last visible message + * @return {object} DOM element for the last visible message */ findFirstVisibleMessage(messageEl) { let el = messageEl @@ -789,7 +793,7 @@ export default { * @param {string} messageId message id * @param {boolean} smooth true to smooth scroll, false to jump directly * @param {boolean} highlightAnimation true to highlight and set focus to the message - * @returns {bool} true if element was found, false otherwise + * @return {bool} true if element was found, false otherwise */ focusMessage(messageId, smooth = true, highlightAnimation = true) { const element = document.getElementById(`message_${messageId}`) @@ -799,7 +803,7 @@ export default { return false } - this.$nextTick(async() => { + this.$nextTick(async () => { // FIXME: this doesn't wait for the smooth scroll to end await element.scrollIntoView({ behavior: smooth ? 'smooth' : 'auto', @@ -821,7 +825,8 @@ export default { /** * gets the last known message id. - * @returns {string} The last known message id. + * + * @return {string} The last known message id. */ getLastKnownMessageId() { let i = this.messagesList.length - 1 @@ -836,7 +841,8 @@ export default { }, /** * gets the first message's id. - * @returns {string} + * + * @return {string} */ getFirstKnownMessageId() { return this.messagesList[0].id.toString() diff --git a/src/components/NewMessageForm/AdvancedInput/AdvancedInput.vue b/src/components/NewMessageForm/AdvancedInput/AdvancedInput.vue index eae9624c5..c54995088 100644 --- a/src/components/NewMessageForm/AdvancedInput/AdvancedInput.vue +++ b/src/components/NewMessageForm/AdvancedInput/AdvancedInput.vue @@ -107,7 +107,7 @@ import debounce from 'debounce' * vue-at component or not. * * @param {CSSStyleSheet} sheet the style sheet to check. - * @returns {Boolean} True if it is the style sheet from vue-at, false + * @return {boolean} True if it is the style sheet from vue-at, false * otherwise. */ function isDefaultAtWhoStyleSheet(sheet) { @@ -281,7 +281,8 @@ export default { * The vue-at library only searches in the display name by default. * But luckily our server responds already only with matching items, * so we just filter none and show them all. - * @returns {boolean} True as we never filter anything out + * + * @return {boolean} True as we never filter anything out */ atFilter() { return true @@ -347,7 +348,7 @@ export default { * Sets the autocomplete mention candidates based on the matched text * after the "@". * - * @param {String} chunk the matched text to look candidate mentions for. + * @param {string} chunk the matched text to look candidate mentions for. */ handleAtEvent: debounce(function(chunk) { this.queryPossibleMentions(chunk) diff --git a/src/components/NewMessageForm/NewMessageForm.vue b/src/components/NewMessageForm/NewMessageForm.vue index d506e6c60..ea426b765 100644 --- a/src/components/NewMessageForm/NewMessageForm.vue +++ b/src/components/NewMessageForm/NewMessageForm.vue @@ -185,7 +185,7 @@ export default { /** * The current conversation token * - * @returns {String} + * @return {string} */ token() { return this.$store.getters.getToken() @@ -314,8 +314,8 @@ export default { * * The parsed text is also trimmed. * - * @param {String} text the raw text - * @returns {String} the parsed text + * @param {string} text the raw text + * @return {string} the parsed text */ rawToParsed(text) { text = text.replace(/<br>/g, '\n') @@ -397,7 +397,7 @@ export default { async handleFileShare() { picker.pick() - .then(async(path) => { + .then(async (path) => { console.debug(`path ${path} selected for sharing`) if (!path.startsWith('/')) { throw new Error(t('files', 'Invalid path selected')) @@ -440,7 +440,6 @@ export default { * @param {File[] | FileList} files pasted files list * @param {bool} rename whether to rename the files * @param {bool} isVoiceMessage indicates whether the file is a vooicemessage - */ async handleFiles(files, rename = false, isVoiceMessage) { // Create a unique id for the upload operation diff --git a/src/components/Quote.vue b/src/components/Quote.vue index 220181401..64ac90019 100644 --- a/src/components/Quote.vue +++ b/src/components/Quote.vue @@ -134,7 +134,8 @@ export default { computed: { /** * The message actor display name. - * @returns {string} + * + * @return {string} */ getDisplayName() { const displayName = this.actorDisplayName.trim() @@ -186,7 +187,8 @@ export default { * This is a simplified version of the last chat message. * Parameters are parsed without markup (just replaced with the name), * e.g. no avatars on mentions. - * @returns {string} A simple message to show below the conversation name + * + * @return {string} A simple message to show below the conversation name */ simpleQuotedMessage() { if (!Object.keys(this.messageParameters).length) { diff --git a/src/components/RightSidebar/Participants/CurrentParticipants/CurrentParticipants.vue b/src/components/RightSidebar/Participants/CurrentParticipants/CurrentParticipants.vue index 6e4c3d1bc..015c0295f 100644 --- a/src/components/RightSidebar/Participants/CurrentParticipants/CurrentParticipants.vue +++ b/src/components/RightSidebar/Participants/CurrentParticipants/CurrentParticipants.vue @@ -68,7 +68,7 @@ export default { /** * Gets the participants array. * - * @returns {array} + * @return {Array} */ participantsList() { let participants = this.$store.getters.participantsList(this.token) @@ -134,7 +134,7 @@ export default { * @param {string} participant2.actorType Second participant actor type * @param {string} participant2.status Second participant user status * @param {int} participant2.inCall Second participant in call flag - * @returns {number} + * @return {number} */ sortParticipants(participant1, participant2) { const p1IsGroup = participant1.actorType === ATTENDEE.ACTOR_TYPE.GROUPS diff --git a/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.spec.js b/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.spec.js index 4e72252ab..62afba853 100644 --- a/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.spec.js +++ b/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.spec.js @@ -22,6 +22,10 @@ describe('Participant.vue', () => { let testStoreConfig let tooltipMock + /** + * @param wrapper + * @param htmlEl + */ async function getLastTooltipValue(wrapper, htmlEl) { tooltipMock.mockClear() await wrapper.vm.forceEnableTooltips() @@ -76,6 +80,10 @@ describe('Participant.vue', () => { jest.clearAllMocks() }) + /** + * @param participant + * @param showUserStatus + */ function mountParticipant(participant, showUserStatus = false) { return shallowMount(Participant, { localVue, @@ -173,6 +181,9 @@ describe('Participant.vue', () => { }) describe('user name', () => { + /** + * @param wrapper + */ async function getUserTooltip(wrapper) { const tooltipEl = wrapper.find('.participant-row__user-name').element return getLastTooltipValue(wrapper, tooltipEl) @@ -183,34 +194,34 @@ describe('Participant.vue', () => { participant.statusMessage = '' }) - test('renders plain user name for regular user', async() => { + test('renders plain user name for regular user', async () => { const wrapper = mountParticipant(participant) expect(wrapper.text()).toBe('Alice') expect(await getUserTooltip(wrapper)).toBe('Alice') }) - test('renders guest suffix for guests', async() => { + test('renders guest suffix for guests', async () => { participant.participantType = PARTICIPANT.TYPE.GUEST const wrapper = mountParticipant(participant) expect(wrapper.text()).toStrictEqual(expect.stringMatching(/^Alice\s+\(guest\)$/)) expect(await getUserTooltip(wrapper)).toBe('Alice (guest)') }) - test('renders moderator suffix for moderators', async() => { + test('renders moderator suffix for moderators', async () => { participant.participantType = PARTICIPANT.TYPE.MODERATOR const wrapper = mountParticipant(participant) expect(wrapper.text()).toStrictEqual(expect.stringMatching(/^Alice\s+\(moderator\)$/)) expect(await getUserTooltip(wrapper)).toBe('Alice (moderator)') }) - test('renders guest moderator suffix for guest moderators', async() => { + test('renders guest moderator suffix for guest moderators', async () => { participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR const wrapper = mountParticipant(participant) expect(wrapper.text()).toStrictEqual(expect.stringMatching(/^Alice\s+\(moderator\)\s+\(guest\)$/)) expect(await getUserTooltip(wrapper)).toBe('Alice (moderator) (guest)') }) - test('renders bot suffix for bots', async() => { + test('renders bot suffix for bots', async () => { participant.actorType = ATTENDEE.ACTOR_TYPE.USERS participant.actorId = ATTENDEE.BRIDGE_BOT_ID const wrapper = mountParticipant(participant) @@ -220,12 +231,15 @@ describe('Participant.vue', () => { }) describe('user status', () => { + /** + * @param wrapper + */ async function getStatusTooltip(wrapper) { const tooltipEl = wrapper.find('.participant-row__status>span').element return getLastTooltipValue(wrapper, tooltipEl) } - test('renders user status', async() => { + test('renders user status', async () => { const wrapper = mountParticipant(participant) expect(wrapper.find('.participant-row__status').text()).toBe('🌧️ rainy') expect(await getStatusTooltip(wrapper)).toBe('🌧️ rainy') @@ -238,7 +252,7 @@ describe('Participant.vue', () => { expect(wrapper.find('.participant-row__status').exists()).toBe(false) }) - test('renders dnd status', async() => { + test('renders dnd status', async () => { participant.statusMessage = '' participant.status = 'dnd' const wrapper = mountParticipant(participant) @@ -246,7 +260,7 @@ describe('Participant.vue', () => { expect(await getStatusTooltip(wrapper)).toBe('🌧️ Do not disturb') }) - test('renders away status', async() => { + test('renders away status', async () => { participant.statusMessage = '' participant.status = 'away' const wrapper = mountParticipant(participant) @@ -258,6 +272,9 @@ describe('Participant.vue', () => { describe('call icons', () => { let getParticipantRaisedHandMock + /** + * @param wrapper + */ async function getCallIconTooltip(wrapper) { const tooltipEl = wrapper.find('.participant-row__callstate-icon').element return getLastTooltipValue(wrapper, tooltipEl) @@ -278,7 +295,7 @@ describe('Participant.vue', () => { expect(wrapper.findComponent(Microphone).exists()).toBe(false) expect(wrapper.findComponent(Hand).exists()).toBe(false) }) - test('renders video call icon', async() => { + test('renders video call icon', async () => { participant.inCall = PARTICIPANT.CALL_FLAG.WITH_VIDEO const wrapper = mountParticipant(participant) expect(wrapper.findComponent(Video).exists()).toBe(true) @@ -288,7 +305,7 @@ describe('Participant.vue', () => { expect(await getCallIconTooltip(wrapper)).toBe('Joined with video') }) - test('renders audio call icon', async() => { + test('renders audio call icon', async () => { participant.inCall = PARTICIPANT.CALL_FLAG.WITH_AUDIO const wrapper = mountParticipant(participant) expect(wrapper.findComponent(Video).exists()).toBe(false) @@ -298,7 +315,7 @@ describe('Participant.vue', () => { expect(await getCallIconTooltip(wrapper)).toBe('Joined with audio') }) - test('renders phone call icon', async() => { + test('renders phone call icon', async () => { participant.inCall = PARTICIPANT.CALL_FLAG.WITH_PHONE const wrapper = mountParticipant(participant) expect(wrapper.findComponent(Video).exists()).toBe(false) @@ -308,7 +325,7 @@ describe('Participant.vue', () => { expect(await getCallIconTooltip(wrapper)).toBe('Joined via phone') }) - test('renders hand raised icon', async() => { + test('renders hand raised icon', async () => { participant.inCall = PARTICIPANT.CALL_FLAG.WITH_VIDEO getParticipantRaisedHandMock = jest.fn().mockReturnValue({ state: true }) @@ -322,7 +339,7 @@ describe('Participant.vue', () => { expect(await getCallIconTooltip(wrapper)).toBe('Raised their hand') }) - test('renders video call icon when joined with multiple', async() => { + test('renders video call icon when joined with multiple', async () => { participant.inCall = PARTICIPANT.CALL_FLAG.WITH_VIDEO | PARTICIPANT.CALL_FLAG.WITH_PHONE const wrapper = mountParticipant(participant) expect(wrapper.findComponent(Video).exists()).toBe(true) @@ -365,6 +382,9 @@ describe('Participant.vue', () => { store = new Vuex.Store(testStoreConfig) }) + /** + * + */ async function testCanDemote() { const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Demote from moderator') @@ -378,49 +398,52 @@ describe('Participant.vue', () => { }) } + /** + * + */ async function testCannotDemote() { const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Demote to moderator') expect(actionButton.exists()).toBe(false) } - test('allows a moderator to demote a moderator', async() => { + test('allows a moderator to demote a moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.MODERATOR await testCanDemote() }) - test('allows a moderator to demote a guest moderator', async() => { + test('allows a moderator to demote a guest moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR await testCanDemote() }) - test('allows a guest moderator to demote a moderator', async() => { + test('allows a guest moderator to demote a moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR participant.participantType = PARTICIPANT.TYPE.MODERATOR await testCanDemote() }) - test('allows a guest moderator to demote a guest moderator', async() => { + test('allows a guest moderator to demote a guest moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR await testCanDemote() }) - test('does not allow to demote an owner', async() => { + test('does not allow to demote an owner', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.OWNER await testCannotDemote() }) - test('does not allow demoting groups', async() => { + test('does not allow demoting groups', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.actorType = ATTENDEE.ACTOR_TYPE.GROUPS await testCannotDemote() }) - test('does not allow demoting self', async() => { + test('does not allow demoting self', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR conversation.sessionId = 'current-session-id' participant.participantType = PARTICIPANT.TYPE.MODERATOR @@ -428,7 +451,7 @@ describe('Participant.vue', () => { await testCannotDemote() }) - test('does not allow demoting self as guest', async() => { + test('does not allow demoting self as guest', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR conversation.sessionId = 'current-session-id' participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR @@ -436,7 +459,7 @@ describe('Participant.vue', () => { await testCannotDemote() }) - test('does not allow a non-moderator to demote', async() => { + test('does not allow a non-moderator to demote', async () => { conversation.participantType = PARTICIPANT.TYPE.USER await testCannotDemote() }) @@ -451,6 +474,9 @@ describe('Participant.vue', () => { store = new Vuex.Store(testStoreConfig) }) + /** + * + */ async function testCanPromote() { const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Promote to moderator') @@ -464,66 +490,69 @@ describe('Participant.vue', () => { }) } + /** + * + */ async function testCannotPromote() { const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Promote to moderator') expect(actionButton.exists()).toBe(false) } - test('allows a moderator to promote a user to moderator', async() => { + test('allows a moderator to promote a user to moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR await testCanPromote() }) - test('allows a moderator to promote a self-joined user to moderator', async() => { + test('allows a moderator to promote a self-joined user to moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.USER_SELF_JOINED await testCanPromote() }) - test('allows a moderator to promote a guest to moderator', async() => { + test('allows a moderator to promote a guest to moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST await testCanPromote() }) - test('allows a guest moderator to promote a user to moderator', async() => { + test('allows a guest moderator to promote a user to moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR await testCanPromote() }) - test('allows a guest moderator to promote a guest to moderator', async() => { + test('allows a guest moderator to promote a guest to moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST await testCanPromote() }) - test('does not allow to promote a moderator', async() => { + test('does not allow to promote a moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.MODERATOR await testCannotPromote() }) - test('does not allow to promote a guest moderator', async() => { + test('does not allow to promote a guest moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR await testCannotPromote() }) - test('does not allow promoting groups', async() => { + test('does not allow promoting groups', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.actorType = ATTENDEE.ACTOR_TYPE.GROUPS await testCannotPromote() }) - test('does not allow promoting the bridge bot', async() => { + test('does not allow promoting the bridge bot', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.actorType = ATTENDEE.ACTOR_TYPE.USERS participant.actorId = ATTENDEE.BRIDGE_BOT_ID await testCannotPromote() }) - test('does not allow a non-moderator to promote', async() => { + test('does not allow a non-moderator to promote', async () => { conversation.participantType = PARTICIPANT.TYPE.USER await testCannotPromote() }) @@ -538,7 +567,7 @@ describe('Participant.vue', () => { store = new Vuex.Store(testStoreConfig) }) - test('allows moderators to resend invitations for email participants', async() => { + test('allows moderators to resend invitations for email participants', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.actorType = ATTENDEE.ACTOR_TYPE.EMAILS const wrapper = mountParticipant(participant) @@ -553,14 +582,14 @@ describe('Participant.vue', () => { }) }) - test('does not allow non-moderators to resend invitations', async() => { + test('does not allow non-moderators to resend invitations', async () => { participant.actorType = ATTENDEE.ACTOR_TYPE.EMAILS const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Resend invitation') expect(actionButton.exists()).toBe(false) }) - test('does not display resend invitations action when not an email actor', async() => { + test('does not display resend invitations action when not an email actor', async () => { participant.actorType = ATTENDEE.ACTOR_TYPE.USERS const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Resend invitation') @@ -577,6 +606,9 @@ describe('Participant.vue', () => { store = new Vuex.Store(testStoreConfig) }) + /** + * @param buttonText + */ async function testCanRemove(buttonText = 'Remove participant') { const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, buttonText) @@ -590,49 +622,52 @@ describe('Participant.vue', () => { }) } + /** + * + */ async function testCannotRemove() { const wrapper = mountParticipant(participant) const actionButton = findActionButton(wrapper, 'Remove participant') expect(actionButton.exists()).toBe(false) } - test('allows a moderator to remove a moderator', async() => { + test('allows a moderator to remove a moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.MODERATOR await testCanRemove() }) - test('allows a moderator to remove a guest moderator', async() => { + test('allows a moderator to remove a guest moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR await testCanRemove() }) - test('allows a guest moderator to remove a moderator', async() => { + test('allows a guest moderator to remove a moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR participant.participantType = PARTICIPANT.TYPE.MODERATOR await testCanRemove() }) - test('allows a guest moderator to remove a guest moderator', async() => { + test('allows a guest moderator to remove a guest moderator', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR await testCanRemove() }) - test('allows a moderator to remove groups', async() => { + test('allows a moderator to remove groups', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.actorType = ATTENDEE.ACTOR_TYPE.GROUPS await testCanRemove('Remove group and members') }) - test('does not allow to remove an owner', async() => { + test('does not allow to remove an owner', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR participant.participantType = PARTICIPANT.TYPE.OWNER await testCannotRemove() }) - test('does not allow removing self', async() => { + test('does not allow removing self', async () => { conversation.participantType = PARTICIPANT.TYPE.MODERATOR conversation.sessionId = 'current-session-id' participant.participantType = PARTICIPANT.TYPE.MODERATOR @@ -640,7 +675,7 @@ describe('Participant.vue', () => { await testCannotRemove() }) - test('does not allow removing self as guest', async() => { + test('does not allow removing self as guest', async () => { conversation.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR conversation.sessionId = 'current-session-id' participant.participantType = PARTICIPANT.TYPE.GUEST_MODERATOR @@ -648,12 +683,15 @@ describe('Participant.vue', () => { await testCannotRemove() }) - test('does not allow a non-moderator to remove', async() => { + test('does not allow a non-moderator to remove', async () => { conversation.participantType = PARTICIPANT.TYPE.USER await testCannotRemove() }) }) describe('dial-in PIN', () => { + /** + * + */ function testPinVisible() { const wrapper = mountParticipant(participant) let actionTexts = wrapper.findAllComponents(ActionText) @@ -716,7 +754,7 @@ describe('Participant.vue', () => { expect(wrapper.findAllComponents(ActionButton).exists()).toBe(false) }) - test('triggers event when clicking', async() => { + test('triggers event when clicking', async () => { const eventHandler = jest.fn() const wrapper = mountParticipant(participant) wrapper.vm.$on('clickParticipant', eventHandler) @@ -726,7 +764,7 @@ describe('Participant.vue', () => { expect(eventHandler).toHaveBeenCalledWith(participant) }) - test('does not trigger click event when not a search result', async() => { + test('does not trigger click event when not a search result', async () => { const eventHandler = jest.fn() delete participant.label delete participant.source diff --git a/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.vue b/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.vue index 17c5ba7e4..cb3b5a5ce 100644 --- a/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.vue +++ b/src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.vue @@ -256,7 +256,8 @@ export default { /** * Check if the current participant belongs to the selected participants array * in the store - * @returns {boolean} + * + * @return {boolean} */ isSelected() { if (this.isSelectable) { @@ -274,7 +275,8 @@ export default { * If the Participant component is used as to display a search result, it will * return true. We use this not to display actions on the searched contacts and * groups. - * @returns {boolean} + * + * @return {boolean} */ isSearched() { return this.participant.label !== undefined diff --git a/src/components/RightSidebar/Participants/ParticipantsSearchResults/ParticipantsSearchResults.vue b/src/components/RightSidebar/Participants/ParticipantsSearchResults/ParticipantsSearchResults.vue index be50fff23..d2dd08cad 100644 --- a/src/components/RightSidebar/Participants/ParticipantsSearchResults/ParticipantsSearchResults.vue +++ b/src/components/RightSidebar/Participants/ParticipantsSearchResults/ParticipantsSearchResults.vue @@ -131,7 +131,8 @@ export default { type: Boolean, default: false, }, - /** If so, this component will add clicked participant to the selected + /** + * If so, this component will add clicked participant to the selected * participants store; */ selectable: { diff --git a/src/components/RightSidebar/Participants/ParticipantsTab.vue b/src/components/RightSidebar/Participants/ParticipantsTab.vue index c7008820d..18a7f2727 100644 --- a/src/components/RightSidebar/Participants/ParticipantsTab.vue +++ b/src/components/RightSidebar/Participants/ParticipantsTab.vue @@ -234,7 +234,8 @@ export default { /** * Add the selected group/user/circle to the conversation - * @param {Object} item The autocomplete suggestion to start a conversation with + * + * @param {object} item The autocomplete suggestion to start a conversation with * @param {string} item.id The ID of the target * @param {string} item.source The source of the target */ diff --git a/src/components/RightSidebar/RightSidebar.vue b/src/components/RightSidebar/RightSidebar.vue index 0749560e8..40578d833 100644 --- a/src/components/RightSidebar/RightSidebar.vue +++ b/src/components/RightSidebar/RightSidebar.vue @@ -184,7 +184,8 @@ export default { /** * The conversation title value passed into the AppSidebar component. - * @returns {string} The conversation's title. + * + * @return {string} The conversation's title. */ title() { if (this.isRenamingConversation) { @@ -244,6 +245,7 @@ export default { /** * Updates the conversationName value while editing the conversation's title. + * * @param {string} title the conversation title emitted by the AppSidevar vue * component. */ diff --git a/src/components/SettingsDialog/SettingsDialog.vue b/src/components/SettingsDialog/SettingsDialog.vue index 73936f0fd..38ef02535 100644 --- a/src/components/SettingsDialog/SettingsDialog.vue +++ b/src/components/SettingsDialog/SettingsDialog.vue @@ -196,7 +196,7 @@ export default { .startAt(this.attachmentFolder) .build() picker.pick() - .then(async(path) => { + .then(async (path) => { console.debug(`Path '${path}' selected for talk attachments`) if (path !== '' && !path.startsWith('/')) { throw new Error(t('spreed', 'Invalid path selected')) |