Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/polls.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDaniel Rudolf <github.com@daniel-rudolf.de>2021-04-16 20:10:14 +0300
committerDaniel Rudolf <github.com@daniel-rudolf.de>2021-04-16 20:10:14 +0300
commit4d2d973c06aa0e36762286b65a60d83a3064ac40 (patch)
treeaabf5c6201c4e10fbda92a19d02c13e15f82afaa /tests
parent6d2480df04fa5d411c310e7abf769c2821ab0bcd (diff)
Add PHPUnit integration tests for polls:share:* commands
Signed-off-by: Daniel Rudolf <github.com@daniel-rudolf.de>
Diffstat (limited to 'tests')
-rw-r--r--tests/Integration/Command/Share/AddTest.php206
-rw-r--r--tests/Integration/Command/Share/RemoveTest.php187
-rw-r--r--tests/Integration/Command/Share/TShareCommandTest.php129
3 files changed, 522 insertions, 0 deletions
diff --git a/tests/Integration/Command/Share/AddTest.php b/tests/Integration/Command/Share/AddTest.php
new file mode 100644
index 00000000..8d064722
--- /dev/null
+++ b/tests/Integration/Command/Share/AddTest.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ * @copyright Copyright (c) 2021 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Polls\Tests\Integration\Command\Share;
+
+use OCA\Polls\Command\Share\Add;
+use OCA\Polls\Db\Poll;
+use OCA\Polls\Db\Share;
+use OCA\Polls\Exceptions\ShareAlreadyExistsException;
+use OCA\Polls\Model\Email;
+use OCA\Polls\Model\Group;
+use OCA\Polls\Model\User;
+use OCP\AppFramework\Db\DoesNotExistException;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Console\Exception\RuntimeException as ConsoleRuntimeException;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class AddTest extends TestCase
+{
+ use TShareCommandTest;
+
+ public function setUp(): void {
+ parent::setUp();
+
+ $this->setUpMocks();
+ }
+
+ public function testMissingArguments(): void {
+ $this->pollMapper
+ ->expects($this->never())
+ ->method('find');
+
+ $this->expectException(ConsoleRuntimeException::class);
+ $this->expectExceptionMessage('Not enough arguments (missing: "id").');
+
+ $command = new Add(
+ $this->pollMapper,
+ $this->shareMapper,
+ $this->shareService,
+ $this->userManager,
+ $this->groupManager
+ );
+
+ $tester = new CommandTester($command);
+ $tester->execute([]);
+ }
+
+ public function testPollNotFound(): void {
+ $pollId = 123;
+
+ $this->pollMapper
+ ->expects($this->once())
+ ->method('find')
+ ->with($pollId)
+ ->willReturnCallback(function (int $id): Poll {
+ throw new DoesNotExistException('');
+ });
+
+ $command = new Add(
+ $this->pollMapper,
+ $this->shareMapper,
+ $this->shareService,
+ $this->userManager,
+ $this->groupManager
+ );
+
+ $tester = new CommandTester($command);
+ $tester->execute(['id' => $pollId]);
+
+ $this->assertEquals("Poll not found.\n", $tester->getDisplay());
+ }
+
+ /**
+ * @dataProvider validProvider
+ */
+ public function testValid(array $input, array $pollData): void {
+ $expectedShareCount = count($pollData['expectedShares']['user'])
+ + count($pollData['expectedShares']['group'])
+ + count($pollData['expectedShares']['email']);
+ $expectedInvitationCount = count($pollData['expectedInvitations']['user'])
+ + count($pollData['expectedInvitations']['group'])
+ + count($pollData['expectedInvitations']['email']);
+
+ $expectedInvitationShareTokens = [];
+ foreach ($pollData['expectedInvitations'] as $type => $shares) {
+ foreach ($shares as $userId) {
+ $expectedInvitationShareTokens[] = $this->getShareToken($pollData['pollId'], $type, $userId);
+ }
+ }
+
+ $this->pollMapper
+ ->expects($this->once())
+ ->method('find')
+ ->with($pollData['pollId'])
+ ->willReturnCallback([$this, 'createPollMock']);
+
+ $this->shareService
+ ->expects($this->exactly($expectedShareCount))
+ ->method('add')
+ ->with($pollData['pollId'], $this->logicalOr(User::TYPE, Group::TYPE, Email::TYPE), $this->anything())
+ ->willReturnCallback(function (int $pollId, string $type, string $userId = '') use ($pollData): Share {
+ $userIdConstraint = $this->logicalOr(...$pollData['expectedShares'][$type] ?? []);
+ $userIdConstraint->evaluate($userId);
+
+ if (in_array($userId, $pollData['initialShares'][$type] ?? [])) {
+ throw new ShareAlreadyExistsException();
+ }
+
+ return $this->createShareMock($pollId, $type, $userId);
+ });
+
+ $this->shareService
+ ->expects($this->exactly($expectedInvitationCount))
+ ->method('sendInvitation')
+ ->with($this->logicalOr(...$expectedInvitationShareTokens));
+
+ $command = new Add(
+ $this->pollMapper,
+ $this->shareMapper,
+ $this->shareService,
+ $this->userManager,
+ $this->groupManager
+ );
+
+ $tester = new CommandTester($command);
+ $tester->execute($input);
+
+ $this->assertEquals("Users successfully invited to poll.\n", $tester->getDisplay());
+ }
+
+ public function validProvider(): array {
+ return [
+ [
+ [
+ 'id' => 1,
+ ],
+ [
+ 'pollId' => 1,
+ ],
+ ],
+ [
+ [
+ 'id' => 123,
+ '--user' => ['user1', 'user2'],
+ '--group' => ['group1'],
+ '--email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ [
+ 'pollId' => 123,
+ 'expectedShares' => [
+ 'user' => ['user1', 'user2'],
+ 'group' => ['group1'],
+ 'email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ 'expectedInvitations' => [
+ 'user' => ['user1', 'user2'],
+ 'group' => ['group1'],
+ 'email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ ],
+ ],
+ [
+ [
+ 'id' => 456,
+ '--user' => ['user2', 'user3', 'user4'],
+ '--email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ [
+ 'pollId' => 456,
+ 'initialShares' => [
+ 'user' => ['user1', 'user2'],
+ 'email' => ['foo@example.com'],
+ ],
+ 'expectedShares' => [
+ 'user' => ['user2', 'user3', 'user4'],
+ 'email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ 'expectedInvitations' => [
+ 'user' => ['user3', 'user4'],
+ 'email' => ['bar@example.com'],
+ ],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/tests/Integration/Command/Share/RemoveTest.php b/tests/Integration/Command/Share/RemoveTest.php
new file mode 100644
index 00000000..39960707
--- /dev/null
+++ b/tests/Integration/Command/Share/RemoveTest.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * @copyright Copyright (c) 2021 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Polls\Tests\Integration\Command\Share;
+
+use OCA\Polls\Command\Share\Remove;
+use OCA\Polls\Db\Poll;
+use OCP\AppFramework\Db\DoesNotExistException;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Console\Exception\RuntimeException as ConsoleRuntimeException;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class RemoveTest extends TestCase
+{
+ use TShareCommandTest;
+
+ public function setUp(): void {
+ parent::setUp();
+
+ $this->setUpMocks();
+ }
+
+ public function testMissingArguments(): void {
+ $this->pollMapper
+ ->expects($this->never())
+ ->method('find');
+
+ $this->expectException(ConsoleRuntimeException::class);
+ $this->expectExceptionMessage('Not enough arguments (missing: "id").');
+
+ $command = new Remove(
+ $this->pollMapper,
+ $this->shareMapper,
+ $this->shareService,
+ $this->userManager,
+ $this->groupManager
+ );
+
+ $tester = new CommandTester($command);
+ $tester->execute([]);
+ }
+
+ public function testPollNotFound(): void {
+ $pollId = 123;
+
+ $this->pollMapper
+ ->expects($this->once())
+ ->method('find')
+ ->with($pollId)
+ ->willReturnCallback(static function (int $id): Poll {
+ throw new DoesNotExistException('');
+ });
+
+ $command = new Remove(
+ $this->pollMapper,
+ $this->shareMapper,
+ $this->shareService,
+ $this->userManager,
+ $this->groupManager
+ );
+
+ $tester = new CommandTester($command);
+ $tester->execute(['id' => $pollId]);
+
+ $this->assertEquals("Poll not found.\n", $tester->getDisplay());
+ }
+
+ /**
+ * @dataProvider validProvider
+ */
+ public function testValid(array $input, array $pollData): void {
+ $initialShares = [];
+ $expectedShareCount = 0;
+ $expectedShareTokens = [];
+ foreach ($pollData['initialShares'] as $type => $shares) {
+ foreach ($shares as $userId) {
+ $initialShares[] = $this->createShareMock($pollData['pollId'], $type, $userId);
+
+ if (in_array($userId, $pollData['expectedShares'][$type])) {
+ $expectedShareTokens[] = $this->getShareToken($pollData['pollId'], $type, $userId);
+ $expectedShareCount++;
+ }
+ }
+ }
+
+ $this->pollMapper
+ ->expects($this->once())
+ ->method('find')
+ ->with($pollData['pollId'])
+ ->willReturnCallback([$this, 'createPollMock']);
+
+ $this->shareMapper
+ ->method('findByPoll')
+ ->with($pollData['pollId'])
+ ->willReturn($initialShares);
+
+ $this->shareService
+ ->expects($this->exactly($expectedShareCount))
+ ->method('delete')
+ ->with($this->logicalOr(...$expectedShareTokens));
+
+ $command = new Remove(
+ $this->pollMapper,
+ $this->shareMapper,
+ $this->shareService,
+ $this->userManager,
+ $this->groupManager
+ );
+
+ $tester = new CommandTester($command);
+ $tester->execute($input);
+
+ $this->assertEquals("Poll invitations successfully revoked.\n", $tester->getDisplay());
+ }
+
+ public function validProvider(): array {
+ return [
+ [
+ [
+ 'id' => 1,
+ ],
+ [
+ 'pollId' => 1,
+ ],
+ ],
+ [
+ [
+ 'id' => 123,
+ '--user' => ['user1', 'user2'],
+ '--group' => ['group1'],
+ '--email' => ['foo@example.com'],
+ ],
+ [
+ 'pollId' => 123,
+ 'initialShares' => [
+ 'user' => ['user1', 'user2', 'user3'],
+ 'group' => ['group1'],
+ 'email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ 'expectedShares' => [
+ 'user' => ['user1', 'user2'],
+ 'group' => ['group1'],
+ 'email' => ['foo@example.com'],
+ ],
+ ],
+ ],
+ [
+ [
+ 'id' => 456,
+ '--user' => ['user1', 'user2', 'user3', 'user4'],
+ '--email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ [
+ 'pollId' => 456,
+ 'initialShares' => [
+ 'user' => ['user2', 'user3'],
+ 'email' => ['foo@example.com', 'bar@example.com', 'baz@example.com'],
+ ],
+ 'expectedShares' => [
+ 'user' => ['user2', 'user3'],
+ 'email' => ['foo@example.com', 'bar@example.com'],
+ ],
+ ]
+ ],
+ ];
+ }
+}
diff --git a/tests/Integration/Command/Share/TShareCommandTest.php b/tests/Integration/Command/Share/TShareCommandTest.php
new file mode 100644
index 00000000..0fdc040d
--- /dev/null
+++ b/tests/Integration/Command/Share/TShareCommandTest.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * @copyright Copyright (c) 2021 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Polls\Tests\Integration\Command\Share;
+
+use OCA\Polls\Db\Poll;
+use OCA\Polls\Db\PollMapper;
+use OCA\Polls\Db\Share;
+use OCA\Polls\Db\ShareMapper;
+use OCA\Polls\Service\ShareService;
+use OCP\IGroupManager;
+use OCP\IUserManager;
+use PHPUnit\Framework\MockObject\MockObject;
+
+trait TShareCommandTest {
+ /** @var PollMapper|MockObject */
+ protected $pollMapper;
+
+ /** @var ShareMapper|MockObject */
+ protected $shareMapper;
+
+ /** @var ShareService|MockObject */
+ protected $shareService;
+
+ /** @var IUserManager|MockObject */
+ protected $userManager;
+
+ /** @var IGroupManager|MockObject */
+ protected $groupManager;
+
+ /** @var int */
+ protected $lastShareId = 0;
+
+ protected function setUpMocks(): void {
+ $this->pollMapper = $this->createMock(PollMapper::class);
+ $this->shareMapper = $this->createMock(ShareMapper::class);
+ $this->shareService = $this->createMock(ShareService::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+ $this->groupManager = $this->createMock(IGroupManager::class);
+ }
+
+ public function createPollMock(int $id): Poll {
+ /** @var Poll|MockObject $poll */
+ $poll = $this->createMock(
+ Poll::class,
+ ['getId']
+ );
+
+ $poll->method('getId')
+ ->willReturn($id);
+
+ return $poll;
+ }
+
+ public function createShareMock(int $pollId, string $type, string $userId): Share {
+ /** @var Share|MockObject $share */
+ $share = $this->createMock(
+ Share::class,
+ ['getId', 'getPollId', 'getType', 'getEmailAddress', 'getToken'],
+ ['getUserId']
+ );
+
+ $id = ++$this->lastShareId;
+ $token = $this->getShareToken($pollId, $type, $userId);
+
+ $share->method('getId')
+ ->willReturn($id);
+
+ $share->method('getPollId')
+ ->willReturn($pollId);
+
+ $share->method('getType')
+ ->willReturn($type);
+
+ $share->method('getUserId')
+ ->willReturn($userId);
+
+ $share->method('getEmailAddress')
+ ->willReturn($userId);
+
+ $share->method('getToken')
+ ->willReturn($token);
+
+ return $share;
+ }
+
+ public function getShareToken(int $pollId, string $type, string $userId): string {
+ return substr(md5($pollId . '_' . $type . '_' . $userId), 0, 16);
+ }
+
+ protected function createMock($originalClassName, array $addMethods = null, array $onlyMethods = null): MockObject {
+ $mockBuilder = $this->getMockBuilder($originalClassName)
+ ->disableOriginalConstructor()
+ ->disableOriginalClone()
+ ->disableArgumentCloning()
+ ->disallowMockingUnknownTypes()
+ ->disableAutoReturnValueGeneration();
+
+ if ($addMethods !== null) {
+ $mockBuilder->addMethods($addMethods);
+ }
+
+ if ($onlyMethods !== null) {
+ $mockBuilder->onlyMethods($onlyMethods);
+ }
+
+ return $mockBuilder->getMock();
+ }
+}