mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +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
|
- The `disabled`, `ignore_http_cache`, and `fetch_via_proxy` flags
|
||||||
- Changing the URL, username, or password of a feed
|
- Changing the URL, username, or password of a feed
|
||||||
- Titles and types are not available during feed discovery and are filled with generic data
|
- 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
|
# Differences
|
||||||
|
|
||||||
|
|
|
@ -110,9 +110,10 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
'blocklist_rules' => "block_rule",
|
'blocklist_rules' => "block_rule",
|
||||||
];
|
];
|
||||||
protected const ARTICLE_COLUMNS = [
|
protected const ARTICLE_COLUMNS = [
|
||||||
"id", "url", "title", "author", "fingerprint", "subscription",
|
"id", "url", "title", "subscription",
|
||||||
|
"author", "fingerprint",
|
||||||
"published_date", "modified_date",
|
"published_date", "modified_date",
|
||||||
"starred", "unread",
|
"starred", "unread", "hidden",
|
||||||
"content", "media_url", "media_type"
|
"content", "media_url", "media_type"
|
||||||
];
|
];
|
||||||
protected const CALLS = [ // handler method Admin Path Body Query Required fields
|
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
|
// 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"]) {
|
if ($status === ["read", "removed"]) {
|
||||||
$c->unread(false);
|
$c->unread(false);
|
||||||
} elseif ($status === ["read", "unread"]) {
|
} elseif ($status === ["read", "unread"]) {
|
||||||
|
@ -1013,14 +1015,16 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
$out[] = $this->transformEntry($entry, $meta['num'], $meta['tz']);
|
$out[] = $this->transformEntry($entry, $meta['num'], $meta['tz']);
|
||||||
}
|
}
|
||||||
// next compile a map of feeds to add to the entries
|
// next compile a map of feeds to add to the entries
|
||||||
$feeds = [];
|
if ($out) {
|
||||||
foreach (Arsse::$db->subscriptionList(Arsse::$user->id) as $r) {
|
$feeds = [];
|
||||||
$feeds[(int) $r['id']] = $this->transformFeed($r, $meta['num'], $meta['root']);
|
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
|
// add the feed objects to each entry
|
||||||
for ($a = 0; $a < sizeof($out); $a++) {
|
// NOTE: If ever we implement multiple enclosure, this would be the right place to add them
|
||||||
$out[$a]['feed'] = $feeds[$out[$a]['feed_id']];
|
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
|
// finally compute the total number of entries match the query, if the query hs a limit or offset
|
||||||
if ($c->limit || $c->offset) {
|
if ($c->limit || $c->offset) {
|
||||||
|
|
|
@ -26,54 +26,61 @@ use JKingWeb\Arsse\Test\Result;
|
||||||
/** @covers \JKingWeb\Arsse\REST\Miniflux\V1<extended> */
|
/** @covers \JKingWeb\Arsse\REST\Miniflux\V1<extended> */
|
||||||
class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
protected const NOW = "2020-12-09T22:35:10.023419Z";
|
protected const NOW = "2020-12-09T22:35:10.023419Z";
|
||||||
|
protected const TOKEN = "Tk2o9YubmZIL2fm2w8Z4KlDEQJz532fNSOcTG0s2_xc=";
|
||||||
protected $h;
|
protected const USERS = [
|
||||||
protected $transaction;
|
['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 {}"],
|
||||||
protected $token = "Tk2o9YubmZIL2fm2w8Z4KlDEQJz532fNSOcTG0s2_xc=";
|
['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 $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' => 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],
|
['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' => 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],
|
['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 {
|
protected function req(string $method, string $target, $data = "", array $headers = [], ?string $user = "john.doe@example.com", bool $body = true): ResponseInterface {
|
||||||
$prefix = "/v1";
|
$prefix = "/v1";
|
||||||
|
@ -122,23 +129,23 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
Arsse::$user->id = null;
|
Arsse::$user->id = null;
|
||||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("subjectMissing"));
|
\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->assertMessage($exp, $this->req("GET", "/", "", $headers, $auth ? "john.doe@example.com" : null));
|
||||||
$this->assertSame($success ? $user : null, Arsse::$user->id);
|
$this->assertSame($success ? $user : null, Arsse::$user->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideAuthResponses(): iterable {
|
public function provideAuthResponses(): iterable {
|
||||||
return [
|
return [
|
||||||
[null, false, false],
|
[null, false, false],
|
||||||
[null, true, true],
|
[null, true, true],
|
||||||
[$this->token, false, true],
|
[self::TOKEN, false, true],
|
||||||
[[$this->token, "BOGUS"], false, true],
|
[[self::TOKEN, "BOGUS"], false, true],
|
||||||
["", true, true],
|
["", true, true],
|
||||||
[["", "BOGUS"], true, true],
|
[["", "BOGUS"], true, true],
|
||||||
["NOT A TOKEN", false, false],
|
["NOT A TOKEN", false, false],
|
||||||
["NOT A TOKEN", true, false],
|
["NOT A TOKEN", true, false],
|
||||||
[["BOGUS", $this->token], false, false],
|
[["BOGUS", self::TOKEN], false, false],
|
||||||
[["", $this->token], false, false],
|
[["", self::TOKEN], false, false],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,16 +246,16 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
public function provideUserQueries(): iterable {
|
public function provideUserQueries(): iterable {
|
||||||
self::clearData();
|
self::clearData();
|
||||||
return [
|
return [
|
||||||
[true, "/users", new Response($this->users)],
|
[true, "/users", new Response(self::USERS)],
|
||||||
[true, "/me", new Response($this->users[0])],
|
[true, "/me", new Response(self::USERS[0])],
|
||||||
[true, "/users/john.doe@example.com", new Response($this->users[0])],
|
[true, "/users/john.doe@example.com", new Response(self::USERS[0])],
|
||||||
[true, "/users/1", new Response($this->users[0])],
|
[true, "/users/1", new Response(self::USERS[0])],
|
||||||
[true, "/users/jane.doe@example.com", new Response($this->users[1])],
|
[true, "/users/jane.doe@example.com", new Response(self::USERS[1])],
|
||||||
[true, "/users/2", new Response($this->users[1])],
|
[true, "/users/2", new Response(self::USERS[1])],
|
||||||
[true, "/users/jack.doe@example.com", new ErrorResponse("404", 404)],
|
[true, "/users/jack.doe@example.com", new ErrorResponse("404", 404)],
|
||||||
[true, "/users/47", new ErrorResponse("404", 404)],
|
[true, "/users/47", new ErrorResponse("404", 404)],
|
||||||
[false, "/users", new ErrorResponse("403", 403)],
|
[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/john.doe@example.com", new ErrorResponse("403", 403)],
|
||||||
[false, "/users/1", new ErrorResponse("403", 403)],
|
[false, "/users/1", new ErrorResponse("403", 403)],
|
||||||
[false, "/users/jane.doe@example.com", 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 {
|
public function provideUserModifications(): iterable {
|
||||||
$out1 = ['num' => 2, 'admin' => false];
|
$out1 = ['num' => 2, 'admin' => false];
|
||||||
$out2 = ['num' => 1, 'admin' => false];
|
$out2 = ['num' => 1, 'admin' => false];
|
||||||
$resp1 = array_merge($this->users[1], ['username' => "john.doe@example.com"]);
|
$resp1 = array_merge(self::USERS[1], ['username' => "john.doe@example.com"]);
|
||||||
$resp2 = array_merge($this->users[1], ['id' => 1, 'is_admin' => true]);
|
$resp2 = array_merge(self::USERS[1], ['id' => 1, 'is_admin' => true]);
|
||||||
return [
|
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", ['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)],
|
[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 {
|
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 [
|
return [
|
||||||
[[], null, null, null, null, new ErrorResponse(["MissingInputValue", 'field' => "username"], 422)],
|
[[], null, null, null, null, new ErrorResponse(["MissingInputValue", 'field' => "username"], 422)],
|
||||||
[['username' => "ook"], null, null, null, null, new ErrorResponse(["MissingInputValue", 'field' => "password"], 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 {
|
public function testListFeeds(): void {
|
||||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->feeds)));
|
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||||
$exp = new Response($this->feedsOut);
|
$exp = new Response(self::FEEDS_OUT);
|
||||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testListFeedsOfACategory(): void {
|
public function testListFeedsOfACategory(): void {
|
||||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->feeds)));
|
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||||
$exp = new Response($this->feedsOut);
|
$exp = new Response(self::FEEDS_OUT);
|
||||||
$this->assertMessage($exp, $this->req("GET", "/categories/2112/feeds"));
|
$this->assertMessage($exp, $this->req("GET", "/categories/2112/feeds"));
|
||||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 2111, true);
|
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 2111, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testListFeedsOfTheRootCategory(): void {
|
public function testListFeedsOfTheRootCategory(): void {
|
||||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->feeds)));
|
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||||
$exp = new Response($this->feedsOut);
|
$exp = new Response(self::FEEDS_OUT);
|
||||||
$this->assertMessage($exp, $this->req("GET", "/categories/1/feeds"));
|
$this->assertMessage($exp, $this->req("GET", "/categories/1/feeds"));
|
||||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 0, false);
|
\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 {
|
public function testGetAFeed(): void {
|
||||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v($this->feeds[0]))->thenReturn($this->v($this->feeds[1]));
|
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v(self::FEEDS[0]))->thenReturn($this->v(self::FEEDS[1]));
|
||||||
$this->assertMessage(new Response($this->feedsOut[0]), $this->req("GET", "/feeds/1"));
|
$this->assertMessage(new Response(self::FEEDS_OUT[0]), $this->req("GET", "/feeds/1"));
|
||||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 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);
|
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 55);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,7 +686,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
/** @dataProvider provideFeedModifications */
|
/** @dataProvider provideFeedModifications */
|
||||||
public function testModifyAFeed(array $in, array $data, $out, ResponseInterface $exp): void {
|
public function testModifyAFeed(array $in, array $data, $out, ResponseInterface $exp): void {
|
||||||
$this->h = \Phake::partialMock(V1::class);
|
$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) {
|
if ($out instanceof \Exception) {
|
||||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($out);
|
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($out);
|
||||||
} else {
|
} else {
|
||||||
|
@ -691,7 +698,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
public function provideFeedModifications(): iterable {
|
public function provideFeedModifications(): iterable {
|
||||||
self::clearData();
|
self::clearData();
|
||||||
$success = new Response($this->feedsOut[0]);
|
$success = new Response(self::FEEDS_OUT[0]);
|
||||||
return [
|
return [
|
||||||
[[], [], true, $success],
|
[[], [], true, $success],
|
||||||
[[], [], new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
[[], [], new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||||
|
@ -730,7 +737,6 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideIcons(): iterable {
|
public function provideIcons(): iterable {
|
||||||
self::clearData();
|
|
||||||
return [
|
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' => 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)],
|
[['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)],
|
[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