From 45a43488ee6ed493fdee7035b48b04449b10eec7 Mon Sep 17 00:00:00 2001 From: "J. King" Date: Fri, 26 Jul 2019 23:23:22 -0400 Subject: [PATCH] Increase compatibility with misbehaving Fever clients --- lib/REST/Fever/API.php | 29 +++++++++++++++++++---------- tests/cases/REST/Fever/TestAPI.php | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/REST/Fever/API.php b/lib/REST/Fever/API.php index 83c3be8..fe3c709 100644 --- a/lib/REST/Fever/API.php +++ b/lib/REST/Fever/API.php @@ -33,15 +33,21 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { const PARAM_BOOL = ["groups", "feeds", "items", "favicons", "links", "unread_item_ids", "saved_item_ids"]; // GET parameters which contain meaningful values const PARAM_GET = [ - 'api' => V::T_STRING, // this parameter requires special handling - 'page' => V::T_INT, // parameter for hot links - 'range' => V::T_INT, // parameter for hot links - 'offset' => V::T_INT, // parameter for hot links - 'since_id' => V::T_INT, - 'max_id' => V::T_INT, - 'with_ids' => V::T_STRING, - 'group_ids' => V::T_STRING, // undocumented parameter for 'items' lookup - 'feed_ids' => V::T_STRING, // undocumented parameter for 'items' lookup + 'api' => V::T_STRING, // this parameter requires special handling + 'page' => V::T_INT, // parameter for hot links + 'range' => V::T_INT, // parameter for hot links + 'offset' => V::T_INT, // parameter for hot links + 'since_id' => V::T_INT, + 'max_id' => V::T_INT, + 'with_ids' => V::T_STRING, + 'group_ids' => V::T_STRING, // undocumented parameter for 'items' lookup + 'feed_ids' => V::T_STRING, // undocumented parameter for 'items' lookup + // these should be POST parameters only, but some clients misbehave + 'mark' => V::T_STRING, + 'as' => V::T_STRING, + 'id' => V::T_INT, + 'before' => V::T_DATE, + 'unread_recently_read' => V::T_BOOL, ]; // POST parameters, all of which contain meaningful values const PARAM_POST = [ @@ -134,6 +140,9 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // either an 'unread_item_ids' or a // 'saved_item_ids' entry will be added later $listSaved = $this->setMarks($P, $listUnread); + } elseif ($G['mark'] && $G['as'] && is_int($G['id'])) { + // some clients send GET rather than POST parameters for marking + $listSaved = $this->setMarks($G, $listUnread); } if ($G['feeds'] || $G['groups']) { if ($G['groups']) { @@ -244,7 +253,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { return true; } - protected function setMarks(array $P, &$listUnread): bool { + protected function setMarks(array $P, &$listUnread): bool { $listSaved = false; $c = new Context; $id = $P['id']; diff --git a/tests/cases/REST/Fever/TestAPI.php b/tests/cases/REST/Fever/TestAPI.php index 3393dde..83116cc 100644 --- a/tests/cases/REST/Fever/TestAPI.php +++ b/tests/cases/REST/Fever/TestAPI.php @@ -392,6 +392,24 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest { } } + /** @dataProvider provideMarkingContexts */ + public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out) { + $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)->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); + $act = $this->h->dispatch($this->req("api&$get")); + $this->assertMessage($exp, $act); + if ($c && $data) { + \Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, $data, $c); + } else { + \Phake::verify(Arsse::$db, \Phake::times(0))->articleMark; + } + } + public function provideMarkingContexts() { $markRead = ['read' => true]; $markUnread = ['read' => false];