Browse Source

Merge pull request #12785 from nextcloud/add-real-federated-server-for-integration-tests

Add real federated server for integration tests
pull/12786/head
Joas Schilling 1 year ago
committed by GitHub
parent
commit
000e53959d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 20
      tests/integration/features/bootstrap/CommandLineTrait.php
  2. 308
      tests/integration/features/bootstrap/FeatureContext.php
  3. 12
      tests/integration/features/bootstrap/SharingContext.php
  4. 100
      tests/integration/features/federation/chat.feature
  5. 10
      tests/integration/features/federation/poll.feature
  6. 126
      tests/integration/run.sh

20
tests/integration/features/bootstrap/CommandLineTrait.php

@ -8,6 +8,11 @@ use PHPUnit\Framework\Assert;
require __DIR__ . '/../../vendor/autoload.php';
// The following attributes are expected to be available in the class that uses
// this trait:
// - currentServer
// - localServerUrl
// - remoteServerUrl
trait CommandLineTrait {
/** @var int return code of last command */
private int $lastCode = 0;
@ -26,7 +31,7 @@ trait CommandLineTrait {
* @param []string $env environment variables
* @return int exit code
*/
public function runOcc($args = [], $env = null) {
public function runOcc($args = [], $env = []) {
// Set UTF-8 locale to ensure that escapeshellarg will not strip
// multibyte characters.
setlocale(LC_CTYPE, "C.UTF-8");
@ -45,6 +50,12 @@ trait CommandLineTrait {
$args[] = '--no-ansi';
$argString = implode(' ', $args);
if ($this->currentServer === 'REMOTE') {
$env['NEXTCLOUD_CONFIG_DIR'] = getenv('REAL_FEDERATED_SERVER_CONFIG_DIR');
} else {
$env['NEXTCLOUD_CONFIG_DIR'] = getenv('MAIN_SERVER_CONFIG_DIR');
}
$descriptor = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
@ -58,7 +69,12 @@ trait CommandLineTrait {
if ($clearOpcodeCache) {
// Clean opcode cache
$client = new GuzzleHttp\Client();
$client->request('GET', 'http://localhost:8080/apps/testing/clean_opcode_cache.php');
if ($this->currentServer === 'REMOTE') {
$client->request('GET', $this->remoteServerUrl . 'apps/testing/clean_opcode_cache.php');
} else {
$client->request('GET', $this->localServerUrl . 'apps/testing/clean_opcode_cache.php');
}
}
return $this->lastCode;

308
tests/integration/features/bootstrap/FeatureContext.php

@ -61,7 +61,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
protected static ?array $nextChatRequestParameters = null;
/** @var array<string, int> */
protected static array $modifiedSince;
/** @var array<string, string> */
/** @var array */
protected static array $createdTeams = [];
/** @var array<string, int> */
protected static array $userToBanId;
@ -86,9 +86,15 @@ class FeatureContext implements Context, SnippetAcceptingContext {
/** @var CookieJar[] */
private array $cookieJars;
protected string $localServerUrl;
protected string $localRemoteServerUrl;
protected string $remoteServerUrl;
protected string $baseUrl;
protected string $baseRemoteUrl;
protected string $currentServer;
/** @var string[] */
protected array $createdUsers = [];
@ -106,9 +112,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
private ?SharingContext $sharingContext;
private ?bool $guestsAppWasEnabled = null;
private array $guestsAppWasEnabled = [];
private string $guestsOldWhitelist;
private array $guestsOldWhitelist = [];
use CommandLineTrait;
use RecordingTrait;
@ -117,8 +123,8 @@ class FeatureContext implements Context, SnippetAcceptingContext {
return self::$identifierToToken[$identifier];
}
public static function getTeamIdForLabel(string $label): string {
return self::$createdTeams[$label] ?? throw new \RuntimeException('Unknown team: ' . $label);
public static function getTeamIdForLabel(string $server, string $label): string {
return self::$createdTeams[$server][$label] ?? throw new \RuntimeException('Unknown team: ' . $label);
}
public static function getMessageIdForText(string $text): int {
@ -158,14 +164,21 @@ class FeatureContext implements Context, SnippetAcceptingContext {
*/
public function __construct() {
$this->cookieJars = [];
$this->baseUrl = getenv('TEST_SERVER_URL');
$this->baseRemoteUrl = getenv('TEST_REMOTE_URL');
$this->localServerUrl = getenv('TEST_SERVER_URL');
$this->localRemoteServerUrl = getenv('TEST_LOCAL_REMOTE_URL');
$this->remoteServerUrl = getenv('TEST_REMOTE_URL');
foreach (['LOCAL', 'REMOTE'] as $server) {
$this->changedConfigs[$server] = [];
$this->guestsAppWasEnabled[$server] = null;
$this->guestsOldWhitelist[$server] = '';
}
}
/**
* @BeforeScenario
*/
public function setUp() {
public function setUp(BeforeScenarioScope $scope) {
self::$identifierToToken = [];
self::$identifierToId = [];
self::$tokenToIdentifier = [];
@ -185,10 +198,18 @@ class FeatureContext implements Context, SnippetAcceptingContext {
self::$phoneNumberToActorId = [];
self::$modifiedSince = [];
$this->createdUsers = [];
$this->createdGroups = [];
self::$createdTeams = [];
$this->createdGuestAccountUsers = [];
foreach (['LOCAL', 'REMOTE'] as $server) {
$this->createdUsers[$server] = [];
$this->createdGroups[$server] = [];
self::$createdTeams[$server] = [];
$this->createdGuestAccountUsers[$server] = [];
}
// Force getting sibling contexts to ensure that sharingContext is set
// before using it.
$this->getOtherRequiredSiblingContexts($scope);
$this->usingServer('LOCAL');
}
/**
@ -204,18 +225,37 @@ class FeatureContext implements Context, SnippetAcceptingContext {
* @AfterScenario
*/
public function tearDown() {
foreach ($this->createdUsers as $user) {
$this->deleteUser($user);
}
foreach ($this->createdGroups as $group) {
$this->deleteGroup($group);
}
foreach (self::$createdTeams as $team => $id) {
$this->deleteTeam($team);
foreach (['LOCAL', 'REMOTE'] as $server) {
$this->usingServer($server);
foreach ($this->createdUsers[$server] as $user) {
$this->deleteUser($user);
}
foreach ($this->createdGroups[$server] as $group) {
$this->deleteGroup($group);
}
foreach (self::$createdTeams[$server] as $team => $id) {
$this->deleteTeam($team);
}
foreach ($this->createdGuestAccountUsers[$server] as $user) {
$this->deleteGuestUser($user);
}
}
foreach ($this->createdGuestAccountUsers as $user) {
$this->deleteGuestUser($user);
}
/**
* Given /^using server (LOCAL|REMOTE)$/
* @param string $server
*/
public function usingServer(string $server) {
if ($server === 'LOCAL') {
$this->baseUrl = $this->localServerUrl;
} else {
$this->baseUrl = $this->remoteServerUrl;
}
$this->currentServer = $server;
$this->sharingContext->setCurrentServer($this->currentServer, $this->localServerUrl);
}
/**
@ -493,8 +533,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
}
if (isset($expectedRoom['lastMessageActorId'])) {
$data['lastMessageActorId'] = $room['lastMessage'] ? $room['lastMessage']['actorId'] : '';
$data['lastMessageActorId'] = str_replace(rtrim($this->baseUrl, '/'), '{$BASE_URL}', $data['lastMessageActorId']);
$data['lastMessageActorId'] = str_replace(rtrim($this->baseRemoteUrl, '/'), '{$REMOTE_URL}', $data['lastMessageActorId']);
$data['lastMessageActorId'] = str_replace(rtrim($this->localServerUrl, '/'), '{$LOCAL_URL}', $data['lastMessageActorId']);
$data['lastMessageActorId'] = str_replace(rtrim($this->localRemoteServerUrl, '/'), '{$LOCAL_REMOTE_URL}', $data['lastMessageActorId']);
$data['lastMessageActorId'] = str_replace(rtrim($this->remoteServerUrl, '/'), '{$REMOTE_URL}', $data['lastMessageActorId']);
}
if (isset($expectedRoom['lastReadMessage'])) {
$data['lastReadMessage'] = self::$messageIdToText[(int) $room['lastReadMessage']] ?? (!$room['lastReadMessage'] ? 'ZERO': 'UNKNOWN_MESSAGE');
@ -568,8 +609,12 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$verb = $acceptsDeclines === 'accepts' ? 'POST' : 'DELETE';
$this->setCurrentUser($user);
if ($server === 'LOCAL') {
$this->sendRemoteRequest($verb, '/apps/spreed/api/' . $apiVersion . '/federation/invitation/' . $inviteId);
if ($this->currentServer === 'LOCAL' && $server === 'LOCAL') {
$this->baseUrl = $this->localRemoteServerUrl;
$this->sendRequest($verb, '/apps/spreed/api/' . $apiVersion . '/federation/invitation/' . $inviteId);
$this->baseUrl = $this->localServerUrl;
} else {
$this->sendRequest($verb, '/apps/spreed/api/' . $apiVersion . '/federation/invitation/' . $inviteId);
}
$this->assertStatusCode($this->response, $status);
$response = $this->getDataFromResponse($this->response);
@ -636,6 +681,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
return 'LOCAL';
}
if ($server === 'localhost:8180') {
return 'LOCAL_REMOTE';
}
if ($server === 'localhost:8280') {
return 'REMOTE';
}
return 'unknown-server';
@ -791,8 +839,18 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$attendee['actorId'] = sha1(self::$userToSessionId[trim($attendee['actorId'], '"')]);
}
if (isset($attendee['actorId'], $attendee['actorType']) && $attendee['actorType'] === 'federated_users') {
$attendee['actorId'] .= '@' . rtrim($this->baseRemoteUrl, '/');
if (isset($attendee['actorId']) && str_ends_with($attendee['actorId'], '@{$LOCAL_URL}')) {
$attendee['actorId'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $attendee['actorId']);
}
if (isset($attendee['actorId']) && str_ends_with($attendee['actorId'], '@{$LOCAL_REMOTE_URL}')) {
$attendee['actorId'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $attendee['actorId']);
}
if (isset($attendee['actorId']) && str_ends_with($attendee['actorId'], '@{$REMOTE_URL}')) {
$attendee['actorId'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $attendee['actorId']);
}
if (isset($attendee['actorId'], $attendee['actorType']) && $attendee['actorType'] === 'federated_users' && !str_contains($attendee['actorId'], '@')) {
$attendee['actorId'] .= '@' . rtrim($this->localRemoteServerUrl, '/');
}
if (isset($attendee['actorId'], $attendee['actorType'], $attendee['phoneNumber'])
@ -1448,7 +1506,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$attendeeId = 123456789;
} else {
if ($actorType === 'remote') {
$actorId .= '@' . rtrim($this->baseRemoteUrl, '/');
$actorId .= '@' . rtrim($this->localRemoteServerUrl, '/');
$actorType = 'federated_user';
}
@ -1480,7 +1538,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$actorId = '123456789';
} else {
if ($actorType === 'remote') {
$actorId .= '@' . rtrim($this->baseRemoteUrl, '/');
$actorId .= '@' . rtrim($this->localRemoteServerUrl, '/');
$actorType = 'federated_user';
}
}
@ -1574,7 +1632,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$actorId = '123456789';
} else {
if ($actorType === 'remote') {
$actorId .= '@' . rtrim($this->baseRemoteUrl, '/');
$actorId .= '@' . rtrim($this->localRemoteServerUrl, '/');
$actorType = 'federated_user';
}
}
@ -1847,7 +1905,11 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->setCurrentUser($user);
if ($newType === 'federated_user') {
$newId .= '@' . $this->baseRemoteUrl;
if (!str_contains($newId, '@')) {
$newId .= '@' . $this->localRemoteServerUrl;
} else {
$newId = str_replace('REMOTE', $this->remoteServerUrl, $newId);
}
}
$this->sendRequest(
@ -2120,8 +2182,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
public function userSendsMessageToRoom(string $user, string $sendingMode, string $message, string $identifier, string $statusCode, string $apiVersion = 'v1') {
$message = substr($message, 1, -1);
$message = str_replace('\n', "\n", $message);
$message = str_replace('{$BASE_URL}', $this->baseUrl, $message);
$message = str_replace('{$REMOTE_URL}', $this->baseRemoteUrl, $message);
$message = str_replace('{$LOCAL_URL}', $this->localServerUrl, $message);
$message = str_replace('{$LOCAL_REMOTE_URL}', $this->localRemoteServerUrl, $message);
$message = str_replace('{$REMOTE_URL}', $this->remoteServerUrl, $message);
if ($message === '413 Payload Too Large') {
$message .= "\n" . str_repeat('1', 32000);
@ -2403,19 +2466,25 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$expected['status'] = 1;
}
if (str_ends_with($expected['actorId'], '@{$BASE_URL}')) {
$expected['actorId'] = str_replace('{$BASE_URL}', rtrim($this->baseUrl, '/'), $expected['actorId']);
if (str_ends_with($expected['actorId'], '@{$LOCAL_URL}')) {
$expected['actorId'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $expected['actorId']);
}
if (str_ends_with($expected['actorId'], '@{$LOCAL_REMOTE_URL}')) {
$expected['actorId'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $expected['actorId']);
}
if (str_ends_with($expected['actorId'], '@{$REMOTE_URL}')) {
$expected['actorId'] = str_replace('{$REMOTE_URL}', rtrim($this->baseRemoteUrl, '/'), $expected['actorId']);
$expected['actorId'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $expected['actorId']);
}
if (isset($expected['details'])) {
if (str_contains($expected['details'], '@{$BASE_URL}')) {
$expected['details'] = str_replace('{$BASE_URL}', rtrim($this->baseUrl, '/'), $expected['details']);
if (str_contains($expected['details'], '@{$LOCAL_URL}')) {
$expected['details'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $expected['details']);
}
if (str_contains($expected['details'], '@{$LOCAL_REMOTE_URL}')) {
$expected['details'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $expected['details']);
}
if (str_contains($expected['details'], '@{$REMOTE_URL}')) {
$expected['details'] = str_replace('{$REMOTE_URL}', rtrim($this->baseRemoteUrl, '/'), $expected['details']);
$expected['details'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $expected['details']);
}
}
@ -2865,26 +2934,35 @@ class FeatureContext implements Context, SnippetAcceptingContext {
}
$expected[$i]['message'] = str_replace('\n', "\n", $expected[$i]['message']);
if (str_ends_with($expected[$i]['actorId'], '@{$BASE_URL}')) {
$expected[$i]['actorId'] = str_replace('{$BASE_URL}', rtrim($this->baseUrl, '/'), $expected[$i]['actorId']);
if (str_ends_with($expected[$i]['actorId'], '@{$LOCAL_URL}')) {
$expected[$i]['actorId'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $expected[$i]['actorId']);
}
if (str_ends_with($expected[$i]['actorId'], '@{$LOCAL_REMOTE_URL}')) {
$expected[$i]['actorId'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $expected[$i]['actorId']);
}
if (str_ends_with($expected[$i]['actorId'], '@{$REMOTE_URL}')) {
$expected[$i]['actorId'] = str_replace('{$REMOTE_URL}', rtrim($this->baseRemoteUrl, '/'), $expected[$i]['actorId']);
$expected[$i]['actorId'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $expected[$i]['actorId']);
}
if (str_contains($expected[$i]['messageParameters'], '{$BASE_URL}')) {
$expected[$i]['messageParameters'] = str_replace('{$BASE_URL}', str_replace('/', '\/', rtrim($this->baseUrl, '/')), $expected[$i]['messageParameters']);
if (str_contains($expected[$i]['messageParameters'], '{$LOCAL_URL}')) {
$expected[$i]['messageParameters'] = str_replace('{$LOCAL_URL}', str_replace('/', '\/', rtrim($this->localServerUrl, '/')), $expected[$i]['messageParameters']);
}
if (str_contains($expected[$i]['messageParameters'], '{$LOCAL_REMOTE_URL}')) {
$expected[$i]['messageParameters'] = str_replace('{$LOCAL_REMOTE_URL}', str_replace('/', '\/', rtrim($this->localRemoteServerUrl, '/')), $expected[$i]['messageParameters']);
}
if (str_contains($expected[$i]['messageParameters'], '{$REMOTE_URL}')) {
$expected[$i]['messageParameters'] = str_replace('{$REMOTE_URL}', str_replace('/', '\/', rtrim($this->baseRemoteUrl, '/')), $expected[$i]['messageParameters']);
$expected[$i]['messageParameters'] = str_replace('{$REMOTE_URL}', str_replace('/', '\/', rtrim($this->remoteServerUrl, '/')), $expected[$i]['messageParameters']);
}
if (isset($expected[$i]['lastEditActorId'])) {
if (str_ends_with($expected[$i]['lastEditActorId'], '@{$BASE_URL}')) {
$expected[$i]['lastEditActorId'] = str_replace('{$BASE_URL}', rtrim($this->baseUrl, '/'), $expected[$i]['lastEditActorId']);
if (str_ends_with($expected[$i]['lastEditActorId'], '@{$LOCAL_URL}')) {
$expected[$i]['lastEditActorId'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $expected[$i]['lastEditActorId']);
}
if (str_ends_with($expected[$i]['lastEditActorId'], '@{$LOCAL_REMOTE_URL}')) {
$expected[$i]['lastEditActorId'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $expected[$i]['lastEditActorId']);
}
if (str_ends_with($expected[$i]['lastEditActorId'], '@{$REMOTE_URL}')) {
$expected[$i]['lastEditActorId'] = str_replace('{$REMOTE_URL}', rtrim($this->baseRemoteUrl, '/'), $expected[$i]['lastEditActorId']);
$expected[$i]['lastEditActorId'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $expected[$i]['lastEditActorId']);
}
}
@ -3113,17 +3191,23 @@ class FeatureContext implements Context, SnippetAcceptingContext {
Assert::assertMatchesRegularExpression('/^guest\/[0-9a-f]{40}$/', $mentions[$key]['mentionId']);
$mentions[$key]['mentionId'] = 'GUEST_ID';
}
if (str_ends_with($row['id'], '@{$BASE_URL}')) {
$row['id'] = str_replace('{$BASE_URL}', rtrim($this->baseUrl, '/'), $row['id']);
if (str_ends_with($row['id'], '@{$LOCAL_URL}')) {
$row['id'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $row['id']);
}
if (str_ends_with($row['id'], '@{$LOCAL_REMOTE_URL}')) {
$row['id'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $row['id']);
}
if (str_ends_with($row['id'], '@{$REMOTE_URL}')) {
$row['id'] = str_replace('{$REMOTE_URL}', rtrim($this->baseRemoteUrl, '/'), $row['id']);
$row['id'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $row['id']);
}
if (str_ends_with($row['mentionId'], '@{$BASE_URL}')) {
$row['mentionId'] = str_replace('{$BASE_URL}', rtrim($this->baseUrl, '/'), $row['mentionId']);
$row['mentionId'] = str_replace('{$BASE_URL}', rtrim($this->localServerUrl, '/'), $row['mentionId']);
}
if (str_ends_with($row['mentionId'], '@{$LOCAL_REMOTE_URL}')) {
$row['mentionId'] = str_replace('{$LOCAL_REMOTE_URL}', rtrim($this->localRemoteServerUrl, '/'), $row['mentionId']);
}
if (str_ends_with($row['mentionId'], '@{$REMOTE_URL}')) {
$row['mentionId'] = str_replace('{$REMOTE_URL}', rtrim($this->baseRemoteUrl, '/'), $row['mentionId']);
$row['mentionId'] = str_replace('{$REMOTE_URL}', rtrim($this->remoteServerUrl, '/'), $row['mentionId']);
}
if (array_key_exists('avatar', $row)) {
Assert::assertMatchesRegularExpression('/' . self::$identifierToToken[$row['avatar']] . '\/avatar/', $mentions[$key]['avatar']);
@ -3497,7 +3581,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->sendRequest('POST', '/apps/provisioning_api/api/v1/config/apps/' . $appId . '/' . $row[0], [
'value' => $row[1],
]);
$this->changedConfigs[$appId][] = $row[0];
$this->changedConfigs[$this->currentServer][$appId][] = $row[0];
}
$this->setCurrentUser($currentUser);
}
@ -3565,8 +3649,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
[$roomToken, $message] = explode('/', $notification['object_id']);
$messageText = self::$messageIdToText[$message] ?? 'UNKNOWN_MESSAGE';
$messageText = str_replace($this->baseUrl, '{$BASE_URL}', $messageText);
$messageText = str_replace($this->baseRemoteUrl, '{$REMOTE_URL}', $messageText);
$messageText = str_replace($this->localServerUrl, '{$LOCAL_URL}', $messageText);
$messageText = str_replace($this->localRemoteServerUrl, '{$LOCAL_REMOTE_URL}', $messageText);
$messageText = str_replace($this->remoteServerUrl, '{$REMOTE_URL}', $messageText);
$data['object_id'] = self::$tokenToIdentifier[$roomToken] . '/' . $messageText;
} elseif (strpos($expectedNotification['object_id'], 'INVITE_ID') !== false) {
@ -3609,9 +3694,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->sendRequest('GET', '/cloud/apps?filter=enabled');
$this->assertStatusCode($this->response, 200);
$data = $this->getDataFromResponse($this->response);
$this->guestsAppWasEnabled = in_array('guests', $data['apps'], true);
$this->guestsAppWasEnabled[$this->currentServer] = in_array('guests', $data['apps'], true);
if (!$this->guestsAppWasEnabled) {
if (!$this->guestsAppWasEnabled[$this->currentServer]) {
// enable Guests app
/*
$this->sendRequest('POST', '/cloud/apps/guests');
@ -3624,7 +3709,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
// save previously set whitelist
$this->sendRequest('GET', '/apps/provisioning_api/api/v1/config/apps/guests/whitelist');
$this->assertStatusCode($this->response, 200);
$this->guestsOldWhitelist = $this->getDataFromResponse($this->response)['data'];
$this->guestsOldWhitelist[$this->currentServer] = $this->getDataFromResponse($this->response)['data'];
// set whitelist to allow spreed only
$this->sendRequest('POST', '/apps/provisioning_api/api/v1/config/apps/guests/whitelist', [
@ -3639,46 +3724,57 @@ class FeatureContext implements Context, SnippetAcceptingContext {
* @AfterScenario
*/
public function resetSpreedAppData() {
$currentUser = $this->setCurrentUser('admin');
$this->sendRequest('DELETE', '/apps/spreedcheats/');
foreach ($this->changedConfigs as $appId => $configs) {
foreach ($configs as $config) {
$this->sendRequest('DELETE', '/apps/provisioning_api/api/v1/config/apps/' . $appId . '/' . $config);
foreach (['LOCAL', 'REMOTE'] as $server) {
$this->usingServer($server);
$currentUser = $this->setCurrentUser('admin');
$this->sendRequest('DELETE', '/apps/spreedcheats/');
foreach ($this->changedConfigs[$server] as $appId => $configs) {
foreach ($configs as $config) {
$this->sendRequest('DELETE', '/apps/provisioning_api/api/v1/config/apps/' . $appId . '/' . $config);
}
}
}
$this->setCurrentUser($currentUser);
if ($this->changedBruteforceSetting) {
$this->enableDisableBruteForceProtection('disable');
$this->setCurrentUser($currentUser);
if ($this->changedBruteforceSetting) {
$this->enableDisableBruteForceProtection('disable');
}
}
$this->usingServer('LOCAL');
}
/**
* @AfterScenario
*/
public function resetGuestsAppState() {
if ($this->guestsAppWasEnabled === null) {
// Guests app was not touched
return;
}
foreach (['LOCAL', 'REMOTE'] as $server) {
$this->usingServer($server);
$currentUser = $this->setCurrentUser('admin');
if ($this->guestsAppWasEnabled[$server] === null) {
// Guests app was not touched
return;
}
if ($this->guestsOldWhitelist) {
// restore old whitelist
$this->sendRequest('POST', '/apps/provisioning_api/api/v1/config/apps/guests/whitelist', [
'value' => $this->guestsOldWhitelist,
]);
} else {
// restore to default
$this->sendRequest('DELETE', '/apps/provisioning_api/api/v1/config/apps/guests/whitelist');
}
$currentUser = $this->setCurrentUser('admin');
// restore app's enabled state
$this->sendRequest($this->guestsAppWasEnabled ? 'POST' : 'DELETE', '/cloud/apps/guests');
if ($this->guestsOldWhitelist[$server]) {
// restore old whitelist
$this->sendRequest('POST', '/apps/provisioning_api/api/v1/config/apps/guests/whitelist', [
'value' => $this->guestsOldWhitelist[$server],
]);
} else {
// restore to default
$this->sendRequest('DELETE', '/apps/provisioning_api/api/v1/config/apps/guests/whitelist');
}
$this->setCurrentUser($currentUser);
$this->guestsAppWasEnabled = null;
// restore app's enabled state
$this->sendRequest($this->guestsAppWasEnabled[$server] ? 'POST' : 'DELETE', '/cloud/apps/guests');
$this->setCurrentUser($currentUser);
$this->guestsAppWasEnabled[$server] = null;
}
}
/*
@ -3793,14 +3889,14 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$output = $this->getLastStdOut();
$data = json_decode($output, true);
self::$createdTeams[$team] = $data['id'];
self::$createdTeams[$this->currentServer][$team] = $data['id'];
}
/**
* @Given /^add user "([^"]*)" to team "([^"]*)"$/
*/
public function addTeamMember(string $user, string $team): void {
$this->runOcc(['circles:members:add', '--type', '1', self::$createdTeams[$team], $user]);
$this->runOcc(['circles:members:add', '--type', '1', self::$createdTeams[$this->currentServer][$team], $user]);
$this->theCommandWasSuccessful();
}
@ -3808,10 +3904,10 @@ class FeatureContext implements Context, SnippetAcceptingContext {
* @Given /^delete team "([^"]*)"$/
*/
public function deleteTeam(string $team): void {
$this->runOcc(['circles:manage:destroy', self::$createdTeams[$team]]);
$this->runOcc(['circles:manage:destroy', self::$createdTeams[$this->currentServer][$team]]);
$this->theCommandWasSuccessful();
unset(self::$createdTeams[$team]);
unset(self::$createdTeams[$this->currentServer][$team]);
}
/**
@ -3837,7 +3933,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
]);
Assert::assertEquals(0, $lastCode, 'Guest creation succeeded for ' . $email);
$this->createdGuestAccountUsers[$email] = $email;
$this->createdGuestAccountUsers[$this->currentServer][$email] = $email;
$this->setCurrentUser($currentUser);
}
@ -3861,7 +3957,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->sendRequest('GET', '/cloud/users' . '/' . $user);
$this->assertStatusCode($this->response, 200, 'Failed to do first login');
$this->createdUsers[$user] = $user;
$this->createdUsers[$this->currentServer][$user] = $user;
$this->setCurrentUser($currentUser);
}
@ -3888,7 +3984,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->sendRequest('DELETE', '/cloud/users/' . $user);
$this->setCurrentUser($currentUser);
unset($this->createdUsers[$user]);
unset($this->createdUsers[$this->currentServer][$user]);
return $this->response;
}
@ -3898,7 +3994,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->sendRequest('DELETE', '/cloud/users/' . $user);
$this->setCurrentUser($currentUser);
unset($this->createdGuestAccountUsers[$user]);
unset($this->createdGuestAccountUsers[$this->currentServer][$user]);
return $this->response;
}
@ -3937,7 +4033,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->setCurrentUser($currentUser);
$this->createdGroups[$group] = $group;
$this->createdGroups[$this->currentServer][$group] = $group;
}
/**
@ -3961,7 +4057,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->sendRequest('DELETE', '/cloud/groups/' . $group);
$this->setCurrentUser($currentUser);
unset($this->createdGroups[$group]);
unset($this->createdGroups[$this->currentServer][$group]);
$this->setCurrentUser($currentUser);
}
@ -4053,8 +4149,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
unset($reaction['timestamp']);
$reaction['actorId'] = ($reaction['actorType'] === 'guests') ? self::$sessionIdToUser[$reaction['actorId']] : (string) $reaction['actorId'];
if ($reaction['actorType'] === 'federated_users') {
$reaction['actorId'] = str_replace(rtrim($this->baseUrl, '/'), '{$BASE_URL}', $reaction['actorId']);
$reaction['actorId'] = str_replace(rtrim($this->baseRemoteUrl, '/'), '{$REMOTE_URL}', $reaction['actorId']);
$reaction['actorId'] = str_replace(rtrim($this->localServerUrl, '/'), '{$LOCAL_URL}', $reaction['actorId']);
$reaction['actorId'] = str_replace(rtrim($this->localRemoteServerUrl, '/'), '{$LOCAL_REMOTE_URL}', $reaction['actorId']);
$reaction['actorId'] = str_replace(rtrim($this->remoteServerUrl, '/'), '{$REMOTE_URL}', $reaction['actorId']);
}
return $reaction;
}, $list);
@ -4663,17 +4760,6 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$this->assertStatusCode($this->response, $statusCode);
}
/**
* @param string $verb
* @param string $url
* @param TableNode|array|null $body
* @param array $headers
*/
public function sendRemoteRequest($verb, $url, $body = null, array $headers = []) {
$fullUrl = $this->baseRemoteUrl . 'ocs/v2.php' . $url;
$this->sendRequestFullUrl($verb, $fullUrl, $body, $headers);
}
/**
* @param string $verb
* @param string $fullUrl

12
tests/integration/features/bootstrap/SharingContext.php

@ -13,6 +13,7 @@ use Psr\Http\Message\ResponseInterface;
class SharingContext implements Context {
private string $baseUrl;
private string $currentServer;
private ?ResponseInterface $response = null;
private string $currentUser = '';
private array $adminUser;
@ -31,6 +32,15 @@ class SharingContext implements Context {
}
}
/**
* @param string $currentServer
* @param string $baseUrl
*/
public function setCurrentServer(string $currentServer, string $baseUrl) {
$this->currentServer = $currentServer;
$this->baseUrl = $baseUrl;
}
/**
* @Given user :user creates folder :destination
*
@ -165,7 +175,7 @@ class SharingContext implements Context {
* @param int $statusCode
*/
public function userSharesWithTeamWithOcs(string $user, string $path, string $sharee, int $statusCode) {
$this->userSharesWithTeam($user, $path, FeatureContext::getTeamIdForLabel($sharee));
$this->userSharesWithTeam($user, $path, FeatureContext::getTeamIdForLabel($this->currentServer, $sharee));
$this->theOCSStatusCodeShouldBe($statusCode);
}

100
tests/integration/features/federation/chat.feature

@ -22,15 +22,15 @@ Feature: federation/chat
| id | type |
| LOCAL::room | 2 |
And user "participant1" gets the following candidate mentions in room "room" for "" with 200
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant2@{$REMOTE_URL} | participant2-displayname | federated_user/participant2@{$REMOTE_URL} |
| users | participant3 | participant3-displayname | participant3 |
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | federated_user/participant2@{$LOCAL_REMOTE_URL} |
| users | participant3 | participant3-displayname | participant3 |
And user "participant2" gets the following candidate mentions in room "LOCAL::room" for "" with 200
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant1@{$BASE_URL} | participant1-displayname | participant1 |
| federated_users | participant3@{$BASE_URL} | participant3-displayname | participant3 |
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant1@{$LOCAL_URL} | participant1-displayname | participant1 |
| federated_users | participant3@{$LOCAL_URL} | participant3-displayname | participant3 |
Scenario: Get mention suggestions (translating federated users of the same server to local users)
Given the following "spreed" app config is set
@ -56,15 +56,15 @@ Feature: federation/chat
| id | type |
| LOCAL::room | 2 |
And user "participant1" gets the following candidate mentions in room "room" for "" with 200
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant2@{$REMOTE_URL} | participant2-displayname | federated_user/participant2@{$REMOTE_URL} |
| federated_users | participant3@{$REMOTE_URL} | participant3-displayname | federated_user/participant3@{$REMOTE_URL} |
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | federated_user/participant2@{$LOCAL_REMOTE_URL} |
| federated_users | participant3@{$LOCAL_REMOTE_URL} | participant3-displayname | federated_user/participant3@{$LOCAL_REMOTE_URL} |
And user "participant2" gets the following candidate mentions in room "LOCAL::room" for "" with 200
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant1@{$BASE_URL} | participant1-displayname | participant1 |
| users | participant3 | participant3-displayname | federated_user/participant3@{$REMOTE_URL} |
| source | id | label | mentionId |
| calls | all | room | all |
| federated_users | participant1@{$LOCAL_URL} | participant1-displayname | participant1 |
| users | participant3 | participant3-displayname | federated_user/participant3@{$LOCAL_REMOTE_URL} |
Scenario: Basic chatting including posting, getting, editing and deleting
Given the following "spreed" app config is set
@ -98,42 +98,42 @@ Feature: federation/chat
| id | type | lastMessage |
| LOCAL::room | 2 | Message 1-1 |
Then user "participant1" sees the following messages in room "room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| room | federated_users | participant2@{$REMOTE_URL} | participant2-displayname | Message 1-1 | [] | Message 1 |
| room | users | participant1 | participant1-displayname | Message 1 | [] | |
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| room | federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | Message 1-1 | [] | Message 1 |
| room | users | participant1 | participant1-displayname | Message 1 | [] | |
When next message request has the following parameters set
| timeout | 0 |
And user "participant2" sees the following messages in room "LOCAL::room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| LOCAL::room | users | participant2 | participant2-displayname | Message 1-1 | [] | Message 1 |
| LOCAL::room | federated_users | participant1@{$BASE_URL} | participant1-displayname | Message 1 | [] | |
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| LOCAL::room | users | participant2 | participant2-displayname | Message 1-1 | [] | Message 1 |
| LOCAL::room | federated_users | participant1@{$LOCAL_URL} | participant1-displayname | Message 1 | [] | |
And user "participant1" edits message "Message 1" in room "room" to "Message 1 - Edit 1" with 200
And user "participant2" edits message "Message 1-1" in room "LOCAL::room" to "Message 1-1 - Edit 1" with 200
Then user "participant2" is participant of the following rooms (v4)
| id | type | lastMessage |
| LOCAL::room | 2 | Message 1-1 - Edit 1 |
Then user "participant1" sees the following messages in room "room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage | lastEditActorType | lastEditActorId | lastEditActorDisplayName |
| room | federated_users | participant2@{$REMOTE_URL} | participant2-displayname | Message 1-1 - Edit 1 | [] | Message 1 - Edit 1 | federated_users | participant2@{$REMOTE_URL} | participant2-displayname |
| room | users | participant1 | participant1-displayname | Message 1 - Edit 1 | [] | | users | participant1 | participant1-displayname |
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage | lastEditActorType | lastEditActorId | lastEditActorDisplayName |
| room | federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | Message 1-1 - Edit 1 | [] | Message 1 - Edit 1 | federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname |
| room | users | participant1 | participant1-displayname | Message 1 - Edit 1 | [] | | users | participant1 | participant1-displayname |
When next message request has the following parameters set
| timeout | 0 |
And user "participant2" sees the following messages in room "LOCAL::room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage | lastEditActorType | lastEditActorId | lastEditActorDisplayName |
| LOCAL::room | users | participant2 | participant2-displayname | Message 1-1 - Edit 1 | [] | Message 1 - Edit 1 | users | participant2 | participant2-displayname |
| LOCAL::room | federated_users | participant1@{$BASE_URL} | participant1-displayname | Message 1 - Edit 1 | [] | | federated_users | participant1@{$BASE_URL} | participant1-displayname |
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage | lastEditActorType | lastEditActorId | lastEditActorDisplayName |
| LOCAL::room | users | participant2 | participant2-displayname | Message 1-1 - Edit 1 | [] | Message 1 - Edit 1 | users | participant2 | participant2-displayname |
| LOCAL::room | federated_users | participant1@{$LOCAL_URL} | participant1-displayname | Message 1 - Edit 1 | [] | | federated_users | participant1@{$LOCAL_URL} | participant1-displayname |
And user "participant1" deletes message "Message 1 - Edit 1" from room "room" with 200
And user "participant2" deletes message "Message 1-1 - Edit 1" from room "LOCAL::room" with 200
Then user "participant1" sees the following messages in room "room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| room | federated_users | participant2@{$REMOTE_URL} | participant2-displayname | Message deleted by author | {"actor":{"type":"user","id":"participant2","name":"participant2-displayname","server":"{$REMOTE_URL}"}} | Message deleted by you |
| room | users | participant1 | participant1-displayname | Message deleted by you | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} | |
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| room | federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | Message deleted by author | {"actor":{"type":"user","id":"participant2","name":"participant2-displayname","server":"{$LOCAL_REMOTE_URL}"}} | Message deleted by you |
| room | users | participant1 | participant1-displayname | Message deleted by you | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} | |
When next message request has the following parameters set
| timeout | 0 |
And user "participant2" sees the following messages in room "LOCAL::room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| LOCAL::room | users | participant2 | participant2-displayname | Message deleted by you | {"actor":{"type":"user","id":"participant2","name":"participant2-displayname"}} | Message deleted by author |
| LOCAL::room | federated_users | participant1@{$BASE_URL} | participant1-displayname | Message deleted by author | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname","server":"{$BASE_URL}"}} | |
| room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage |
| LOCAL::room | users | participant2 | participant2-displayname | Message deleted by you | {"actor":{"type":"user","id":"participant2","name":"participant2-displayname"}} | Message deleted by author |
| LOCAL::room | federated_users | participant1@{$LOCAL_URL} | participant1-displayname | Message deleted by author | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname","server":"{$LOCAL_URL}"}} | |
Then user "participant2" is participant of the following rooms (v4)
| id | type | lastMessage |
| LOCAL::room | 2 | Message deleted by author |
@ -159,11 +159,11 @@ Feature: federation/chat
Then user "participant1" is participant of the following unordered rooms (v4)
| id | name | type | remoteServer | remoteToken | lastMessage | lastMessageActorType | lastMessageActorId |
| room | room | 2 | | | Message 1 | users | participant1 |
| LOCAL::room | room | 2 | LOCAL | room | Message 1 | federated_users | participant1@{$BASE_URL} |
| LOCAL::room | room | 2 | LOCAL | room | Message 1 | federated_users | participant1@{$LOCAL_URL} |
When user "participant1" sends reply "Message 1-1" on message "Message 1" to room "LOCAL::room" with 201
Then user "participant1" is participant of the following unordered rooms (v4)
| id | name | type | remoteServer | remoteToken | lastMessage | lastMessageActorType | lastMessageActorId |
| room | room | 2 | | | Message 1-1 | federated_users | participant1@{$REMOTE_URL} |
| room | room | 2 | | | Message 1-1 | federated_users | participant1@{$LOCAL_REMOTE_URL} |
| LOCAL::room | room | 2 | LOCAL | room | Message 1-1 | users | participant1 |
Scenario: Read marker checking
@ -258,12 +258,12 @@ Feature: federation/chat
Then user "participant2" sees the following entries for dashboard widgets "spreed" (v2)
| title | subtitle | link | iconUrl | sinceId | overlayIconUrl |
| room | You were mentioned | LOCAL::room | {$BASE_URL}ocs/v2.php/apps/spreed/api/v1/room/{token}/avatar{version} | | |
And user "participant1" sends message 'Hi @"federated_user/participant2@{$REMOTE_URL}" bye' to room "room" with 201
And user "participant1" sends message 'Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye' to room "room" with 201
And user "participant1" sends message 'Hi @all bye' to room "room" with 201
Then user "participant2" has the following notifications
| app | object_type | object_id | subject | message |
| spreed | chat | LOCAL::room/Hi @all bye | participant1-displayname mentioned everyone in conversation room | Hi room bye |
| spreed | chat | LOCAL::room/Hi @"federated_user/participant2@{$REMOTE_URL}" bye | participant1-displayname mentioned you in conversation room | Hi @participant2-displayname bye |
| spreed | chat | LOCAL::room/Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye | participant1-displayname mentioned you in conversation room | Hi @participant2-displayname bye |
| spreed | chat | LOCAL::room/Message 1-1 | participant1-displayname replied to your message in conversation room | Message 1-1 |
When next message request has the following parameters set
| timeout | 0 |
@ -293,11 +293,11 @@ Feature: federation/chat
Given user "participant2" joins room "LOCAL::room" with 200 (v4)
Given user "participant2" leaves room "LOCAL::room" with 200 (v4)
And user "guest" joins room "room" with 200 (v4)
When user "guest" sends message 'Hi @"federated_user/participant2@{$REMOTE_URL}" bye' to room "room" with 201
When user "guest" sends message 'Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye' to room "room" with 201
When user "guest" sends message "Message 2" to room "room" with 201
Then user "participant2" has the following notifications
| app | object_type | object_id | subject | message |
| spreed | chat | LOCAL::room/Hi @"federated_user/participant2@{$REMOTE_URL}" bye | A guest mentioned you in conversation room | Hi @participant2-displayname bye |
| spreed | chat | LOCAL::room/Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye | A guest mentioned you in conversation room | Hi @participant2-displayname bye |
Then user "participant2" reads message "Message 2" in room "LOCAL::room" with 200 (v1)
Then user "participant2" has the following notifications
| app | object_type | object_id | subject | message |
@ -322,13 +322,13 @@ Feature: federation/chat
Given user "participant2" joins room "LOCAL::room" with 200 (v4)
Given user "participant2" sets session state to 1 in room "LOCAL::room" with 200 (v4)
And user "guest" joins room "room" with 200 (v4)
When user "guest" sends message 'Sent to @"federated_user/participant2@{$REMOTE_URL}" while active' to room "room" with 201
When user "guest" sends message 'Sent to @"federated_user/participant2@{$LOCAL_REMOTE_URL}" while active' to room "room" with 201
Given user "participant2" sets session state to 0 in room "LOCAL::room" with 200 (v4)
When user "guest" sends message 'User @"federated_user/participant2@{$REMOTE_URL}" is inactive' to room "room" with 201
When user "guest" sends message 'User @"federated_user/participant2@{$LOCAL_REMOTE_URL}" is inactive' to room "room" with 201
When user "guest" sends message "Message 3" to room "room" with 201
Then user "participant2" has the following notifications
| app | object_type | object_id | subject | message |
| spreed | chat | LOCAL::room/User @"federated_user/participant2@{$REMOTE_URL}" is inactive | A guest mentioned you in conversation room | User @participant2-displayname is inactive |
| spreed | chat | LOCAL::room/User @"federated_user/participant2@{$LOCAL_REMOTE_URL}" is inactive | A guest mentioned you in conversation room | User @participant2-displayname is inactive |
Then user "participant2" reads message "Message 3" in room "LOCAL::room" with 200 (v1)
Then user "participant2" has the following notifications
| app | object_type | object_id | subject | message |
@ -362,10 +362,10 @@ Feature: federation/chat
# Join and leave to clear the invite notification
Given user "participant2" joins room "LOCAL::room" with 200 (v4)
Given user "participant2" leaves room "LOCAL::room" with 200 (v4)
When user "participant3" sends message 'Hi @"federated_user/participant2@{$REMOTE_URL}" bye' to room "LOCAL::room" with 201
When user "participant3" sends message 'Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye' to room "LOCAL::room" with 201
Then user "participant2" has the following notifications
| app | object_type | object_id | subject | message |
| spreed | chat | LOCAL::room/Hi @"federated_user/participant2@{$REMOTE_URL}" bye | participant3-displayname mentioned you in conversation room | Hi @participant2-displayname bye |
| spreed | chat | LOCAL::room/Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye | participant3-displayname mentioned you in conversation room | Hi @participant2-displayname bye |
Scenario: Mentioning and replying to self does not do notifications
Given the following "spreed" app config is set
@ -396,7 +396,7 @@ Feature: federation/chat
# Join and leave to clear the invite notification
Given user "participant2" joins room "LOCAL::room" with 200 (v4)
Given user "participant2" leaves room "LOCAL::room" with 200 (v4)
When user "participant2" sends message 'Hi @"federated_user/participant2@{$REMOTE_URL}" bye' to room "LOCAL::room" with 201
When user "participant2" sends message 'Hi @"federated_user/participant2@{$LOCAL_REMOTE_URL}" bye' to room "LOCAL::room" with 201
And user "participant2" sends message "Message 1" to room "LOCAL::room" with 201
When user "participant2" sends reply "Message 1-1" on message "Message 1" to room "LOCAL::room" with 201
Then user "participant2" has the following notifications
@ -449,10 +449,10 @@ Feature: federation/chat
| actorType | actorId | actorDisplayName | reaction |
| users | participant1 | participant1-displayname | 🚀 |
And user "participant2" react with "🚀" on message "Message 1" to room "LOCAL::room" with 201
| actorType | actorId | actorDisplayName | reaction |
| federated_users | participant1@{$BASE_URL} | participant1-displayname | 🚀 |
| users | participant2 | participant2-displayname | 🚀 |
| actorType | actorId | actorDisplayName | reaction |
| federated_users | participant1@{$LOCAL_URL} | participant1-displayname | 🚀 |
| users | participant2 | participant2-displayname | 🚀 |
And user "participant1" retrieve reactions "all" of message "Message 1" in room "room" with 200
| actorType | actorId | actorDisplayName | reaction |
| users | participant1 | participant1-displayname | 🚀 |
| federated_users | participant2@{$REMOTE_URL} | participant2-displayname | 🚀 |
| federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | 🚀 |

10
tests/integration/features/federation/poll.feature

@ -26,7 +26,7 @@ Feature: federation/poll
| maxVotes | unlimited |
Then user "participant1" sees the following messages in room "room" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters |
| room | federated_users | participant2@{$REMOTE_URL} | participant2-displayname | {object} | {"actor":{"type":"user","id":"participant2","name":"participant2-displayname","server":"http:\/\/localhost:8180"},"object":{"type":"talk-poll","id":POLL_ID(What is the question?),"name":"What is the question?"}} |
| room | federated_users | participant2@{$LOCAL_REMOTE_URL} | participant2-displayname | {object} | {"actor":{"type":"user","id":"participant2","name":"participant2-displayname","server":"http:\/\/localhost:8180"},"object":{"type":"talk-poll","id":POLL_ID(What is the question?),"name":"What is the question?"}} |
Then user "participant2" sees poll "What is the question?" in room "LOCAL::room" with 200
| id | POLL_ID(What is the question?) |
| question | What is the question? |
@ -49,7 +49,7 @@ Feature: federation/poll
| resultMode | public |
| maxVotes | unlimited |
| actorType | federated_users |
| actorId | participant2@{$REMOTE_URL} |
| actorId | participant2@{$LOCAL_REMOTE_URL} |
| actorDisplayName | participant2-displayname |
| status | open |
| votedSelf | [1] |
@ -62,7 +62,7 @@ Feature: federation/poll
| resultMode | public |
| maxVotes | unlimited |
| actorType | federated_users |
| actorId | participant2@{$REMOTE_URL} |
| actorId | participant2@{$LOCAL_REMOTE_URL} |
| actorDisplayName | participant2-displayname |
| status | open |
| votedSelf | [1] |
@ -92,7 +92,7 @@ Feature: federation/poll
| actorDisplayName | participant2-displayname |
| status | closed |
| votedSelf | not voted |
| details | [{"actorType":"federated_users","actorId":"participant1@{$BASE_URL}","actorDisplayName":"participant1-displayname","optionId":1}] |
| details | [{"actorType":"federated_users","actorId":"participant1@{$LOCAL_URL}","actorDisplayName":"participant1-displayname","optionId":1}] |
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? |
@ -102,7 +102,7 @@ Feature: federation/poll
| resultMode | public |
| maxVotes | unlimited |
| actorType | federated_users |
| actorId | participant2@{$REMOTE_URL} |
| actorId | participant2@{$LOCAL_REMOTE_URL} |
| actorDisplayName | participant2-displayname |
| status | closed |
| votedSelf | [1] |

126
tests/integration/run.sh

@ -32,7 +32,6 @@ echo -e "Running on process ID: \033[1;35m$PHPPID1\033[0m"
# Output filtered php server logs
tail -f phpserver.log | grep --line-buffered -v -E ":[0-9]+ Accepted$" | grep --line-buffered -v -E ":[0-9]+ Closing$" &
# The federated server is started and stopped by the tests themselves
PORT_FED=8180
export PORT_FED
@ -44,22 +43,68 @@ echo -e "Running on process ID: \033[1;35m$PHPPID2\033[0m"
# Output filtered federated php server logs
tail -f phpserver_fed.log | grep --line-buffered -v -E ":[0-9]+ Accepted$" | grep --line-buffered -v -E ":[0-9]+ Closing$" &
MAIN_SERVER_CONFIG_DIR=${ROOT_DIR}/config
MAIN_SERVER_DATA_DIR=$(${ROOT_DIR}/occ config:system:get datadirectory)
MAIN_SERVER_APPS_PATHS=$(${ROOT_DIR}/occ config:system:get apps_paths --output json)
REAL_FEDERATED_SERVER_CONFIG_DIR="$MAIN_SERVER_DATA_DIR/tests-talk-real-federated-server/config"
REAL_FEDERATED_SERVER_DATA_DIR="$MAIN_SERVER_DATA_DIR/tests-talk-real-federated-server/data"
DESTROY_REAL_FEDERATED_SERVER=false
if [ ! -d "$REAL_FEDERATED_SERVER_CONFIG_DIR" ] || NEXTCLOUD_CONFIG_DIR="$REAL_FEDERATED_SERVER_CONFIG_DIR" ${ROOT_DIR}/occ status | grep "installed: false"; then
DESTROY_REAL_FEDERATED_SERVER=true
echo ''
echo -e "\033[0;31mReal federated server not installed in $REAL_FEDERATED_SERVER_CONFIG_DIR\033[0m"
echo -e "\033[0;33mPerforming basic SQLite installation with data directory in $REAL_FEDERATED_SERVER_DATA_DIR\033[0m"
mkdir --parents "$REAL_FEDERATED_SERVER_CONFIG_DIR" "$REAL_FEDERATED_SERVER_DATA_DIR"
NEXTCLOUD_CONFIG_DIR="$REAL_FEDERATED_SERVER_CONFIG_DIR" ${ROOT_DIR}/occ maintenance:install --admin-pass=admin --data-dir="$REAL_FEDERATED_SERVER_DATA_DIR"
echo ''
if [ $MAIN_SERVER_APPS_PATHS ]; then
echo -e "\033[0;33mCopying custom apps_paths\033[0m"
echo "{\"system\":{\"apps_paths\":$MAIN_SERVER_APPS_PATHS}}" > "$REAL_FEDERATED_SERVER_CONFIG_DIR/apps_paths.json"
NEXTCLOUD_CONFIG_DIR="$REAL_FEDERATED_SERVER_CONFIG_DIR" ${ROOT_DIR}/occ config:import < "$REAL_FEDERATED_SERVER_CONFIG_DIR/apps_paths.json"
echo ''
fi
fi
PORT_FED_REAL=8280
export PORT_FED_REAL
echo "" > phpserver_fed_real.log
PHP_CLI_SERVER_WORKERS=3 NEXTCLOUD_CONFIG_DIR="$REAL_FEDERATED_SERVER_CONFIG_DIR" php -S localhost:${PORT_FED_REAL} -t ${ROOT_DIR} &> phpserver_fed_real.log &
PHPPID3=$!
echo -e "Running on process ID: \033[1;35m$PHPPID3\033[0m"
# Output filtered real federated php server logs
tail -f phpserver_fed_real.log | grep --line-buffered -v -E ":[0-9]+ Accepted$" | grep --line-buffered -v -E ":[0-9]+ Closing$" &
# Kill all sub-processes in case of ctrl+c
trap 'pkill -P $PHPPID1; pkill -P $PHPPID2; pkill -P $PROCESS_ID; wait $PHPPID1; wait $PHPPID2;' INT TERM
trap 'pkill -P $PHPPID1; pkill -P $PHPPID2; pkill -P $PHPPID3; pkill -P $PROCESS_ID; wait $PHPPID1; wait $PHPPID2; wait $PHPPID3;' INT TERM
NEXTCLOUD_ROOT_DIR=${ROOT_DIR}
export NEXTCLOUD_ROOT_DIR
export TEST_SERVER_URL="http://localhost:8080/"
export TEST_REMOTE_URL="http://localhost:8180/"
export TEST_LOCAL_REMOTE_URL="http://localhost:8180/"
export TEST_REMOTE_URL="http://localhost:8280/"
export MAIN_SERVER_CONFIG_DIR
export REAL_FEDERATED_SERVER_CONFIG_DIR
export NEXTCLOUD_CONFIG_DIR="$MAIN_SERVER_CONFIG_DIR"
OVERWRITE_CLI_URL=$(${ROOT_DIR}/occ config:system:get overwrite.cli.url)
${ROOT_DIR}/occ config:system:set overwrite.cli.url --value "http://localhost:8080/"
SKELETON_DIR=$(${ROOT_DIR}/occ config:system:get skeletondirectory)
if [[ "$SKELETON_DIR" ]]; then
echo "Resetting custom skeletondirectory so that tests pass"
${ROOT_DIR}/occ config:system:delete skeletondirectory
fi
export NEXTCLOUD_CONFIG_DIR="$REAL_FEDERATED_SERVER_CONFIG_DIR"
OVERWRITE_CLI_URL=$(${ROOT_DIR}/occ config:system:get overwrite.cli.url)
${ROOT_DIR}/occ config:system:set overwrite.cli.url --value "$TEST_REMOTE_URL"
for CONFIG_DIR in $MAIN_SERVER_CONFIG_DIR $REAL_FEDERATED_SERVER_CONFIG_DIR; do
export NEXTCLOUD_CONFIG_DIR="$CONFIG_DIR"
SKELETON_DIR=$(${ROOT_DIR}/occ config:system:get skeletondirectory)
if [[ "$SKELETON_DIR" ]]; then
echo "Resetting custom skeletondirectory so that tests pass"
${ROOT_DIR}/occ config:system:delete skeletondirectory
fi
done
echo ''
echo -e "\033[0;36m#\033[0m"
@ -75,29 +120,40 @@ ${ROOT_DIR}/occ app:getpath guests || (cd ../../../ && git clone --depth 1 --bra
${ROOT_DIR}/occ app:getpath circles || (cd ../../../ && git clone --depth 1 --branch ${CIRCLES_BRANCH} https://github.com/nextcloud/circles)
${ROOT_DIR}/occ app:getpath call_summary_bot || (cd ../../../ && git clone --depth 1 --branch ${CSB_BRANCH} https://github.com/nextcloud/call_summary_bot)
${ROOT_DIR}/occ app:enable spreed || exit 1
${ROOT_DIR}/occ app:enable --force spreedcheats || exit 1
${ROOT_DIR}/occ app:enable --force notifications || exit 1
${ROOT_DIR}/occ app:enable --force guests || exit 1
${ROOT_DIR}/occ app:enable --force circles || exit 1
${ROOT_DIR}/occ app:enable --force call_summary_bot || exit 1
for CONFIG_DIR in $MAIN_SERVER_CONFIG_DIR $REAL_FEDERATED_SERVER_CONFIG_DIR; do
export NEXTCLOUD_CONFIG_DIR="$CONFIG_DIR"
${ROOT_DIR}/occ app:enable spreed || exit 1
${ROOT_DIR}/occ app:enable --force spreedcheats || exit 1
${ROOT_DIR}/occ app:enable --force notifications || exit 1
${ROOT_DIR}/occ app:enable --force guests || exit 1
${ROOT_DIR}/occ app:enable --force circles || exit 1
${ROOT_DIR}/occ app:enable --force call_summary_bot || exit 1
${ROOT_DIR}/occ app:list | grep spreed
${ROOT_DIR}/occ app:list | grep notifications
${ROOT_DIR}/occ app:list | grep guests
${ROOT_DIR}/occ app:list | grep circles
${ROOT_DIR}/occ app:list | grep call_summary_bot
${ROOT_DIR}/occ app:list | grep spreed
${ROOT_DIR}/occ app:list | grep notifications
${ROOT_DIR}/occ app:list | grep guests
${ROOT_DIR}/occ app:list | grep circles
${ROOT_DIR}/occ app:list | grep call_summary_bot
done
echo ''
echo -e "\033[0;36m#\033[0m"
echo -e "\033[0;36m# Optimizing configuration\033[0m"
echo -e "\033[0;36m#\033[0m"
# Disable bruteforce protection because the integration tests do trigger them
${ROOT_DIR}/occ config:system:set auth.bruteforce.protection.enabled --value false --type bool
# Disable rate limit protection because the integration tests do trigger them
${ROOT_DIR}/occ config:system:set ratelimit.protection.enabled --value false --type bool
# Allow local remote urls otherwise we can not share
${ROOT_DIR}/occ config:system:set allow_local_remote_servers --value true --type bool
for CONFIG_DIR in $MAIN_SERVER_CONFIG_DIR $REAL_FEDERATED_SERVER_CONFIG_DIR; do
export NEXTCLOUD_CONFIG_DIR="$CONFIG_DIR"
# Disable bruteforce protection because the integration tests do trigger them
${ROOT_DIR}/occ config:system:set auth.bruteforce.protection.enabled --value false --type bool
# Disable rate limit protection because the integration tests do trigger them
${ROOT_DIR}/occ config:system:set ratelimit.protection.enabled --value false --type bool
# Allow local remote urls otherwise we can not share
${ROOT_DIR}/occ config:system:set allow_local_remote_servers --value true --type bool
done
# Restore default config dir to local server in case it is used from the tests
export NEXTCLOUD_CONFIG_DIR="$MAIN_SERVER_CONFIG_DIR"
echo ''
echo -e "\033[1;33m#\033[0m"
@ -119,10 +175,12 @@ echo -e "\033[0;36m#\033[0m"
# Kill child PHP processes
pkill -P $PHPPID1;
pkill -P $PHPPID2;
pkill -P $PHPPID3;
# Kill parent PHP processes
kill -TERM $PHPPID1;
kill -TERM $PHPPID2;
kill -TERM $PHPPID3;
# Kill child processes of this script (e.g. tail)
pkill -P $PROCESS_ID;
@ -131,14 +189,24 @@ echo ''
echo -e "\033[0;36m#\033[0m"
echo -e "\033[0;36m# Reverting configuration changes and disabling spreedcheats\033[0m"
echo -e "\033[0;36m#\033[0m"
${ROOT_DIR}/occ app:disable spreedcheats
${ROOT_DIR}/occ config:system:set overwrite.cli.url --value $OVERWRITE_CLI_URL
if [[ "$SKELETON_DIR" ]]; then
${ROOT_DIR}/occ config:system:set skeletondirectory --value "$SKELETON_DIR"
for CONFIG_DIR in $MAIN_SERVER_CONFIG_DIR $REAL_FEDERATED_SERVER_CONFIG_DIR; do
export NEXTCLOUD_CONFIG_DIR="$CONFIG_DIR"
${ROOT_DIR}/occ app:disable spreedcheats
${ROOT_DIR}/occ config:system:set overwrite.cli.url --value $OVERWRITE_CLI_URL
if [[ "$SKELETON_DIR" ]]; then
${ROOT_DIR}/occ config:system:set skeletondirectory --value "$SKELETON_DIR"
fi
done
if $DESTROY_REAL_FEDERATED_SERVER; then
rm -rf "$REAL_FEDERATED_SERVER_CONFIG_DIR" "$REAL_FEDERATED_SERVER_DATA_DIR"
fi
rm -rf ../../../spreedcheats
wait $PHPPID1
wait $PHPPID2
wait $PHPPID3
exit $RESULT
Loading…
Cancel
Save