mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Adjust TT-RSS to ignore hidden items
This commit is contained in:
parent
f33359f3e3
commit
ade0402210
2 changed files with 130 additions and 229 deletions
|
@ -26,6 +26,7 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
|||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
public const LEVEL = 14; // emulated API level
|
||||
public const VERSION = "17.4"; // emulated TT-RSS version
|
||||
|
||||
protected const LABEL_OFFSET = 1024; // offset below zero at which labels begin, counting down
|
||||
protected const LIMIT_ARTICLES = 200; // maximum number of articles returned by getHeadlines
|
||||
protected const LIMIT_EXCERPT = 100; // maximum length of excerpts in getHeadlines, counted in grapheme units
|
||||
|
@ -81,6 +82,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
'mode' => ValueInfo::T_INT, // whether to set, clear, or toggle the selected state in `updateArticle`
|
||||
'data' => ValueInfo::T_STRING, // note text in `updateArticle` if setting a note
|
||||
];
|
||||
protected const VIEW_MODES = ["all_articles", "adaptive", "unread", "marked", "has_note", "published"];
|
||||
// generic error construct
|
||||
protected const FATAL_ERR = [
|
||||
'seq' => null,
|
||||
|
@ -234,7 +236,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
public function opGetCounters(array $data): array {
|
||||
$user = Arsse::$user->id;
|
||||
$starred = Arsse::$db->articleStarred($user);
|
||||
$fresh = Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H")));
|
||||
$fresh = Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H", $this->now()))->hidden(false));
|
||||
$countAll = 0;
|
||||
$countSubs = 0;
|
||||
$feeds = [];
|
||||
|
@ -339,7 +341,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
'id' => "FEED:".self::FEED_FRESH,
|
||||
'bare_id' => self::FEED_FRESH,
|
||||
'icon' => "images/fresh.png",
|
||||
'unread' => Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H"))),
|
||||
'unread' => Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H", $this->now()))->hidden(false)),
|
||||
], $tSpecial),
|
||||
array_merge([ // Starred articles
|
||||
'name' => Arsse::$lang->msg("API.TTRSS.Feed.Starred"),
|
||||
|
@ -391,7 +393,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
];
|
||||
$unread += ($l['articles'] - $l['read']);
|
||||
}
|
||||
// if there are labels, all the label category,
|
||||
// if there are labels, add the "Labels" category,
|
||||
if ($items) {
|
||||
$out[] = [
|
||||
'name' => Arsse::$lang->msg("API.TTRSS.Category.Labels"),
|
||||
|
@ -523,7 +525,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// FIXME: this is pretty inefficient
|
||||
$f = $map[self::CAT_SPECIAL];
|
||||
$cats[$f]['unread'] += Arsse::$db->articleStarred($user)['unread']; // starred
|
||||
$cats[$f]['unread'] += Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H"))); // fresh
|
||||
$cats[$f]['unread'] += Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H", $this->now()))->hidden(false)); // fresh
|
||||
if (!$read) {
|
||||
// if we're only including unread entries, remove any categories with zero unread items (this will by definition also exclude empties)
|
||||
$count = sizeof($cats);
|
||||
|
@ -675,8 +677,8 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
if ($cat == self::CAT_ALL || $cat == self::CAT_SPECIAL) {
|
||||
// gather some statistics
|
||||
$starred = Arsse::$db->articleStarred($user)['unread'];
|
||||
$fresh = Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H")));
|
||||
$global = Arsse::$db->articleCount($user, (new Context)->unread(true));
|
||||
$fresh = Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H", $this->now()))->hidden(false));
|
||||
$global = Arsse::$db->articleCount($user, (new Context)->unread(true)->hidden(false));
|
||||
$published = 0; // TODO: if the Published feed is implemented, the getFeeds method needs to be adjusted accordingly
|
||||
$archived = 0; // the archived feed is non-functional in the TT-RSS protocol itself
|
||||
// build the list; exclude anything with zero unread if requested
|
||||
|
@ -737,7 +739,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// NOTE: the list is a flat one: it includes children, but not other descendents
|
||||
foreach (Arsse::$db->folderList($user, $cat, false) as $c) {
|
||||
// get the number of unread for the category and its descendents; those with zero unread are excluded in "unread-only" mode
|
||||
$count = Arsse::$db->articleCount($user, (new Context)->unread(true)->folder((int) $c['id']));
|
||||
$count = Arsse::$db->articleCount($user, (new Context)->unread(true)->folder((int) $c['id'])->hidden(false));
|
||||
if (!$unread || $count) {
|
||||
$out[] = [
|
||||
'id' => (int) $c['id'],
|
||||
|
@ -1037,7 +1039,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$cat = $data['is_cat'] ?? false;
|
||||
$out = ['status' => "OK"];
|
||||
// first prepare the context; unsupported contexts simply return early
|
||||
$c = new Context;
|
||||
$c = (new Context)->hidden(false);
|
||||
if ($cat) { // categories
|
||||
switch ($id) {
|
||||
case self::CAT_SPECIAL:
|
||||
|
@ -1073,7 +1075,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// TODO: if the Published feed is implemented, the catchup function needs to be modified accordingly
|
||||
return $out;
|
||||
case self::FEED_FRESH:
|
||||
$c->modifiedSince(Date::sub("PT24H"));
|
||||
$c->modifiedSince(Date::sub("PT24H", $this->now()));
|
||||
break;
|
||||
case self::FEED_ALL:
|
||||
// no context needed here
|
||||
|
@ -1188,6 +1190,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
"id",
|
||||
"guid",
|
||||
"title",
|
||||
"author",
|
||||
"url",
|
||||
"unread",
|
||||
"starred",
|
||||
|
@ -1296,10 +1299,14 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
"subscription",
|
||||
"subscription_title",
|
||||
"note",
|
||||
($data['show_content'] || $data['show_excerpt']) ? "content" : "",
|
||||
($data['include_attachments']) ? "media_url": "",
|
||||
($data['include_attachments']) ? "media_type": "",
|
||||
];
|
||||
if ($data['show_content'] || $data['show_excerpt']) {
|
||||
$columns[] = "content";
|
||||
}
|
||||
if ($data['include_attachments']) {
|
||||
$columns[] = "media_url";
|
||||
$columns[] = "media_type";
|
||||
}
|
||||
foreach ($this->fetchArticles($data, $columns) as $article) {
|
||||
$row = [
|
||||
'id' => (int) $article['id'],
|
||||
|
@ -1387,9 +1394,10 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$id = $data['feed_id'];
|
||||
$cat = $data['is_cat'] ?? false;
|
||||
$shallow = !($data['include_nested'] ?? false);
|
||||
$viewMode = in_array($data['view_mode'], ["all_articles", "adaptive", "unread", "marked", "has_note", "published"]) ? $data['view_mode'] : "all_articles";
|
||||
$viewMode = in_array($data['view_mode'], self::VIEW_MODES) ? $data['view_mode'] : "all_articles";
|
||||
assert(in_array($viewMode, self::VIEW_MODES), new \JKingWeb\Arsse\Exception("constantUnknown", $viewMode));
|
||||
// prepare the context; unsupported, invalid, or inherently empty contexts return synthetic empty result sets
|
||||
$c = new Context;
|
||||
$c = (new Context)->hidden(false);
|
||||
$tr = Arsse::$db->begin();
|
||||
// start with the feed or category ID
|
||||
if ($cat) { // categories
|
||||
|
@ -1433,13 +1441,13 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// TODO: if the Published feed is implemented, the headline function needs to be modified accordingly
|
||||
return new ResultEmpty;
|
||||
case self::FEED_FRESH:
|
||||
$c->modifiedSince(Date::sub("PT24H"))->unread(true);
|
||||
$c->modifiedSince(Date::sub("PT24H", $this->now()))->unread(true);
|
||||
break;
|
||||
case self::FEED_ALL:
|
||||
// no context needed here
|
||||
break;
|
||||
case self::FEED_READ:
|
||||
$c->markedSince(Date::sub("PT24H"))->unread(false); // FIXME: this selects any recently touched (read, starred, annotated) article which is read, not necessarily a recently read one
|
||||
$c->markedSince(Date::sub("PT24H", $this->now()))->unread(false); // FIXME: this selects any recently touched (read, starred, annotated) article which is read, not necessarily a recently read one
|
||||
break;
|
||||
default:
|
||||
// any actual feed
|
||||
|
@ -1477,8 +1485,6 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// not implemented
|
||||
// TODO: if the Published feed is implemented, the headline function needs to be modified accordingly
|
||||
return new ResultEmpty;
|
||||
default:
|
||||
throw new \JKingWeb\Arsse\Exception("constantUnknown", $viewMode); // @codeCoverageIgnore
|
||||
}
|
||||
// handle the search string, if any
|
||||
if (isset($data['search'])) {
|
||||
|
|
|
@ -23,6 +23,8 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
|||
/** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\API<extended>
|
||||
* @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Exception */
|
||||
class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
protected const NOW = "2020-12-21T23:09:17.189065Z";
|
||||
|
||||
protected $h;
|
||||
protected $folders = [
|
||||
['id' => 5, 'parent' => 3, 'children' => 0, 'feeds' => 1, 'name' => "Local"],
|
||||
|
@ -1113,7 +1115,7 @@ LONG_STRING;
|
|||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->topFolders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
|
||||
$exp = [
|
||||
[
|
||||
|
@ -1177,7 +1179,7 @@ LONG_STRING;
|
|||
\Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
|
||||
$exp = [
|
||||
['id' => "global-unread", 'counter' => 35],
|
||||
|
@ -1298,7 +1300,7 @@ LONG_STRING;
|
|||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), true)->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
|
||||
// the expectations are packed tightly since they're very verbose; one can use var_export() (or convert to JSON) to pretty-print them
|
||||
$exp = ['categories' => ['identifier' => 'id','label' => 'name','items' => [['name' => 'Special','id' => 'CAT:-1','bare_id' => -1,'type' => 'category','unread' => 0,'items' => [['name' => 'All articles','id' => 'FEED:-4','bare_id' => -4,'icon' => 'images/folder.png','unread' => 35,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Fresh articles','id' => 'FEED:-3','bare_id' => -3,'icon' => 'images/fresh.png','unread' => 7,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Starred articles','id' => 'FEED:-1','bare_id' => -1,'icon' => 'images/star.png','unread' => 4,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Published articles','id' => 'FEED:-2','bare_id' => -2,'icon' => 'images/feed.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Archived articles','id' => 'FEED:0','bare_id' => 0,'icon' => 'images/archive.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Recently read','id' => 'FEED:-6','bare_id' => -6,'icon' => 'images/time.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => '']]],['name' => 'Labels','id' => 'CAT:-2','bare_id' => -2,'type' => 'category','unread' => 6,'items' => [['name' => 'Fascinating','id' => 'FEED:-1027','bare_id' => -1027,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => ''],['name' => 'Interesting','id' => 'FEED:-1029','bare_id' => -1029,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => ''],['name' => 'Logical','id' => 'FEED:-1025','bare_id' => -1025,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => '']]],['name' => 'Photography','id' => 'CAT:4','bare_id' => 4,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(0 feeds)','items' => []],['name' => 'Politics','id' => 'CAT:3','bare_id' => 3,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(3 feeds)','items' => [['name' => 'Local','id' => 'CAT:5','bare_id' => 5,'parent_id' => 3,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(1 feed)','items' => [['name' => 'Toronto Star','id' => 'FEED:2','bare_id' => 2,'icon' => 'feed-icons/2.ico','error' => 'oops','param' => '2011-11-11T11:11:11Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'National','id' => 'CAT:6','bare_id' => 6,'parent_id' => 3,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(2 feeds)','items' => [['name' => 'CBC News','id' => 'FEED:4','bare_id' => 4,'icon' => 'feed-icons/4.ico','error' => '','param' => '2017-10-09T15:58:34Z','unread' => 0,'auxcounter' => 0,'checkbox' => false],['name' => 'Ottawa Citizen','id' => 'FEED:5','bare_id' => 5,'icon' => false,'error' => '','param' => '2017-07-07T17:07:17Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]]]],['name' => 'Science','id' => 'CAT:1','bare_id' => 1,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(2 feeds)','items' => [['name' => 'Rocketry','id' => 'CAT:2','bare_id' => 2,'parent_id' => 1,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(1 feed)','items' => [['name' => 'NASA JPL','id' => 'FEED:1','bare_id' => 1,'icon' => false,'error' => '','param' => '2017-09-15T22:54:16Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'Ars Technica','id' => 'FEED:3','bare_id' => 3,'icon' => 'feed-icons/3.ico','error' => 'argh','param' => '2016-05-23T06:40:02Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'Uncategorized','id' => 'CAT:0','bare_id' => 0,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'parent_id' => null,'param' => '(1 feed)','items' => [['name' => 'Eurogamer','id' => 'FEED:6','bare_id' => 6,'icon' => 'feed-icons/6.ico','error' => '','param' => '2010-02-12T20:08:47Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]]]]];
|
||||
|
@ -1343,19 +1345,19 @@ LONG_STRING;
|
|||
for ($a = 0; $a < sizeof($in2); $a++) {
|
||||
$this->assertMessage($exp, $this->req($in2[$a]), "Test $a failed");
|
||||
}
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], new Context);
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->starred(true));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->label(1088));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->subscription(2112));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folder(42));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folderShallow(0));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->labelled(true));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->hidden(false));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->starred(true)->hidden(false));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->label(1088)->hidden(false));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->subscription(2112)->hidden(false));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folder(42)->hidden(false));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folderShallow(0)->hidden(false));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->labelled(true)->hidden(false));
|
||||
// verify the time-based mock
|
||||
$t = Date::sub("PT24H");
|
||||
for ($a = 0; $a < sizeof($in3); $a++) {
|
||||
$this->assertMessage($exp, $this->req($in3[$a]), "Test $a failed");
|
||||
}
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], $this->equalTo((new Context)->modifiedSince($t), 2)); // within two seconds
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], $this->equalTo((new Context)->hidden(false)->modifiedSince($t), 2)); // within two seconds
|
||||
}
|
||||
|
||||
public function testRetrieveFeedList(): void {
|
||||
|
@ -1385,8 +1387,8 @@ LONG_STRING;
|
|||
];
|
||||
// statistical mocks
|
||||
\Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(35);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->hidden(false)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true)->hidden(false))->thenReturn(35);
|
||||
// label mocks
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
|
@ -1400,7 +1402,7 @@ LONG_STRING;
|
|||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterFolders(null))));
|
||||
foreach ($this->folders as $f) {
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterFolders($f['id']))));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true)->folder($f['id']))->thenReturn($this->reduceFolders($f['id']));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true)->hidden(false)->folder($f['id']))->thenReturn($this->reduceFolders($f['id']));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterSubs($f['id']))));
|
||||
}
|
||||
$exp = [
|
||||
|
@ -1694,206 +1696,99 @@ LONG_STRING;
|
|||
$this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5]));
|
||||
}
|
||||
|
||||
public function testRetrieveCompactHeadlines(): void {
|
||||
$in1 = [
|
||||
// erroneous input
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx"],
|
||||
// empty results
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 0],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2, 'is_cat' => true], // is_cat is not used in getCompactHeadlines
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'view_mode' => "published"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6, 'view_mode' => "unread"],
|
||||
// non-empty results
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2112],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'view_mode' => "adaptive"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2112, 'view_mode' => "adaptive"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2112, 'view_mode' => "unread"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'view_mode' => "marked"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'view_mode' => "has_note"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'limit' => 5],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'skip' => 2],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'limit' => 5, 'skip' => 2],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'since_id' => 47],
|
||||
];
|
||||
$in2 = [
|
||||
// time-based contexts, handled separately
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6, 'view_mode' => "adaptive"],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3],
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'view_mode' => "marked"],
|
||||
];
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v([['id' => 0]])));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1);
|
||||
$c = (new Context);
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(2112), ["id"], ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $c, ["id"], ["edited_date desc"])->thenReturn(new Result($this->v($this->articles)));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->starred(true), ["id"], ["marked_date desc"])->thenReturn(new Result($this->v([['id' => 1]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 2]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->unread(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 3]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088)->unread(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 4]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->starred(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 5]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->annotated(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 6]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 7]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->offset(2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 8]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5)->offset(2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 9]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->oldestArticle(48), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 10]])));
|
||||
$out1 = [
|
||||
$this->respErr("INCORRECT_USAGE"),
|
||||
$this->respGood([]),
|
||||
$this->respGood([]),
|
||||
$this->respGood([]),
|
||||
$this->respGood([]),
|
||||
$this->respGood([]),
|
||||
$this->respGood([]),
|
||||
$this->respGood([['id' => 101],['id' => 102]]),
|
||||
$this->respGood([['id' => 1]]),
|
||||
$this->respGood([['id' => 2]]),
|
||||
$this->respGood([['id' => 3]]),
|
||||
$this->respGood([['id' => 2]]), // the result is 2 rather than 4 because there are no unread, so the unread context is not used
|
||||
$this->respGood([['id' => 4]]),
|
||||
$this->respGood([['id' => 5]]),
|
||||
$this->respGood([['id' => 6]]),
|
||||
$this->respGood([['id' => 7]]),
|
||||
$this->respGood([['id' => 8]]),
|
||||
$this->respGood([['id' => 9]]),
|
||||
$this->respGood([['id' => 10]]),
|
||||
];
|
||||
$out2 = [
|
||||
$this->respGood([['id' => 1001]]),
|
||||
$this->respGood([['id' => 1001]]),
|
||||
$this->respGood([['id' => 1002]]),
|
||||
$this->respGood([['id' => 1003]]),
|
||||
];
|
||||
for ($a = 0; $a < sizeof($in1); $a++) {
|
||||
$this->assertMessage($out1[$a], $this->req($in1[$a]), "Test $a failed");
|
||||
}
|
||||
for ($a = 0; $a < sizeof($in2); $a++) {
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(false)->markedSince(Date::sub("PT24H")), 2), ["id"], ["marked_date desc"])->thenReturn(new Result($this->v([['id' => 1001]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H")), 2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 1002]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H"))->starred(true), 2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 1003]])));
|
||||
$this->assertMessage($out2[$a], $this->req($in2[$a]), "Test $a failed");
|
||||
}
|
||||
}
|
||||
|
||||
public function testRetrieveFullHeadlines(): void {
|
||||
$in1 = [
|
||||
// empty results
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 0],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1, 'is_cat' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'view_mode' => "published"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6, 'view_mode' => "unread"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'view_mode' => "unread", 'search' => "unread:false"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'search' => "pub:true"],
|
||||
];
|
||||
$in2 = [
|
||||
// simple context tests
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2112],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'view_mode' => "adaptive"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2112, 'view_mode' => "adaptive"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2112, 'view_mode' => "unread"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'view_mode' => "marked"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'view_mode' => "has_note"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'limit' => 5],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'skip' => 2],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'limit' => 5, 'skip' => 2],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'since_id' => 47],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'is_cat' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'is_cat' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -2, 'is_cat' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 0, 'is_cat' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'is_cat' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'is_cat' => true, 'include_nested' => true],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'order_by' => "feed_dates"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'order_by' => "date_reverse"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'search' => "interesting"],
|
||||
];
|
||||
$in3 = [
|
||||
// time-based context tests
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6, 'view_mode' => "adaptive"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'view_mode' => "marked"],
|
||||
];
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
|
||||
/** @dataProvider provideHeadlines */
|
||||
public function testRetrieveHeadlines(bool $full, array $in, $out, Context $c, array $fields, array $order, ResponseInterface $exp): void {
|
||||
$base = ['op' => $full ? "getHeadlines" : "getCompactHeadlines", 'sid' => "PriestsOfSyrinx"];
|
||||
$in = array_merge($base, $in);
|
||||
$this->h = \Phake::partialMock(API::class);
|
||||
\Phake::when($this->h)->now->thenReturn(Date::normalize(self::NOW));
|
||||
\Phake::when(Arsse::$db)->labelList->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3]));
|
||||
\Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]);
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(0));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1);
|
||||
$c = (new Context)->limit(200);
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(2112), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->starred(true), $this->anything(), ["marked_date desc"])->thenReturn($this->generateHeadlines(1));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(2));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->unread(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(3));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088)->unread(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(4));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->starred(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(5));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->annotated(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(6));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(7));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->offset(2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(8));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5)->offset(2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(9));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->oldestArticle(48), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(10));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(11));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->labelled(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(12));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(0), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(13));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(14));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folder(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(15));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c), $this->anything(), ["edited_date"])->thenReturn($this->generateHeadlines(16));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->searchTerms(["interesting"]), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(17));
|
||||
$out2 = [
|
||||
$this->respErr("INCORRECT_USAGE"),
|
||||
$this->outputHeadlines(11),
|
||||
$this->outputHeadlines(1),
|
||||
$this->outputHeadlines(2),
|
||||
$this->outputHeadlines(3),
|
||||
$this->outputHeadlines(2), // the result is 2 rather than 4 because there are no unread, so the unread context is not used
|
||||
$this->outputHeadlines(4),
|
||||
$this->outputHeadlines(5),
|
||||
$this->outputHeadlines(6),
|
||||
$this->outputHeadlines(7),
|
||||
$this->outputHeadlines(8),
|
||||
$this->outputHeadlines(9),
|
||||
$this->outputHeadlines(10),
|
||||
$this->outputHeadlines(11),
|
||||
$this->outputHeadlines(11),
|
||||
$this->outputHeadlines(12),
|
||||
$this->outputHeadlines(13),
|
||||
$this->outputHeadlines(14),
|
||||
$this->outputHeadlines(15),
|
||||
$this->outputHeadlines(11), // defaulting sorting is not fully implemented
|
||||
$this->outputHeadlines(16),
|
||||
$this->outputHeadlines(17),
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(2);
|
||||
if ($out instanceof \Exception) {
|
||||
\Phake::when(Arsse::$db)->articleList->thenThrow($out);
|
||||
} else {
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn($out);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out) {
|
||||
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $c, $fields, $order);
|
||||
} else {
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->articleList;
|
||||
}
|
||||
}
|
||||
|
||||
public function provideHeadlines(): iterable {
|
||||
$t = Date::normalize(self::NOW);
|
||||
$c = (new Context)->hidden(false)->limit(200);
|
||||
$out = $this->generateHeadlines(47);
|
||||
$gone = new ExceptionInput("idMissing");
|
||||
$comp = new Result($this->v([['id' => 47], ['id' => 2112]]));
|
||||
$expFull = $this->outputHeadlines(47);
|
||||
$expComp = $this->respGood([['id' => 47], ['id' => 2112]]);
|
||||
$fields = ["id", "guid", "title", "author", "url", "unread", "starred", "edited_date", "published_date", "subscription", "subscription_title", "note"];
|
||||
$sort = ["edited_date desc"];
|
||||
return [
|
||||
[true, [], null, $c, [], [], $this->respErr("INCORRECT_USAGE")],
|
||||
[true, ['feed_id' => 0], null, $c, [], [], $this->respGood([])],
|
||||
[true, ['feed_id' => -1], $out, (clone $c)->starred(true), $fields, ["marked_date desc"], $expFull],
|
||||
[true, ['feed_id' => -2], null, $c, [], [], $this->respGood([])],
|
||||
[true, ['feed_id' => -4], $out, $c, $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 2112], $gone, (clone $c)->subscription(2112), $fields, $sort, $this->respGood([])],
|
||||
[true, ['feed_id' => -2112], $out, (clone $c)->label(1088), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'view_mode' => "adaptive"], $out, (clone $c)->unread(true), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'view_mode' => "published"], null, $c, [], [], $this->respGood([])],
|
||||
[true, ['feed_id' => -2112, 'view_mode' => "adaptive"], $out, (clone $c)->label(1088)->unread(true), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -2112, 'view_mode' => "unread"], $out, (clone $c)->label(1088)->unread(true), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 42, 'view_mode' => "marked"], $out, (clone $c)->subscription(42)->starred(true), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 42, 'view_mode' => "has_note"], $out, (clone $c)->subscription(42)->annotated(true), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 42, 'view_mode' => "unread", 'search' => "unread:false"], null, $c, [], [], $this->respGood([])],
|
||||
[true, ['feed_id' => 42, 'search' => "pub:true"], null, $c, [], [], $this->respGood([])],
|
||||
[true, ['feed_id' => -4, 'limit' => 5], $out, (clone $c)->limit(5), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'skip' => 2], $out, (clone $c)->offset(2), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'limit' => 5, 'skip' => 2], $out, (clone $c)->limit(5)->offset(2), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'since_id' => 47], $out, (clone $c)->oldestArticle(48), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -3, 'is_cat' => true], $out, $c, $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'is_cat' => true], $out, $c, $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -2, 'is_cat' => true], $out, (clone $c)->labelled(true), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -1, 'is_cat' => true], null, $c, [], [], $this->respGood([])],
|
||||
[true, ['feed_id' => 0, 'is_cat' => true], $out, (clone $c)->folderShallow(0), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 0, 'is_cat' => true, 'include_nested' => true], $out, (clone $c)->folderShallow(0), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 42, 'is_cat' => true], $out, (clone $c)->folderShallow(42), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => 42, 'is_cat' => true, 'include_nested' => true], $out, (clone $c)->folder(42), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'order_by' => "feed_dates"], $out, $c, $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -4, 'order_by' => "date_reverse"], $out, $c, $fields, ["edited_date"], $expFull],
|
||||
[true, ['feed_id' => 42, 'search' => "interesting"], $out, (clone $c)->subscription(42)->searchTerms(["interesting"]), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -6], $out, (clone $c)->unread(false)->markedSince(Date::sub("PT24H", $t)), $fields, ["marked_date desc"], $expFull],
|
||||
[true, ['feed_id' => -6, 'view_mode' => "unread"], null, $c, $fields, $sort, $this->respGood([])],
|
||||
[true, ['feed_id' => -3], $out, (clone $c)->unread(true)->modifiedSince(Date::sub("PT24H", $t)), $fields, $sort, $expFull],
|
||||
[true, ['feed_id' => -3, 'view_mode' => "marked"], $out, (clone $c)->unread(true)->starred(true)->modifiedSince(Date::sub("PT24H", $t)), $fields, $sort, $expFull],
|
||||
[false, [], null, (clone $c)->limit(null), [], [], $this->respErr("INCORRECT_USAGE")],
|
||||
[false, ['feed_id' => 0], null, (clone $c)->limit(null), [], [], $this->respGood([])],
|
||||
[false, ['feed_id' => -1], $comp, (clone $c)->limit(null)->starred(true), ["id"], ["marked_date desc"], $expComp],
|
||||
[false, ['feed_id' => -2], null, (clone $c)->limit(null), [], [], $this->respGood([])],
|
||||
[false, ['feed_id' => -4], $comp, (clone $c)->limit(null), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => 2112], $gone, (clone $c)->limit(null)->subscription(2112), ["id"], $sort, $this->respGood([])],
|
||||
[false, ['feed_id' => -2112], $comp, (clone $c)->limit(null)->label(1088), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -4, 'view_mode' => "adaptive"], $comp, (clone $c)->limit(null)->unread(true), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -4, 'view_mode' => "published"], null, (clone $c)->limit(null), [], [], $this->respGood([])],
|
||||
[false, ['feed_id' => -2112, 'view_mode' => "adaptive"], $comp, (clone $c)->limit(null)->label(1088)->unread(true), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -2112, 'view_mode' => "unread"], $comp, (clone $c)->limit(null)->label(1088)->unread(true), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => 42, 'view_mode' => "marked"], $comp, (clone $c)->limit(null)->subscription(42)->starred(true), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => 42, 'view_mode' => "has_note"], $comp, (clone $c)->limit(null)->subscription(42)->annotated(true), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -4, 'limit' => 5], $comp, (clone $c)->limit(5), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -4, 'skip' => 2], $comp, (clone $c)->limit(null)->offset(2), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -4, 'limit' => 5, 'skip' => 2], $comp, (clone $c)->limit(5)->offset(2), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -4, 'since_id' => 47], $comp, (clone $c)->limit(null)->oldestArticle(48), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -6], $comp, (clone $c)->limit(null)->unread(false)->markedSince(Date::sub("PT24H", $t)), ["id"], ["marked_date desc"], $expComp],
|
||||
[false, ['feed_id' => -6, 'view_mode' => "unread"], null, (clone $c)->limit(null), ["id"], $sort, $this->respGood([])],
|
||||
[false, ['feed_id' => -3], $comp, (clone $c)->limit(null)->unread(true)->modifiedSince(Date::sub("PT24H", $t)), ["id"], $sort, $expComp],
|
||||
[false, ['feed_id' => -3, 'view_mode' => "marked"], $comp, (clone $c)->limit(null)->unread(true)->starred(true)->modifiedSince(Date::sub("PT24H", $t)), ["id"], $sort, $expComp],
|
||||
];
|
||||
$out3 = [
|
||||
$this->outputHeadlines(1001),
|
||||
$this->outputHeadlines(1001),
|
||||
$this->outputHeadlines(1002),
|
||||
$this->outputHeadlines(1003),
|
||||
];
|
||||
for ($a = 0; $a < sizeof($in1); $a++) {
|
||||
$this->assertMessage($this->respGood([]), $this->req($in1[$a]), "Test $a failed");
|
||||
}
|
||||
for ($a = 0; $a < sizeof($in2); $a++) {
|
||||
$this->assertMessage($out2[$a], $this->req($in2[$a]), "Test $a failed");
|
||||
}
|
||||
for ($a = 0; $a < sizeof($in3); $a++) {
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(false)->markedSince(Date::sub("PT24H")), 2), $this->anything(), ["marked_date desc"])->thenReturn($this->generateHeadlines(1001));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H")), 2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1002));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H"))->starred(true), 2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1003));
|
||||
$this->assertMessage($out3[$a], $this->req($in3[$a]), "Test $a failed");
|
||||
}
|
||||
}
|
||||
|
||||
public function testRetrieveFullHeadlinesCheckingExtraFields(): void {
|
||||
|
@ -1919,7 +1814,7 @@ LONG_STRING;
|
|||
\Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]);
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(1));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true)->hidden(false))->thenReturn(1);
|
||||
// sanity check; this makes sure extra fields are not included in default situations
|
||||
$test = $this->req($in[0]);
|
||||
$this->assertMessage($this->outputHeadlines(1), $test);
|
||||
|
@ -1970,7 +1865,7 @@ LONG_STRING;
|
|||
]);
|
||||
$this->assertMessage($exp, $test);
|
||||
// test 'include_header' with an erroneous result
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(200)->subscription(2112), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(200)->subscription(2112)->hidden(false), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$test = $this->req($in[6]);
|
||||
$exp = $this->respGood([
|
||||
['id' => 2112, 'is_cat' => false, 'first_id' => 0],
|
||||
|
@ -1985,7 +1880,7 @@ LONG_STRING;
|
|||
]);
|
||||
$this->assertMessage($exp, $test);
|
||||
// test 'include_header' with skip
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(1)->subscription(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1867));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(1)->subscription(42)->hidden(false), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1867));
|
||||
$test = $this->req($in[8]);
|
||||
$exp = $this->respGood([
|
||||
['id' => 42, 'is_cat' => false, 'first_id' => 1867],
|
||||
|
|
Loading…
Reference in a new issue