mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
First set of article query tests
This commit is contained in:
parent
23ca6bb77b
commit
af51377fe9
3 changed files with 132 additions and 85 deletions
|
@ -26,6 +26,9 @@ Miniflux version 2.0.27 is emulated, though not all features are implemented
|
|||
- The `disabled`, `ignore_http_cache`, and `fetch_via_proxy` flags
|
||||
- Changing the URL, username, or password of a feed
|
||||
- Titles and types are not available during feed discovery and are filled with generic data
|
||||
- Reading time is not calculated and will always be zero
|
||||
- Only the first enclosure of an article is retained
|
||||
- Comment URLs of articles are not exposed
|
||||
|
||||
# Differences
|
||||
|
||||
|
|
|
@ -110,9 +110,10 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
'blocklist_rules' => "block_rule",
|
||||
];
|
||||
protected const ARTICLE_COLUMNS = [
|
||||
"id", "url", "title", "author", "fingerprint", "subscription",
|
||||
"id", "url", "title", "subscription",
|
||||
"author", "fingerprint",
|
||||
"published_date", "modified_date",
|
||||
"starred", "unread",
|
||||
"starred", "unread", "hidden",
|
||||
"content", "media_url", "media_type"
|
||||
];
|
||||
protected const CALLS = [ // handler method Admin Path Body Query Required fields
|
||||
|
@ -916,7 +917,8 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
}
|
||||
// FIXME: specifying e.g. ?status=read&status=removed should yield all hidden articles and all read articles, but the best we can do is all read articles which are or are not hidden
|
||||
sort($status = array_unique($query['status']));
|
||||
$status = array_unique($query['status']);
|
||||
sort($status);
|
||||
if ($status === ["read", "removed"]) {
|
||||
$c->unread(false);
|
||||
} elseif ($status === ["read", "unread"]) {
|
||||
|
@ -1013,14 +1015,16 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$out[] = $this->transformEntry($entry, $meta['num'], $meta['tz']);
|
||||
}
|
||||
// next compile a map of feeds to add to the entries
|
||||
$feeds = [];
|
||||
foreach (Arsse::$db->subscriptionList(Arsse::$user->id) as $r) {
|
||||
$feeds[(int) $r['id']] = $this->transformFeed($r, $meta['num'], $meta['root']);
|
||||
}
|
||||
// add the feed objects to each entry
|
||||
// NOTE: If ever we implement multiple enclosure, this would be the right place to add them
|
||||
for ($a = 0; $a < sizeof($out); $a++) {
|
||||
$out[$a]['feed'] = $feeds[$out[$a]['feed_id']];
|
||||
if ($out) {
|
||||
$feeds = [];
|
||||
foreach (Arsse::$db->subscriptionList(Arsse::$user->id) as $r) {
|
||||
$feeds[(int) $r['id']] = $this->transformFeed($r, $meta['num'], $meta['root']);
|
||||
}
|
||||
// add the feed objects to each entry
|
||||
// NOTE: If ever we implement multiple enclosure, this would be the right place to add them
|
||||
for ($a = 0; $a < sizeof($out); $a++) {
|
||||
$out[$a]['feed'] = $feeds[$out[$a]['feed_id']];
|
||||
}
|
||||
}
|
||||
// finally compute the total number of entries match the query, if the query hs a limit or offset
|
||||
if ($c->limit || $c->offset) {
|
||||
|
|
|
@ -26,54 +26,61 @@ use JKingWeb\Arsse\Test\Result;
|
|||
/** @covers \JKingWeb\Arsse\REST\Miniflux\V1<extended> */
|
||||
class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
protected const NOW = "2020-12-09T22:35:10.023419Z";
|
||||
|
||||
protected $h;
|
||||
protected $transaction;
|
||||
protected $token = "Tk2o9YubmZIL2fm2w8Z4KlDEQJz532fNSOcTG0s2_xc=";
|
||||
protected $users = [
|
||||
[
|
||||
'id' => 1,
|
||||
'username' => "john.doe@example.com",
|
||||
'last_login_at' => self::NOW,
|
||||
'google_id' => "",
|
||||
'openid_connect_id' => "",
|
||||
'is_admin' => true,
|
||||
'theme' => "custom",
|
||||
'language' => "fr_CA",
|
||||
'timezone' => "Asia/Gaza",
|
||||
'entry_sorting_direction' => "asc",
|
||||
'entries_per_page' => 200,
|
||||
'keyboard_shortcuts' => false,
|
||||
'show_reading_time' => false,
|
||||
'entry_swipe' => false,
|
||||
'stylesheet' => "p {}",
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'username' => "jane.doe@example.com",
|
||||
'last_login_at' => self::NOW,
|
||||
'google_id' => "",
|
||||
'openid_connect_id' => "",
|
||||
'is_admin' => false,
|
||||
'theme' => "light_serif",
|
||||
'language' => "en_US",
|
||||
'timezone' => "UTC",
|
||||
'entry_sorting_direction' => "desc",
|
||||
'entries_per_page' => 100,
|
||||
'keyboard_shortcuts' => true,
|
||||
'show_reading_time' => true,
|
||||
'entry_swipe' => true,
|
||||
'stylesheet' => "",
|
||||
],
|
||||
protected const TOKEN = "Tk2o9YubmZIL2fm2w8Z4KlDEQJz532fNSOcTG0s2_xc=";
|
||||
protected const USERS = [
|
||||
['id' => 1, 'username' => "john.doe@example.com", 'last_login_at' => self::NOW, 'google_id' => "", 'openid_connect_id' => "", 'is_admin' => true, 'theme' => "custom", 'language' => "fr_CA", 'timezone' => "Asia/Gaza", 'entry_sorting_direction' => "asc", 'entries_per_page' => 200, 'keyboard_shortcuts' => false, 'show_reading_time' => false, 'entry_swipe' => false, 'stylesheet' => "p {}"],
|
||||
['id' => 2, 'username' => "jane.doe@example.com", 'last_login_at' => self::NOW, 'google_id' => "", 'openid_connect_id' => "", 'is_admin' => false, 'theme' => "light_serif", 'language' => "en_US", 'timezone' => "UTC", 'entry_sorting_direction' => "desc", 'entries_per_page' => 100, 'keyboard_shortcuts' => true, 'show_reading_time' => true, 'entry_swipe' => true, 'stylesheet' => ""],
|
||||
];
|
||||
protected $feeds = [
|
||||
protected const FEEDS = [
|
||||
['id' => 1, 'feed' => 12, 'url' => "http://example.com/ook", 'title' => "Ook", 'source' => "http://example.com/", 'icon_id' => 47, 'icon_url' => "http://example.com/icon", 'folder' => 2112, 'top_folder' => 5, 'folder_name' => "Cat Eek", 'top_folder_name' => "Cat Ook", 'pinned' => 0, 'err_count' => 1, 'err_msg' => "Oopsie", 'order_type' => 0, 'keep_rule' => "this|that", 'block_rule' => "both", 'added' => "2020-12-21 21:12:00", 'updated' => "2021-01-05 13:51:32", 'edited' => "2021-01-01 00:00:00", 'modified' => "2020-11-30 04:08:52", 'next_fetch' => "2021-01-20 00:00:00", 'etag' => "OOKEEK", 'scrape' => 0, 'unread' => 42],
|
||||
['id' => 55, 'feed' => 12, 'url' => "http://j%20k:super%20secret@example.com/eek", 'title' => "Eek", 'source' => "http://example.com/", 'icon_id' => null, 'icon_url' => null, 'folder' => null, 'top_folder' => null, 'folder_name' => null, 'top_folder_name' => null, 'pinned' => 0, 'err_count' => 0, 'err_msg' => null, 'order_type' => 0, 'keep_rule' => null, 'block_rule' => null, 'added' => "2020-12-21 21:12:00", 'updated' => "2021-01-05 13:51:32", 'edited' => null, 'modified' => "2020-11-30 04:08:52", 'next_fetch' => null, 'etag' => null, 'scrape' => 1, 'unread' => 0],
|
||||
];
|
||||
protected $feedsOut = [
|
||||
protected const FEEDS_OUT = [
|
||||
['id' => 1, 'user_id' => 42, 'feed_url' => "http://example.com/ook", 'site_url' => "http://example.com/", 'title' => "Ook", 'checked_at' => "2021-01-05T13:51:32.000000Z", 'next_check_at' => "2021-01-20T00:00:00.000000Z", 'etag_header' => "OOKEEK", 'last_modified_header' => "Fri, 01 Jan 2021 00:00:00 GMT", 'parsing_error_message' => "Oopsie", 'parsing_error_count' => 1, 'scraper_rules' => "", 'rewrite_rules' => "", 'crawler' => false, 'blocklist_rules' => "both", 'keeplist_rules' => "this|that", 'user_agent' => "", 'username' => "", 'password' => "", 'disabled' => false, 'ignore_http_cache' => false, 'fetch_via_proxy' => false, 'category' => ['id' => 6, 'title' => "Cat Ook", 'user_id' => 42], 'icon' => ['feed_id' => 1,'icon_id' => 47]],
|
||||
['id' => 55, 'user_id' => 42, 'feed_url' => "http://example.com/eek", 'site_url' => "http://example.com/", 'title' => "Eek", 'checked_at' => "2021-01-05T13:51:32.000000Z", 'next_check_at' => "0001-01-01T00:00:00.000000Z", 'etag_header' => "", 'last_modified_header' => "", 'parsing_error_message' => "", 'parsing_error_count' => 0, 'scraper_rules' => "", 'rewrite_rules' => "", 'crawler' => true, 'blocklist_rules' => "", 'keeplist_rules' => "", 'user_agent' => "", 'username' => "j k", 'password' => "super secret", 'disabled' => false, 'ignore_http_cache' => false, 'fetch_via_proxy' => false, 'category' => ['id' => 1,'title' => "All", 'user_id' => 42], 'icon' => null],
|
||||
];
|
||||
protected const ENTRIES = [
|
||||
[
|
||||
'id' => 42,
|
||||
'url' => "http://example.com/42",
|
||||
'title' => "Title 42",
|
||||
'subscription' => 2112,
|
||||
'author' => "Thomas Costain",
|
||||
'fingerprint' => "FINGERPRINT",
|
||||
'published_date' => "2021-01-22 02:21:12",
|
||||
'modified_date' => "2021-01-22 13:44:47",
|
||||
'starred' => 0,
|
||||
'unread' => 0,
|
||||
'hidden' => 0,
|
||||
'content' => "Content 42",
|
||||
'media_url' => null,
|
||||
'media_type' => null,
|
||||
],
|
||||
];
|
||||
protected const ENTRIES_OUT = [
|
||||
[
|
||||
'id' => 42,
|
||||
'user_id' => 42,
|
||||
'feed_id' => 55,
|
||||
'status' => "read",
|
||||
'hash' => "FINGERPRINT",
|
||||
'title' => "Title 42",
|
||||
'url' => "http://example.com/42",
|
||||
'comments_url' => "",
|
||||
'published_at' => "2021-01-22T02:21:12+00:00",
|
||||
'created_at' => "2021-01-22T13:44:47.000000+00:00",
|
||||
'content' => "Content 42",
|
||||
'author' => "Thomas Costain",
|
||||
'share_code' => "",
|
||||
'starred' => false,
|
||||
'reading_time' => 0,
|
||||
'enclosures' => null,
|
||||
'feed' => self::FEEDS_OUT[1],
|
||||
],
|
||||
];
|
||||
|
||||
protected $h;
|
||||
protected $transaction;
|
||||
|
||||
protected function req(string $method, string $target, $data = "", array $headers = [], ?string $user = "john.doe@example.com", bool $body = true): ResponseInterface {
|
||||
$prefix = "/v1";
|
||||
|
@ -122,23 +129,23 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
Arsse::$user->id = null;
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->tokenLookup("miniflux.login", $this->token)->thenReturn(['user' => $user]);
|
||||
\Phake::when(Arsse::$db)->tokenLookup("miniflux.login", self::TOKEN)->thenReturn(['user' => $user]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/", "", $headers, $auth ? "john.doe@example.com" : null));
|
||||
$this->assertSame($success ? $user : null, Arsse::$user->id);
|
||||
}
|
||||
|
||||
public function provideAuthResponses(): iterable {
|
||||
return [
|
||||
[null, false, false],
|
||||
[null, true, true],
|
||||
[$this->token, false, true],
|
||||
[[$this->token, "BOGUS"], false, true],
|
||||
["", true, true],
|
||||
[["", "BOGUS"], true, true],
|
||||
["NOT A TOKEN", false, false],
|
||||
["NOT A TOKEN", true, false],
|
||||
[["BOGUS", $this->token], false, false],
|
||||
[["", $this->token], false, false],
|
||||
[null, false, false],
|
||||
[null, true, true],
|
||||
[self::TOKEN, false, true],
|
||||
[[self::TOKEN, "BOGUS"], false, true],
|
||||
["", true, true],
|
||||
[["", "BOGUS"], true, true],
|
||||
["NOT A TOKEN", false, false],
|
||||
["NOT A TOKEN", true, false],
|
||||
[["BOGUS", self::TOKEN], false, false],
|
||||
[["", self::TOKEN], false, false],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -239,16 +246,16 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function provideUserQueries(): iterable {
|
||||
self::clearData();
|
||||
return [
|
||||
[true, "/users", new Response($this->users)],
|
||||
[true, "/me", new Response($this->users[0])],
|
||||
[true, "/users/john.doe@example.com", new Response($this->users[0])],
|
||||
[true, "/users/1", new Response($this->users[0])],
|
||||
[true, "/users/jane.doe@example.com", new Response($this->users[1])],
|
||||
[true, "/users/2", new Response($this->users[1])],
|
||||
[true, "/users", new Response(self::USERS)],
|
||||
[true, "/me", new Response(self::USERS[0])],
|
||||
[true, "/users/john.doe@example.com", new Response(self::USERS[0])],
|
||||
[true, "/users/1", new Response(self::USERS[0])],
|
||||
[true, "/users/jane.doe@example.com", new Response(self::USERS[1])],
|
||||
[true, "/users/2", new Response(self::USERS[1])],
|
||||
[true, "/users/jack.doe@example.com", new ErrorResponse("404", 404)],
|
||||
[true, "/users/47", new ErrorResponse("404", 404)],
|
||||
[false, "/users", new ErrorResponse("403", 403)],
|
||||
[false, "/me", new Response($this->users[1])],
|
||||
[false, "/me", new Response(self::USERS[1])],
|
||||
[false, "/users/john.doe@example.com", new ErrorResponse("403", 403)],
|
||||
[false, "/users/1", new ErrorResponse("403", 403)],
|
||||
[false, "/users/jane.doe@example.com", new ErrorResponse("403", 403)],
|
||||
|
@ -318,8 +325,8 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function provideUserModifications(): iterable {
|
||||
$out1 = ['num' => 2, 'admin' => false];
|
||||
$out2 = ['num' => 1, 'admin' => false];
|
||||
$resp1 = array_merge($this->users[1], ['username' => "john.doe@example.com"]);
|
||||
$resp2 = array_merge($this->users[1], ['id' => 1, 'is_admin' => true]);
|
||||
$resp1 = array_merge(self::USERS[1], ['username' => "john.doe@example.com"]);
|
||||
$resp2 = array_merge(self::USERS[1], ['id' => 1, 'is_admin' => true]);
|
||||
return [
|
||||
[false, "/users/1", ['is_admin' => 0], null, null, null, null, null, null, new ErrorResponse(["InvalidInputType", 'field' => "is_admin", 'expected' => "boolean", 'actual' => "integer"], 422)],
|
||||
[false, "/users/1", ['entry_sorting_direction' => "bad"], null, null, null, null, null, null, new ErrorResponse(["InvalidInputValue", 'field' => "entry_sorting_direction"], 422)],
|
||||
|
@ -376,7 +383,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function provideUserAdditions(): iterable {
|
||||
$resp1 = array_merge($this->users[1], ['username' => "ook", 'password' => "eek"]);
|
||||
$resp1 = array_merge(self::USERS[1], ['username' => "ook", 'password' => "eek"]);
|
||||
return [
|
||||
[[], null, null, null, null, new ErrorResponse(["MissingInputValue", 'field' => "username"], 422)],
|
||||
[['username' => "ook"], null, null, null, null, new ErrorResponse(["MissingInputValue", 'field' => "password"], 422)],
|
||||
|
@ -545,21 +552,21 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testListFeeds(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->feeds)));
|
||||
$exp = new Response($this->feedsOut);
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
$exp = new Response(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||
}
|
||||
|
||||
public function testListFeedsOfACategory(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->feeds)));
|
||||
$exp = new Response($this->feedsOut);
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
$exp = new Response(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/2112/feeds"));
|
||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 2111, true);
|
||||
}
|
||||
|
||||
public function testListFeedsOfTheRootCategory(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->feeds)));
|
||||
$exp = new Response($this->feedsOut);
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
$exp = new Response(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/1/feeds"));
|
||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 0, false);
|
||||
}
|
||||
|
@ -572,10 +579,10 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testGetAFeed(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v($this->feeds[0]))->thenReturn($this->v($this->feeds[1]));
|
||||
$this->assertMessage(new Response($this->feedsOut[0]), $this->req("GET", "/feeds/1"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v(self::FEEDS[0]))->thenReturn($this->v(self::FEEDS[1]));
|
||||
$this->assertMessage(new Response(self::FEEDS_OUT[0]), $this->req("GET", "/feeds/1"));
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 1);
|
||||
$this->assertMessage(new Response($this->feedsOut[1]), $this->req("GET", "/feeds/55"));
|
||||
$this->assertMessage(new Response(self::FEEDS_OUT[1]), $this->req("GET", "/feeds/55"));
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 55);
|
||||
}
|
||||
|
||||
|
@ -679,7 +686,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideFeedModifications */
|
||||
public function testModifyAFeed(array $in, array $data, $out, ResponseInterface $exp): void {
|
||||
$this->h = \Phake::partialMock(V1::class);
|
||||
\Phake::when($this->h)->getFeed->thenReturn(new Response($this->feedsOut[0]));
|
||||
\Phake::when($this->h)->getFeed->thenReturn(new Response(self::FEEDS_OUT[0]));
|
||||
if ($out instanceof \Exception) {
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($out);
|
||||
} else {
|
||||
|
@ -691,7 +698,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function provideFeedModifications(): iterable {
|
||||
self::clearData();
|
||||
$success = new Response($this->feedsOut[0]);
|
||||
$success = new Response(self::FEEDS_OUT[0]);
|
||||
return [
|
||||
[[], [], true, $success],
|
||||
[[], [], new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||
|
@ -730,7 +737,6 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function provideIcons(): iterable {
|
||||
self::clearData();
|
||||
return [
|
||||
[['id' => 44, 'type' => "image/svg+xml", 'data' => "<svg/>"], new Response(['id' => 44, 'data' => "image/svg+xml;base64,PHN2Zy8+", 'mime_type' => "image/svg+xml"])],
|
||||
[['id' => 47, 'type' => "", 'data' => "<svg/>"], new ErrorResponse("404", 404)],
|
||||
|
@ -740,4 +746,38 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
[new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||
];
|
||||
}
|
||||
|
||||
/** @dataProvider provideEntryQueries */
|
||||
public function testGetEntries(string $url, ?Context $c, ?array $order, $out, bool $getFeeds, ResponseInterface $exp) {
|
||||
if ($out instanceof \Exception) {
|
||||
\Phake::when(Arsse::$db)->articleList->thenThrow($out);
|
||||
} else {
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v($out)));
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("GET", $url));
|
||||
if ($c) {
|
||||
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $c, array_keys(self::ENTRIES[0]), $order);
|
||||
} else {
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->articleList;
|
||||
}
|
||||
}
|
||||
|
||||
public function provideEntryQueries(): iterable {
|
||||
self::clearData();
|
||||
$c = new Context;
|
||||
return [
|
||||
["/entries?after=A", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "after"], 400)],
|
||||
["/entries?before=B", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "before"], 400)],
|
||||
["/entries?category_id=0", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "category_id"], 400)],
|
||||
["/entries?after_entry_id=0", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "after_entry_id"], 400)],
|
||||
["/entries?before_entry_id=0", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "before_entry_id"], 400)],
|
||||
["/entries?limit=-1", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "limit"], 400)],
|
||||
["/entries?offset=-1", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "offset"], 400)],
|
||||
["/entries?direction=sideways", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "direction"], 400)],
|
||||
["/entries?order=false", null, null, [], false, new ErrorResponse(["InvalidInputValue", 'field' => "order"], 400)],
|
||||
["/entries?starred&starred", null, null, [], false, new ErrorResponse(["DuplicateInputValue", 'field' => "starred"], 400)],
|
||||
["/entries?after&after=0", null, null, [], false, new ErrorResponse(["DuplicateInputValue", 'field' => "after"], 400)],
|
||||
["/entries", $c, [], [], false, new Response(['total' => 0, 'entries' => []])],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue