diff options
author | Sean Molenaar <sean@seanmolenaar.eu> | 2020-12-26 13:09:41 +0100 |
---|---|---|
committer | Sean Molenaar <SMillerDev@users.noreply.github.com> | 2020-12-30 11:21:44 +0100 |
commit | 05377d023ef4d43818a4b42039c8143cb0f907e4 (patch) | |
tree | c01fc681c42671dad774de7dc7c46524eb9ae015 /lib/Service | |
parent | 27bd54058050a70bd1c9ec8cfcdf42d38541f1b0 (diff) |
Remove PHPunit integration tests
Signed-off-by: Sean Molenaar <sean@seanmolenaar.eu>
Diffstat (limited to 'lib/Service')
-rw-r--r-- | lib/Service/FeedService.php | 521 | ||||
-rw-r--r-- | lib/Service/FeedServiceV2.php | 122 | ||||
-rw-r--r-- | lib/Service/FolderServiceV2.php | 59 | ||||
-rw-r--r-- | lib/Service/ImportService.php | 125 | ||||
-rw-r--r-- | lib/Service/ItemService.php | 71 | ||||
-rw-r--r-- | lib/Service/ItemServiceV2.php | 25 | ||||
-rw-r--r-- | lib/Service/OpmlService.php | 7 | ||||
-rw-r--r-- | lib/Service/Service.php | 48 | ||||
-rw-r--r-- | lib/Service/StatusService.php | 5 |
9 files changed, 292 insertions, 691 deletions
diff --git a/lib/Service/FeedService.php b/lib/Service/FeedService.php deleted file mode 100644 index c671a035c..000000000 --- a/lib/Service/FeedService.php +++ /dev/null @@ -1,521 +0,0 @@ -<?php -/** - * Nextcloud - News - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Alessandro Cosentino <cosenal@gmail.com> - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @copyright 2012 Alessandro Cosentino - * @copyright 2012-2014 Bernhard Posselt - */ - -namespace OCA\News\Service; - -use FeedIo\Reader\ReadErrorException; -use HTMLPurifier; - -use OCA\News\AppInfo\Application; -use OCP\IConfig; -use OCA\News\Service\Exceptions\ServiceConflictException; -use OCA\News\Service\Exceptions\ServiceNotFoundException; -use OCP\AppFramework\Db\Entity; -use OCP\IL10N; -use OCP\AppFramework\Db\DoesNotExistException; - -use OCA\News\Db\Feed; -use OCA\News\Db\Item; -use OCA\News\Db\FeedMapper; -use OCA\News\Db\ItemMapper; -use OCA\News\Fetcher\Fetcher; -use OCA\News\Utility\Time; -use Psr\Log\LoggerInterface; - -/** - * Class LegacyFeedService - * - * @package OCA\News\Service - * @deprecated use FeedServiceV2 - */ -class FeedService extends Service -{ - - private $feedFetcher; - private $itemMapper; - private $feedMapper; - private $l10n; - private $timeFactory; - private $autoPurgeMinimumInterval; - private $purifier; - private $loggerParams; - - public function __construct( - FeedMapper $legacyFeedMapper, - Fetcher $feedFetcher, - ItemMapper $legacyItemMapper, - LoggerInterface $logger, - IL10N $l10n, - Time $timeFactory, - IConfig $config, - HTMLPurifier $purifier - ) { - parent::__construct($legacyFeedMapper, $logger); - $this->feedFetcher = $feedFetcher; - $this->feedMapper = $legacyFeedMapper; - $this->itemMapper = $legacyItemMapper; - $this->logger = $logger; - $this->l10n = $l10n; - $this->timeFactory = $timeFactory; - $this->autoPurgeMinimumInterval = $config->getAppValue( - Application::NAME, - 'autoPurgeMinimumInterval', - Application::DEFAULT_SETTINGS['autoPurgeMinimumInterval'] - ); - $this->purifier = $purifier; - $this->loggerParams = ['app' => Application::NAME]; - } - - /** - * Finds all feeds of a user - * - * @param string $userId the name of the user - * - * @return Feed[] - */ - public function findAllForUser($userId, array $params = []): array - { - return $this->feedMapper->findAllFromUser($userId); - } - - - /** - * Finds all feeds from all users - * - * @return array of feeds - */ - public function findAllFromAllUsers() - { - return $this->findAll(); - } - - - /** - * Creates a new feed - * - * @param string $feedUrl the url to the feed - * @param int|null $folderId the folder where it should be put into, null for root - * folder - * @param string $userId for which user the feed should be created - * @param string|null $title if given, this is used for the opml feed title - * @param string|null $user if given, basic auth is set for this feed - * @param string|null $password if given, basic auth is set for this - * feed. Ignored if user is null or an empty string - * - * @return Feed the newly created feed - * @throws ServiceConflictException if the feed exists already - * @throws ServiceNotFoundException if the url points to an invalid feed - */ - public function create( - string $feedUrl, - ?int $folderId, - string $userId, - string $title = null, - string $user = null, - string $password = null - ) { - // first try if the feed exists already - try { - /** - * @var Feed $feed - * @var Item[] $items - */ - list($feed, $items) = $this->feedFetcher->fetch($feedUrl, true, null, false, $user, $password); - // try again if feed exists depending on the reported link - if ($feed === null) { - throw new ServiceNotFoundException($this->l10n->t('Can not add feed: Unable to parse feed')); - } - try { - $hash = $feed->getUrlHash(); - $this->feedMapper->findByUrlHash($hash, $userId); - throw new ServiceConflictException( - $this->l10n->t('Can not add feed: Exists already') - ); - } catch (DoesNotExistException $ex) { - // If no matching feed was found everything was ok - } - - // insert feed - $itemCount = count($items); - $feed->setBasicAuthUser($user); - $feed->setBasicAuthPassword($password); - $feed->setFolderId($folderId); - $feed->setUserId($userId); - $feed->setArticlesPerUpdate($itemCount); - - if (!empty($title)) { - $feed->setTitle($title); - } - - $feed = $this->feedMapper->insert($feed); - - // insert items in reverse order because the first one is usually - // the newest item - $unreadCount = 0; - foreach (array_reverse($items) as $item) { - $item->setFeedId($feed->getId()); - - // check if item exists (guidhash is the same) - // and ignore it if it does - try { - $this->itemMapper->findByGuidHash( - $item->getGuidHash(), - $item->getFeedId(), - $userId - ); - continue; - } catch (DoesNotExistException $ex) { - $unreadCount += 1; - $item->setBody($this->purifier->purify($item->getBody())); - $this->itemMapper->insert($item); - } - } - - // set unread count - $feed->setUnreadCount($unreadCount); - - return $feed; - } catch (ReadErrorException $ex) { - $this->logger->debug($ex->getMessage(), $this->loggerParams); - throw new ServiceNotFoundException($ex->getMessage()); - } - } - - - /** - * Runs all the feed updates - */ - public function updateAll() - { - // TODO: this method is not covered by any tests - $feeds = $this->feedMapper->findAll(); - foreach ($feeds as $feed) { - try { - $this->update($feed->getId(), $feed->getUserId()); - } catch (\Exception $ex) { - // something is really wrong here, log it - $this->logger->error( - 'Unexpected error when updating feed ' . $ex->getMessage(), - $this->loggerParams - ); - } - } - } - - - /** - * Updates a single feed - * - * @param string $userId the id of the user - * @param int $feedId the id of the feed that should be updated - * @param bool $forceUpdate update even if the article exists already - * - * @throws ServiceNotFoundException if the feed does not exist - * @return Feed the updated feed entity - */ - public function update(string $userId, int $feedId, $forceUpdate = false) - { - /** @var Feed $existingFeed */ - $existingFeed = $this->find($userId, $feedId); - - if ($existingFeed->getPreventUpdate() === true) { - return $existingFeed; - } - - // for backwards compability it can be that the location is not set - // yet, if so use the url - $location = $existingFeed->getLocation(); - if (!$location) { - $location = $existingFeed->getUrl(); - } - - try { - list($fetchedFeed, $items) = $this->feedFetcher->fetch( - $location, - false, - $existingFeed->getHttpLastModified(), - $existingFeed->getFullTextEnabled(), - $existingFeed->getBasicAuthUser(), - $existingFeed->getBasicAuthPassword() - ); - - // if there is no feed it means that no update took place - if (!$fetchedFeed) { - return $existingFeed; - } - - // update number of articles on every feed update - $itemCount = count($items); - - // this is needed to adjust to updates that add more items - // than when the feed was created. You can't update the count - // if it's lower because it may be due to the caching headers - // that were sent as the request and it might cause unwanted - // deletion and reappearing of feeds - if ($itemCount > $existingFeed->getArticlesPerUpdate()) { - $existingFeed->setArticlesPerUpdate($itemCount); - } - - $existingFeed->setHttpLastModified( - $fetchedFeed->getHttpLastModified() - ); - $existingFeed->setHttpEtag($fetchedFeed->getHttpEtag()); - $existingFeed->setLocation($fetchedFeed->getLocation()); - - // insert items in reverse order because the first one is - // usually the newest item - for ($i = $itemCount - 1; $i >= 0; $i--) { - $item = $items[$i]; - $item->setFeedId($existingFeed->getId()); - - try { - $dbItem = $this->itemMapper->findByGuidHash( - $item->getGuidHash(), - $feedId, - $userId - ); - - // in case of update - if ($forceUpdate - || $item->getUpdatedDate() > $dbItem->getUpdatedDate() - ) { - $dbItem->setTitle($item->getTitle()); - $dbItem->setUrl($item->getUrl()); - $dbItem->setAuthor($item->getAuthor()); - $dbItem->setSearchIndex($item->getSearchIndex()); - $dbItem->setRtl($item->getRtl()); - $dbItem->setLastModified($item->getLastModified()); - $dbItem->setPubDate($item->getPubDate()); - $dbItem->setUpdatedDate($item->getUpdatedDate()); - $dbItem->setEnclosureMime($item->getEnclosureMime()); - $dbItem->setEnclosureLink($item->getEnclosureLink()); - $dbItem->setBody( - $this->purifier->purify($item->getBody()) - ); - - // update modes: 0 nothing, 1 set unread - if ($existingFeed->getUpdateMode() === 1) { - $dbItem->setUnread(true); - } - - $this->itemMapper->update($dbItem); - } - } catch (DoesNotExistException $ex) { - $item->setBody( - $this->purifier->purify($item->getBody()) - ); - $this->itemMapper->insert($item); - } - } - - // mark feed as successfully updated - $existingFeed->setUpdateErrorCount(0); - $existingFeed->setLastUpdateError(''); - } catch (ReadErrorException $ex) { - $existingFeed->setUpdateErrorCount( - $existingFeed->getUpdateErrorCount() + 1 - ); - $existingFeed->setLastUpdateError($ex->getMessage()); - } - - $this->feedMapper->update($existingFeed); - - return $this->find($userId, $feedId); - } - - /** - * Import articles - * - * @param array $json the array with json - * @param string $userId the username - * - * @return Feed if one had to be created for nonexistent feeds - */ - public function importArticles($json, $userId) - { - $url = 'http://nextcloud/nofeed'; - $urlHash = md5($url); - - // build assoc array for fast access - $feeds = $this->findAllForUser($userId); - $feedsDict = []; - foreach ($feeds as $feed) { - $feedsDict[$feed->getLink()] = $feed; - } - - $createdFeed = false; - - // loop over all items and get the corresponding feed - // if the feed does not exist, create a separate feed for them - foreach ($json as $entry) { - $item = Item::fromImport($entry); - $feedLink = $entry['feedLink']; // this is not set on the item yet - - if (array_key_exists($feedLink, $feedsDict)) { - $feed = $feedsDict[$feedLink]; - $item->setFeedId($feed->getId()); - } elseif (array_key_exists($url, $feedsDict)) { - $feed = $feedsDict[$url]; - $item->setFeedId($feed->getId()); - } else { - $createdFeed = true; - $feed = new Feed(); - $feed->setUserId($userId); - $feed->setLink($url); - $feed->setUrl($url); - $feed->setTitle($this->l10n->t('Articles without feed')); - $feed->setAdded($this->timeFactory->getTime()); - $feed->setFolderId(null); - $feed->setPreventUpdate(true); - /** @var Feed $feed */ - $feed = $this->feedMapper->insert($feed); - - $item->setFeedId($feed->getId()); - $feedsDict[$feed->getLink()] = $feed; - } - - try { - // if item exists, copy the status - $existingItem = $this->itemMapper->findByGuidHash( - $item->getGuidHash(), - $feed->getId(), - $userId - ); - $existingItem->setStatus($item->getStatus()); - $this->itemMapper->update($existingItem); - } catch (DoesNotExistException $ex) { - $item->setBody($this->purifier->purify($item->getBody())); - $item->generateSearchIndex(); - $this->itemMapper->insert($item); - } - } - - if ($createdFeed) { - return $this->feedMapper->findByUrlHash($urlHash, $userId); - } - - return null; - } - - - /** - * Use this to mark a feed as deleted. That way it can be un-deleted - * - * @param int $feedId the id of the feed that should be deleted - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException when feed does not exist - */ - public function markDeleted(int $feedId, string $userId) - { - $feed = $this->find($userId, $feedId); - $feed->setDeletedAt($this->timeFactory->getTime()); - $this->feedMapper->update($feed); - } - - - /** - * Use this to undo a feed deletion - * - * @param int $feedId the id of the feed that should be restored - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException when feed does not exist - */ - public function unmarkDeleted(int $feedId, string $userId) - { - $feed = $this->find($userId, $feedId); - $feed->setDeletedAt(0); - $this->feedMapper->update($feed); - } - - - /** - * Deletes all deleted feeds - * - * @param string $userId if given it purges only feeds of that user - * @param boolean $useInterval defaults to true, if true it only purges - * entries in a given interval to give the user a chance to undo the - * deletion - */ - public function purgeDeleted($userId = null, $useInterval = true) - { - $deleteOlderThan = null; - - if ($useInterval) { - $now = $this->timeFactory->getTime(); - $deleteOlderThan = $now - $this->autoPurgeMinimumInterval; - } - - $toDelete = $this->feedMapper->getToDelete($deleteOlderThan, $userId); - - foreach ($toDelete as $feed) { - $this->feedMapper->delete($feed); - } - } - - - /** - * Deletes all feeds of a user, delete items first since the user_id - * is not defined in there - * - * @param string $userId the name of the user - */ - public function deleteUser($userId) - { - $this->feedMapper->deleteUser($userId); - } - - /** - * @param int $feedId ID of the feed. - * @param string $userId ID of the user. - * @param array $diff An array containing the fields to update, e.g.: - * <code> - * [ - * 'ordering' => 1, - * 'fullTextEnabled' => true, - * 'pinned' => true, - * 'updateMode' => 0, - * 'title' => 'title' - * ] - * </code> - * - * @throws ServiceNotFoundException if feed does not exist - * @return Feed The patched feed - */ - public function patch(int $feedId, string $userId, array $diff = []) - { - $feed = $this->find($userId, $feedId); - - foreach ($diff as $attribute => $value) { - $method = 'set' . ucfirst($attribute); - $feed->$method($value); - } - - // special feed updates - if (array_key_exists('fullTextEnabled', $diff)) { - // disable caching for the next update - $feed->setHttpEtag(''); - $feed->setHttpLastModified(0); - $this->feedMapper->update($feed); - return $this->update($userId, $feedId, true); - } - - return $this->feedMapper->update($feed); - } - - public function findAll(): array - { - return $this->feedMapper->findAll(); - } -} diff --git a/lib/Service/FeedServiceV2.php b/lib/Service/FeedServiceV2.php index 16402d0da..88f18a3bf 100644 --- a/lib/Service/FeedServiceV2.php +++ b/lib/Service/FeedServiceV2.php @@ -29,7 +29,6 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCA\News\Db\Feed; use OCA\News\Db\Item; -use OCA\News\Db\FeedMapper; use OCA\News\Db\ItemMapper; use OCA\News\Fetcher\Fetcher; use OCA\News\Config\Config; @@ -105,22 +104,6 @@ class FeedServiceV2 extends Service } /** - * Finds a feed of a user - * - * @param string $userId the name of the user - * @param string $id the id of the feed - * - * @return Feed - * - * @throws DoesNotExistException - * @throws MultipleObjectsReturnedException - */ - public function findForUser(string $userId, string $id): Feed - { - return $this->mapper->findFromUser($userId, $id); - } - - /** * @param int|null $id * * @return Feed[] @@ -139,6 +122,7 @@ class FeedServiceV2 extends Service */ public function findAllForUserRecursive(string $userId): array { + /** @var Feed[] $feeds */ $feeds = $this->mapper->findAllFromUser($userId); foreach ($feeds as &$feed) { @@ -168,11 +152,23 @@ class FeedServiceV2 extends Service */ public function existsForUser(string $userID, string $url): bool { + return $this->findByURL($userID, $url) !== null; + } + + /** + * Check if a feed exists for a user + * + * @param string $userID the name of the user + * @param string $url the feed URL + * + * @return Entity|Feed|null + */ + public function findByURL(string $userID, string $url): ?Entity + { try { - $this->mapper->findByURL($userID, $url); - return true; + return $this->mapper->findByURL($userID, $url); } catch (DoesNotExistException $e) { - return false; + return null; } } @@ -274,58 +270,59 @@ class FeedServiceV2 extends Service $feed->getBasicAuthUser(), $feed->getBasicAuthPassword() ); + } catch (ReadErrorException $ex) { + $feed->setUpdateErrorCount($feed->getUpdateErrorCount() + 1); + $feed->setLastUpdateError($ex->getMessage()); - // if there is no feed it means that no update took place - if (!$fetchedFeed) { - return $feed; - } + return $this->mapper->update($feed); + } - // update number of articles on every feed update - $itemCount = count($items); + // if there is no feed it means that no update took place + if (!$fetchedFeed) { + return $feed; + } - // this is needed to adjust to updates that add more items - // than when the feed was created. You can't update the count - // if it's lower because it may be due to the caching headers - // that were sent as the request and it might cause unwanted - // deletion and reappearing of feeds - if ($itemCount > $feed->getArticlesPerUpdate()) { - $feed->setArticlesPerUpdate($itemCount); - } + // update number of articles on every feed update + $itemCount = count($items); - $feed->setHttpLastModified($fetchedFeed->getHttpLastModified()) - ->setHttpEtag($fetchedFeed->getHttpEtag()) - ->setLocation($fetchedFeed->getLocation()); + // this is needed to adjust to updates that add more items + // than when the feed was created. You can't update the count + // if it's lower because it may be due to the caching headers + // that were sent as the request and it might cause unwanted + // deletion and reappearing of feeds + if ($itemCount > $feed->getArticlesPerUpdate()) { + $feed->setArticlesPerUpdate($itemCount); + } - // insert items in reverse order because the first one is - // usually the newest item - for ($i = $itemCount - 1; $i >= 0; $i--) { - $item = $items[$i]; - $item->setFeedId($feed->getId()) - ->setBody($this->purifier->purify($item->getBody())); + $feed->setHttpLastModified($fetchedFeed->getHttpLastModified()) + ->setHttpEtag($fetchedFeed->getHttpEtag()) + ->setLocation($fetchedFeed->getLocation()); - // update modes: 0 nothing, 1 set unread - if ($feed->getUpdateMode() === 1) { - $item->setUnread(true); - } + foreach (array_reverse($items) as &$item) { + $item->setFeedId($feed->getId()) + ->setBody($this->purifier->purify($item->getBody())); - $this->itemService->insertOrUpdate($item); + // update modes: 0 nothing, 1 set unread + if ($feed->getUpdateMode() === Feed::UPDATE_MODE_NORMAL) { + $item->setUnread(true); } - // mark feed as successfully updated - $feed->setUpdateErrorCount(0); - $feed->setLastUpdateError(null); - } catch (ReadErrorException $ex) { - $feed->setUpdateErrorCount($feed->getUpdateErrorCount() + 1); - $feed->setLastUpdateError($ex->getMessage()); + $item = $this->itemService->insertOrUpdate($item); } - return $this->mapper->update($feed); - } - public function delete(string $user, int $id): void - { - $feed = $this->mapper->findFromUser($user, $id); - $this->mapper->delete($feed); + // mark feed as successfully updated + $feed->setUpdateErrorCount(0); + $feed->setLastUpdateError(null); + + $unreadCount = 0; + array_map(function (Item $item) use (&$unreadCount) { + if ($item->isUnread()) { + $unreadCount++; + } + }, $items); + + return $this->mapper->update($feed)->setUnreadCount($unreadCount); } /** @@ -341,6 +338,11 @@ class FeedServiceV2 extends Service $this->mapper->purgeDeleted($userID, $minTimestamp); } + /** + * Fetch all feeds. + * + * @see FeedServiceV2::fetch() + */ public function fetchAll(): void { foreach ($this->findAll() as $feed) { diff --git a/lib/Service/FolderServiceV2.php b/lib/Service/FolderServiceV2.php index ae04c8089..25903c17b 100644 --- a/lib/Service/FolderServiceV2.php +++ b/lib/Service/FolderServiceV2.php @@ -64,28 +64,6 @@ class FolderServiceV2 extends Service } /** - * Finds a folder of a user - * - * @param string $userId The name/ID of the user - * @param int|null $folderId ID of the folder - * - * @return Folder - * - * @throws ServiceConflictException - * @throws ServiceNotFoundException - */ - public function findForUser(string $userId, ?int $folderId): Entity - { - try { - return $this->mapper->findFromUser($userId, $folderId); - } catch (DoesNotExistException $e) { - throw new ServiceNotFoundException('Folder not found'); - } catch (MultipleObjectsReturnedException $e) { - throw new ServiceConflictException('Multiple folders found'); - } - } - - /** * Find all folders and it's feeds. * * @param string $userId The name/ID of the owner @@ -134,23 +112,6 @@ class FolderServiceV2 extends Service } /** - * Delete a feed. - * - * @param string $userId Folder owner - * @param int $folderId Folder ID - * - * @return Folder - * @throws ServiceConflictException - * @throws ServiceNotFoundException - */ - public function delete(string $userId, int $folderId): Entity - { - $folder = $this->findForUser($userId, $folderId); - - return $this->mapper->delete($folder); - } - - /** * Purge all deleted folders. * * @param string|null $userID The user to purge @@ -174,8 +135,9 @@ class FolderServiceV2 extends Service */ public function rename(string $userId, int $folderId, string $newName): Entity { - $folder = $this->findForUser($userId, $folderId); + $folder = $this->find($userId, $folderId); $folder->setName($newName); + return $this->mapper->update($folder); } @@ -192,7 +154,7 @@ class FolderServiceV2 extends Service */ public function markDelete(string $userId, int $folderId, bool $mark): Entity { - $folder = $this->findForUser($userId, $folderId); + $folder = $this->find($userId, $folderId); $time = $mark ? $this->timeFactory->getTime() : 0; $folder->setDeletedAt($time); @@ -212,21 +174,8 @@ class FolderServiceV2 extends Service */ public function open(string $userId, ?int $folderId, bool $open): Entity { - $folder = $this->findForUser($userId, $folderId); + $folder = $this->find($userId, $folderId); $folder->setOpened($open); return $this->mapper->update($folder); } - - /** - * Delete all folders of a user - * - * @param string $userId User ID/name - */ - public function deleteUser(string $userId): void - { - $folders = $this->findAllForUser($userId); - foreach ($folders as $folder) { - $this->mapper->delete($folder); - } - } } diff --git a/lib/Service/ImportService.php b/lib/Service/ImportService.php new file mode 100644 index 000000000..c3334fad2 --- /dev/null +++ b/lib/Service/ImportService.php @@ -0,0 +1,125 @@ +<?php +/** + * Nextcloud - News + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Alessandro Cosentino <cosenal@gmail.com> + * @author Bernhard Posselt <dev@bernhard-posselt.com> + * @copyright 2012 Alessandro Cosentino + * @copyright 2012-2014 Bernhard Posselt + */ + +namespace OCA\News\Service; + +use \OCA\News\Db\Item; |