You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1642 lines
52 KiB
1642 lines
52 KiB
<?php
|
|
/**
|
|
* @author Joas Schilling <coding@schilljs.com>
|
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
|
*
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
|
* @license AGPL-3.0
|
|
*
|
|
* This code is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
*/
|
|
require __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use Behat\Behat\Context\Context;
|
|
use Behat\Behat\Context\SnippetAcceptingContext;
|
|
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
|
|
use Behat\Gherkin\Node\TableNode;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Cookie\CookieJar;
|
|
use GuzzleHttp\Exception\ClientException;
|
|
use PHPUnit\Framework\Assert;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
/**
|
|
* Defines application features from the specific context.
|
|
*/
|
|
class FeatureContext implements Context, SnippetAcceptingContext {
|
|
|
|
/** @var array[] */
|
|
protected static $identifierToToken;
|
|
/** @var array[] */
|
|
protected static $tokenToIdentifier;
|
|
/** @var array[] */
|
|
protected static $sessionIdToUser;
|
|
/** @var array[] */
|
|
protected static $userToSessionId;
|
|
/** @var array[] */
|
|
protected static $messages;
|
|
|
|
/** @var string */
|
|
protected $currentUser;
|
|
|
|
/** @var ResponseInterface */
|
|
private $response;
|
|
|
|
/** @var CookieJar[] */
|
|
private $cookieJars;
|
|
|
|
/** @var string */
|
|
protected $baseUrl;
|
|
|
|
/** @var string */
|
|
protected $lastEtag;
|
|
|
|
/** @var array */
|
|
protected $createdUsers = [];
|
|
|
|
/** @var array */
|
|
protected $createdGroups = [];
|
|
|
|
/** @var array */
|
|
protected $changedConfigs = [];
|
|
|
|
/** @var SharingContext */
|
|
private $sharingContext;
|
|
|
|
use CommandLineTrait;
|
|
|
|
public static function getTokenForIdentifier(string $identifier) {
|
|
return self::$identifierToToken[$identifier];
|
|
}
|
|
|
|
/**
|
|
* FeatureContext constructor.
|
|
*/
|
|
public function __construct() {
|
|
$this->cookieJars = [];
|
|
$this->baseUrl = getenv('TEST_SERVER_URL');
|
|
}
|
|
|
|
/**
|
|
* @BeforeScenario
|
|
*/
|
|
public function setUp() {
|
|
self::$identifierToToken = [];
|
|
self::$tokenToIdentifier = [];
|
|
self::$sessionIdToUser = [];
|
|
self::$userToSessionId = [];
|
|
self::$messages = [];
|
|
|
|
$this->createdUsers = [];
|
|
$this->createdGroups = [];
|
|
}
|
|
|
|
/**
|
|
* @BeforeScenario
|
|
*/
|
|
public function getOtherRequiredSiblingContexts(BeforeScenarioScope $scope) {
|
|
$environment = $scope->getEnvironment();
|
|
|
|
$this->sharingContext = $environment->getContext("SharingContext");
|
|
}
|
|
|
|
/**
|
|
* @AfterScenario
|
|
*/
|
|
public function tearDown() {
|
|
foreach ($this->createdUsers as $user) {
|
|
$this->deleteUser($user);
|
|
}
|
|
foreach ($this->createdGroups as $group) {
|
|
$this->deleteGroup($group);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" is participant of the following rooms(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userIsParticipantOfRooms($user, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room');
|
|
$this->assertStatusCode($this->response, 200);
|
|
|
|
$rooms = $this->getDataFromResponse($this->response);
|
|
|
|
$rooms = array_filter($rooms, function ($room) {
|
|
return $room['type'] !== 4;
|
|
});
|
|
|
|
if ($formData === null) {
|
|
Assert::assertEmpty($rooms);
|
|
return;
|
|
}
|
|
|
|
$this->assertRooms($rooms, $formData);
|
|
}
|
|
|
|
/**
|
|
* @param array $rooms
|
|
* @param TableNode $formData
|
|
*/
|
|
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) {
|
|
$data = [];
|
|
if (isset($expectedRoom['id'])) {
|
|
$data['id'] = self::$tokenToIdentifier[$room['token']];
|
|
}
|
|
if (isset($expectedRoom['name'])) {
|
|
$data['name'] = $room['name'];
|
|
}
|
|
if (isset($expectedRoom['description'])) {
|
|
$data['description'] = $room['description'];
|
|
}
|
|
if (isset($expectedRoom['type'])) {
|
|
$data['type'] = (string) $room['type'];
|
|
}
|
|
if (isset($expectedRoom['hasPassword'])) {
|
|
$data['hasPassword'] = (string) $room['hasPassword'];
|
|
}
|
|
if (isset($expectedRoom['readOnly'])) {
|
|
$data['readOnly'] = (string) $room['readOnly'];
|
|
}
|
|
if (isset($expectedRoom['listable'])) {
|
|
$data['listable'] = (string) $room['listable'];
|
|
}
|
|
if (isset($expectedRoom['participantType'])) {
|
|
$data['participantType'] = (string) $room['participantType'];
|
|
}
|
|
if (isset($expectedRoom['sipEnabled'])) {
|
|
$data['sipEnabled'] = (string) $room['sipEnabled'];
|
|
}
|
|
if (isset($expectedRoom['attendeePin'])) {
|
|
$data['attendeePin'] = $room['attendeePin'] ? '**PIN**' : '';
|
|
}
|
|
if (isset($expectedRoom['lastMessage'])) {
|
|
$data['lastMessage'] = $room['lastMessage'] ? $room['lastMessage']['message'] : '';
|
|
}
|
|
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);
|
|
}
|
|
|
|
return $data;
|
|
}, $rooms, $formData->getHash()));
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" (is|is not) participant of room "([^"]*)"(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $isOrNotParticipant
|
|
* @param string $identifier
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userIsParticipantOfRoom($user, $isOrNotParticipant, $identifier, $apiVersion = 'v1', TableNode $formData = null) {
|
|
if (strpos($user, 'guest') === 0) {
|
|
$this->guestIsParticipantOfRoom($user, $isOrNotParticipant, $identifier, $apiVersion, $formData);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room');
|
|
$this->assertStatusCode($this->response, 200);
|
|
|
|
$isParticipant = $isOrNotParticipant === 'is';
|
|
|
|
$rooms = $this->getDataFromResponse($this->response);
|
|
|
|
$rooms = array_filter($rooms, function ($room) {
|
|
return $room['type'] !== 4;
|
|
});
|
|
|
|
if ($isParticipant) {
|
|
Assert::assertNotEmpty($rooms);
|
|
}
|
|
|
|
foreach ($rooms as $room) {
|
|
if (self::$tokenToIdentifier[$room['token']] === $identifier) {
|
|
Assert::assertEquals($isParticipant, true, 'Room ' . $identifier . ' found in user´s room list');
|
|
|
|
if ($formData) {
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier]);
|
|
|
|
$rooms = [$this->getDataFromResponse($this->response)];
|
|
|
|
$this->assertRooms($rooms, $formData);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
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'], '"')]);
|
|
}
|
|
if (isset($attendee['participantType'])) {
|
|
$attendee['participantType'] = (string)$this->mapParticipantTypeTestInput($attendee['participantType']);
|
|
}
|
|
return $attendee;
|
|
}, $formData->getHash());
|
|
|
|
usort($expected, [$this, 'sortAttendees']);
|
|
usort($result, [$this, 'sortAttendees']);
|
|
|
|
Assert::assertEquals($expected, $result);
|
|
} 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'];
|
|
}
|
|
|
|
private function mapParticipantTypeTestInput($participantType) {
|
|
if (is_int($participantType)) {
|
|
return $participantType;
|
|
}
|
|
|
|
switch ($participantType) {
|
|
case 'OWNER': return 1;
|
|
case 'MODERATOR': return 2;
|
|
case 'USER': return 3;
|
|
case 'GUEST': return 4;
|
|
case 'USER_SELF_JOINED': return 5;
|
|
case 'GUEST_MODERATOR': return 6;
|
|
}
|
|
|
|
Assert::fail('Invalid test input value for participant type');
|
|
}
|
|
|
|
/**
|
|
* @param string $guest
|
|
* @param string $isOrNotParticipant
|
|
* @param string $identifier
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
private function guestIsParticipantOfRoom($guest, $isOrNotParticipant, $identifier, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($guest);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier]);
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
|
|
$isParticipant = $isOrNotParticipant === 'is';
|
|
|
|
if ($formData) {
|
|
$rooms = [$response];
|
|
|
|
$this->assertRooms($rooms, $formData);
|
|
}
|
|
|
|
if ($isParticipant) {
|
|
$this->assertStatusCode($this->response, 200);
|
|
Assert::assertEquals(self::$userToSessionId[$guest], $response['sessionId']);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->response->getStatusCode() === 200) {
|
|
// Public rooms can always be got, but if the guest is not a
|
|
// participant the sessionId will be 0.
|
|
Assert::assertEquals(0, $response['sessionId']);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->assertStatusCode($this->response, 404);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" creates room "([^"]*)"(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userCreatesRoom($user, $identifier, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->userCreatesRoomWith($user, $identifier, 201, $apiVersion, $formData);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" creates room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param int $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userCreatesRoomWith($user, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('POST', '/apps/spreed/api/' . $apiVersion . '/room', $formData);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
|
|
if ($statusCode === 201) {
|
|
self::$identifierToToken[$identifier] = $response['token'];
|
|
self::$tokenToIdentifier[$response['token']] = $identifier;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" tries to create room with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param int $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userTriesToCreateRoom($user, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('POST', '/apps/spreed/api/' . $apiVersion . '/room', $formData);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" gets the room for path "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $path
|
|
* @param int $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userGetsTheRoomForPath($user, $path, $statusCode, $apiVersion = 'v1') {
|
|
$fileId = $this->getFileIdForPath($user, $path);
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/file/' . $fileId);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
if ($statusCode !== '200') {
|
|
return;
|
|
}
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
|
|
$identifier = 'file ' . $path . ' room';
|
|
self::$identifierToToken[$identifier] = $response['token'];
|
|
self::$tokenToIdentifier[$response['token']] = $identifier;
|
|
}
|
|
|
|
/**
|
|
* @param string $user
|
|
* @param string $path
|
|
* @return int
|
|
*/
|
|
private function getFileIdForPath($user, $path) {
|
|
$this->currentUser = $user;
|
|
|
|
$url = "/$user/$path";
|
|
|
|
$headers = [];
|
|
$headers['Depth'] = 0;
|
|
|
|
$body = '<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">' .
|
|
' <d:prop>' .
|
|
' <oc:fileid/>' .
|
|
' </d:prop>' .
|
|
'</d:propfind>';
|
|
|
|
$this->sendingToDav('PROPFIND', $url, $headers, $body);
|
|
|
|
$this->assertStatusCode($this->response, 207);
|
|
|
|
$xmlResponse = simplexml_load_string($this->response->getBody());
|
|
$xmlResponse->registerXPathNamespace('oc', 'http://owncloud.org/ns');
|
|
|
|
return (int)$xmlResponse->xpath('//oc:fileid')[0];
|
|
}
|
|
|
|
/**
|
|
* @param string $verb
|
|
* @param string $url
|
|
* @param array $headers
|
|
* @param string $body
|
|
*/
|
|
private function sendingToDav(string $verb, string $url, array $headers = null, string $body = null) {
|
|
$fullUrl = $this->baseUrl . 'remote.php/dav/files' . $url;
|
|
$client = new Client();
|
|
$options = [];
|
|
if ($this->currentUser === 'admin') {
|
|
$options['auth'] = 'admin';
|
|
} else {
|
|
$options['auth'] = [$this->currentUser, '123456'];
|
|
}
|
|
$options['headers'] = [
|
|
'OCS_APIREQUEST' => 'true'
|
|
];
|
|
if ($headers !== null) {
|
|
$options['headers'] = array_merge($options['headers'], $headers);
|
|
}
|
|
if ($body !== null) {
|
|
$options['body'] = $body;
|
|
}
|
|
|
|
try {
|
|
$this->response = $client->{$verb}($fullUrl, $options);
|
|
} catch (GuzzleHttp\Exception\ClientException $ex) {
|
|
$this->response = $ex->getResponse();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" gets the room for last share with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param int $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userGetsTheRoomForLastShare($user, $statusCode, $apiVersion = 'v1') {
|
|
$shareToken = $this->sharingContext->getLastShareToken();
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/publicshare/' . $shareToken);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
if ($statusCode !== '200') {
|
|
return;
|
|
}
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
|
|
$identifier = 'file last share room';
|
|
self::$identifierToToken[$identifier] = $response['token'];
|
|
self::$tokenToIdentifier[$response['token']] = $identifier;
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" creates the password request room for last share with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param int $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userCreatesThePasswordRequestRoomForLastShare($user, $statusCode, $apiVersion = 'v1') {
|
|
$shareToken = $this->sharingContext->getLastShareToken();
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('POST', '/apps/spreed/api/' . $apiVersion . '/publicshareauth', ['shareToken' => $shareToken]);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
if ($statusCode !== '201') {
|
|
return;
|
|
}
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
|
|
$identifier = 'password request for last share room';
|
|
self::$identifierToToken[$identifier] = $response['token'];
|
|
self::$tokenToIdentifier[$response['token']] = $identifier;
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" joins room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userJoinsRoom($user, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants/active',
|
|
$formData
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
if ($statusCode !== '200') {
|
|
return;
|
|
}
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
if (array_key_exists('sessionId', $response)) {
|
|
// In the chat guest users are identified by their sessionId. The
|
|
// sessionId is larger than the size of the actorId column in the
|
|
// database, though, so the ID stored in the database and returned
|
|
// in chat messages is a hashed version instead.
|
|
self::$sessionIdToUser[sha1($response['sessionId'])] = $user;
|
|
self::$userToSessionId[$user] = $response['sessionId'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" leaves room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userExitsRoom($user, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('DELETE', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants/active');
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" removes themselves from room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userLeavesRoom($user, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('DELETE', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants/self');
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" removes "([^"]*)" from room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $toRemove
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userRemovesUserFromRoom($user, $toRemove, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'DELETE', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants',
|
|
new TableNode([['participant', $toRemove]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" deletes room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userDeletesRoom($user, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('DELETE', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier]);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" renames room "([^"]*)" to "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $newName
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userRenamesRoom($user, $identifier, $newName, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier],
|
|
new TableNode([['roomName', $newName]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @When /^user "([^"]*)" sets description for room "([^"]*)" to "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $description
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode
|
|
*/
|
|
public function userSetsDescriptionForRoomTo($user, $identifier, $description, $statusCode, $apiVersion = 'v3') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'PUT', '/apps/spreed/api/' .$apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/description',
|
|
new TableNode([['description', $description]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @When /^user "([^"]*)" sets password "([^"]*)" for room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $password
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSetsTheRoomPassword($user, $password, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/password',
|
|
new TableNode([['password', $password]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @When /^user "([^"]*)" sets lobby state for room "([^"]*)" to "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $lobbyStateString
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSetsLobbyStateForRoomTo($user, $identifier, $lobbyStateString, $statusCode, $apiVersion = 'v1') {
|
|
if ($lobbyStateString === 'no lobby') {
|
|
$lobbyState = 0;
|
|
} elseif ($lobbyStateString === 'non moderators') {
|
|
$lobbyState = 1;
|
|
} else {
|
|
Assert::fail('Invalid lobby state');
|
|
}
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'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))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $newType
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userChangesTypeOfTheRoom($user, $identifier, $newType, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
$newType === 'public' ? 'POST' : 'DELETE',
|
|
'/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/public'
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" (locks|unlocks) room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $newState
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userChangesReadOnlyStateOfTheRoom($user, $newState, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/read-only',
|
|
new TableNode([['state', $newState === 'unlocks' ? 0 : 1]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" allows listing room "([^"]*)" for "(none|users|all)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $newState
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userChangesListableScopeOfTheRoom($user, $identifier, $newState, $statusCode, $apiVersion = 'v3') {
|
|
$this->setCurrentUser($user);
|
|
if ($newState === 'none') {
|
|
$newStateValue = 0; // Room::LISTABLE_NONE
|
|
} elseif ($newState === 'users') {
|
|
$newStateValue = 1; // Room::LISTABLE_USERS
|
|
} elseif ($newState === 'all') {
|
|
$newStateValue = 2; // Room::LISTABLE_ALL
|
|
} else {
|
|
Assert::fail('Invalid listable scope value');
|
|
}
|
|
|
|
$this->sendRequest(
|
|
'PUT', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/listable',
|
|
new TableNode([['scope', $newStateValue]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" adds "([^"]*)" to room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $newUser
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userAddUserToRoom($user, $newUser, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants',
|
|
new TableNode([['newParticipant', $newUser]])
|
|
);
|
|
$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))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $isPromotion
|
|
* @param string $participant
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userPromoteDemoteInRoom($user, $isPromotion, $participant, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$requestParameters = [['participant', $participant]];
|
|
|
|
if (substr($participant, 0, strlen('guest')) === 'guest') {
|
|
$sessionId = self::$userToSessionId[$participant];
|
|
$requestParameters = [['sessionId', $sessionId]];
|
|
}
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
$isPromotion === 'promotes' ? 'POST' : 'DELETE',
|
|
'/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/moderators',
|
|
new TableNode($requestParameters)
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" joins call "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userJoinsCall($user, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/call/' . self::$identifierToToken[$identifier],
|
|
$formData
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
if (array_key_exists('sessionId', $response)) {
|
|
// In the chat guest users are identified by their sessionId. The
|
|
// sessionId is larger than the size of the actorId column in the
|
|
// database, though, so the ID stored in the database and returned
|
|
// in chat messages is a hashed version instead.
|
|
self::$sessionIdToUser[sha1($response['sessionId'])] = $user;
|
|
self::$userToSessionId[$user] = $response['sessionId'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" leaves call "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userLeavesCall($user, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('DELETE', '/apps/spreed/api/' . $apiVersion . '/call/' . self::$identifierToToken[$identifier]);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sees (\d+) peers in call "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $numPeers
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSeesPeersInCall($user, $numPeers, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/call/' . self::$identifierToToken[$identifier]);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
if ($statusCode === '200') {
|
|
$response = $this->getDataFromResponse($this->response);
|
|
Assert::assertCount((int) $numPeers, $response);
|
|
} else {
|
|
Assert::assertEquals((int) $numPeers, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sends message "([^"]*)" to room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $message
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSendsMessageToRoom($user, $message, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier],
|
|
new TableNode([['message', $message]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
sleep(1); // make sure Postgres manages the order of the messages
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
if (isset($response['id'])) {
|
|
self::$messages[$message] = $response['id'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" reads message "([^"]*)" in room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $message
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userReadsMessageInRoom($user, $message, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '/read',
|
|
new TableNode([['lastReadMessage', self::$messages[$message]]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sends message "([^"]*)" with reference id "([^"]*)" to room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $message
|
|
* @param string $referenceId
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSendsMessageWithReferenceIdToRoom($user, $message, $referenceId, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier],
|
|
new TableNode([['message', $message], ['referenceId', $referenceId]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
sleep(1); // make sure Postgres manages the order of the messages
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
if (isset($response['id'])) {
|
|
self::$messages[$message] = $response['id'];
|
|
}
|
|
|
|
Assert::assertStringStartsWith($response['referenceId'], $referenceId);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sends reply "([^"]*)" on message "([^"]*)" to room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $reply
|
|
* @param string $message
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSendsReplyToRoom($user, $reply, $message, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$replyTo = self::$messages[$message];
|
|
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier],
|
|
new TableNode([['message', $reply], ['replyTo', $replyTo]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
sleep(1); // make sure Postgres manages the order of the messages
|
|
|
|
$response = $this->getDataFromResponse($this->response);
|
|
if (isset($response['id'])) {
|
|
self::$messages[$reply] = $response['id'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sees the following messages in room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSeesTheFollowingMessagesInRoom($user, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '?lookIntoFuture=0');
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
$this->compareDataResponse($formData);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sees the following messages in room "([^"]*)" starting with "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $knwonMessage
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userAwaitsTheFollowingMessagesInRoom($user, $identifier, $knwonMessage, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '?lookIntoFuture=1&includeLastKnown=1&lastKnownMessageId=' . self::$messages[$knwonMessage]);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
$this->compareDataResponse($formData);
|
|
}
|
|
|
|
/**
|
|
* @param TableNode|null $formData
|
|
*/
|
|
protected function compareDataResponse(TableNode $formData = null) {
|
|
$actual = $this->getDataFromResponse($this->response);
|
|
$messages = [];
|
|
array_map(function (array $message) use (&$messages) {
|
|
// Filter out system messages
|
|
if ($message['systemMessage'] === '') {
|
|
$messages[] = $message;
|
|
}
|
|
}, $actual);
|
|
|
|
foreach ($messages as $message) {
|
|
// Include the received messages in the list of messages used for
|
|
// replies; this is needed to get special messages not explicitly
|
|
// sent like those for shared files.
|
|
self::$messages[$message['message']] = $message['id'];
|
|
}
|
|
|
|
if ($formData === null) {
|
|
Assert::assertEmpty($messages);
|
|
return;
|
|
}
|
|
$includeParents = in_array('parentMessage', $formData->getRow(0), true);
|
|
$includeReferenceId = in_array('referenceId', $formData->getRow(0), true);
|
|
|
|
$count = count($formData->getHash());
|
|
Assert::assertCount($count, $messages, 'Message count does not match');
|
|
for ($i = 0; $i < $count; $i++) {
|
|
if ($formData->getHash()[$i]['messageParameters'] === '"IGNORE"') {
|
|
$messages[$i]['messageParameters'] = 'IGNORE';
|
|
}
|
|
}
|
|
Assert::assertEquals($formData->getHash(), array_map(function ($message) use ($includeParents, $includeReferenceId) {
|
|
$data = [
|
|
'room' => self::$tokenToIdentifier[$message['token']],
|
|
'actorType' => $message['actorType'],
|
|
'actorId' => ($message['actorType'] === 'guests')? self::$sessionIdToUser[$message['actorId']]: $message['actorId'],
|
|
'actorDisplayName' => $message['actorDisplayName'],
|
|
// TODO test timestamp; it may require using Runkit, php-timecop
|
|
// or something like that.
|
|
'message' => $message['message'],
|
|
'messageParameters' => json_encode($message['messageParameters']),
|
|
];
|
|
if ($includeParents) {
|
|
$data['parentMessage'] = $message['parent']['message'] ?? '';
|
|
}
|
|
if ($includeReferenceId) {
|
|
$data['referenceId'] = $message['referenceId'];
|
|
}
|
|
return $data;
|
|
}, $messages));
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sees the following system messages in room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSeesTheFollowingSystemMessagesInRoom($user, $identifier, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '?lookIntoFuture=0');
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
$messages = $this->getDataFromResponse($this->response);
|
|
$messages = array_filter($messages, function (array $message) {
|
|
return $message['systemMessage'] !== '';
|
|
});
|
|
|
|
foreach ($messages as $systemMessage) {
|
|
// Include the received system messages in the list of messages used
|
|
// for replies.
|
|
self::$messages[$systemMessage['systemMessage']] = $systemMessage['id'];
|
|
}
|
|
|
|
if ($formData === null) {
|
|
Assert::assertEmpty($messages);
|
|
return;
|
|
}
|
|
|
|
Assert::assertCount(count($formData->getHash()), $messages, 'Message count does not match');
|
|
Assert::assertEquals($formData->getHash(), array_map(function ($message) {
|
|
return [
|
|
'room' => self::$tokenToIdentifier[$message['token']],
|
|
'actorType' => (string) $message['actorType'],
|
|
'actorId' => ($message['actorType'] === 'guests')? self::$sessionIdToUser[$message['actorId']]: (string) $message['actorId'],
|
|
'actorDisplayName' => (string) $message['actorDisplayName'],
|
|
'systemMessage' => (string) $message['systemMessage'],
|
|
];
|
|
}, $messages));
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" gets the following candidate mentions in room "([^"]*)" for "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $identifier
|
|
* @param string $search
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
* @param TableNode|null $formData
|
|
*/
|
|
public function userGetsTheFollowingCandidateMentionsInRoomFor($user, $identifier, $search, $statusCode, $apiVersion = 'v1', TableNode $formData = null) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '/mentions?search=' . $search);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
|
|
$mentions = $this->getDataFromResponse($this->response);
|
|
|
|
if ($formData === null) {
|
|
Assert::assertEmpty($mentions);
|
|
return;
|
|
}
|
|
|
|
Assert::assertCount(count($formData->getHash()), $mentions, 'Mentions count does not match');
|
|
|
|
usort($mentions, function ($a, $b) {
|
|
if ($a['source'] === $b['source']) {
|
|
return $a['label'] <=> $b['label'];
|
|
}
|
|
return $a['source'] <=> $b['source'];
|
|
});
|
|
|
|
$expected = $formData->getHash();
|
|
usort($expected, function ($a, $b) {
|
|
if ($a['source'] === $b['source']) {
|
|
return $a['label'] <=> $b['label'];
|
|
}
|
|
return $a['source'] <=> $b['source'];
|
|
});
|
|
|
|
foreach ($expected as $key => $row) {
|
|
if ($row['id'] === 'GUEST_ID') {
|
|
Assert::assertRegExp('/^guest\/[0-9a-f]{40}$/', $mentions[$key]['id']);
|
|
$mentions[$key]['id'] = 'GUEST_ID';
|
|
}
|
|
Assert::assertEquals($row, $mentions[$key]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^guest "([^"]*)" sets name to "([^"]*)" in room "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $name
|
|
* @param string $identifier
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function guestSetsName($user, $name, $identifier, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/guest/' . self::$identifierToToken[$identifier] . '/name',
|
|
new TableNode([['displayName', $name]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^last response has (no) last common read message header$/
|
|
*
|
|
* @param string $no
|
|
*/
|
|
public function hasNoChatLastCommonReadHeader($no) {
|
|
Assert::assertArrayNotHasKey('X-Chat-Last-Common-Read', $this->response->getHeaders(), 'X-Chat-Last-Common-Read is set to ' . ($this->response->getHeader('X-Chat-Last-Common-Read')[0] ?? '0'));
|
|
}
|
|
|
|
/**
|
|
* @Then /^last response has last common read message header (set to|less than) "([^"]*)"$/
|
|
*
|
|
* @param string $setOrLower
|
|
* @param string $message
|
|
*/
|
|
public function hasChatLastCommonReadHeader($setOrLower, $message) {
|
|
Assert::assertArrayHasKey('X-Chat-Last-Common-Read', $this->response->getHeaders());
|
|
if ($setOrLower === 'set to') {
|
|
Assert::assertEquals(self::$messages[$message], $this->response->getHeader('X-Chat-Last-Common-Read')[0]);
|
|
} else {
|
|
// Less than might be required for the first message, because the last read message before is the join/room creation message and we don't know that ID
|
|
Assert::assertLessThan(self::$messages[$message], $this->response->getHeader('X-Chat-Last-Common-Read')[0]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" sets setting "([^"]*)" to "([^"]*)" with (\d+)(?: \((v(1|2|3))\))?$/
|
|
*
|
|
* @param string $user
|
|
* @param string $setting
|
|
* @param string $value
|
|
* @param string $statusCode
|
|
* @param string $apiVersion
|
|
*/
|
|
public function userSetting($user, $setting, $value, $statusCode, $apiVersion = 'v1') {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'POST', '/apps/spreed/api/' . $apiVersion . '/settings/user',
|
|
new TableNode([['key', $setting], ['value', $value]])
|
|
);
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Then /^user "([^"]*)" has capability "([^"]*)" set to "([^"]*)"$/
|
|
*
|
|
* @param string $user
|
|
* @param string $capability
|
|
* @param string $value
|
|
*/
|
|
public function userCheckCapability($user, $capability, $value) {
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest(
|
|
'GET', '/cloud/capabilities'
|
|
);
|
|
|
|
|
|
$data = $this->getDataFromResponse($this->response);
|
|
$capabilities = $data['capabilities'];
|
|
|
|
$keys = explode('=>', $capability);
|
|
$finalKey = array_pop($keys);
|
|
$cur = $capabilities;
|
|
|
|
foreach ($keys as $key) {
|
|
Assert::assertArrayHasKey($key, $cur);
|
|
$cur = $cur[$key];
|
|
}
|
|
Assert::assertEquals($value, $cur[$finalKey]);
|
|
}
|
|
|
|
/**
|
|
* Parses the xml answer to get the array of users returned.
|
|
* @param ResponseInterface $response
|
|
* @return array
|
|
*/
|
|
protected function getDataFromResponse(ResponseInterface $response) {
|
|
$jsonBody = json_decode($response->getBody()->getContents(), true);
|
|
return $jsonBody['ocs']['data'];
|
|
}
|
|
|
|
/**
|
|
* @Then /^status code is ([0-9]*)$/
|
|
*
|
|
* @param int $statusCode
|
|
*/
|
|
public function isStatusCode($statusCode) {
|
|
$this->assertStatusCode($this->response, $statusCode);
|
|
}
|
|
|
|
/**
|
|
* @Given /^the following app config is set$/
|
|
*
|
|
* @param TableNode $formData
|
|
*/
|
|
public function setAppConfig(TableNode $formData): void {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
foreach ($formData->getRows() as $row) {
|
|
$this->sendRequest('POST', '/apps/provisioning_api/api/v1/config/apps/spreed/' . $row[0], [
|
|
'value' => $row[1],
|
|
]);
|
|
$this->changedConfigs[] = $row[0];
|
|
}
|
|
$this->setCurrentUser($currentUser);
|
|
}
|
|
|
|
/**
|
|
* @BeforeScenario
|
|
* @AfterScenario
|
|
*/
|
|
public function resetSpreedAppData() {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('DELETE', '/apps/spreedcheats/');
|
|
foreach ($this->changedConfigs as $config) {
|
|
$this->sendRequest('DELETE', '/apps/provisioning_api/api/v1/config/apps/spreed/' . $config);
|
|
}
|
|
|
|
$this->setCurrentUser($currentUser);
|
|
}
|
|
|
|
/*
|
|
* User management
|
|
*/
|
|
|
|
/**
|
|
* @Given /^as user "([^"]*)"$/
|
|
* @param string $user
|
|
*/
|
|
public function setCurrentUser($user) {
|
|
$this->currentUser = $user;
|
|
}
|
|
|
|
/**
|
|
* @Given /^user "([^"]*)" exists$/
|
|
* @param string $user
|
|
*/
|
|
public function assureUserExists($user) {
|
|
$response = $this->userExists($user);
|
|
if ($response->getStatusCode() !== 200) {
|
|
$this->createUser($user);
|
|
// Set a display name different than the user ID to be able to
|
|
// ensure in the tests that the right value was returned.
|
|
$this->setUserDisplayName($user);
|
|
$response = $this->userExists($user);
|
|
$this->assertStatusCode($response, 200);
|
|
}
|
|
}
|
|
|
|
private function userExists($user) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('GET', '/cloud/users/' . $user);
|
|
$this->setCurrentUser($currentUser);
|
|
return $this->response;
|
|
}
|
|
|
|
private function createUser($user) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('POST', '/cloud/users', [
|
|
'userid' => $user,
|
|
'password' => '123456'
|
|
]);
|
|
$this->assertStatusCode($this->response, 200, 'Failed to create user');
|
|
|
|
//Quick hack to login once with the current user
|
|
$this->setCurrentUser($user);
|
|
$this->sendRequest('GET', '/cloud/users' . '/' . $user);
|
|
$this->assertStatusCode($this->response, 200, 'Failed to do first login');
|
|
|
|
$this->createdUsers[] = $user;
|
|
|
|
$this->setCurrentUser($currentUser);
|
|
}
|
|
|
|
/**
|
|
* @Given /^user "([^"]*)" is deleted$/
|
|
* @param string $user
|
|
*/
|
|
public function userIsDeleted($user) {
|
|
$deleted = false;
|
|
|
|
$this->deleteUser($user);
|
|
|
|
$response = $this->userExists($user);
|
|
$deleted = $response->getStatusCode() === 404;
|
|
|
|
if (!$deleted) {
|
|
Assert::fail("User $user exists");
|
|
}
|
|
}
|
|
|
|
private function deleteUser($user) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('DELETE', '/cloud/users/' . $user);
|
|
$this->setCurrentUser($currentUser);
|
|
|
|
unset($this->createdUsers[array_search($user, $this->createdUsers, true)]);
|
|
|
|
return $this->response;
|
|
}
|
|
|
|
private function setUserDisplayName($user) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('PUT', '/cloud/users/' . $user, [
|
|
'key' => 'displayname',
|
|
'value' => $user . '-displayname'
|
|
]);
|
|
$this->setCurrentUser($currentUser);
|
|
}
|
|
|
|
/**
|
|
* @Given /^group "([^"]*)" exists$/
|
|
* @param string $group
|
|
*/
|
|
public function assureGroupExists($group) {
|
|
$response = $this->groupExists($group);
|
|
if ($response->getStatusCode() !== 200) {
|
|
$this->createGroup($group);
|
|
$response = $this->groupExists($group);
|
|
$this->assertStatusCode($response, 200);
|
|
}
|
|
}
|
|
|
|
private function groupExists($group) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('GET', '/cloud/groups/' . $group);
|
|
$this->setCurrentUser($currentUser);
|
|
return $this->response;
|
|
}
|
|
|
|
private function createGroup($group) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('POST', '/cloud/groups', [
|
|
'groupid' => $group,
|
|
]);
|
|
$this->setCurrentUser($currentUser);
|
|
|
|
$this->createdGroups[] = $group;
|
|
}
|
|
|
|
private function deleteGroup($group) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('DELETE', '/cloud/groups/' . $group);
|
|
$this->setCurrentUser($currentUser);
|
|
|
|
unset($this->createdGroups[array_search($group, $this->createdGroups, true)]);
|
|
}
|
|
|
|
/**
|
|
* @When /^user "([^"]*)" is member of group "([^"]*)"$/
|
|
* @param string $user
|
|
* @param string $group
|
|
*/
|
|
public function addingUserToGroup($user, $group) {
|
|
$currentUser = $this->currentUser;
|
|
$this->setCurrentUser('admin');
|
|
$this->sendRequest('POST', "/cloud/users/$user/groups", [
|
|
'groupid' => $group,
|
|
]);
|
|
$this->assertStatusCode($this->response, 200);
|
|
$this->setCurrentUser($currentUser);
|
|
}
|
|
|
|
/*
|
|
* Requests
|
|
*/
|
|
|
|
/**
|
|
* @Given /^user "([^"]*)" logs in$/
|
|
* @param string $user
|
|
*/
|
|
public function userLogsIn(string $user) {
|
|
$loginUrl = $this->baseUrl . '/login';
|
|
|
|
$cookieJar = $this->getUserCookieJar($user);
|
|
|
|
// Request a new session and extract CSRF token
|
|
$client = new Client();
|
|
$this->response = $client->get(
|
|
$loginUrl,
|
|
[
|
|
'cookies' => $cookieJar,
|
|
]
|
|
);
|
|
|
|
$requestToken = $this->extractRequestTokenFromResponse($this->response);
|
|
|
|
// Login and extract new token
|
|
$password = ($user === 'admin') ? 'admin' : '123456';
|
|
$client = new Client();
|
|
$this->response = $client->post(
|
|
$loginUrl,
|
|
[
|
|
'form_params' => [
|
|
'user' => $user,
|
|
'password' => $password,
|
|
'requesttoken' => $requestToken,
|
|
],
|
|
'cookies' => $cookieJar,
|
|
]
|
|
);
|
|
|
|
$this->assertStatusCode($this->response, 200);
|
|
}
|
|
|
|
/**
|
|
* @param ResponseInterface $response
|
|
* @return string
|
|
*/
|
|
private function extractRequestTokenFromResponse(ResponseInterface $response): string {
|
|
return substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $response->getBody()->getContents()), 0, 89);
|
|
}
|
|
|
|
/**
|
|
* @When /^sending "([^"]*)" to "([^"]*)" with$/
|
|
* @param string $verb
|
|
* @param string $url
|
|
* @param TableNode|array|null $body
|
|
* @param array $headers
|
|
*/
|
|
public function sendRequest($verb, $url, $body = null, array $headers = []) {
|
|
$fullUrl = $this->baseUrl . 'ocs/v2.php' . $url;
|
|
$client = new Client();
|
|
$options = ['cookies' => $this->getUserCookieJar($this->currentUser)];
|
|
if ($this->currentUser === 'admin') {
|
|
$options['auth'] = ['admin', 'admin'];
|
|
} elseif (strpos($this->currentUser, 'guest') !== 0) {
|
|
$options['auth'] = [$this->currentUser, '123456'];
|
|
}
|
|
if ($body instanceof TableNode) {
|
|
$fd = $body->getRowsHash();
|
|
$options['form_params'] = $fd;
|
|
} elseif (is_array($body)) {
|
|
$options['form_params'] = $body;
|
|
}
|
|
|
|
$options['headers'] = array_merge($headers, [
|
|
'OCS-ApiRequest' => 'true',
|
|
'Accept' => 'application/json',
|
|
]);
|
|
|
|
try {
|
|
$this->response = $client->{$verb}($fullUrl, $options);
|
|
} catch (ClientException $ex) {
|
|
$this->response = $ex->getResponse();
|
|
}
|
|
}
|
|
|
|
protected function getUserCookieJar($user) {
|
|
if (!isset($this->cookieJars[$user])) {
|
|
$this->cookieJars[$user] = new CookieJar();
|
|
}
|
|
return $this->cookieJars[$user];
|
|
}
|
|
|
|
/**
|
|
* @param ResponseInterface $response
|
|
* @param int $statusCode
|
|
* @param string $message
|
|
*/
|
|
protected function assertStatusCode(ResponseInterface $response, int $statusCode, string $message = '') {
|
|
Assert::assertEquals($statusCode, $response->getStatusCode(), $message);
|
|
}
|
|
}
|