Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ The format is almost based on [Keep a Changelog](https://keepachangelog.com/en/1

## [16.x.x]
### Changed
- Added vue and ng-vue packages
- Reimplemented relative time formatting as a filter
- Added vue and ng-vue packages (#1421)
- Reimplemented relative time formatting as a filter (#1450)
- Added new `news:updater:update-user` command to update the feeds of a single user (#1360).

### Fixed

Expand Down
1 change: 1 addition & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Report a [feed issue](https://github.com/nextcloud/news/discussions/new)
<command>OCA\News\Command\ExploreGenerator</command>
<command>OCA\News\Command\ShowFeed</command>
<command>OCA\News\Command\Updater\UpdateFeed</command>
<command>OCA\News\Command\Updater\UpdateUser</command>
<command>OCA\News\Command\Updater\BeforeUpdate</command>
<command>OCA\News\Command\Updater\AfterUpdate</command>
<command>OCA\News\Command\Config\FolderList</command>
Expand Down
70 changes: 70 additions & 0 deletions lib/Command/Updater/UpdateUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*/

namespace OCA\News\Command\Updater;

use Exception;
use OCA\News\Service\FeedServiceV2;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateUser extends Command
{
/**
* @var FeedServiceV2 Feed service
*/
private $feedService;

public function __construct(FeedServiceV2 $feedService)
{
parent::__construct();
$this->feedService = $feedService;
}

/**
* @return void
*/
protected function configure()
{
$this->setName('news:updater:update-user')
->addArgument(
'user-id',
InputArgument::REQUIRED,
'user id of a user, string'
)
->setDescription('Console API for updating a single user\'s feed');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$userId = $input->getArgument('user-id');
$feeds = $this->feedService->findAllForUser($userId);
$updateErrors = false;
foreach ($feeds as $feed) {
try {
$updated_feed = $this->feedService->fetch($feed);
if ($updated_feed->getUpdateErrorCount() !== 0) {
$output->writeln($updated_feed->getLastUpdateError());
$updateErrors = true;
}
} catch (Exception $e) {
$output->writeln(
'<error>Could not update feed with id ' . $feed->getId() .
'. ' . $e->getMessage() . '</error> '
);
return 1;
}
}
if ($updateErrors) {
return 255;
}
return 0;
}
}
140 changes: 140 additions & 0 deletions tests/Unit/Command/UpdateUserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*/

namespace OCA\News\Tests\Unit\Command;

use OCA\News\Command\Updater\UpdateUser;
use OCA\News\Db\Feed;
use OCA\News\Service\Exceptions\ServiceNotFoundException;
use OCA\News\Service\FeedServiceV2;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateUserTest extends TestCase
{
/** @var MockObject|FeedServiceV2 */
protected $service;
/** @var MockObject|InputInterface */
protected $consoleInput;
/** @var MockObject|OutputInterface */
protected $consoleOutput;

/** @var UpdateUser */
protected $command;

protected function setUp(): void
{
$this->service = $this->getMockBuilder(FeedServiceV2::class)
->disableOriginalConstructor()
->getMock();

$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();

$this->command = new UpdateUser($this->service);
}

/**
* Test a valid call will work
*/
public function testValid()
{
$this->consoleInput->expects($this->exactly(1))
->method('getArgument')
->will($this->returnValueMap([
['user-id', 'admin'],
]));

$feed = $this->createMock(Feed::class);

$feed->expects($this->exactly(1))
->method('getUpdateErrorCount')
->willReturn(0);
$feed->expects($this->exactly(0))
->method('getLastUpdateError');

$this->service->expects($this->exactly(1))
->method('findAllForUser')
->with('admin')
->willReturn([$feed]);

$this->service->expects($this->exactly(1))
->method('fetch')
->with($feed)
->willReturn($feed);

$result = $this->command->run($this->consoleInput, $this->consoleOutput);
$this->assertSame(0, $result);
}

/**
* Test valid calls that fails on some updates
*/
public function testValidFeedError()
{
$this->consoleInput->expects($this->exactly(1))
->method('getArgument')
->will($this->returnValueMap([
['user-id', 'admin'],
]));

$feed = $this->createMock(Feed::class);
$feed->expects($this->exactly(1))
->method('getUpdateErrorCount')
->willReturn(10);
$feed->expects($this->exactly(1))
->method('getLastUpdateError')
->willReturn('Problem');

$this->service->expects($this->exactly(1))
->method('findAllForUser')
->with('admin')
->willReturn([$feed]);

$this->service->expects($this->exactly(1))
->method('fetch')
->with($feed)
->willReturn($feed);

$this->consoleOutput->expects($this->exactly(1))
->method('writeln')
->with('Problem');

$result = $this->command->run($this->consoleInput, $this->consoleOutput);
$this->assertSame(255, $result);
}

/**
* Test valid calls that fails completely
*/
public function testInValid()
{
$this->consoleInput->expects($this->exactly(1))
->method('getArgument')
->will($this->returnValueMap([
['user-id', 'admin'],
]));

$feed = $this->createMock(Feed::class);

$this->service->expects($this->exactly(1))
->method('findAllForUser')
->with('admin')
->willReturn([$feed]);

$this->service->expects($this->exactly(1))
->method('fetch')
->with($feed)
->will($this->throwException(new ServiceNotFoundException('')));

$result = $this->command->run($this->consoleInput, $this->consoleOutput);
$this->assertSame(1, $result);
}
}