mirror of
https://github.com/chylex/Nextcloud-News.git
synced 2025-04-09 19:15:42 +02:00
Fix generation commands and make them available in ./occ (#402)
This commit is contained in:
parent
6a4e56e727
commit
71ba5a3ad1
19
.travis.yml
19
.travis.yml
@ -2,15 +2,15 @@ sudo: false
|
||||
dist: trusty
|
||||
language: php
|
||||
php:
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.0.33
|
||||
- 7.1.26
|
||||
- 7.2
|
||||
- 7.3
|
||||
- nightly
|
||||
|
||||
env:
|
||||
global:
|
||||
- CORE_BRANCH=stable14
|
||||
- CORE_BRANCH=stable15
|
||||
- MOZ_HEADLESS=1
|
||||
matrix:
|
||||
- DB=pgsql
|
||||
@ -20,16 +20,6 @@ matrix:
|
||||
- env: DB=pgsql CORE_BRANCH=master
|
||||
- php: nightly
|
||||
include:
|
||||
- php: 7.1
|
||||
env: DB=sqlite
|
||||
- php: 7.2
|
||||
env: DB=sqlite
|
||||
- php: 7.1
|
||||
env: DB=mysql
|
||||
- php: 7.2
|
||||
env: DB=mysql
|
||||
- php: 7.2
|
||||
env: DB=pgsql CORE_BRANCH=master
|
||||
- php: 7.3
|
||||
env: DB=sqlite
|
||||
- php: 7.3
|
||||
@ -59,9 +49,10 @@ before_script:
|
||||
- ./occ app:check-code news
|
||||
- ./occ background:cron # enable default cron
|
||||
- php -S localhost:8080 &
|
||||
- cd apps/news
|
||||
|
||||
script:
|
||||
- ./occ news:generate-explore --votes 100 "https://nextcloud.com/blogfeed"
|
||||
- cd apps/news
|
||||
- make test
|
||||
|
||||
after_failure:
|
||||
|
2
Makefile
2
Makefile
@ -150,6 +150,7 @@ endif
|
||||
appstore:
|
||||
rm -rf $(appstore_build_directory) $(appstore_artifact_directory)
|
||||
mkdir -p $(appstore_build_directory) $(appstore_artifact_directory)
|
||||
./bin/tools/generate_authors.php
|
||||
cp -r \
|
||||
"appinfo" \
|
||||
"css" \
|
||||
@ -189,3 +190,4 @@ test:
|
||||
# \Test\TestCase is only allowed to access the db if TRAVIS environment variable is set
|
||||
env TRAVIS=1 ./vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml --coverage-clover build/php-unit.clover
|
||||
$(MAKE) phpcs
|
||||
./bin/tools/generate_authors.php
|
||||
|
@ -15,6 +15,7 @@ use OCA\News\Command\Updater\UpdateFeed;
|
||||
use OCA\News\Command\Updater\AllFeeds;
|
||||
use OCA\News\Command\Updater\BeforeUpdate;
|
||||
use OCA\News\Command\Updater\AfterUpdate;
|
||||
use OCA\News\Command\ExploreGenerator;
|
||||
|
||||
$app = new Application();
|
||||
$container = $app->getContainer();
|
||||
@ -22,3 +23,4 @@ $application->add($container->query(AllFeeds::class));
|
||||
$application->add($container->query(UpdateFeed::class));
|
||||
$application->add($container->query(BeforeUpdate::class));
|
||||
$application->add($container->query(AfterUpdate::class));
|
||||
$application->add($container->query(ExploreGenerator::class));
|
||||
|
10
bin/tools/generate_authors.php
Normal file → Executable file
10
bin/tools/generate_authors.php
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Nextcloud - News
|
||||
@ -15,13 +16,20 @@ exec($cmd, $contributors);
|
||||
// extract data from git output into an array
|
||||
$regex = '/^\s*(?P<commit_count>\d+)\s*(?P<name>.*\w)\s*<(?P<email>[^\s]+)>$/';
|
||||
$contributors = array_map(function ($contributor) use ($regex) {
|
||||
$result = [];
|
||||
preg_match($regex, $contributor, $result);
|
||||
return $result;
|
||||
}, $contributors);
|
||||
|
||||
// filter out bots
|
||||
$contributors = array_filter($contributors, function ($contributor) {
|
||||
return strpos($contributor['name'], 'Jenkins') !== 0;
|
||||
if (empty($contributor['name']) || empty($contributor['email'])) {
|
||||
return false;
|
||||
}
|
||||
if (strpos($contributor['email'], 'bot') || strpos($contributor['name'], 'bot')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// turn tuples into markdown
|
||||
|
126
bin/tools/generate_explore.php
Normal file → Executable file
126
bin/tools/generate_explore.php
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Nextcloud - News
|
||||
@ -8,58 +9,89 @@
|
||||
* @author Bernhard Posselt <dev@bernhard-posselt.com>
|
||||
* @copyright Bernhard Posselt 2016
|
||||
*/
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../../../../lib/base.php';
|
||||
|
||||
use FeedIo\FeedIo;
|
||||
use Favicon\Favicon;
|
||||
use OCA\News\AppInfo\Application;
|
||||
|
||||
$generator = new ExploreGenerator();
|
||||
$generator->parse_argv($argv);
|
||||
print(json_encode($generator->read(), JSON_PRETTY_PRINT));
|
||||
print("\n");
|
||||
|
||||
/**
|
||||
* This is used for generating a JSON config section for a feed by executing:
|
||||
* php -f generate_authors.php www.feed.com
|
||||
* @deprecated Use ./occ news:generate-explore instead.
|
||||
*/
|
||||
class ExploreGenerator
|
||||
{
|
||||
/**
|
||||
* Feed and favicon fetcher.
|
||||
*/
|
||||
protected $reader;
|
||||
protected $favicon;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
/**
|
||||
* Argument data
|
||||
*/
|
||||
protected $url;
|
||||
protected $votes;
|
||||
|
||||
/**
|
||||
* Set up class.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$app = new Application();
|
||||
$container = $app->getContainer();
|
||||
|
||||
$this->reader = $container->query(FeedIo::class);
|
||||
$this->favicon = new Favicon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse required arguments.
|
||||
* @param array $argv Arguments to the script.
|
||||
* @return void
|
||||
*/
|
||||
public function parse_argv($argv = [])
|
||||
{
|
||||
if (count($argv) < 2 || count($argv) > 3)
|
||||
{
|
||||
print('Usage: php -f generate_explore http://path.com/feed [vote_count]');
|
||||
print("\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$this->votes = (count($argv) === 3) ? $argv[2] : 100;
|
||||
$this->url = $argv[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the provided feed and return the important data.
|
||||
* @return array Object representation of the feed
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
try {
|
||||
$resource = $this->reader->read($this->url);
|
||||
$feed = $resource->getFeed();
|
||||
$result = [
|
||||
'title' => $feed->getTitle(),
|
||||
'favicon' => $this->favicon->get($feed->getLink()),
|
||||
'url' => $feed->getLink(),
|
||||
'feed' => $this->url,
|
||||
'description' => $feed->getDescription(),
|
||||
'votes' => $this->votes,
|
||||
];
|
||||
|
||||
return $result;
|
||||
} catch (\Throwable $ex) {
|
||||
return [ 'error' => $ex->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($argv) < 2 || count($argv) > 3) {
|
||||
print('Usage: php -f generate_explore http://path.com/feed [vote_count]');
|
||||
print("\n");
|
||||
exit();
|
||||
} elseif (count($argv) === 3) {
|
||||
$votes = $argv[2];
|
||||
} else {
|
||||
$votes = 100;
|
||||
}
|
||||
|
||||
$url = $argv[1];
|
||||
|
||||
try {
|
||||
$config = new PicoFeed\Config\Config();
|
||||
$reader = new PicoFeed\Reader\Reader($config);
|
||||
$resource = $reader->discover($url);
|
||||
|
||||
$location = $resource->getUrl();
|
||||
$content = $resource->getContent();
|
||||
$encoding = $resource->getEncoding();
|
||||
|
||||
$parser = $reader->getParser($location, $content, $encoding);
|
||||
|
||||
$feed = $parser->execute();
|
||||
|
||||
$favicon = new PicoFeed\Reader\Favicon($config);
|
||||
|
||||
$result = [
|
||||
"title" => $feed->getTitle(),
|
||||
"favicon" => $favicon->find($url),
|
||||
"url" => $feed->getSiteUrl(),
|
||||
"feed" => $feed->getFeedUrl(),
|
||||
"description" => $feed->getDescription(),
|
||||
"votes" => $votes
|
||||
];
|
||||
|
||||
if ($feed->getLogo()) {
|
||||
$result["image"] = $feed->getLogo();
|
||||
}
|
||||
|
||||
print(json_encode($result, JSON_PRETTY_PRINT));
|
||||
|
||||
} catch (\Exception $ex) {
|
||||
print($ex->getMessage());
|
||||
}
|
||||
|
||||
print("\n");
|
@ -40,7 +40,8 @@
|
||||
"pear/net_url2": "2.2.2",
|
||||
"riimu/kit-pathjoin": "1.2.0",
|
||||
"debril/feed-io": "^3.0",
|
||||
"arthurhoaro/favicon": "^1.2"
|
||||
"arthurhoaro/favicon": "^1.2",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.5",
|
||||
|
@ -9,5 +9,5 @@ As a developer you can interact with the News app in the following ways:
|
||||
* [Customize the explore section](explore/)
|
||||
|
||||
|
||||
The News app uses [picoFeed](https://github.com/miniflux/picoFeed) for parsing feeds and full text feeds. picoFeed is a fantastic library so if you [add custom full text configurations](https://github.com/miniflux/picoFeed/blob/master/docs/grabber.markdown#how-to-write-a-grabber-rules-file) or fix bugs, please consider **contributing your changes** back to the library to help others :)
|
||||
The News app uses [FeedIO](https://github.com/alexdebril/feed-io) for parsing feeds and full text feeds. FeedIO is a fantastic library so if you contribute or fix bugs, please consider **contributing your changes** back to the library to help others :)
|
||||
|
||||
|
@ -22,13 +22,13 @@ The file has the following format:
|
||||
}
|
||||
```
|
||||
|
||||
To ease the pain of constructing the JSON object, you can use a small script to automatically create it:
|
||||
To ease the pain of constructing the JSON object, you can use a nextcloud command to automatically create it:
|
||||
|
||||
php -f bin/tools/generate_explore.php https://path.com/to/feed.rss
|
||||
php ./occ news:generate-explore https://path.com/to/feed.rss
|
||||
|
||||
By passing a second parameter you can set the vote count which determines the sorting on the explore page:
|
||||
|
||||
php -f bin/tools/generate_explore.php https://path.com/to/feed.rss 1000
|
||||
php ./occ news:generate-explore https://path.com/to/feed.rss 1000
|
||||
|
||||
You can paste the output directly into the appropriate json file but you may need to add additional categories and commas
|
||||
|
||||
|
@ -8,7 +8,7 @@ There are essentially three different use cases for plugins:
|
||||
* Dropping in additional CSS or JavaScript
|
||||
|
||||
## The Basics
|
||||
Whatever plugin you want to create, you first need to create a basic structure. A plugin is basically just an app so you can take advantage of the full [Nextcloud app API](https://docs.nextcloud.org/server/9/developer_manual/app/index.html). If you want you can [take a look at the developer docs](https://docs.nextcloud.org/server/9/developer_manual/app/index.html) or [dig into the tutorial](https://docs.nextcloud.org/server/9/developer_manual/app/tutorial.html).
|
||||
Whatever plugin you want to create, you first need to create a basic structure. A plugin is basically just an app so you can take advantage of the full [Nextcloud app API](https://docs.nextcloud.org/server/latest/developer_manual/app/index.html). If you want you can [take a look at the developer docs](https://docs.nextcloud.org/server/latest/developer_manual/app/index.html) or [dig into the tutorial](https://docs.nextcloud.org/server/latest/developer_manual/app/tutorial.html).
|
||||
|
||||
However if you just want to start slow, the full process is described below.
|
||||
|
||||
|
@ -76,7 +76,6 @@ class Application extends App
|
||||
return $c->query(MapperFactory::class)->build();
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* App config parser.
|
||||
*/
|
||||
@ -123,7 +122,6 @@ class Application extends App
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
$container->registerService(Config::class, function (IContainer $c): Config {
|
||||
$config = new Config(
|
||||
$c->query('ConfigView'),
|
||||
|
94
lib/Command/ExploreGenerator.php
Normal file
94
lib/Command/ExploreGenerator.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Nextcloud - News
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Sean Molenaar <sean@seanmolenaar.eu>
|
||||
* @copyright Sean Molenaar 2019
|
||||
*/
|
||||
namespace OCA\News\Command;
|
||||
|
||||
use FeedIo\FeedIo;
|
||||
use Favicon\Favicon;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* This is used for generating a JSON config section for a feed by executing:
|
||||
* ./occ news:generate-explore www.feed.com
|
||||
*/
|
||||
class ExploreGenerator extends Command
|
||||
{
|
||||
/**
|
||||
* Feed and favicon fetcher.
|
||||
*/
|
||||
protected $reader;
|
||||
protected $favicon;
|
||||
|
||||
/**
|
||||
* Set up class.
|
||||
*
|
||||
* @param FeedIo $reader Feed reader
|
||||
* @param Favicon $favicon Favicon fetcher
|
||||
*/
|
||||
public function __construct(FeedIo $reader, Favicon $favicon)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
$this->favicon = $favicon;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$result = [
|
||||
'title' => 'Feed - Title',
|
||||
'favicon' => 'www.web.com/favicon.ico',
|
||||
'url' => 'www.web.com',
|
||||
'feed' => 'www.web.com/rss.xml',
|
||||
'description' => 'description is here',
|
||||
'votes' => 100,
|
||||
];
|
||||
|
||||
$this->setName('news:generate-explore')
|
||||
->setDescription(
|
||||
'Prints a JSON string which represents the given ' .
|
||||
'feed URL and votes, e.g.: ' . json_encode($result)
|
||||
)
|
||||
->addArgument('feed', InputArgument::REQUIRED, 'Feed to parse')
|
||||
->addOption('votes', null, InputOption::VALUE_OPTIONAL, 'Votes for the feed, defaults to 100');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$url = $input->getArgument('feed');
|
||||
$votes = $input->getOption('votes');
|
||||
if (!$votes) {
|
||||
$votes = 100;
|
||||
}
|
||||
|
||||
try {
|
||||
$resource = $this->reader->read($url);
|
||||
$feed = $resource->getFeed();
|
||||
$result = [
|
||||
'title' => $feed->getTitle(),
|
||||
'favicon' => $this->favicon->get($feed->getLink()),
|
||||
'url' => $feed->getLink(),
|
||||
'feed' => $url,
|
||||
'description' => $feed->getDescription(),
|
||||
'votes' => $votes,
|
||||
];
|
||||
|
||||
$output->writeln(json_encode($result, JSON_PRETTY_PRINT));
|
||||
} catch (\Throwable $ex) {
|
||||
$output->writeln('<error>Failed to fetch feed info:</error>');
|
||||
$output->writeln($ex->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
200
tests/Unit/Command/ExploreGeneratorTest.php
Normal file
200
tests/Unit/Command/ExploreGeneratorTest.php
Normal file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Sean Molenaar <sean@seanmolenaar.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\News\Tests\Unit\Command;
|
||||
|
||||
use FeedIo\Feed;
|
||||
use FeedIo\FeedIo;
|
||||
use Favicon\Favicon;
|
||||
use FeedIo\Reader\Result;
|
||||
use OCA\News\Command\ExploreGenerator;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class ExploreGeneratorTest extends TestCase {
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $favicon;
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $feedio;
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $consoleInput;
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $consoleOutput;
|
||||
|
||||
/** @var \Symfony\Component\Console\Command\Command */
|
||||
protected $command;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$feedio = $this->feedio = $this->getMockBuilder(FeedIo::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$favicon = $this->favicon = $this->getMockBuilder(Favicon::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
|
||||
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();
|
||||
|
||||
/** @var \FeedIo\FeedIo $feedio, \Favicon\Favicon $favicon */
|
||||
$this->command = new ExploreGenerator($feedio, $favicon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a valid feed will write the data needed.
|
||||
*/
|
||||
public function testValidFeed()
|
||||
{
|
||||
$result = $this->getMockBuilder(Result::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$feed = $this->getMockBuilder(Feed::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$feed->expects($this->once())
|
||||
->method('getTitle')
|
||||
->willReturn('Title');
|
||||
$feed->expects($this->exactly(2))
|
||||
->method('getLink')
|
||||
->willReturn('Link');
|
||||
$feed->expects($this->once())
|
||||
->method('getDescription')
|
||||
->willReturn('Description');
|
||||
|
||||
$result->expects($this->once())
|
||||
->method('getFeed')
|
||||
->willReturn($feed);
|
||||
|
||||
$this->favicon->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn('https://feed.io/favicon.ico');
|
||||
|
||||
$this->feedio->expects($this->once())
|
||||
->method('read')
|
||||
->with('https://feed.io/rss.xml')
|
||||
->willReturn($result);
|
||||
|
||||
$this->consoleInput->expects($this->once())
|
||||
->method('getArgument')
|
||||
->with('feed')
|
||||
->willReturn('https://feed.io/rss.xml');
|
||||
|
||||
$this->consoleInput->expects($this->once())
|
||||
->method('getOption')
|
||||
->with('votes')
|
||||
->willReturn(100);
|
||||
|
||||
$this->consoleOutput->expects($this->once())
|
||||
->method('writeln')
|
||||
->with($this->stringContains('https:\/\/feed.io\/rss.xml'));
|
||||
|
||||
self::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a valid feed will write the data needed.
|
||||
*/
|
||||
public function testFailingFeed()
|
||||
{
|
||||
|
||||
$this->favicon->expects($this->never())
|
||||
->method('get');
|
||||
|
||||
$this->feedio->expects($this->once())
|
||||
->method('read')
|
||||
->with('https://feed.io/rss.xml')
|
||||
->will($this->throwException(new \Exception('Failure')));
|
||||
|
||||
$this->consoleInput->expects($this->once())
|
||||
->method('getArgument')
|
||||
->with('feed')
|
||||
->willReturn('https://feed.io/rss.xml');
|
||||
|
||||
$this->consoleInput->expects($this->once())
|
||||
->method('getOption')
|
||||
->with('votes')
|
||||
->willReturn(100);
|
||||
|
||||
$this->consoleOutput->expects($this->at(0))
|
||||
->method('writeln')
|
||||
->with($this->stringContains('<error>'));
|
||||
|
||||
$this->consoleOutput->expects($this->at(1))
|
||||
->method('writeln')
|
||||
->with($this->stringContains('Failure'));
|
||||
|
||||
self::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a valid feed and votes will write the data needed.
|
||||
*/
|
||||
public function testFeedWithVotes()
|
||||
{
|
||||
$result = $this->getMockBuilder(Result::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$feed = $this->getMockBuilder(Feed::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$feed->expects($this->once())
|
||||
->method('getTitle')
|
||||
->willReturn('Title');
|
||||
$feed->expects($this->exactly(2))
|
||||
->method('getLink')
|
||||
->willReturn('Link');
|
||||
$feed->expects($this->once())
|
||||
->method('getDescription')
|
||||
->willReturn('Description');
|
||||
|
||||
$result->expects($this->once())
|
||||
->method('getFeed')
|
||||
->willReturn($feed);
|
||||
|
||||
$this->favicon->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn('https://feed.io/favicon.ico');
|
||||
|
||||
$this->feedio->expects($this->once())
|
||||
->method('read')
|
||||
->with('https://feed.io/rss.xml')
|
||||
->willReturn($result);
|
||||
|
||||
$this->consoleInput->expects($this->once())
|
||||
->method('getArgument')
|
||||
->with('feed')
|
||||
->willReturn('https://feed.io/rss.xml');
|
||||
|
||||
$this->consoleInput->expects($this->once())
|
||||
->method('getOption')
|
||||
->with('votes')
|
||||
->willReturn(200);
|
||||
|
||||
$this->consoleOutput->expects($this->once())
|
||||
->method('writeln')
|
||||
->with($this->stringContains('200'));
|
||||
|
||||
self::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user