user = 'test'; $this->otherUser = 'otheruser'; $this->request = OC::$server->get(IRequest::class); $this->otherRequest = OC::$server->get(IRequest::class); $this->publicRequest = $this->createMock(IRequest::class); $this->userManager = OC::$server->get(IUserManager::class); if (!$this->userManager->userExists($this->user)) { $this->userManager->createUser($this->user, 'password'); } $this->userId = $this->userManager->get($this->user)->getUID(); if (!$this->userManager->userExists($this->otherUser)) { $this->userManager->createUser($this->otherUser, 'password'); } $this->otherUserId = $this->userManager->get($this->otherUser)->getUID(); /** @var IFactory $l10nFactory */ $l10nFactory = OC::$server->get(IFactory::class); $l = $l10nFactory->get('bookmarks'); $this->bookmarks = OC::$server->get(BookmarkService::class); $this->bookmarkMapper = OC::$server->get(BookmarkMapper::class); $this->tagMapper = OC::$server->get(TagMapper::class); $this->folderMapper = OC::$server->get(FolderMapper::class); $this->treeMapper = OC::$server->get(TreeMapper::class); $this->publicFolderMapper = OC::$server->get(PublicFolderMapper::class); $this->shareMapper = OC::$server->get(ShareMapper::class); $this->sharedFolderMapper = OC::$server->get(SharedFolderMapper::class); $timeFactory = OC::$server->get(ITimeFactory::class); $logger = OC::$server->get(LoggerInterface::class); $urlGenerator = OC::$server->get(IURLGenerator::class); $htmlExporter = OC::$server->get(HtmlExporter::class); $this->authorizer = OC::$server->get(Authorizer::class); $this->folders = OC::$server->get(FolderService::class); $this->lockManager = OC::$server->get(LockManager::class); /** @var IRootFolder $rootFolder */ $rootFolder = OC::$server->get(IRootFolder::class); $this->controller = new BookmarkController('bookmarks', $this->request, $l, $this->bookmarkMapper, $this->tagMapper, $this->folderMapper, $this->treeMapper, $this->publicFolderMapper, $timeFactory, $logger, $urlGenerator, $htmlExporter, $this->authorizer, $this->bookmarks, $this->folders, $rootFolder, $this->lockManager); $this->otherController = new BookmarkController('bookmarks', $this->request, $l, $this->bookmarkMapper, $this->tagMapper, $this->folderMapper, $this->treeMapper, $this->publicFolderMapper, $timeFactory, $logger, $urlGenerator, $htmlExporter, $this->authorizer, $this->bookmarks, $this->folders, $rootFolder, $this->lockManager); $this->publicController = new BookmarkController('bookmarks', $this->publicRequest, $l, $this->bookmarkMapper, $this->tagMapper, $this->folderMapper, $this->treeMapper, $this->publicFolderMapper, $timeFactory, $logger, $urlGenerator, $htmlExporter, $this->authorizer, $this->bookmarks, $this->folders, $rootFolder, $this->lockManager); } /** * @throws AlreadyExistsError * @throws UrlParseError * @throws UserLimitExceededError * @throws MultipleObjectsReturnedException */ public function setupBookmarks(): void { $this->authorizer->setUserId($this->userId); $bookmark1 = Bookmark::fromArray([ 'userId' => $this->userId, 'url' => 'https://www.golem.de', 'title' => 'Golem', 'description' => 'PublicNoTag', ]); $bookmark1 = $this->bookmarkMapper->insertOrUpdate($bookmark1); $this->tagMapper->addTo(['four'], $bookmark1->getId()); $bookmark2 = Bookmark::fromArray([ 'userId' => $this->userId, 'url' => 'https://9gag.com', 'title' => '9gag', 'description' => 'PublicTag', ]); $bookmark2 = $this->bookmarkMapper->insertOrUpdate($bookmark2); $this->tagMapper->addTo(['four'], $bookmark2->getId()); $this->bookmark1Id = $bookmark1->getId(); $this->bookmark2Id = $bookmark2->getId(); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws DoesNotExistException * @throws UnsupportedOperation */ public function setupBookmarksWithPublicFolder(): void { $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $this->folder1 = new Folder(); $this->folder1->setTitle('foo'); $this->folder1->setUserId($this->userId); $this->folderMapper->insert($this->folder1); $this->folder2 = new Folder(); $this->folder2->setTitle('bar'); $this->folder2->setUserId($this->userId); $this->folderMapper->insert($this->folder2); $this->treeMapper->move(TreeMapper::TYPE_FOLDER, $this->folder2->getId(), $this->folder1->getId()); $this->publicFolder = new PublicFolder(); $this->publicFolder->setFolderId($this->folder1->getId()); $this->publicFolderMapper->insert($this->publicFolder); // inject token into public request stub $this->publicRequest->method('getHeader') ->willReturn('Bearer ' . $this->publicFolder->getId()); $this->treeMapper->addToFolders(TreeMapper::TYPE_BOOKMARK, $this->bookmark1Id, [$this->folder1->getId()]); $this->treeMapper->addToFolders(TreeMapper::TYPE_BOOKMARK, $this->bookmark2Id, [$this->folder2->getId()]); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function setupBookmarksWithSharedFolder(): void { $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId($this->userId); $this->folders->createShare($this->folder1->getId(), $this->otherUserId, \OCP\Share\IShare::TYPE_USER, true, false); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testRead(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $output = $this->controller->getSingleBookmark($this->bookmark2Id); $data = $output->getData(); $this->assertEquals('success', $data['status'], var_export($data, true)); $this->assertEquals("https://9gag.com/", $data['item']['url']); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testReadFailure(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->otherUserId); $output = $this->otherController->getSingleBookmark($this->bookmark1Id); $data = $output->getData(); $this->assertEquals('error', $data['status'], var_export($data, true)); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testPublicReadFailure(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId(null); $this->expectException(UnauthenticatedError::class); $this->publicController->getSingleBookmark($this->bookmark1Id); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testReadNotFound(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $output = $this->controller->getSingleBookmark(987); $data = $output->getData(); $this->assertSame('error', $data['status'], var_export($data, true)); $this->assertSame(404, $output->getStatus()); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testPrivateget(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $output = $this->controller->getBookmarks(); $data = $output->getData(); $this->assertCount(2, $data['data']); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testCreate(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $res = $this->controller->newBookmark('https://www.heise.de', 'Heise', 'Private', ['four']); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); // the bookmark should exist $params = new QueryParameters(); $this->assertCount(1, $this->bookmarkMapper->findAll($this->userId, $params->setUrl('https://www.heise.de'))); // user should see this bookmark $output = $this->controller->getBookmarks(); $data = $output->getData(); $this->assertCount(3, $data['data']); // others should not see this bookmark $this->authorizer->setUserId($this->otherUserId); $output = $this->otherController->getBookmarks(-1); $data = $output->getData(); $this->assertCount(0, $data['data']); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testEditBookmark(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $res = $this->controller->newBookmark('https://www.heise.de', 'Heise', 'PublicNoTag', ['four']); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $id = $res->getData()['item']['id']; $this->controller->editBookmark($id, 'https://www.heise.de', ''); $bookmark = $this->bookmarkMapper->find($id); $this->assertEquals('https://www.heise.de/', $bookmark->getUrl()); // normalized URL $this->assertEquals('', $bookmark->getTitle()); // normalized URL } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testEditBookmarkFolders(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId($this->userId); $res = $this->controller->newBookmark('https://www.heise.de', 'Heise', 'PublicNoTag', ['four'], [$this->folder1->getId()]); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $id = $res->getData()['item']['id']; $this->controller->editBookmark($id, 'https://www.heise.de', '', null, null, [$this->folder2->getId()]); $bookmark = $this->bookmarkMapper->find($id); $parents = $this->treeMapper->findParentsOf(TreeMapper::TYPE_BOOKMARK, $id); $this->assertEquals('https://www.heise.de/', $bookmark->getUrl()); // normalized URL $this->assertEquals('', $bookmark->getTitle()); // normalized URL $this->assertEquals([$this->folder2->getId()], array_map(function ($f) { return $f->getId(); }, $parents)); // has the folders we set } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testDeleteBookmark(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $res = $this->controller->newBookmark('https://www.google.com', 'Google', 'PrivateTag', ['one', 'two']); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $id = $res->getData()['item']['id']; $this->controller->deleteBookmark($id); $params = new QueryParameters(); $this->assertCount(0, $this->bookmarkMapper->findAll($this->userId, $params->setUrl('https://www.google.com'))); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testClick(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId($this->userId); $r = $this->controller->clickBookmark('https://www.golem.de'); $this->assertSame(Http::STATUS_OK, $r->getStatus()); } /** * @throws AlreadyExistsError * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError */ public function testClickFail(): void { $this->cleanUp(); $this->setupBookmarks(); $this->authorizer->setUserId(null); $r = $this->publicController->clickBookmark('https://www.golem.de'); $this->assertNotSame(Http::STATUS_OK, $r->getStatus()); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testPublicRead(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId(null); $res = $this->publicController->getSingleBookmark($this->bookmark2Id); $data = $res->getData(); $this->assertEquals('success', $data['status'], var_export($data, true)); $this->assertEquals('https://9gag.com/', $data['item']['url']); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testPublicReadNotFound(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId(null); $output = $this->publicController->getSingleBookmark(987); $data = $output->getData(); $this->assertSame('error', $data['status'], var_export($data, true)); $this->assertSame(403, $output->getStatus()); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testPublicget(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId(null); $output = $this->publicController->getBookmarks(-1, null, 'or', '', [], 10, false, $this->folder2->getId()); $data = $output->getData(); $this->assertEquals('success', $data['status'], var_export($data, true)); $this->assertCount(1, $data['data']); // TODO: 1-level search Limit! } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testPublicCreateFail(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId(null); $res = $this->publicController->newBookmark('https://www.heise.de', 'Heise', 'Private', ['four'], [$this->folder2->getId()]); $this->assertEquals('error', $res->getData()['status'], var_export($res->getData(), true)); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testPublicEditBookmarkFail(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId(null); $res = $this->publicController->editBookmark($this->bookmark1Id, 'https://www.heise.de', ''); $this->assertEquals('error', $res->getData()['status'], var_export($res->getData(), true)); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testPublicDeleteBookmarkFail(): void { $this->cleanUp(); $this->setupBookmarksWithPublicFolder(); $this->authorizer->setUserId(null); $res = $this->publicController->deleteBookmark($this->bookmark1Id); $this->assertEquals('error', $res->getData()['status'], var_export($res->getData(), true)); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testReadShared(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->otherUserId); $output = $this->otherController->getSingleBookmark($this->bookmark2Id); $data = $output->getData(); $this->assertEquals('success', $data['status'], var_export($data, true)); $this->assertEquals('https://9gag.com/', $data['item']['url']); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testQueryShared(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->otherUserId); $output = $this->otherController->getBookmarks(); $data = $output->getData(); $this->assertCount(1, $data['data'], var_export($data, true)); // TODO: 1 level search Limit } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testCreateShared(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->otherUserId); $res = $this->otherController->newBookmark('https://www.heise.de', 'Heise', 'Private', ['four'], [$this->folder1->getId()]); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); // the bookmark should exist $params = new QueryParameters(); $this->assertCount(1, $this->bookmarkMapper->findAll($this->userId, $params->setUrl('https://www.heise.de'))); // user should see this bookmark $this->authorizer->setUserId($this->userId); $output = $this->controller->getBookmarks(); $data = $output->getData(); $this->assertCount(3, $data['data']); // others should see this bookmark $this->authorizer->setUserId($this->otherUserId); $output = $this->otherController->getBookmarks(); $data = $output->getData(); $this->assertCount(2, $data['data']); // TODO: 1 level search limit } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testEditBookmarkShared(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->userId); $res = $this->controller->newBookmark('https://www.heise.de', 'Heise', 'PublicNoTag', ['four'], [$this->folder1->getId()]); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $id = $res->getData()['item']['id']; $this->authorizer->setUserId($this->otherUserId); $res = $this->otherController->editBookmark($id, 'https://www.heise.de', ''); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $bookmark = $this->bookmarkMapper->find($id); $this->assertEquals('https://www.heise.de/', $bookmark->getUrl()); // normalized URL $this->assertEquals("", $bookmark->getTitle()); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testDeleteBookmarkShared(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->userId); $res = $this->controller->newBookmark('https://www.google.com', 'Google', 'PrivateTag', ['one', 'two'], [$this->folder1->getId()]); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $id = $res->getData()['item']['id']; $this->authorizer->setUserId($this->otherUserId); $res = $this->otherController->deleteBookmark($id); $this->assertEquals('success', $res->getData()['status'], var_export($res->getData(), true)); $params = new QueryParameters(); $this->assertCount(0, $this->bookmarkMapper->findAll($this->userId, $params->setUrl('https://www.google.com'))); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testClickSharedFail(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->otherUserId); $r = $this->otherController->clickBookmark('https://www.golem.de'); $this->assertNotSame(Http::STATUS_OK, $r->getStatus()); } /** * @throws AlreadyExistsError * @throws DoesNotExistException * @throws MultipleObjectsReturnedException * @throws UrlParseError * @throws UserLimitExceededError * @throws UnsupportedOperation */ public function testLock(): void { $this->cleanUp(); $this->setupBookmarksWithSharedFolder(); $this->authorizer->setUserId($this->userId); // First come, gets the lock $output = $this->controller->acquireLock(); $this->assertEquals(Http::STATUS_OK, $output->getStatus()); // Second gets an error $output = $this->controller->acquireLock(); $this->assertEquals(Http::STATUS_LOCKED, $output->getStatus()); // Releasing... $output = $this->controller->releaseLock(); $this->assertEquals(Http::STATUS_OK, $output->getStatus()); // Then we get the lock again $output = $this->controller->acquireLock(); $this->assertEquals(Http::STATUS_OK, $output->getStatus()); // other users can lock independently $this->authorizer->setUserId($this->otherUserId); $output = $this->otherController->acquireLock(); $this->assertEquals(Http::STATUS_OK, $output->getStatus()); } }