Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 145 additions & 26 deletions tests/integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,30 +155,6 @@ public function userIsParticipantOfRooms($user, $apiVersion = 'v1', TableNode $f
private function assertRooms($rooms, TableNode $formData) {
Assert::assertCount(count($formData->getHash()), $rooms, 'Room count does not match');
Assert::assertEquals($formData->getHash(), array_map(function ($room, $expectedRoom) {
$participantNames = array_map(function ($participant) {
return $participant['name'];
}, $room['participants']);

// When participants have the same last ping the order in which they
// are returned from the server is undefined. That is the most
// common case during the tests, so by default the list of
// participants returned by the server is sorted alphabetically. In
// order to check the exact order of participants returned by the
// server " [exact order]" can be appended in the test definition to
// the list of expected participants of the room.
if (strpos($expectedRoom['participants'], ' [exact order]') === false) {
sort($participantNames);
} else {
// "end(array_keys(..." would generate the Strict Standards
// error "Only variables should be passed by reference".
$participantNamesKeys = array_keys($participantNames);
$lastParticipantKey = end($participantNamesKeys);

// Append " [exact order]" to the last participant so the
// imploded string is the same as the expected one.
$participantNames[$lastParticipantKey] .= ' [exact order]';
}

$data = [];
if (isset($expectedRoom['id'])) {
$data['id'] = self::$tokenToIdentifier[$room['token']];
Expand All @@ -199,8 +175,37 @@ private function assertRooms($rooms, TableNode $formData) {
$data['participantType'] = (string) $room['participantType'];
}
if (isset($expectedRoom['participants'])) {
$participantNames = array_map(function ($participant) {
return $participant['name'];
}, $room['participants']);

// When participants have the same last ping the order in which they
// are returned from the server is undefined. That is the most
// common case during the tests, so by default the list of
// participants returned by the server is sorted alphabetically. In
// order to check the exact order of participants returned by the
// server " [exact order]" can be appended in the test definition to
// the list of expected participants of the room.
if (strpos($expectedRoom['participants'], ' [exact order]') === false) {
sort($participantNames);
} else {
// "end(array_keys(..." would generate the Strict Standards
// error "Only variables should be passed by reference".
$participantNamesKeys = array_keys($participantNames);
$lastParticipantKey = end($participantNamesKeys);

// Append " [exact order]" to the last participant so the
// imploded string is the same as the expected one.
$participantNames[$lastParticipantKey] .= ' [exact order]';
}
$data['participants'] = implode(', ', $participantNames);
}
if (isset($expectedRoom['sipEnabled'])) {
$data['sipEnabled'] = (string) $room['sipEnabled'];
}
if (isset($expectedRoom['attendeePin'])) {
$data['attendeePin'] = $room['attendeePin'] ? '**PIN**' : '';
}

return $data;
}, $rooms, $formData->getHash()));
Expand Down Expand Up @@ -257,6 +262,72 @@ public function userIsParticipantOfRoom($user, $isOrNotParticipant, $identifier,
Assert::assertEquals($isParticipant, false, 'Room ' . $identifier . ' not found in user´s room list');
}

/**
* @Then /^user "([^"]*)" sees the following attendees in room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
*
* @param string $user
* @param string $identifier
* @param string $statusCode
* @param string $apiVersion
* @param TableNode $formData
*/
public function userSeesAttendeesInRoom($user, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
$this->setCurrentUser($user);
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants');
$this->assertStatusCode($this->response, $statusCode);

if ($formData instanceof TableNode) {
$attendees = $this->getDataFromResponse($this->response);
$expectedKeys = array_flip($formData->getRows()[0]);

$result = [];
foreach ($attendees as $attendee) {
$data = [];
if (isset($expectedKeys['actorType'])) {
$data['actorType'] = $attendee['actorType'];
}
if (isset($expectedKeys['actorId'])) {
$data['actorId'] = $attendee['actorId'];
}
if (isset($expectedKeys['participantType'])) {
$data['participantType'] = (string) $attendee['participantType'];
}
if (isset($expectedKeys['inCall'])) {
$data['inCall'] = (string) $attendee['inCall'];
}
if (isset($expectedKeys['attendeePin'])) {
$data['attendeePin'] = $attendee['attendeePin'] ? '**PIN**' : '';
}

$result[] = $data;
}

$expected = array_map(function ($attendee) {
if (isset($attendee['actorId']) && substr($attendee['actorId'], 0, strlen('"guest')) === '"guest') {
$attendee['actorId'] = sha1(self::$userToSessionId[trim($attendee['actorId'], '"')]);
}
return $attendee;
}, $formData->getHash());

usort($expected, [$this, 'sortAttendees']);
usort($result, [$this, 'sortAttendees']);

Assert::assertEquals($result, $expected);
} else {
Assert::assertNull($formData);
}
}

protected function sortAttendees(array $a1, array $a2): int {
if ($a1['participantType'] !== $a2['participantType']) {
return $a1['participantType'] <=> $a2['participantType'];
}
if ($a1['actorType'] !== $a2['actorType']) {
return $a1['actorType'] <=> $a2['actorType'];
}
return $a1['actorId'] <=> $a2['actorId'];
}

/**
* @param string $guest
* @param string $isOrNotParticipant
Expand Down Expand Up @@ -625,17 +696,42 @@ public function userSetsLobbyStateForRoomTo($user, $identifier, $lobbyStateStrin
$lobbyState = 1;
} else {
Assert::fail('Invalid lobby state');
return;
}

$this->setCurrentUser($user);
$this->sendRequest(
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/webinary/lobby',
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/webinar/lobby',
new TableNode([['state', $lobbyState]])
);
$this->assertStatusCode($this->response, $statusCode);
}

/**
* @When /^user "([^"]*)" sets SIP state for room "([^"]*)" to "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
*
* @param string $user
* @param string $identifier
* @param string $SIPStateString
* @param string $statusCode
* @param string $apiVersion
*/
public function userSetsSIPStateForRoomTo($user, $identifier, $SIPStateString, $statusCode, $apiVersion = 'v1') {
if ($SIPStateString === 'disabled') {
$SIPState = 0;
} elseif ($SIPStateString === 'enabled') {
$SIPState = 1;
} else {
Assert::fail('Invalid SIP state');
}

$this->setCurrentUser($user);
$this->sendRequest(
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/webinar/sip',
new TableNode([['state', $SIPState]])
);
$this->assertStatusCode($this->response, $statusCode);
}

/**
* @Then /^user "([^"]*)" makes room "([^"]*)" (public|private) with (\d+)(?: \((v(1|2|3))\))?$/
*
Expand Down Expand Up @@ -690,6 +786,29 @@ public function userAddUserToRoom($user, $newUser, $identifier, $statusCode, $ap
$this->assertStatusCode($this->response, $statusCode);
}

/**
* @Then /^user "([^"]*)" adds (user|group|email|circle) "([^"]*)" to room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
*
* @param string $user
* @param string $newType
* @param string $newId
* @param string $identifier
* @param string $statusCode
* @param string $apiVersion
*/
public function userAddAttendeeToRoom($user, $newType, $newId, $identifier, $statusCode, $apiVersion = 'v1') {
var_dump($newType);
$this->setCurrentUser($user);
$this->sendRequest(
'POST', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants',
new TableNode([
['source', $newType . 's'],
['newParticipant', $newId],
])
);
$this->assertStatusCode($this->response, $statusCode);
}

/**
* @Then /^user "([^"]*)" (promotes|demotes) "([^"]*)" in room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
*
Expand Down
67 changes: 67 additions & 0 deletions tests/integration/features/conversation/sip-dialin.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Feature: public
Background:
Given user "participant1" exists
Given user "participant2" exists
Given user "participant3" exists
Given group "group1" exists
Given user "participant1" is member of group "group1"

Scenario: SIP admin enables SIP
Given the following app config is set
| sip_bridge_dialin_info | +49-1234-567890 |
| sip_bridge_shared_secret | 1234567890abcdef |
| sip_bridge_groups | ["group1"] |
Given user "participant1" creates room "room"
| roomType | 3 |
| roomName | room |
And user "participant1" is participant of the following rooms (v3)
| id | type | participantType | sipEnabled | attendeePin |
| room | 3 | 1 | 0 | |
When user "participant1" sets SIP state for room "room" to "enabled" with 200 (v3)
Then user "participant1" is participant of the following rooms (v3)
| id | type | participantType | sipEnabled | attendeePin |
| room | 3 | 1 | 1 | **PIN** |
When user "participant1" adds user "participant2" to room "room" with 200 (v3)
When user "participant1" adds "participant3" to room "room" with 200 (v3)
When user "participant1" adds email "[email protected]" to room "room" with 200 (v3)
# Guests don't get a PIN as they can not be recognized and are deleted on leave
When user "guest" joins room "room" with 200
Then user "participant1" sees the following attendees in room "room" with 200 (v3)
| participantType | inCall | actorType | actorId | attendeePin |
| 4 | 0 | emails | [email protected] | **PIN** |
| 4 | 0 | guests | "guest" | |
| 1 | 0 | users | participant1 | **PIN** |
| 3 | 0 | users | participant2 | **PIN** |
| 3 | 0 | users | participant3 | **PIN** |
When user "participant2" sets SIP state for room "room" to "disabled" with 403 (v3)
Then user "participant1" sees the following attendees in room "room" with 200 (v3)
| participantType | inCall | actorType | actorId | attendeePin |
| 4 | 0 | emails | [email protected] | **PIN** |
| 4 | 0 | guests | "guest" | |
| 1 | 0 | users | participant1 | **PIN** |
| 3 | 0 | users | participant2 | **PIN** |
| 3 | 0 | users | participant3 | **PIN** |
When user "participant1" sets SIP state for room "room" to "disabled" with 200 (v3)
Then user "participant1" sees the following attendees in room "room" with 200 (v3)
| participantType | inCall | actorType | actorId | attendeePin |
| 4 | 0 | emails | [email protected] | |
| 4 | 0 | guests | "guest" | |
| 1 | 0 | users | participant1 | |
| 3 | 0 | users | participant2 | |
| 3 | 0 | users | participant3 | |

Scenario: Non-SIP admin tries to enable SIP
Given the following app config is set
| sip_bridge_dialin_info | +49-1234-567890 |
| sip_bridge_shared_secret | 1234567890abcdef |
| sip_bridge_groups | ["group1"] |
Given user "participant2" creates room "room"
| roomType | 3 |
| roomName | room |
And user "participant2" is participant of the following rooms (v3)
| id | type | participantType | sipEnabled | attendeePin |
| room | 3 | 1 | 0 | |
When user "participant2" sets SIP state for room "room" to "enabled" with 403 (v3)
And user "participant2" is participant of the following rooms (v3)
| id | type | participantType | sipEnabled | attendeePin |
| room | 3 | 1 | 0 | |