diff --git a/lib/REST/Fever/API.php b/lib/REST/Fever/API.php index 3382e6cb..2d5fcc1c 100644 --- a/lib/REST/Fever/API.php +++ b/lib/REST/Fever/API.php @@ -161,17 +161,17 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { } if ($G['items']) { $out['items'] = $this->getItems($G); - $out['total_items'] = Arsse::$db->articleCount(Arsse::$user->id); + $out['total_items'] = Arsse::$db->articleCount(Arsse::$user->id, (new Context)->hidden(false)); } if ($G['links']) { // TODO: implement hot links $out['links'] = []; } if ($G['unread_item_ids'] || $listUnread) { - $out['unread_item_ids'] = $this->getItemIds((new Context)->unread(true)); + $out['unread_item_ids'] = $this->getItemIds((new Context)->unread(true)->hidden(false)); } if ($G['saved_item_ids'] || $listSaved) { - $out['saved_item_ids'] = $this->getItemIds((new Context)->starred(true)); + $out['saved_item_ids'] = $this->getItemIds((new Context)->starred(true)->hidden(false)); } return $out; } @@ -263,17 +263,18 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { case "group": if ($id > 0) { // concrete groups - $c->tag($id); + $c->tag($id)->hidden(false); } elseif ($id < 0) { // group negative-one is the "Sparks" supergroup i.e. no feeds $c->not->folder(0); } else { // group zero is the "Kindling" supergroup i.e. all feeds - // nothing need to be done for this + // only exclude hidden articles + $c->hidden(false); } break; case "feed": - $c->subscription($id); + $c->subscription($id)->hidden(false); break; default: return $listSaved; @@ -308,7 +309,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { } protected function setUnread(): void { - $lastUnread = Arsse::$db->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->getValue(); + $lastUnread = Arsse::$db->articleList(Arsse::$user->id, (new Context)->hidden(false)->limit(1), ["marked_date"], ["marked_date desc"])->getValue(); if (!$lastUnread) { // there are no articles return; @@ -316,7 +317,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // Fever takes the date of the last read article less fifteen seconds as a cut-off. // We take the date of last mark (whether it be read, unread, saved, unsaved), which // may not actually signify a mark, but we'll otherwise also count back fifteen seconds - $c = new Context; + $c = (new Context)->hidden(false); $lastUnread = Date::normalize($lastUnread, "sql"); $since = Date::sub("PT15S", $lastUnread); $c->unread(false)->markedSince($since); @@ -373,11 +374,11 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { } protected function getItems(array $G): array { - $c = (new Context)->limit(50); + $c = (new Context)->hidden(false)->limit(50); $reverse = false; // handle the standard options if ($G['with_ids']) { - $c->articles(explode(",", $G['with_ids'])); + $c->articles(explode(",", $G['with_ids']))->hidden(null); } elseif ($G['max_id']) { $c->latestArticle($G['max_id'] - 1); $reverse = true; @@ -410,7 +411,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { return $out; } - protected function getItemIds(Context $c = null): string { + protected function getItemIds(Context $c): string { $out = []; foreach (Arsse::$db->articleList(Arsse::$user->id, $c) as $r) { $out[] = (int) $r['id']; diff --git a/tests/cases/REST/Fever/TestAPI.php b/tests/cases/REST/Fever/TestAPI.php index d0632c97..1aa77ba3 100644 --- a/tests/cases/REST/Fever/TestAPI.php +++ b/tests/cases/REST/Fever/TestAPI.php @@ -303,7 +303,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { $fields = ["id", "subscription", "title", "author", "content", "url", "starred", "unread", "published_date"]; $order = [$desc ? "id desc" : "id"]; \Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->articles['db'])); - \Phake::when(Arsse::$db)->articleCount(Arsse::$user->id)->thenReturn(1024); + \Phake::when(Arsse::$db)->articleCount(Arsse::$user->id, (new Context)->hidden(false))->thenReturn(1024); $exp = new JsonResponse([ 'items' => $this->articles['rest'], 'total_items' => 1024, @@ -316,24 +316,24 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { public function provideItemListContexts(): iterable { $c = (new Context)->limit(50); return [ - ["items", (clone $c), false], - ["items&group_ids=1,2,3,4", (clone $c)->tags([1,2,3,4]), false], - ["items&feed_ids=1,2,3,4", (clone $c)->subscriptions([1,2,3,4]), false], + ["items", (clone $c)->hidden(false), false], + ["items&group_ids=1,2,3,4", (clone $c)->tags([1,2,3,4])->hidden(false), false], + ["items&feed_ids=1,2,3,4", (clone $c)->subscriptions([1,2,3,4])->hidden(false), false], ["items&with_ids=1,2,3,4", (clone $c)->articles([1,2,3,4]), false], - ["items&since_id=1", (clone $c)->oldestArticle(2), false], - ["items&max_id=2", (clone $c)->latestArticle(1), true], + ["items&since_id=1", (clone $c)->oldestArticle(2)->hidden(false), false], + ["items&max_id=2", (clone $c)->latestArticle(1)->hidden(false), true], ["items&with_ids=1,2,3,4&max_id=6", (clone $c)->articles([1,2,3,4]), false], ["items&with_ids=1,2,3,4&since_id=6", (clone $c)->articles([1,2,3,4]), false], - ["items&max_id=3&since_id=6", (clone $c)->latestArticle(2), true], - ["items&feed_ids=1,2,3,4&since_id=6", (clone $c)->subscriptions([1,2,3,4])->oldestArticle(7), false], + ["items&max_id=3&since_id=6", (clone $c)->latestArticle(2)->hidden(false), true], + ["items&feed_ids=1,2,3,4&since_id=6", (clone $c)->subscriptions([1,2,3,4])->oldestArticle(7)->hidden(false), false], ]; } public function testListItemIds(): void { $saved = [['id' => 1],['id' => 2],['id' => 3]]; $unread = [['id' => 4],['id' => 5],['id' => 6]]; - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved)); - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true))->thenReturn(new Result($unread)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread)); $exp = new JsonResponse(['saved_item_ids' => "1,2,3"]); $this->assertMessage($exp, $this->h->dispatch($this->req("api&saved_item_ids"))); $exp = new JsonResponse(['unread_item_ids' => "4,5,6"]); @@ -350,8 +350,8 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { public function testSetMarks(string $post, Context $c, array $data, array $out): void { $saved = [['id' => 1],['id' => 2],['id' => 3]]; $unread = [['id' => 4],['id' => 5],['id' => 6]]; - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved)); - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true))->thenReturn(new Result($unread)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread)); \Phake::when(Arsse::$db)->articleMark->thenReturn(0); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->article(2112))->thenThrow(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing")); $exp = new JsonResponse($out); @@ -368,8 +368,8 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out): void { $saved = [['id' => 1],['id' => 2],['id' => 3]]; $unread = [['id' => 4],['id' => 5],['id' => 6]]; - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved)); - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true))->thenReturn(new Result($unread)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread)); \Phake::when(Arsse::$db)->articleMark->thenReturn(0); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->article(2112))->thenThrow(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing")); $exp = new JsonResponse($out); @@ -395,20 +395,20 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { ["mark=item&as=read&id=2112", (new Context)->article(2112), $markRead, $listUnread], // article doesn't exist ["mark=item&as=saved&id=5", (new Context)->article(5), $markSaved, $listSaved], ["mark=item&as=unsaved&id=42", (new Context)->article(42), $markUnsaved, $listSaved], - ["mark=feed&as=read&id=5", (new Context)->subscription(5), $markRead, $listUnread], - ["mark=feed&as=unread&id=42", (new Context)->subscription(42), $markUnread, $listUnread], - ["mark=feed&as=saved&id=5", (new Context)->subscription(5), $markSaved, $listSaved], - ["mark=feed&as=unsaved&id=42", (new Context)->subscription(42), $markUnsaved, $listSaved], - ["mark=group&as=read&id=5", (new Context)->tag(5), $markRead, $listUnread], - ["mark=group&as=unread&id=42", (new Context)->tag(42), $markUnread, $listUnread], - ["mark=group&as=saved&id=5", (new Context)->tag(5), $markSaved, $listSaved], - ["mark=group&as=unsaved&id=42", (new Context)->tag(42), $markUnsaved, $listSaved], + ["mark=feed&as=read&id=5", (new Context)->subscription(5)->hidden(false), $markRead, $listUnread], + ["mark=feed&as=unread&id=42", (new Context)->subscription(42)->hidden(false), $markUnread, $listUnread], + ["mark=feed&as=saved&id=5", (new Context)->subscription(5)->hidden(false), $markSaved, $listSaved], + ["mark=feed&as=unsaved&id=42", (new Context)->subscription(42)->hidden(false), $markUnsaved, $listSaved], + ["mark=group&as=read&id=5", (new Context)->tag(5)->hidden(false), $markRead, $listUnread], + ["mark=group&as=unread&id=42", (new Context)->tag(42)->hidden(false), $markUnread, $listUnread], + ["mark=group&as=saved&id=5", (new Context)->tag(5)->hidden(false), $markSaved, $listSaved], + ["mark=group&as=unsaved&id=42", (new Context)->tag(42)->hidden(false), $markUnsaved, $listSaved], ["mark=item&as=invalid&id=42", new Context, [], []], ["mark=invalid&as=unread&id=42", new Context, [], []], - ["mark=group&as=read&id=0", (new Context), $markRead, $listUnread], - ["mark=group&as=unread&id=0", (new Context), $markUnread, $listUnread], - ["mark=group&as=saved&id=0", (new Context), $markSaved, $listSaved], - ["mark=group&as=unsaved&id=0", (new Context), $markUnsaved, $listSaved], + ["mark=group&as=read&id=0", (new Context)->hidden(false), $markRead, $listUnread], + ["mark=group&as=unread&id=0", (new Context)->hidden(false), $markUnread, $listUnread], + ["mark=group&as=saved&id=0", (new Context)->hidden(false), $markSaved, $listSaved], + ["mark=group&as=unsaved&id=0", (new Context)->hidden(false), $markUnsaved, $listSaved], ["mark=group&as=read&id=-1", (new Context)->not->folder(0), $markRead, $listUnread], ["mark=group&as=unread&id=-1", (new Context)->not->folder(0), $markUnread, $listUnread], ["mark=group&as=saved&id=-1", (new Context)->not->folder(0), $markSaved, $listSaved], @@ -466,14 +466,14 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { public function testUndoReadMarks(): void { $unread = [['id' => 4],['id' => 5],['id' => 6]]; $out = ['unread_item_ids' => "4,5,6"]; - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]])); - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true))->thenReturn(new Result($unread)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]])); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread)); \Phake::when(Arsse::$db)->articleMark->thenReturn(0); $exp = new JsonResponse($out); $act = $this->h->dispatch($this->req("api", ['unread_recently_read' => 1])); $this->assertMessage($exp, $act); - \Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, ['read' => false], (new Context)->unread(false)->markedSince("1999-12-31T23:59:45Z")); - \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([])); + \Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, ['read' => false], (new Context)->unread(false)->markedSince("1999-12-31T23:59:45Z")->hidden(false)); + \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([])); $act = $this->h->dispatch($this->req("api", ['unread_recently_read' => 1])); $this->assertMessage($exp, $act); \Phake::verify(Arsse::$db)->articleMark; // only called one time, above