summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2022-12-07 14:55:48 +0100
committerJoas Schilling <coding@schilljs.com>2022-12-12 12:08:24 +0100
commitd390d3bec3b0efddf580a4e45c527430b1c4c830 (patch)
tree8535347d3f0f46cadf76119d99c017f60cdf2abc
parenta0d6794ebe12949dd32c55decaf2997cbf7c74ae (diff)
Allow to "Request assistance" and reset it
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--appinfo/routes/routesBreakoutRoomController.php4
-rw-r--r--docs/breakout-rooms.md24
-rw-r--r--lib/Controller/BreakoutRoomController.php33
-rw-r--r--lib/Model/BreakoutRoom.php2
-rw-r--r--lib/Service/BreakoutRoomService.php19
-rw-r--r--lib/Service/RoomService.php2
-rw-r--r--tests/integration/features/bootstrap/FeatureContext.php19
-rw-r--r--tests/integration/features/conversation/breakout-rooms.feature40
8 files changed, 143 insertions, 0 deletions
diff --git a/appinfo/routes/routesBreakoutRoomController.php b/appinfo/routes/routesBreakoutRoomController.php
index 802e6711d..ff912f29a 100644
--- a/appinfo/routes/routesBreakoutRoomController.php
+++ b/appinfo/routes/routesBreakoutRoomController.php
@@ -36,6 +36,10 @@ return [
['name' => 'BreakoutRoom#removeBreakoutRooms', 'url' => '/api/{apiVersion}/breakout-rooms/{token}', 'verb' => 'DELETE', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\BreakoutRoomController::broadcastChatMessage() */
['name' => 'BreakoutRoom#broadcastChatMessage', 'url' => '/api/{apiVersion}/breakout-rooms/{token}/broadcast', 'verb' => 'POST', 'requirements' => $requirements],
+ /** @see \OCA\Talk\Controller\BreakoutRoomController::requestAssistance() */
+ ['name' => 'BreakoutRoom#requestAssistance', 'url' => '/api/{apiVersion}/breakout-rooms/{token}/request-assistance', 'verb' => 'POST', 'requirements' => $requirements],
+ /** @see \OCA\Talk\Controller\BreakoutRoomController::resetRequestForAssistance() */
+ ['name' => 'BreakoutRoom#resetRequestForAssistance', 'url' => '/api/{apiVersion}/breakout-rooms/{token}/request-assistance', 'verb' => 'DELETE', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\BreakoutRoomController::startBreakoutRooms() */
['name' => 'BreakoutRoom#startBreakoutRooms', 'url' => '/api/{apiVersion}/breakout-rooms/{token}/rooms', 'verb' => 'POST', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\BreakoutRoomController::stopBreakoutRooms() */
diff --git a/docs/breakout-rooms.md b/docs/breakout-rooms.md
index 8bd689cd8..58cf124fb 100644
--- a/docs/breakout-rooms.md
+++ b/docs/breakout-rooms.md
@@ -93,3 +93,27 @@ Group and public conversations can be used to host breakout rooms.
+ `403 Forbidden` When the participant is not a moderator
+ `404 Not Found` When the conversation could not be found for the participant
+ `413 Payload Too Large` When the message was longer than the allowed limit of 32000 characters (check the `spreed => config => chat => max-length` capability for the limit)
+
+## Request assistance
+
+This endpoint allows participants to raise their hand (token is the breakout room) and moderators will see it in any of the breakout rooms as well as the parent room.
+
+* Required capability: `breakout-rooms-v1`
+* Method: `POST`
+* Endpoint: `/breakout-rooms/{token}/request-assistance`
+* Response:
+ - Status code:
+ + `200 OK`
+ + `400 Bad Request` When the room is not a breakout room or breakout rooms are not started
+ + `404 Not Found` When the conversation could not be found for the participant
+
+## Reset request for assistance
+
+* Required capability: `breakout-rooms-v1`
+* Method: `DELETE`
+* Endpoint: `/breakout-rooms/{token}/request-assistance`
+* Response:
+ - Status code:
+ + `200 OK`
+ + `400 Bad Request` When the room does not have breakout rooms configured
+ + `404 Not Found` When the conversation could not be found for the participant
diff --git a/lib/Controller/BreakoutRoomController.php b/lib/Controller/BreakoutRoomController.php
index 6e76646f9..b760f7d5d 100644
--- a/lib/Controller/BreakoutRoomController.php
+++ b/lib/Controller/BreakoutRoomController.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\Talk\Controller;
use InvalidArgumentException;
+use OCA\Talk\Model\BreakoutRoom;
use OCA\Talk\Service\BreakoutRoomService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
@@ -88,6 +89,38 @@ class BreakoutRoomController extends AEnvironmentAwareController {
/**
* @NoAdminRequired
+ * @RequireLoggedInParticipant
+ *
+ * @return DataResponse
+ */
+ public function requestAssistance(): DataResponse {
+ try {
+ $this->breakoutRoomService->setBreakoutRoomAssistanceRequest($this->room, BreakoutRoom::STATUS_ASSISTANCE_REQUESTED);
+ } catch (InvalidArgumentException $e) {
+ return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
+ }
+
+ return new DataResponse();
+ }
+
+ /**
+ * @NoAdminRequired
+ * @RequireLoggedInParticipant
+ *
+ * @return DataResponse
+ */
+ public function resetRequestForAssistance(): DataResponse {
+ try {
+ $this->breakoutRoomService->setBreakoutRoomAssistanceRequest($this->room, BreakoutRoom::STATUS_ASSISTANCE_RESET);
+ } catch (InvalidArgumentException $e) {
+ return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
+ }
+
+ return new DataResponse();
+ }
+
+ /**
+ * @NoAdminRequired
* @RequireLoggedInModeratorParticipant
*/
public function startBreakoutRooms(): DataResponse {
diff --git a/lib/Model/BreakoutRoom.php b/lib/Model/BreakoutRoom.php
index 88fb101b0..aaf598e9f 100644
--- a/lib/Model/BreakoutRoom.php
+++ b/lib/Model/BreakoutRoom.php
@@ -33,6 +33,8 @@ class BreakoutRoom {
public const STATUS_STOPPED = 0;
public const STATUS_STARTED = 1;
+ public const STATUS_ASSISTANCE_RESET = 0;
+ public const STATUS_ASSISTANCE_REQUESTED = 2;
public const MINIMUM_ROOM_AMOUNT = 1;
public const MAXIMUM_ROOM_AMOUNT = 20;
diff --git a/lib/Service/BreakoutRoomService.php b/lib/Service/BreakoutRoomService.php
index 4b950c4a2..a9f02b820 100644
--- a/lib/Service/BreakoutRoomService.php
+++ b/lib/Service/BreakoutRoomService.php
@@ -277,6 +277,25 @@ class BreakoutRoomService {
}
}
+ public function setBreakoutRoomAssistanceRequest(Room $breakoutRoom, int $status): void {
+ if ($breakoutRoom->getObjectType() !== BreakoutRoom::PARENT_OBJECT_TYPE) {
+ throw new \InvalidArgumentException('room');
+ }
+
+ if ($breakoutRoom->getLobbyState() !== Webinary::LOBBY_NONE) {
+ throw new \InvalidArgumentException('room');
+ }
+
+ if (!in_array($status, [
+ BreakoutRoom::STATUS_ASSISTANCE_RESET,
+ BreakoutRoom::STATUS_ASSISTANCE_REQUESTED,
+ ], true)) {
+ throw new \InvalidArgumentException('status');
+ }
+
+ $this->roomService->setBreakoutRoomStatus($breakoutRoom, $status);
+ }
+
public function startBreakoutRooms(Room $parent): void {
if ($parent->getBreakoutRoomMode() === BreakoutRoom::MODE_NOT_CONFIGURED) {
throw new \InvalidArgumentException('mode');
diff --git a/lib/Service/RoomService.php b/lib/Service/RoomService.php
index 08cb8ef2f..6473b63e2 100644
--- a/lib/Service/RoomService.php
+++ b/lib/Service/RoomService.php
@@ -633,6 +633,8 @@ class RoomService {
if (!in_array($status, [
BreakoutRoom::STATUS_STOPPED,
BreakoutRoom::STATUS_STARTED,
+ BreakoutRoom::STATUS_ASSISTANCE_RESET,
+ BreakoutRoom::STATUS_ASSISTANCE_REQUESTED,
], true)) {
return false;
}
diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php
index 1e90c8c16..e41000d89 100644
--- a/tests/integration/features/bootstrap/FeatureContext.php
+++ b/tests/integration/features/bootstrap/FeatureContext.php
@@ -2383,6 +2383,25 @@ class FeatureContext implements Context, SnippetAcceptingContext {
}
/**
+ * @Then /^user "([^"]*)" (requests assistance|cancels request for assistance) in room "([^"]*)" with (\d+)(?: \((v1)\))?$/
+ *
+ * @param string $user
+ * @param string $requestCancel
+ * @param string $identifier
+ * @param string $statusCode
+ * @param string $apiVersion
+ */
+ public function userRequestsOrCancelsAssistanceInBreakoutRooms(string $user, string $requestCancel, string $identifier, string $statusCode, string $apiVersion = 'v1') {
+ $this->setCurrentUser($user);
+ $this->sendRequest(
+ $requestCancel === 'requests assistance' ? 'POST' : 'DELETE',
+ '/apps/spreed/api/' . $apiVersion . '/breakout-rooms/' . self::$identifierToToken[$identifier] . '/request-assistance'
+ );
+
+ $this->assertStatusCode($this->response, $statusCode);
+ }
+
+ /**
* @Then /^user "([^"]*)" sets setting "([^"]*)" to "([^"]*)" with (\d+)(?: \((v1)\))?$/
*
* @param string $user
diff --git a/tests/integration/features/conversation/breakout-rooms.feature b/tests/integration/features/conversation/breakout-rooms.feature
index e9320672f..433655d81 100644
--- a/tests/integration/features/conversation/breakout-rooms.feature
+++ b/tests/integration/features/conversation/breakout-rooms.feature
@@ -311,3 +311,43 @@ Feature: conversation/breakout-rooms
| Room 3 | users | participant1 | participant1-displayname | breakout_rooms_stopped |
| Room 3 | users | participant1 | participant1-displayname | breakout_rooms_started |
| Room 3 | users | participant1 | participant1-displayname | conversation_created |
+
+ Scenario: Request assistance and cancel it
+ Given user "participant1" creates room "class room" (v4)
+ | roomType | 3 |
+ | roomName | class room |
+ And user "participant1" adds user "participant2" to room "class room" with 200 (v4)
+ And user "participant1" sees the following attendees in room "class room" with 200 (v4)
+ | actorType | actorId | participantType |
+ | users | participant1 | 1 |
+ | users | participant2 | 3 |
+ When user "participant1" creates 1 automatic breakout rooms for "class room" with 200 (v1)
+ And user "participant1" is participant of the following rooms (v4)
+ | type | name | lobbyState | breakoutRoomMode | breakoutRoomStatus |
+ | 3 | class room | 0 | 1 | 0 |
+ | 3 | Room 1 | 1 | 0 | 0 |
+ And user "participant1" starts breakout rooms in room "class room" with 200 (v1)
+ And user "participant2" is participant of the following rooms (v4)
+ | type | name | lobbyState | breakoutRoomMode | breakoutRoomStatus |
+ | 3 | class room | 0 | 1 | 1 |
+ | 3 | Room 1 | 0 | 0 | 0 |
+ And user "participant2" requests assistance in room "Room 1" with 200 (v1)
+ And user "participant1" is participant of the following rooms (v4)
+ | type | name | lobbyState | breakoutRoomMode | breakoutRoomStatus |
+ | 3 | class room | 0 | 1 | 1 |
+ | 3 | Room 1 | 0 | 0 | 2 |
+ And user "participant2" cancels request for assistance in room "Room 1" with 200 (v1)
+ And user "participant1" is participant of the following rooms (v4)
+ | type | name | lobbyState | breakoutRoomMode | breakoutRoomStatus |
+ | 3 | class room | 0 | 1 | 1 |
+ | 3 | Room 1 | 0 | 0 | 0 |
+ And user "participant2" requests assistance in room "Room 1" with 200 (v1)
+ And user "participant1" is participant of the following rooms (v4)
+ | type | name | lobbyState | breakoutRoomMode | breakoutRoomStatus |
+ | 3 | class room | 0 | 1 | 1 |
+ | 3 | Room 1 | 0 | 0 | 2 |
+ And user "participant1" cancels request for assistance in room "Room 1" with 200 (v1)
+ And user "participant1" is participant of the following rooms (v4)
+ | type | name | lobbyState | breakoutRoomMode | breakoutRoomStatus |
+ | 3 | class room | 0 | 1 | 1 |
+ | 3 | Room 1 | 0 | 0 | 0 |