diff --git a/src/services/pollService.js b/src/services/pollService.js deleted file mode 100644 index d4f2dc9f74a..00000000000 --- a/src/services/pollService.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ -import axios from '@nextcloud/axios' -import { generateOcsUrl } from '@nextcloud/router' - -const pollService = { - // For API documentation see https://nextcloud-talk.readthedocs.io/en/latest/poll/ - - /** - * - * @param {string} token The conversation token - * @param {string} question The question of the polln - * @param {Array} options The options participants can vote for - * @param {number} resultMode Result mode of the poll - * @param {number} maxVotes Maximum amount of options a user can vote for, 0 means unlimited - * @return {object} The poll object - */ - async postNewPoll(token, question, options, resultMode, maxVotes) { - return axios.post(generateOcsUrl('apps/spreed/api/v1/poll/{token}', { token }), { - question, - options, - resultMode, - maxVotes, - }) - }, - - /** - * - * @param {string} token The conversation token - * @param {number} pollId ID of the poll - * @return {object} The poll object - */ - async getPollData(token, pollId) { - return axios.get(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId })) - }, - - /** - * Submit poll vote - * - * @param {string} token The conversation token - * @param {number} pollId ID of the poll - * @param {Array} optionIds The option IDs the participant wants to vote for - * @return {object} The poll object - */ - async submitVote(token, pollId, optionIds) { - return axios.post(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId }), { - optionIds, - }) - }, - - /** - * Ends the poll - * - * @param {string} token The conversation token - * @param {number} pollId ID of the poll - * @return {object} The poll object - */ - async endPoll(token, pollId) { - return axios.delete(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId })) - }, -} - -export default pollService diff --git a/src/services/pollService.ts b/src/services/pollService.ts new file mode 100644 index 00000000000..425485ba53b --- /dev/null +++ b/src/services/pollService.ts @@ -0,0 +1,69 @@ +/** + * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import axios from '@nextcloud/axios' +import { generateOcsUrl } from '@nextcloud/router' + +import type { + closePollResponse, + createPollParams, + createPollResponse, + getPollResponse, + votePollParams, + votePollResponse, +} from '../types/index.ts' + +type createPollPayload = { token: string } & createPollParams + +/** + * @param payload The payload + * @param payload.token The conversation token + * @param payload.question The question of the poll + * @param payload.options The options participants can vote for + * @param payload.resultMode Result mode of the poll (0 - always visible | 1 - hidden until the poll is closed) + * @param payload.maxVotes Maximum amount of options a user can vote for (0 - unlimited | 1 - single answer) + */ +const createPoll = async ({ token, question, options, resultMode, maxVotes }: createPollPayload): createPollResponse => { + return axios.post(generateOcsUrl('apps/spreed/api/v1/poll/{token}', { token }), { + question, + options, + resultMode, + maxVotes, + } as createPollParams) +} + +/** + * @param token The conversation token + * @param pollId Id of the poll + */ +const getPollData = async (token: string, pollId: number): getPollResponse => { + return axios.get(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId })) +} + +/** + * @param token The conversation token + * @param pollId Id of the poll + * @param optionIds Indexes of options the participant votes for + */ +const submitVote = async (token: string, pollId: number, optionIds: votePollParams['optionIds']): votePollResponse => { + return axios.post(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId }), { + optionIds, + } as votePollParams) +} + +/** + * @param token The conversation token + * @param pollId Id of the poll + */ +const endPoll = async (token: string, pollId: number): closePollResponse => { + return axios.delete(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId })) +} + +export { + createPoll, + getPollData, + submitVote, + endPoll, +} diff --git a/src/stores/__tests__/polls.spec.js b/src/stores/__tests__/polls.spec.js index 62a9f94bad2..d44de007014 100644 --- a/src/stores/__tests__/polls.spec.js +++ b/src/stores/__tests__/polls.spec.js @@ -6,12 +6,17 @@ import flushPromises from 'flush-promises' import { setActivePinia, createPinia } from 'pinia' import { ATTENDEE } from '../../constants.js' -import pollService from '../../services/pollService.js' +import { + createPoll, + getPollData, + submitVote, + endPoll, +} from '../../services/pollService.ts' import { generateOCSResponse } from '../../test-helpers.js' import { usePollsStore } from '../polls.js' -jest.mock('../../services/pollService.js', () => ({ - postNewPoll: jest.fn(), +jest.mock('../../services/pollService', () => ({ + createPoll: jest.fn(), getPollData: jest.fn(), submitVote: jest.fn(), endPoll: jest.fn(), @@ -88,7 +93,7 @@ describe('pollsStore', () => { it('receives a poll from server and adds it to the store', async () => { // Arrange const response = generateOCSResponse({ payload: poll }) - pollService.getPollData.mockResolvedValue(response) + getPollData.mockResolvedValue(response) // Act await pollsStore.getPollData({ token: TOKEN, pollId: poll.id }) @@ -101,7 +106,7 @@ describe('pollsStore', () => { // Arrange jest.useFakeTimers() const response = generateOCSResponse({ payload: poll }) - pollService.getPollData.mockResolvedValue(response) + getPollData.mockResolvedValue(response) // Act pollsStore.debounceGetPollData({ token: TOKEN, pollId: poll.id }) @@ -116,7 +121,7 @@ describe('pollsStore', () => { it('creates a poll and adds it to the store', async () => { // Arrange const response = generateOCSResponse({ payload: poll }) - pollService.postNewPoll.mockResolvedValue(response) + createPoll.mockResolvedValue(response) // Act await pollsStore.createPoll({ token: TOKEN, ...pollRequest }) @@ -129,7 +134,7 @@ describe('pollsStore', () => { // Arrange pollsStore.addPoll({ token: TOKEN, poll }) const response = generateOCSResponse({ payload: pollWithVote }) - pollService.submitVote.mockResolvedValue(response) + submitVote.mockResolvedValue(response) // Act await pollsStore.submitVote({ token: TOKEN, pollId: poll.id, optionIds: [0] }) @@ -142,7 +147,7 @@ describe('pollsStore', () => { // Arrange pollsStore.addPoll({ token: TOKEN, poll: pollWithVote }) const response = generateOCSResponse({ payload: pollWithVoteEnded }) - pollService.endPoll.mockResolvedValue(response) + endPoll.mockResolvedValue(response) // Act await pollsStore.endPoll({ token: TOKEN, pollId: poll.id }) diff --git a/src/stores/polls.js b/src/stores/polls.js index 83302c898b0..3592b822e77 100644 --- a/src/stores/polls.js +++ b/src/stores/polls.js @@ -9,7 +9,12 @@ import Vue from 'vue' import { showError, showInfo, TOAST_PERMANENT_TIMEOUT } from '@nextcloud/dialogs' import { t } from '@nextcloud/l10n' -import pollService from '../services/pollService.js' +import { + createPoll, + getPollData, + submitVote, + endPoll, +} from '../services/pollService.ts' export const usePollsStore = defineStore('polls', { state: () => ({ @@ -39,7 +44,7 @@ export const usePollsStore = defineStore('polls', { async getPollData({ token, pollId }) { try { - const response = await pollService.getPollData(token, pollId) + const response = await getPollData(token, pollId) this.addPoll({ token, poll: response.data.ocs.data }) } catch (error) { console.error(error) @@ -72,13 +77,13 @@ export const usePollsStore = defineStore('polls', { async createPoll({ token, question, options, resultMode, maxVotes }) { try { - const response = await pollService.postNewPoll( + const response = await createPoll({ token, question, options, resultMode, maxVotes, - ) + }) this.addPoll({ token, poll: response.data.ocs.data }) return response.data.ocs.data @@ -89,7 +94,7 @@ export const usePollsStore = defineStore('polls', { async submitVote({ token, pollId, optionIds }) { try { - const response = await pollService.submitVote(token, pollId, optionIds) + const response = await submitVote(token, pollId, optionIds) this.addPoll({ token, poll: response.data.ocs.data }) } catch (error) { console.error(error) @@ -99,7 +104,7 @@ export const usePollsStore = defineStore('polls', { async endPoll({ token, pollId }) { try { - const response = await pollService.endPoll(token, pollId) + const response = await endPoll(token, pollId) this.addPoll({ token, poll: response.data.ocs.data }) } catch (error) { console.error(error) diff --git a/src/types/index.ts b/src/types/index.ts index d9b706301a8..86d22a1c251 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -160,3 +160,13 @@ export type requestAssistanceResponse = ApiResponse export type switchToBreakoutRoomParams = operations['breakout_room-switch-breakout-room']['requestBody']['content']['application/json'] export type switchToBreakoutRoomResponse = ApiResponse + +// Polls +export type Poll = components['schemas']['Poll'] + +export type getPollResponse = ApiResponse +export type createPollParams = operations['poll-create-poll']['requestBody']['content']['application/json'] +export type createPollResponse = ApiResponse +export type votePollParams = Required['requestBody']['content']['application/json'] +export type votePollResponse = ApiResponse +export type closePollResponse = ApiResponse