541 lines
13 KiB
PHP
541 lines
13 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
|
|
* This file is licensed under the Affero General Public License version 3 or
|
|
* later.
|
|
* See the COPYING-README file.
|
|
*
|
|
*/
|
|
|
|
namespace Test\SystemTag;
|
|
|
|
use OC\SystemTag\SystemTagManager;
|
|
use OC\SystemTag\SystemTagObjectMapper;
|
|
use OCP\IDBConnection;
|
|
use OCP\IGroupManager;
|
|
use OCP\IUser;
|
|
use OCP\SystemTag\ISystemTag;
|
|
use OCP\SystemTag\ISystemTagManager;
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
use Test\TestCase;
|
|
|
|
/**
|
|
* Class TestSystemTagManager
|
|
*
|
|
* @group DB
|
|
* @package Test\SystemTag
|
|
*/
|
|
class SystemTagManagerTest extends TestCase {
|
|
|
|
/**
|
|
* @var ISystemTagManager
|
|
**/
|
|
private $tagManager;
|
|
|
|
/**
|
|
* @var IDBConnection
|
|
*/
|
|
private $connection;
|
|
|
|
/**
|
|
* @var IGroupManager
|
|
*/
|
|
private $groupManager;
|
|
|
|
/**
|
|
* @var EventDispatcherInterface
|
|
*/
|
|
private $dispatcher;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->connection = \OC::$server->getDatabaseConnection();
|
|
|
|
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')
|
|
->getMock();
|
|
|
|
$this->groupManager = $this->getMockBuilder(IGroupManager::class)->getMock();
|
|
|
|
$this->tagManager = new SystemTagManager(
|
|
$this->connection,
|
|
$this->groupManager,
|
|
$this->dispatcher
|
|
);
|
|
$this->pruneTagsTables();
|
|
}
|
|
|
|
protected function tearDown(): void {
|
|
$this->pruneTagsTables();
|
|
parent::tearDown();
|
|
}
|
|
|
|
protected function pruneTagsTables() {
|
|
$query = $this->connection->getQueryBuilder();
|
|
$query->delete(SystemTagObjectMapper::RELATION_TABLE)->execute();
|
|
$query->delete(SystemTagManager::TAG_TABLE)->execute();
|
|
}
|
|
|
|
public function getAllTagsDataProvider() {
|
|
return [
|
|
[
|
|
// no tags at all
|
|
[]
|
|
],
|
|
[
|
|
// simple
|
|
[
|
|
['one', false, false],
|
|
['two', false, false],
|
|
]
|
|
],
|
|
[
|
|
// duplicate names, different flags
|
|
[
|
|
['one', false, false],
|
|
['one', true, false],
|
|
['one', false, true],
|
|
['one', true, true],
|
|
['two', false, false],
|
|
['two', false, true],
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getAllTagsDataProvider
|
|
*/
|
|
public function testGetAllTags($testTags) {
|
|
$testTagsById = [];
|
|
foreach ($testTags as $testTag) {
|
|
$tag = $this->tagManager->createTag($testTag[0], $testTag[1], $testTag[2]);
|
|
$testTagsById[$tag->getId()] = $tag;
|
|
}
|
|
|
|
$tagList = $this->tagManager->getAllTags();
|
|
|
|
$this->assertCount(count($testTags), $tagList);
|
|
|
|
foreach ($testTagsById as $testTagId => $testTag) {
|
|
$this->assertTrue(isset($tagList[$testTagId]));
|
|
$this->assertSameTag($tagList[$testTagId], $testTag);
|
|
}
|
|
}
|
|
|
|
public function getAllTagsFilteredDataProvider() {
|
|
return [
|
|
[
|
|
[
|
|
// no tags at all
|
|
],
|
|
null,
|
|
null,
|
|
[]
|
|
],
|
|
// filter by visible only
|
|
[
|
|
// none visible
|
|
[
|
|
['one', false, false],
|
|
['two', false, false],
|
|
],
|
|
true,
|
|
null,
|
|
[]
|
|
],
|
|
[
|
|
// one visible
|
|
[
|
|
['one', true, false],
|
|
['two', false, false],
|
|
],
|
|
true,
|
|
null,
|
|
[
|
|
['one', true, false],
|
|
]
|
|
],
|
|
[
|
|
// one invisible
|
|
[
|
|
['one', true, false],
|
|
['two', false, false],
|
|
],
|
|
false,
|
|
null,
|
|
[
|
|
['two', false, false],
|
|
]
|
|
],
|
|
// filter by name pattern
|
|
[
|
|
[
|
|
['one', true, false],
|
|
['one', false, false],
|
|
['two', true, false],
|
|
],
|
|
null,
|
|
'on',
|
|
[
|
|
['one', true, false],
|
|
['one', false, false],
|
|
]
|
|
],
|
|
// filter by name pattern and visibility
|
|
[
|
|
// one visible
|
|
[
|
|
['one', true, false],
|
|
['two', true, false],
|
|
['one', false, false],
|
|
],
|
|
true,
|
|
'on',
|
|
[
|
|
['one', true, false],
|
|
]
|
|
],
|
|
// filter by name pattern in the middle
|
|
[
|
|
// one visible
|
|
[
|
|
['abcdefghi', true, false],
|
|
['two', true, false],
|
|
],
|
|
null,
|
|
'def',
|
|
[
|
|
['abcdefghi', true, false],
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getAllTagsFilteredDataProvider
|
|
*/
|
|
public function testGetAllTagsFiltered($testTags, $visibilityFilter, $nameSearch, $expectedResults) {
|
|
foreach ($testTags as $testTag) {
|
|
$this->tagManager->createTag($testTag[0], $testTag[1], $testTag[2]);
|
|
}
|
|
|
|
$testTagsById = [];
|
|
foreach ($expectedResults as $expectedTag) {
|
|
$tag = $this->tagManager->getTag($expectedTag[0], $expectedTag[1], $expectedTag[2]);
|
|
$testTagsById[$tag->getId()] = $tag;
|
|
}
|
|
|
|
$tagList = $this->tagManager->getAllTags($visibilityFilter, $nameSearch);
|
|
|
|
$this->assertCount(count($testTagsById), $tagList);
|
|
|
|
foreach ($testTagsById as $testTagId => $testTag) {
|
|
$this->assertTrue(isset($tagList[$testTagId]));
|
|
$this->assertSameTag($tagList[$testTagId], $testTag);
|
|
}
|
|
}
|
|
|
|
public function oneTagMultipleFlagsProvider() {
|
|
return [
|
|
['one', false, false],
|
|
['one', true, false],
|
|
['one', false, true],
|
|
['one', true, true],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider oneTagMultipleFlagsProvider
|
|
*/
|
|
public function testCreateDuplicate($name, $userVisible, $userAssignable) {
|
|
$this->expectException(\OCP\SystemTag\TagAlreadyExistsException::class);
|
|
|
|
try {
|
|
$this->tagManager->createTag($name, $userVisible, $userAssignable);
|
|
} catch (\Exception $e) {
|
|
$this->assertTrue(false, 'No exception thrown for the first create call');
|
|
}
|
|
$this->tagManager->createTag($name, $userVisible, $userAssignable);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider oneTagMultipleFlagsProvider
|
|
*/
|
|
public function testGetExistingTag($name, $userVisible, $userAssignable) {
|
|
$tag1 = $this->tagManager->createTag($name, $userVisible, $userAssignable);
|
|
$tag2 = $this->tagManager->getTag($name, $userVisible, $userAssignable);
|
|
|
|
$this->assertSameTag($tag1, $tag2);
|
|
}
|
|
|
|
public function testGetExistingTagById() {
|
|
$tag1 = $this->tagManager->createTag('one', true, false);
|
|
$tag2 = $this->tagManager->createTag('two', false, true);
|
|
|
|
$tagList = $this->tagManager->getTagsByIds([$tag1->getId(), $tag2->getId()]);
|
|
|
|
$this->assertCount(2, $tagList);
|
|
|
|
$this->assertSameTag($tag1, $tagList[$tag1->getId()]);
|
|
$this->assertSameTag($tag2, $tagList[$tag2->getId()]);
|
|
}
|
|
|
|
|
|
public function testGetNonExistingTag() {
|
|
$this->expectException(\OCP\SystemTag\TagNotFoundException::class);
|
|
|
|
$this->tagManager->getTag('nonexist', false, false);
|
|
}
|
|
|
|
|
|
public function testGetNonExistingTagsById() {
|
|
$this->expectException(\OCP\SystemTag\TagNotFoundException::class);
|
|
|
|
$tag1 = $this->tagManager->createTag('one', true, false);
|
|
$this->tagManager->getTagsByIds([$tag1->getId(), 100, 101]);
|
|
}
|
|
|
|
|
|
public function testGetInvalidTagIdFormat() {
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
|
|
$tag1 = $this->tagManager->createTag('one', true, false);
|
|
$this->tagManager->getTagsByIds([$tag1->getId() . 'suffix']);
|
|
}
|
|
|
|
public function updateTagProvider() {
|
|
return [
|
|
[
|
|
// update name
|
|
['one', true, true],
|
|
['two', true, true]
|
|
],
|
|
[
|
|
// update one flag
|
|
['one', false, true],
|
|
['one', true, true]
|
|
],
|
|
[
|
|
// update all flags
|
|
['one', false, false],
|
|
['one', true, true]
|
|
],
|
|
[
|
|
// update all
|
|
['one', false, false],
|
|
['two', true, true]
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider updateTagProvider
|
|
*/
|
|
public function testUpdateTag($tagCreate, $tagUpdated) {
|
|
$tag1 = $this->tagManager->createTag(
|
|
$tagCreate[0],
|
|
$tagCreate[1],
|
|
$tagCreate[2]
|
|
);
|
|
$this->tagManager->updateTag(
|
|
$tag1->getId(),
|
|
$tagUpdated[0],
|
|
$tagUpdated[1],
|
|
$tagUpdated[2]
|
|
);
|
|
$tag2 = $this->tagManager->getTag(
|
|
$tagUpdated[0],
|
|
$tagUpdated[1],
|
|
$tagUpdated[2]
|
|
);
|
|
|
|
$this->assertEquals($tag2->getId(), $tag1->getId());
|
|
$this->assertEquals($tag2->getName(), $tagUpdated[0]);
|
|
$this->assertEquals($tag2->isUserVisible(), $tagUpdated[1]);
|
|
$this->assertEquals($tag2->isUserAssignable(), $tagUpdated[2]);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider updateTagProvider
|
|
*/
|
|
public function testUpdateTagDuplicate($tagCreate, $tagUpdated) {
|
|
$this->expectException(\OCP\SystemTag\TagAlreadyExistsException::class);
|
|
|
|
$this->tagManager->createTag(
|
|
$tagCreate[0],
|
|
$tagCreate[1],
|
|
$tagCreate[2]
|
|
);
|
|
$tag2 = $this->tagManager->createTag(
|
|
$tagUpdated[0],
|
|
$tagUpdated[1],
|
|
$tagUpdated[2]
|
|
);
|
|
|
|
// update to match the first tag
|
|
$this->tagManager->updateTag(
|
|
$tag2->getId(),
|
|
$tagCreate[0],
|
|
$tagCreate[1],
|
|
$tagCreate[2]
|
|
);
|
|
}
|
|
|
|
public function testDeleteTags() {
|
|
$tag1 = $this->tagManager->createTag('one', true, false);
|
|
$tag2 = $this->tagManager->createTag('two', false, true);
|
|
|
|
$this->tagManager->deleteTags([$tag1->getId(), $tag2->getId()]);
|
|
|
|
$this->assertEmpty($this->tagManager->getAllTags());
|
|
}
|
|
|
|
|
|
public function testDeleteNonExistingTag() {
|
|
$this->expectException(\OCP\SystemTag\TagNotFoundException::class);
|
|
|
|
$this->tagManager->deleteTags([100]);
|
|
}
|
|
|
|
public function testDeleteTagRemovesRelations() {
|
|
$tag1 = $this->tagManager->createTag('one', true, false);
|
|
$tag2 = $this->tagManager->createTag('two', true, true);
|
|
|
|
$tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager, $this->dispatcher);
|
|
|
|
$tagMapper->assignTags(1, 'testtype', $tag1->getId());
|
|
$tagMapper->assignTags(1, 'testtype', $tag2->getId());
|
|
$tagMapper->assignTags(2, 'testtype', $tag1->getId());
|
|
|
|
$this->tagManager->deleteTags($tag1->getId());
|
|
|
|
$tagIdMapping = $tagMapper->getTagIdsForObjects(
|
|
[1, 2],
|
|
'testtype'
|
|
);
|
|
|
|
$this->assertEquals([
|
|
1 => [$tag2->getId()],
|
|
2 => [],
|
|
], $tagIdMapping);
|
|
}
|
|
|
|
public function visibilityCheckProvider() {
|
|
return [
|
|
[false, false, false, false],
|
|
[true, false, false, true],
|
|
[false, false, true, true],
|
|
[true, false, true, true],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider visibilityCheckProvider
|
|
*/
|
|
public function testVisibilityCheck($userVisible, $userAssignable, $isAdmin, $expectedResult) {
|
|
$user = $this->getMockBuilder(IUser::class)->getMock();
|
|
$user->expects($this->any())
|
|
->method('getUID')
|
|
->willReturn('test');
|
|
$tag1 = $this->tagManager->createTag('one', $userVisible, $userAssignable);
|
|
|
|
$this->groupManager->expects($this->any())
|
|
->method('isAdmin')
|
|
->with('test')
|
|
->willReturn($isAdmin);
|
|
|
|
$this->assertEquals($expectedResult, $this->tagManager->canUserSeeTag($tag1, $user));
|
|
}
|
|
|
|
public function assignabilityCheckProvider() {
|
|
return [
|
|
// no groups
|
|
[false, false, false, false],
|
|
[true, false, false, false],
|
|
[true, true, false, true],
|
|
[false, true, false, false],
|
|
// admin rulez
|
|
[false, false, true, true],
|
|
[false, true, true, true],
|
|
[true, false, true, true],
|
|
[true, true, true, true],
|
|
// ignored groups
|
|
[false, false, false, false, ['group1'], ['group1']],
|
|
[true, true, false, true, ['group1'], ['group1']],
|
|
[true, true, false, true, ['group1'], ['anothergroup']],
|
|
[false, true, false, false, ['group1'], ['group1']],
|
|
// admin has precedence over groups
|
|
[false, false, true, true, ['group1'], ['anothergroup']],
|
|
[false, true, true, true, ['group1'], ['anothergroup']],
|
|
[true, false, true, true, ['group1'], ['anothergroup']],
|
|
[true, true, true, true, ['group1'], ['anothergroup']],
|
|
// groups only checked when visible and user non-assignable and non-admin
|
|
[true, false, false, false, ['group1'], ['anothergroup1']],
|
|
[true, false, false, true, ['group1'], ['group1']],
|
|
[true, false, false, true, ['group1', 'group2'], ['group2', 'group3']],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider assignabilityCheckProvider
|
|
*/
|
|
public function testAssignabilityCheck($userVisible, $userAssignable, $isAdmin, $expectedResult, $userGroupIds = [], $tagGroupIds = []) {
|
|
$user = $this->getMockBuilder(IUser::class)->getMock();
|
|
$user->expects($this->any())
|
|
->method('getUID')
|
|
->willReturn('test');
|
|
$tag1 = $this->tagManager->createTag('one', $userVisible, $userAssignable);
|
|
$this->tagManager->setTagGroups($tag1, $tagGroupIds);
|
|
|
|
$this->groupManager->expects($this->any())
|
|
->method('isAdmin')
|
|
->with('test')
|
|
->willReturn($isAdmin);
|
|
$this->groupManager->expects($this->any())
|
|
->method('getUserGroupIds')
|
|
->with($user)
|
|
->willReturn($userGroupIds);
|
|
|
|
$this->assertEquals($expectedResult, $this->tagManager->canUserAssignTag($tag1, $user));
|
|
}
|
|
|
|
public function testTagGroups() {
|
|
$tag1 = $this->tagManager->createTag('tag1', true, false);
|
|
$tag2 = $this->tagManager->createTag('tag2', true, false);
|
|
$this->tagManager->setTagGroups($tag1, ['group1', 'group2']);
|
|
$this->tagManager->setTagGroups($tag2, ['group2', 'group3']);
|
|
|
|
$this->assertEquals(['group1', 'group2'], $this->tagManager->getTagGroups($tag1));
|
|
$this->assertEquals(['group2', 'group3'], $this->tagManager->getTagGroups($tag2));
|
|
|
|
// change groups
|
|
$this->tagManager->setTagGroups($tag1, ['group3', 'group4']);
|
|
$this->tagManager->setTagGroups($tag2, []);
|
|
|
|
$this->assertEquals(['group3', 'group4'], $this->tagManager->getTagGroups($tag1));
|
|
$this->assertEquals([], $this->tagManager->getTagGroups($tag2));
|
|
}
|
|
|
|
/**
|
|
* empty groupIds should be ignored
|
|
*/
|
|
public function testEmptyTagGroup() {
|
|
$tag1 = $this->tagManager->createTag('tag1', true, false);
|
|
$this->tagManager->setTagGroups($tag1, ['']);
|
|
$this->assertEquals([], $this->tagManager->getTagGroups($tag1));
|
|
}
|
|
|
|
/**
|
|
* @param ISystemTag $tag1
|
|
* @param ISystemTag $tag2
|
|
*/
|
|
private function assertSameTag($tag1, $tag2) {
|
|
$this->assertEquals($tag1->getId(), $tag2->getId());
|
|
$this->assertEquals($tag1->getName(), $tag2->getName());
|
|
$this->assertEquals($tag1->isUserVisible(), $tag2->isUserVisible());
|
|
$this->assertEquals($tag1->isUserAssignable(), $tag2->isUserAssignable());
|
|
}
|
|
}
|