diff options
author | Joas Schilling <coding@schilljs.com> | 2022-05-31 16:32:06 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2022-06-13 13:52:59 +0300 |
commit | d3bad8f60474712d58e012480883b31806139754 (patch) | |
tree | b9011d1b5f1778a703bac051b1448482d22dd338 | |
parent | e850664c9aa5532e948ae3399a2a26effde0e09d (diff) |
Hide summary also until the actor voted
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r-- | docs/poll.md | 37 | ||||
-rw-r--r-- | lib/Controller/PollController.php | 18 | ||||
-rw-r--r-- | tests/integration/features/bootstrap/FeatureContext.php | 10 | ||||
-rw-r--r-- | tests/integration/features/chat/poll.feature | 41 |
4 files changed, 75 insertions, 31 deletions
diff --git a/docs/poll.md b/docs/poll.md index 73f78f396..eeacdcc16 100644 --- a/docs/poll.md +++ b/docs/poll.md @@ -88,16 +88,27 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1` ## Poll data -| field | type | Description | -|--------------------|----------|-------------------------------------------------------------------------------------------------| -| `id` | int | ID of the poll | -| `question` | string | The question of the poll | -| `options` | string[] | The options participants can vote for | -| `votes` | int[] | Map with optionId => number of votes (empty if the resultMode is hidden and the statue is open) | -| `actorType` | string | Actor type of the poll author (see [Constants - Attendee types](constants.md#attendee-types)) | -| `actorId` | string | Actor ID identifying the poll author | -| `actorDisplayName` | string | Display name of the poll author | -| `status` | int | Status of the poll (see [Constants - Poll status](constants.md#poll-status)) | -| `resultMode` | int | Result mode of the poll (see [Constants - Poll mode](constants.md#poll-mode)) | -| `maxVotes` | int | Maximum amount of options a user can vote for, `0` means unlimited | -| `votedSelf` | int[] | Array of option ids the participant voted for | +| field | type | Description | +|--------------------|----------|------------------------------------------------------------------------------------------------------------------| +| `id` | int | ID of the poll | +| `question` | string | The question of the poll | +| `options` | string[] | The options participants can vote for | +| `votes` | int[] | Map with optionId => number of votes (only available for when the actor voted on public poll or the poll is closed) | +| `actorType` | string | Actor type of the poll author (see [Constants - Attendee types](constants.md#attendee-types)) | +| `actorId` | string | Actor ID identifying the poll author | +| `actorDisplayName` | string | Display name of the poll author | +| `status` | int | Status of the poll (see [Constants - Poll status](constants.md#poll-status)) | +| `resultMode` | int | Result mode of the poll (see [Constants - Poll mode](constants.md#poll-mode)) | +| `maxVotes` | int | Maximum amount of options a user can vote for, `0` means unlimited | +| `votedSelf` | int[] | Array of option ids the participant voted for | +| `numVoters` | int | The number of unique voters that (only available for when the actor voted on public poll or the poll is closed) | +| `details` | array[] | Detailed list who voted for which option (only available for public closed polls), see [Details](#details) below | + +### Details + +| field | type | Description | +|------------------|--------|--------------------------------------------------------------------------------------------------------------| +| actorType | string | The actor type of the participant that voted (see [Constants - Attendee types](constants.md#attendee-types)) | +| actorId | string | The actor id of the participant that voted | +| actorDisplayName | string | The display name of the participant that voted | +| optionId | int | The option that was voted for | diff --git a/lib/Controller/PollController.php b/lib/Controller/PollController.php index 759a92aa7..07f8fa893 100644 --- a/lib/Controller/PollController.php +++ b/lib/Controller/PollController.php @@ -117,10 +117,9 @@ class PollController extends AEnvironmentAwareController { * @RequireModeratorOrNoLobby * * @param int $pollId - * @param bool $details * @return DataResponse */ - public function showPoll(int $pollId, bool $details = false): DataResponse { + public function showPoll(int $pollId): DataResponse { try { $poll = $this->pollService->getPoll($this->room->getId(), $pollId); } catch (DoesNotExistException $e) { @@ -129,7 +128,7 @@ class PollController extends AEnvironmentAwareController { $votedSelf = $this->pollService->getVotesForActor($this->participant, $poll); $detailedVotes = []; - if ($details && ($poll->getResultMode() === Poll::MODE_PUBLIC || $poll->getStatus() === Poll::STATUS_CLOSED)) { + if ($poll->getResultMode() === Poll::MODE_PUBLIC && $poll->getStatus() === Poll::STATUS_CLOSED) { $detailedVotes = $this->pollService->getVotes($poll); } @@ -187,19 +186,26 @@ class PollController extends AEnvironmentAwareController { return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } + $detailedVotes = []; + if ($poll->getResultMode() === Poll::MODE_PUBLIC) { + $detailedVotes = $this->pollService->getVotes($poll); + } + $votedSelf = $this->pollService->getVotesForActor($this->participant, $poll); - return new DataResponse($this->renderPoll($poll, $votedSelf)); + return new DataResponse($this->renderPoll($poll, $votedSelf, $detailedVotes)); } protected function renderPoll(Poll $poll, array $votedSelf = [], array $detailedVotes = []): array { $data = $poll->asArray(); unset($data['roomId']); - if ($poll->getResultMode() === Poll::MODE_HIDDEN && $poll->getStatus() === Poll::STATUS_OPEN) { + $canSeeSummary = !empty($votedSelf) && $poll->getResultMode() === Poll::MODE_PUBLIC; + + if (!$canSeeSummary && $poll->getStatus() === Poll::STATUS_OPEN) { $data['votes'] = []; $data['numVoters'] = 0; - } elseif (!empty($detailedVotes)) { + } elseif ($poll->getResultMode() === Poll::MODE_PUBLIC && $poll->getStatus() === Poll::STATUS_CLOSED) { $data['details'] = array_map(static fn (Vote $vote) => $vote->asArray(), $detailedVotes); } diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index afcffd486..c20cc2be7 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -1554,22 +1554,19 @@ class FeatureContext implements Context, SnippetAcceptingContext { } /** - * @Then /^user "([^"]*)" sees (poll details|poll) "([^"]*)" in room "([^"]*)" with (\d+)(?: \((v1)\))?$/ + * @Then /^user "([^"]*)" sees poll "([^"]*)" in room "([^"]*)" with (\d+)(?: \((v1)\))?$/ * * @param string $user - * @param string $details * @param string $question * @param string $identifier * @param string $statusCode * @param string $apiVersion * @param ?TableNode $formData */ - public function userSeesPollInRoom($user, $details, $question, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) { + public function userSeesPollInRoom($user, $question, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) { $this->setCurrentUser($user); - $query = $details === 'poll details' ? '?details=1' : ''; - - $this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/poll/' . self::$identifierToToken[$identifier] . '/' . self::$questionToPollId[$question] . $query); + $this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/poll/' . self::$identifierToToken[$identifier] . '/' . self::$questionToPollId[$question]); $this->assertStatusCode($this->response, $statusCode); $expected = $this->preparePollExpectedData($formData->getRowsHash()); @@ -1671,6 +1668,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { if (isset($expected['details'])) { $expected['details'] = json_decode($expected['details'], true); } + $expected['numVoters'] = (int) $expected['numVoters']; $expected['options'] = json_decode($expected['options'], true); $result = preg_match('/POLL_ID\(([^)]+)\)/', $expected['id'], $matches); diff --git a/tests/integration/features/chat/poll.feature b/tests/integration/features/chat/poll.feature index 98bef99f0..0aa4f7b48 100644 --- a/tests/integration/features/chat/poll.feature +++ b/tests/integration/features/chat/poll.feature @@ -34,7 +34,7 @@ Feature: chat/poll | question | What is the question? | | options | ["Where are you?","How much is the fish?"] | | votes | {"1":1} | - | numVoters | 1 | + | numVoters | 1 | | resultMode | public | | maxVotes | unlimited | | actorType | users | @@ -42,13 +42,25 @@ Feature: chat/poll | actorDisplayName | participant1-displayname | | status | open | | votedSelf | [1] | - Then user "participant2" sees poll details "What is the question?" in room "room" with 200 + Then user "participant1" sees poll "What is the question?" in room "room" with 200 | id | POLL_ID(What is the question?) | | question | What is the question? | | options | ["Where are you?","How much is the fish?"] | | votes | {"1":1} | - | numVoters | 1 | - | details | [{"actorType":"users","actorId":"participant1","actorDisplayName":"participant1-displayname","optionId":1}] | + | numVoters | 1 | + | resultMode | public | + | maxVotes | unlimited | + | actorType | users | + | actorId | participant1 | + | actorDisplayName | participant1-displayname | + | status | open | + | votedSelf | [1] | + Then user "participant2" sees poll "What is the question?" in room "room" with 200 + | id | POLL_ID(What is the question?) | + | question | What is the question? | + | options | ["Where are you?","How much is the fish?"] | + | votes | [] | + | numVoters | 0 | | resultMode | public | | maxVotes | unlimited | | actorType | users | @@ -69,6 +81,21 @@ Feature: chat/poll | actorDisplayName | participant1-displayname | | status | closed | | votedSelf | [1] | + | details | [{"actorType":"users","actorId":"participant1","actorDisplayName":"participant1-displayname","optionId":1}] | + Then user "participant2" sees poll "What is the question?" in room "room" with 200 + | id | POLL_ID(What is the question?) | + | question | What is the question? | + | options | ["Where are you?","How much is the fish?"] | + | votes | {"1":1} | + | numVoters | 1 | + | resultMode | public | + | maxVotes | unlimited | + | actorType | users | + | actorId | participant1 | + | actorDisplayName | participant1-displayname | + | status | closed | + | votedSelf | not voted | + | details | [{"actorType":"users","actorId":"participant1","actorDisplayName":"participant1-displayname","optionId":1}] | Scenario: Participants can update their votes Given user "participant1" creates room "room" (v4) @@ -189,6 +216,7 @@ Feature: chat/poll | actorDisplayName | participant2-displayname | | status | closed | | votedSelf | not voted | + | details | {} | Scenario: Non-moderators can note create polls without chat permission Given user "participant1" creates room "room" (v4) @@ -226,6 +254,7 @@ Feature: chat/poll | actorDisplayName | participant2-displayname | | status | closed | | votedSelf | not voted | + | details | {} | Scenario: Non-moderators can not close polls of others Given user "participant1" creates room "room" (v4) @@ -278,7 +307,7 @@ Feature: chat/poll | actorDisplayName | participant1-displayname | | status | open | | votedSelf | not voted | - Then user "participant1" sees poll details "What is the question?" in room "room" with 200 + Then user "participant2" sees poll "What is the question?" in room "room" with 200 | id | POLL_ID(What is the question?) | | question | What is the question? | | options | ["Where are you?","How much is the fish?"] | @@ -290,7 +319,7 @@ Feature: chat/poll | actorId | participant1 | | actorDisplayName | participant1-displayname | | status | open | - | votedSelf | not voted | + | votedSelf | [1] | Then user "participant1" closes poll "What is the question?" in room "room" with 200 | id | POLL_ID(What is the question?) | | question | What is the question? | |