зеркало из https://github.com/nextcloud/spreed.git
Merge pull request #6427 from nextcloud/integration-tests-for-invites
Start with integration tests for invites
This commit is contained in:
Коммит
7f1828094f
|
@ -44,6 +44,7 @@ use OCA\Talk\Events\AttendeesAddedEvent;
|
|||
use OCA\Talk\Events\AttendeesRemovedEvent;
|
||||
use OCA\Talk\Events\ChatEvent;
|
||||
use OCA\Talk\Events\RoomEvent;
|
||||
use OCA\Talk\Federation\CloudFederationProviderTalk;
|
||||
use OCA\Talk\Files\Listener as FilesListener;
|
||||
use OCA\Talk\Files\TemplateLoader as FilesTemplateLoader;
|
||||
use OCA\Talk\Flow\RegisterOperationsListener;
|
||||
|
@ -79,12 +80,16 @@ use OCP\AppFramework\App;
|
|||
use OCP\AppFramework\Bootstrap\IBootContext;
|
||||
use OCP\AppFramework\Bootstrap\IBootstrap;
|
||||
use OCP\AppFramework\Bootstrap\IRegistrationContext;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Collaboration\Resources\IProviderManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Federation\ICloudFederationProvider;
|
||||
use OCP\Federation\ICloudFederationProviderManager;
|
||||
use OCP\Group\Events\GroupDeletedEvent;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
use OCP\Group\Events\UserRemovedEvent;
|
||||
use OCP\IConfig;
|
||||
use OCP\IServerContainer;
|
||||
use OCP\IUser;
|
||||
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
|
||||
|
@ -166,6 +171,7 @@ class Application extends App implements IBootstrap {
|
|||
|
||||
$this->registerRoomActivityHooks($dispatcher);
|
||||
$this->registerChatHooks($dispatcher);
|
||||
$context->injectFn(\Closure::fromCallable([$this, 'registerCloudFederationProviderManager']));
|
||||
}
|
||||
|
||||
protected function registerNotifier(IServerContainer $server): void {
|
||||
|
@ -226,4 +232,21 @@ class Application extends App implements IBootstrap {
|
|||
};
|
||||
$dispatcher->addListener(Room::EVENT_AFTER_ROOM_DELETE, $listener);
|
||||
}
|
||||
|
||||
protected function registerCloudFederationProviderManager(
|
||||
IConfig $config,
|
||||
ICloudFederationProviderManager $manager,
|
||||
IAppContainer $appContainer): void {
|
||||
if ($config->getAppValue('spreed', 'federation_enabled', 'no') !== 'yes') {
|
||||
return;
|
||||
}
|
||||
|
||||
$manager->addCloudFederationProvider(
|
||||
'talk-room',
|
||||
'Talk Federation',
|
||||
static function () use ($appContainer): ICloudFederationProvider {
|
||||
return $appContainer->get(CloudFederationProviderTalk::class);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,14 @@ class Config {
|
|||
&& $this->getDialInInfo() !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if Talk federation is enabled on this instance
|
||||
*/
|
||||
public function isFederationEnabled(): bool {
|
||||
// TODO: Set to default true once implementation is complete
|
||||
return $this->config->getAppValue('spreed', 'federation_enabled', 'no') === 'yes';
|
||||
}
|
||||
|
||||
public function getDialInInfo(): string {
|
||||
return $this->config->getAppValue('spreed', 'sip_bridge_dialin_info');
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ use OCA\Talk\Exceptions\InvalidPasswordException;
|
|||
use OCA\Talk\Exceptions\ParticipantNotFoundException;
|
||||
use OCA\Talk\Exceptions\RoomNotFoundException;
|
||||
use OCA\Talk\Exceptions\UnauthorizedException;
|
||||
use OCA\Talk\Federation\FederationManager;
|
||||
use OCA\Talk\GuestManager;
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\MatterbridgeManager;
|
||||
|
@ -67,6 +66,7 @@ use OCP\IUserManager;
|
|||
use OCP\User\Events\UserLiveStatusEvent;
|
||||
use OCP\UserStatus\IManager as IUserStatusManager;
|
||||
use OCP\UserStatus\IUserStatus;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class RoomController extends AEnvironmentAwareController {
|
||||
public const EVENT_BEFORE_ROOMS_GET = self::class . '::preGetRooms';
|
||||
|
@ -109,8 +109,8 @@ class RoomController extends AEnvironmentAwareController {
|
|||
protected $config;
|
||||
/** @var Config */
|
||||
protected $talkConfig;
|
||||
/** @var FederationManager */
|
||||
protected $federationManager;
|
||||
/** @var LoggerInterface */
|
||||
protected $logger;
|
||||
|
||||
/** @var array */
|
||||
protected $commonReadMessages = [];
|
||||
|
@ -135,7 +135,8 @@ class RoomController extends AEnvironmentAwareController {
|
|||
IL10N $l10n,
|
||||
IConfig $config,
|
||||
Config $talkConfig,
|
||||
ICloudIdManager $cloudIdManager) {
|
||||
ICloudIdManager $cloudIdManager,
|
||||
LoggerInterface $logger) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->session = $session;
|
||||
$this->appManager = $appManager;
|
||||
|
@ -156,6 +157,7 @@ class RoomController extends AEnvironmentAwareController {
|
|||
$this->config = $config;
|
||||
$this->talkConfig = $talkConfig;
|
||||
$this->cloudIdManager = $cloudIdManager;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
protected function getTalkHashHeader(): array {
|
||||
|
@ -1129,13 +1131,16 @@ class RoomController extends AEnvironmentAwareController {
|
|||
$this->guestManager->sendEmailInvitation($this->room, $participant);
|
||||
|
||||
return new DataResponse($data);
|
||||
} elseif ($source === 'remote') {
|
||||
if (!$this->federationManager->isEnabled()) {
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
} elseif ($source === 'remotes') {
|
||||
if (!$this->talkConfig->isFederationEnabled()) {
|
||||
return new DataResponse([], Http::STATUS_NOT_IMPLEMENTED);
|
||||
}
|
||||
try {
|
||||
$newUser = $this->cloudIdManager->resolveCloudId($newParticipant);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$this->logger->error($e->getMessage(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
|
@ -1145,6 +1150,7 @@ class RoomController extends AEnvironmentAwareController {
|
|||
'displayName' => $newUser->getDisplayId(),
|
||||
];
|
||||
} else {
|
||||
$this->logger->error('Trying to add participant from unsupported source ' . $source);
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,10 +85,11 @@ class FederationManager {
|
|||
/**
|
||||
* Determine if Talk federation is enabled on this instance
|
||||
* @return bool
|
||||
* @deprecated use \OCA\Talk\Config::isFederationEnabled()
|
||||
*/
|
||||
public function isEnabled(): bool {
|
||||
// TODO: Set to default true once implementation is complete
|
||||
return $this->config->getAppValue(Application::APP_ID, 'federation_enabled', 'false') === 'true';
|
||||
return $this->config->getAppValue(Application::APP_ID, 'federation_enabled', 'no') === 'yes';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -236,7 +236,7 @@ class Notifications {
|
|||
}
|
||||
|
||||
private function prepareRemoteUrl(string $remote): string {
|
||||
if ($this->addressHandler->urlContainProtocol($remote)) {
|
||||
if (!$this->addressHandler->urlContainProtocol($remote)) {
|
||||
return 'https://' . $remote;
|
||||
}
|
||||
return $remote;
|
||||
|
|
|
@ -77,6 +77,11 @@ trait TInitialState {
|
|||
'grid_videos_limit_enforced',
|
||||
$this->talkConfig->getGridVideosLimitEnforced()
|
||||
);
|
||||
|
||||
$this->initialState->provideInitialState(
|
||||
'federation_enabled',
|
||||
$this->talkConfig->isFederationEnabled()
|
||||
);
|
||||
}
|
||||
|
||||
protected function publishInitialStateForUser(IUser $user, IRootFolder $rootFolder, IAppManager $appManager): void {
|
||||
|
|
|
@ -54,6 +54,14 @@
|
|||
:items="addableCircles"
|
||||
@click="handleClickParticipant" />
|
||||
</template>
|
||||
|
||||
<template v-if="addableRemotes.length !== 0">
|
||||
<AppNavigationCaption
|
||||
:title="t('spreed', 'Add federated users')" />
|
||||
<ParticipantsList
|
||||
:items="addableRemotes"
|
||||
@click="handleClickParticipant" />
|
||||
</template>
|
||||
<AppNavigationCaption v-if="sourcesWithoutResults"
|
||||
:title="sourcesWithoutResultsList" />
|
||||
<Hint v-if="contactsLoading" :hint="t('spreed', 'Searching …')" />
|
||||
|
@ -214,6 +222,12 @@ export default {
|
|||
}
|
||||
return []
|
||||
},
|
||||
addableRemotes() {
|
||||
if (this.searchResults !== []) {
|
||||
return this.searchResults.filter((item) => item.source === 'remotes')
|
||||
}
|
||||
return []
|
||||
},
|
||||
// Determines whether this component is used in the new group conversation creation
|
||||
// context
|
||||
isNewGroupConversation() {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { CONVERSATION, SHARE } from '../constants'
|
||||
|
||||
|
@ -80,6 +81,10 @@ const searchPossibleConversations = async function({ searchText, token, onlyUser
|
|||
shareTypes.push(SHARE.TYPE.CIRCLE)
|
||||
if (token !== 'new') {
|
||||
shareTypes.push(SHARE.TYPE.EMAIL)
|
||||
|
||||
if (loadState('spreed', 'federation_enabled')) {
|
||||
shareTypes.push(SHARE.TYPE.REMOTE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,29 @@
|
|||
import mockAxios from '../__mocks__/axios'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { searchPossibleConversations } from './conversationsService'
|
||||
import { SHARE } from '../constants'
|
||||
|
||||
jest.mock('@nextcloud/initial-state', () => ({
|
||||
loadState: jest.fn(),
|
||||
}))
|
||||
|
||||
describe('conversationsService', () => {
|
||||
let loadStateSettings
|
||||
|
||||
beforeEach(() => {
|
||||
loadStateSettings = {
|
||||
federation_enabled: false,
|
||||
}
|
||||
|
||||
loadState.mockImplementation((app, key) => {
|
||||
if (app === 'spreed') {
|
||||
return loadStateSettings[key]
|
||||
}
|
||||
return null
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// cleaning up the mess left behind the previous test
|
||||
mockAxios.reset()
|
||||
|
|
|
@ -426,6 +426,11 @@ class FeatureContext implements Context, SnippetAcceptingContext {
|
|||
if (isset($attendee['actorId']) && substr($attendee['actorId'], 0, strlen('"guest')) === '"guest') {
|
||||
$attendee['actorId'] = sha1(self::$userToSessionId[trim($attendee['actorId'], '"')]);
|
||||
}
|
||||
|
||||
if (isset($attendee['actorId'], $attendee['actorType']) && $attendee['actorType'] === 'federated_users') {
|
||||
$attendee['actorId'] .= '@' . rtrim($this->baseUrl, '/');
|
||||
}
|
||||
|
||||
if (isset($attendee['participantType'])) {
|
||||
$attendee['participantType'] = (string)$this->mapParticipantTypeTestInput($attendee['participantType']);
|
||||
}
|
||||
|
@ -1069,7 +1074,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* @Then /^user "([^"]*)" adds (user|group|email|circle) "([^"]*)" to room "([^"]*)" with (\d+) \((v4)\)$/
|
||||
* @Then /^user "([^"]*)" adds (user|group|email|circle|remote) "([^"]*)" to room "([^"]*)" with (\d+) \((v4)\)$/
|
||||
*
|
||||
* @param string $user
|
||||
* @param string $newType
|
||||
|
@ -1080,6 +1085,11 @@ class FeatureContext implements Context, SnippetAcceptingContext {
|
|||
*/
|
||||
public function userAddAttendeeToRoom(string $user, string $newType, string $newId, string $identifier, int $statusCode, string $apiVersion): void {
|
||||
$this->setCurrentUser($user);
|
||||
|
||||
if ($newType === 'remote') {
|
||||
$newId .= '@' . $this->baseUrl;
|
||||
}
|
||||
|
||||
$this->sendRequest(
|
||||
'POST', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants',
|
||||
new TableNode([
|
||||
|
@ -2108,6 +2118,8 @@ class FeatureContext implements Context, SnippetAcceptingContext {
|
|||
$this->response = $client->{$verb}($fullUrl, $options);
|
||||
} catch (ClientException $ex) {
|
||||
$this->response = $ex->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ServerException $ex) {
|
||||
$this->response = $ex->getResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Feature: federation/invite
|
||||
Background:
|
||||
Given user "participant1" exists
|
||||
Given user "participant2" exists
|
||||
|
||||
Scenario: federation is disabled
|
||||
Given the following app config is set
|
||||
| federation_enabled | no |
|
||||
Given user "participant1" creates room "room" (v4)
|
||||
| roomType | 3 |
|
||||
| roomName | room |
|
||||
And user "participant1" adds remote "participant2" to room "room" with 501 (v4)
|
||||
When user "participant1" sees the following attendees in room "room" with 200 (v4)
|
||||
| actorType | actorId | participantType |
|
||||
| users | participant1 | 1 |
|
||||
|
||||
Scenario: federation is enabled
|
||||
Given the following app config is set
|
||||
| federation_enabled | yes |
|
||||
Given user "participant1" creates room "room" (v4)
|
||||
| roomType | 3 |
|
||||
| roomName | room |
|
||||
And user "participant1" adds remote "participant2" to room "room" with 200 (v4)
|
||||
When user "participant1" sees the following attendees in room "room" with 200 (v4)
|
||||
| actorType | actorId | participantType |
|
||||
| users | participant1 | 1 |
|
||||
| federated_users | participant2 | 3 |
|
|
@ -112,7 +112,7 @@ class FederationTest extends TestCase {
|
|||
$providerId = '3';
|
||||
$roomId = 5;
|
||||
$token = 'abcdefghijklmno';
|
||||
$shareWith = 'test@remote.test.local';
|
||||
$shareWith = 'test@https://remote.test.local';
|
||||
$name = 'abcdefgh';
|
||||
$owner = 'Owner\'s name';
|
||||
$ownerId = 'owner';
|
||||
|
@ -321,6 +321,10 @@ class FederationTest extends TestCase {
|
|||
->with($remote, $notification)
|
||||
->willReturn([]);
|
||||
|
||||
$this->addressHandler->method('urlContainProtocol')
|
||||
->with($remote)
|
||||
->willReturn(true);
|
||||
|
||||
$success = $this->notifications->sendShareAccepted($remote, $id, $token);
|
||||
|
||||
$this->assertEquals(true, $success);
|
||||
|
@ -354,6 +358,10 @@ class FederationTest extends TestCase {
|
|||
->with($remote, $notification)
|
||||
->willReturn([]);
|
||||
|
||||
$this->addressHandler->method('urlContainProtocol')
|
||||
->with($remote)
|
||||
->willReturn(true);
|
||||
|
||||
$success = $this->notifications->sendShareDeclined($remote, $id, $token);
|
||||
|
||||
$this->assertEquals(true, $success);
|
||||
|
|
Загрузка…
Ссылка в новой задаче