mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Adjust most uses of Diactoros to Guzzle PSR-7
This commit is contained in:
parent
e588a52e88
commit
4d18bf27e2
12 changed files with 173 additions and 178 deletions
|
@ -14,7 +14,11 @@ class HTTP {
|
|||
public static function matchType(MessageInterface $msg, string ...$type): bool {
|
||||
$header = $msg->getHeaderLine("Content-Type") ?? "";
|
||||
foreach ($type as $t) {
|
||||
$pattern = "/^".preg_quote(trim($t), "/")."\s*($|;|,)/Di";
|
||||
if (($t[0] ?? "") === "+") {
|
||||
$pattern = "/^[^+;,\s]*".preg_quote(trim($t), "/")."\s*($|;|,)/Di";
|
||||
} else {
|
||||
$pattern = "/^".preg_quote(trim($t), "/")."\s*($|;|,)/Di";
|
||||
}
|
||||
if (preg_match($pattern, $header)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use JKingWeb\Arsse\Misc\HTTP;
|
|||
use JKingWeb\Arsse\Db\ExceptionInput;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\Response\XmlResponse;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
|
@ -183,7 +182,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$d->appendChild($this->makeXMLAssoc($data, $d->createElement("response")));
|
||||
return new XmlResponse($d->saveXML());
|
||||
} else {
|
||||
return new JsonResponse($data, 200, [], \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
|
||||
return HTTP::respJson($data, 200, [], \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ use JKingWeb\Arsse\User\ExceptionConflict;
|
|||
use JKingWeb\Arsse\User\Exception as UserException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\TextResponse as GenericResponse;
|
||||
use Laminas\Diactoros\Uri;
|
||||
|
||||
|
@ -534,17 +533,17 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// TODO: This needs to be refined once PicoFeed is replaced
|
||||
$out[] = ['title' => "Feed", 'type' => "rss", 'url' => $url];
|
||||
}
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
protected function getUsers(): ResponseInterface {
|
||||
$tr = Arsse::$user->begin();
|
||||
return new Response($this->listUsers(Arsse::$user->list(), false));
|
||||
return HTTP::respJson($this->listUsers(Arsse::$user->list(), false));
|
||||
}
|
||||
|
||||
protected function getUserById(array $path): ResponseInterface {
|
||||
try {
|
||||
return new Response($this->listUsers([$path[1]], true)[0] ?? new \stdClass);
|
||||
return HTTP::respJson($this->listUsers([$path[1]], true)[0] ?? new \stdClass);
|
||||
} catch (UserException $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
|
@ -553,14 +552,14 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
protected function getUserByNum(array $path): ResponseInterface {
|
||||
try {
|
||||
$user = Arsse::$user->lookup((int) $path[1]);
|
||||
return new Response($this->listUsers([$user], true)[0] ?? new \stdClass);
|
||||
return HTTP::respJson($this->listUsers([$user], true)[0] ?? new \stdClass);
|
||||
} catch (UserException $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCurrentUser(): ResponseInterface {
|
||||
return new Response($this->listUsers([Arsse::$user->id], false)[0] ?? new \stdClass);
|
||||
return HTTP::respJson($this->listUsers([Arsse::$user->id], false)[0] ?? new \stdClass);
|
||||
}
|
||||
|
||||
protected function createUser(array $data): ResponseInterface {
|
||||
|
@ -582,7 +581,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
throw $e; // @codeCoverageIgnore
|
||||
}
|
||||
return new Response($out, 201);
|
||||
return HTTP::respJson($out, 201);
|
||||
}
|
||||
|
||||
protected function updateUserByNum(array $path, array $data): ResponseInterface {
|
||||
|
@ -628,7 +627,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
throw $e; // @codeCoverageIgnore
|
||||
}
|
||||
return new Response($out, 201);
|
||||
return HTTP::respJson($out, 201);
|
||||
}
|
||||
|
||||
protected function deleteUserByNum(array $path): ResponseInterface {
|
||||
|
@ -667,7 +666,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// always add 1 to the ID since the root folder will always be 1 instead of 0.
|
||||
$out[] = ['id' => $f['id'] + 1, 'title' => $f['name'], 'user_id' => $meta['num']];
|
||||
}
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
protected function createCategory(array $data): ResponseInterface {
|
||||
|
@ -681,7 +680,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
}
|
||||
$meta = Arsse::$user->propertiesGet(Arsse::$user->id, false);
|
||||
return new Response(['id' => $id + 1, 'title' => $data['title'], 'user_id' => $meta['num']], 201);
|
||||
return HTTP::respJson(['id' => $id + 1, 'title' => $data['title'], 'user_id' => $meta['num']], 201);
|
||||
}
|
||||
|
||||
protected function updateCategory(array $path, array $data): ResponseInterface {
|
||||
|
@ -708,7 +707,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
}
|
||||
$meta = Arsse::$user->propertiesGet(Arsse::$user->id, false);
|
||||
return new Response(['id' => (int) $path[1], 'title' => $title, 'user_id' => $meta['num']], 201);
|
||||
return HTTP::respJson(['id' => (int) $path[1], 'title' => $title, 'user_id' => $meta['num']], 201);
|
||||
}
|
||||
|
||||
protected function deleteCategory(array $path): ResponseInterface {
|
||||
|
@ -772,7 +771,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
foreach (Arsse::$db->subscriptionList(Arsse::$user->id) as $r) {
|
||||
$out[] = $this->transformFeed($r, $meta['num'], $meta['root'], $meta['tz']);
|
||||
}
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
protected function getCategoryFeeds(array $path): ResponseInterface {
|
||||
|
@ -792,7 +791,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// the folder does not exist
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
protected function getFeed(array $path): ResponseInterface {
|
||||
|
@ -800,7 +799,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$meta = $this->userMeta(Arsse::$user->id);
|
||||
try {
|
||||
$sub = Arsse::$db->subscriptionPropertiesGet(Arsse::$user->id, (int) $path[1]);
|
||||
return new Response($this->transformFeed($sub, $meta['num'], $meta['root'], $meta['tz']));
|
||||
return HTTP::respJson($this->transformFeed($sub, $meta['num'], $meta['root'], $meta['tz']));
|
||||
} catch (ExceptionInput $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
|
@ -834,7 +833,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
return new ErrorResponse("DuplicateFeed", 409);
|
||||
}
|
||||
}
|
||||
return new Response(['feed_id' => $id], 201);
|
||||
return HTTP::respJson(['feed_id' => $id], 201);
|
||||
}
|
||||
|
||||
protected function updateFeed(array $path, array $data): ResponseInterface {
|
||||
|
@ -881,7 +880,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
if (!$icon || !$icon['type'] || !$icon['data']) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'id' => (int) $icon['id'],
|
||||
'data' => $icon['type'].";base64,".base64_encode($icon['data']),
|
||||
'mime_type' => $icon['type'],
|
||||
|
@ -1038,7 +1037,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
|
||||
protected function getEntries(array $query): ResponseInterface {
|
||||
try {
|
||||
return new Response($this->listEntries($query, new Context));
|
||||
return HTTP::respJson($this->listEntries($query, new Context));
|
||||
} catch (ExceptionInput $e) {
|
||||
return new ErrorResponse("MissingCategory", 400);
|
||||
}
|
||||
|
@ -1047,7 +1046,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
protected function getFeedEntries(array $path, array $query): ResponseInterface {
|
||||
$c = (new Context)->subscription((int) $path[1]);
|
||||
try {
|
||||
return new Response($this->listEntries($query, $c));
|
||||
return HTTP::respJson($this->listEntries($query, $c));
|
||||
} catch (ExceptionInput $e) {
|
||||
// FIXME: this should differentiate between a missing feed and a missing category, but doesn't
|
||||
return new ErrorResponse("404", 404);
|
||||
|
@ -1057,7 +1056,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
protected function getCategoryEntries(array $path, array $query): ResponseInterface {
|
||||
$query['category_id'] = (int) $path[1];
|
||||
try {
|
||||
return new Response($this->listEntries($query, new Context));
|
||||
return HTTP::respJson($this->listEntries($query, new Context));
|
||||
} catch (ExceptionInput $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
|
@ -1065,7 +1064,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
|
||||
protected function getEntry(array $path): ResponseInterface {
|
||||
try {
|
||||
return new Response($this->findEntry((int) $path[1]));
|
||||
return HTTP::respJson($this->findEntry((int) $path[1]));
|
||||
} catch (ExceptionInput $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
|
@ -1074,7 +1073,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
protected function getFeedEntry(array $path): ResponseInterface {
|
||||
$c = (new Context)->subscription((int) $path[1]);
|
||||
try {
|
||||
return new Response($this->findEntry((int) $path[3], $c));
|
||||
return HTTP::respJson($this->findEntry((int) $path[3], $c));
|
||||
} catch (ExceptionInput $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
|
@ -1088,7 +1087,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$c->folder((int) $path[1] - 1);
|
||||
}
|
||||
try {
|
||||
return new Response($this->findEntry((int) $path[3], $c));
|
||||
return HTTP::respJson($this->findEntry((int) $path[3], $c));
|
||||
} catch (ExceptionInput $e) {
|
||||
return new ErrorResponse("404", 404);
|
||||
}
|
||||
|
@ -1200,7 +1199,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
} catch (FeedException $e) {
|
||||
return new ErrorResponse(["FailedImportFeed", 'url' => $e->getParams()['url'], 'code' => $e->getCode()], 502);
|
||||
}
|
||||
return new Response(['message' => Arsse::$lang->msg("API.Miniflux.ImportSuccess")]);
|
||||
return HTTP::respJson(['message' => Arsse::$lang->msg("API.Miniflux.ImportSuccess")]);
|
||||
}
|
||||
|
||||
protected function opmlExport(): ResponseInterface {
|
||||
|
|
|
@ -17,7 +17,6 @@ use JKingWeb\Arsse\Misc\HTTP;
|
|||
use JKingWeb\Arsse\REST\Exception;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
|
||||
class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
public const VERSION = "11.0.5";
|
||||
|
@ -283,7 +282,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
foreach (Arsse::$db->folderList(Arsse::$user->id, null, false) as $folder) {
|
||||
$folders[] = $this->folderTranslate($folder);
|
||||
}
|
||||
return new Response(['folders' => $folders]);
|
||||
return HTTP::respJson(['folders' => $folders]);
|
||||
}
|
||||
|
||||
// create a folder
|
||||
|
@ -302,7 +301,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
}
|
||||
$folder = $this->folderTranslate(Arsse::$db->folderPropertiesGet(Arsse::$user->id, $folder));
|
||||
return new Response(['folders' => [$folder]]);
|
||||
return HTTP::respJson(['folders' => [$folder]]);
|
||||
}
|
||||
|
||||
// delete a folder
|
||||
|
@ -369,7 +368,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// since in our implementation feeds don't belong the users, the 'userId' field will always be an empty string
|
||||
$out[] = ['id' => (int) $feed, 'userId' => ""];
|
||||
}
|
||||
return new Response(['feeds' => $out]);
|
||||
return HTTP::respJson(['feeds' => $out]);
|
||||
}
|
||||
|
||||
// refresh a feed
|
||||
|
@ -421,7 +420,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
if ($newest) {
|
||||
$out['newestItemId'] = $newest;
|
||||
}
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
// return list of feeds for the logged-in user
|
||||
|
@ -437,7 +436,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
if ($newest) {
|
||||
$out['newestItemId'] = $newest;
|
||||
}
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
// delete a feed
|
||||
|
@ -585,7 +584,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$out[] = $this->articleTranslate($item);
|
||||
}
|
||||
$out = ['items' => $out];
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
}
|
||||
|
||||
// mark all articles as read
|
||||
|
@ -663,7 +662,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
|
||||
protected function userStatus(array $url, array $data): ResponseInterface {
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'userId' => (string) Arsse::$user->id,
|
||||
'displayName' => (string) Arsse::$user->id,
|
||||
'lastLoginTimestamp' => time(),
|
||||
|
@ -689,14 +688,14 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
|
||||
// return the server version
|
||||
protected function serverVersion(array $url, array $data): ResponseInterface {
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'version' => self::VERSION,
|
||||
'arsse_version' => Arsse::VERSION,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function serverStatus(array $url, array $data): ResponseInterface {
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'version' => self::VERSION,
|
||||
'arsse_version' => Arsse::VERSION,
|
||||
'warnings' => [
|
||||
|
|
|
@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\REST\NextcloudNews;
|
|||
use JKingWeb\Arsse\Misc\HTTP;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
|
||||
class Versions implements \JKingWeb\Arsse\REST\Handler {
|
||||
public function __construct() {
|
||||
|
@ -31,7 +30,7 @@ class Versions implements \JKingWeb\Arsse\REST\Handler {
|
|||
'v1-2',
|
||||
],
|
||||
];
|
||||
return new Response($out);
|
||||
return HTTP::respJson($out);
|
||||
default:
|
||||
// if any other method was used, this is an error
|
||||
return HTTP::respEmpty(405, ['Allow' => "HEAD,GET"]);
|
||||
|
|
|
@ -21,7 +21,6 @@ use JKingWeb\Arsse\Db\ResultEmpty;
|
|||
use JKingWeb\Arsse\Feed\Exception as FeedException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
public const LEVEL = 15; // emulated API level
|
||||
|
@ -110,7 +109,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// only JSON entities are allowed, but Content-Type is ignored, as is request method
|
||||
$data = @json_decode($data, true);
|
||||
if (json_last_error() !== \JSON_ERROR_NONE || !is_array($data)) {
|
||||
return new Response(self::FATAL_ERR);
|
||||
return HTTP::respJson(self::FATAL_ERR);
|
||||
}
|
||||
try {
|
||||
// normalize input
|
||||
|
@ -136,13 +135,13 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
// TT-RSS operations are case-insensitive by dint of PHP method names being case-insensitive; this will only trigger if the method really doesn't exist
|
||||
throw new Exception("UNKNOWN_METHOD", ['method' => $data['op']]);
|
||||
}
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'seq' => $data['seq'],
|
||||
'status' => 0,
|
||||
'content' => $this->$method($data),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'seq' => $data['seq'],
|
||||
'status' => 1,
|
||||
'content' => $e->getData(),
|
||||
|
@ -152,7 +151,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
} else {
|
||||
// absence of a request body indicates an error
|
||||
return new Response(self::FATAL_ERR);
|
||||
return HTTP::respJson(self::FATAL_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ use JKingWeb\Arsse\Db\ExceptionInput;
|
|||
use JKingWeb\Arsse\Db\Transaction;
|
||||
use JKingWeb\Arsse\REST\Fever\API;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\Response\XmlResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\Fever\API<extended> */
|
||||
|
@ -192,8 +191,8 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function provideTokenAuthenticationRequests(): iterable {
|
||||
$success = new JsonResponse(['auth' => 1]);
|
||||
$failure = new JsonResponse(['auth' => 0]);
|
||||
$success = HTTP::respJson(['auth' => 1]);
|
||||
$failure = HTTP::respJson(['auth' => 0]);
|
||||
$denied = HTTP::respEmpty(401);
|
||||
return [
|
||||
[false, true, null, [], ['api' => null], $failure],
|
||||
|
@ -255,7 +254,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 2, 'name' => "Interesting", 'subscription' => 1],
|
||||
['id' => 2, 'name' => "Interesting", 'subscription' => 3],
|
||||
]));
|
||||
$exp = new JsonResponse([
|
||||
$exp = HTTP::respJson([
|
||||
'groups' => [
|
||||
['id' => 1, 'title' => "Fascinating"],
|
||||
['id' => 2, 'title' => "Interesting"],
|
||||
|
@ -281,7 +280,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 2, 'name' => "Interesting", 'subscription' => 1],
|
||||
['id' => 2, 'name' => "Interesting", 'subscription' => 3],
|
||||
]));
|
||||
$exp = new JsonResponse([
|
||||
$exp = HTTP::respJson([
|
||||
'feeds' => [
|
||||
['id' => 1, 'favicon_id' => 42, 'title' => "Ankh-Morpork News", 'url' => "http://example.com/feed", 'site_url' => "http://example.com/", 'is_spark' => 0, 'last_updated_on_time' => strtotime("2019-01-01T21:12:00Z")],
|
||||
['id' => 2, 'favicon_id' => 0, 'title' => "Ook, Ook Eek Ook!", 'url' => "http://example.net/feed", 'site_url' => "http://example.net/", 'is_spark' => 0, 'last_updated_on_time' => strtotime("1988-06-24T12:21:00Z")],
|
||||
|
@ -301,7 +300,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$order = [$desc ? "id desc" : "id"];
|
||||
$this->dbMock->articleList->returns(new Result($this->articles['db']));
|
||||
$this->dbMock->articleCount->with($this->userId, (new Context)->hidden(false))->returns(1024);
|
||||
$exp = new JsonResponse([
|
||||
$exp = HTTP::respJson([
|
||||
'items' => $this->articles['rest'],
|
||||
'total_items' => 1024,
|
||||
]);
|
||||
|
@ -330,15 +329,15 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$exp = new JsonResponse(['saved_item_ids' => "1,2,3"]);
|
||||
$exp = HTTP::respJson(['saved_item_ids' => "1,2,3"]);
|
||||
$this->assertMessage($exp, $this->req("api&saved_item_ids"));
|
||||
$exp = new JsonResponse(['unread_item_ids' => "4,5,6"]);
|
||||
$exp = HTTP::respJson(['unread_item_ids' => "4,5,6"]);
|
||||
$this->assertMessage($exp, $this->req("api&unread_item_ids"));
|
||||
}
|
||||
|
||||
public function testListHotLinks(): void {
|
||||
// hot links are not actually implemented, so an empty array should be all we get
|
||||
$exp = new JsonResponse(['links' => []]);
|
||||
$exp = HTTP::respJson(['links' => []]);
|
||||
$this->assertMessage($exp, $this->req("api&links"));
|
||||
}
|
||||
|
||||
|
@ -350,7 +349,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), (new Context)->article(2112))->throws(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$exp = new JsonResponse($out);
|
||||
$exp = HTTP::respJson($out);
|
||||
$this->assertMessage($exp, $this->req("api", $post));
|
||||
if ($c && $data) {
|
||||
$this->dbMock->articleMark->calledWith($this->userId, $data, $this->equalTo($c));
|
||||
|
@ -367,7 +366,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), (new Context)->article(2112))->throws(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$exp = new JsonResponse($out);
|
||||
$exp = HTTP::respJson($out);
|
||||
$this->assertMessage($exp, $this->req("api&$get"));
|
||||
if ($c && $data) {
|
||||
$this->dbMock->articleMark->calledWith($this->userId, $data, $this->equalTo($c));
|
||||
|
@ -423,9 +422,9 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
return [
|
||||
'Not an API request' => ["", "", "POST", null, HTTP::respEmpty(404)],
|
||||
'Wrong method' => ["api", "", "PUT", null, HTTP::respEmpty(405, ['Allow' => "OPTIONS,POST"])],
|
||||
'Non-standard method' => ["api", "", "GET", null, new JsonResponse([])],
|
||||
'Wrong content type' => ["api", '{"api_key":"validToken"}', "POST", "application/json", new JsonResponse([])], // some clients send nonsensical content types; Fever seems to have allowed this
|
||||
'Non-standard content type' => ["api", '{"api_key":"validToken"}', "POST", "multipart/form-data; boundary=33b68964f0de4c1f-5144aa6caaa6e4a8-18bfaf416a1786c8-5c5053a45f221bc1", new JsonResponse([])], // some clients send nonsensical content types; Fever seems to have allowed this
|
||||
'Non-standard method' => ["api", "", "GET", null, HTTP::respJson([])],
|
||||
'Wrong content type' => ["api", '{"api_key":"validToken"}', "POST", "application/json", HTTP::respJson([])], // some clients send nonsensical content types; Fever seems to have allowed this
|
||||
'Non-standard content type' => ["api", '{"api_key":"validToken"}', "POST", "multipart/form-data; boundary=33b68964f0de4c1f-5144aa6caaa6e4a8-18bfaf416a1786c8-5c5053a45f221bc1", HTTP::respJson([])], // some clients send nonsensical content types; Fever seems to have allowed this
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -433,21 +432,21 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->hMock->baseResponse->forwards();
|
||||
$this->hMock->logIn->returns(true);
|
||||
$this->dbMock->subscriptionRefreshed->with($this->userId)->returns(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
|
||||
$exp = new JsonResponse([
|
||||
$exp = HTTP::respJson([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 1,
|
||||
'last_refreshed_on_time' => 946684800,
|
||||
]);
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
$this->dbMock->subscriptionRefreshed->with($this->userId)->returns(null); // no subscriptions
|
||||
$exp = new JsonResponse([
|
||||
$exp = HTTP::respJson([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 1,
|
||||
'last_refreshed_on_time' => null,
|
||||
]);
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
$this->hMock->logIn->returns(false);
|
||||
$exp = new JsonResponse([
|
||||
$exp = HTTP::respJson([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 0,
|
||||
]);
|
||||
|
@ -460,7 +459,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->limit(1)->hidden(false)), ["marked_date"], ["marked_date desc"])->returns(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->unread(true)->hidden(false)))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$exp = new JsonResponse($out);
|
||||
$exp = HTTP::respJson($out);
|
||||
$this->assertMessage($exp, $this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->dbMock->articleMark->calledWith($this->userId, ['read' => false], $this->equalTo((new Context)->unread(false)->markedRange("1999-12-31T23:59:45Z", null)->hidden(false)));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->returns(new Result([]));
|
||||
|
@ -485,7 +484,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 44, 'type' => null, 'data' => "IMAGE DATA"],
|
||||
['id' => 47, 'type' => null, 'data' => null],
|
||||
])));
|
||||
$exp = new JsonResponse(['favicons' => [
|
||||
$exp = HTTP::respJson(['favicons' => [
|
||||
['id' => 0, 'data' => $iconType.",".$iconData],
|
||||
['id' => 42, 'data' => "image/svg+xml;base64,PHN2Zy8+"],
|
||||
['id' => 44, 'data' => "application/octet-stream;base64,SU1BR0UgREFUQQ=="],
|
||||
|
|
|
@ -26,7 +26,6 @@ use JKingWeb\Arsse\User\ExceptionConflict;
|
|||
use JKingWeb\Arsse\User\ExceptionInput as UserExceptionInput;
|
||||
use JKingWeb\Arsse\Test\Result;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\TextResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\Miniflux\V1<extended> */
|
||||
|
@ -182,8 +181,8 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['title' => "Feed", 'type' => "rss", 'url' => "http://localhost:8000/Feed/Discovery/Missing"],
|
||||
];
|
||||
return [
|
||||
["http://localhost:8000/Feed/Discovery/Valid", new Response($discovered)],
|
||||
["http://localhost:8000/Feed/Discovery/Invalid", new Response([])],
|
||||
["http://localhost:8000/Feed/Discovery/Valid", HTTP::respJson($discovered)],
|
||||
["http://localhost:8000/Feed/Discovery/Invalid", HTTP::respJson([])],
|
||||
["http://localhost:8000/Feed/Discovery/Missing", new ErrorResponse("Fetch404", 502)],
|
||||
[1, new ErrorResponse(["InvalidInputType", 'field' => "url", 'expected' => "string", 'actual' => "integer"], 422)],
|
||||
["Not a URL", new ErrorResponse(["InvalidInputValue", 'field' => "url"], 422)],
|
||||
|
@ -226,16 +225,16 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function provideUserQueries(): iterable {
|
||||
self::clearData();
|
||||
return [
|
||||
[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", HTTP::respJson(self::USERS)],
|
||||
[true, "/me", HTTP::respJson(self::USERS[0])],
|
||||
[true, "/users/john.doe@example.com", HTTP::respJson(self::USERS[0])],
|
||||
[true, "/users/1", HTTP::respJson(self::USERS[0])],
|
||||
[true, "/users/jane.doe@example.com", HTTP::respJson(self::USERS[1])],
|
||||
[true, "/users/2", HTTP::respJson(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(self::USERS[1])],
|
||||
[false, "/me", HTTP::respJson(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)],
|
||||
|
@ -310,16 +309,16 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
[false, "/users/1", ['entry_sorting_direction' => "bad"], null, null, null, null, null, null, new ErrorResponse(["InvalidInputValue", 'field' => "entry_sorting_direction"], 422)],
|
||||
[false, "/users/1", ['theme' => "stark"], null, null, null, null, null, null, new ErrorResponse("403", 403)],
|
||||
[false, "/users/2", ['is_admin' => true], null, null, null, null, null, null, new ErrorResponse("InvalidElevation", 403)],
|
||||
[false, "/users/2", ['language' => "fr_CA"], null, null, null, null, ['lang' => "fr_CA"], $out1, new Response($resp1, 201)],
|
||||
[false, "/users/2", ['entry_sorting_direction' => "asc"], null, null, null, null, ['sort_asc' => true], $out1, new Response($resp1, 201)],
|
||||
[false, "/users/2", ['entry_sorting_direction' => "desc"], null, null, null, null, ['sort_asc' => false], $out1, new Response($resp1, 201)],
|
||||
[false, "/users/2", ['language' => "fr_CA"], null, null, null, null, ['lang' => "fr_CA"], $out1, HTTP::respJson($resp1, 201)],
|
||||
[false, "/users/2", ['entry_sorting_direction' => "asc"], null, null, null, null, ['sort_asc' => true], $out1, HTTP::respJson($resp1, 201)],
|
||||
[false, "/users/2", ['entry_sorting_direction' => "desc"], null, null, null, null, ['sort_asc' => false], $out1, HTTP::respJson($resp1, 201)],
|
||||
[false, "/users/2", ['entries_per_page' => -1], null, null, null, null, ['page_size' => -1], new UserExceptionInput("invalidNonZeroInteger"), new ErrorResponse(["InvalidInputValue", 'field' => "entries_per_page"], 422)],
|
||||
[false, "/users/2", ['timezone' => "Ook"], null, null, null, null, ['tz' => "Ook"], new UserExceptionInput("invalidTimezone"), new ErrorResponse(["InvalidInputValue", 'field' => "timezone"], 422)],
|
||||
[false, "/users/2", ['username' => "j:k"], "j:k", new UserExceptionInput("invalidUsername"), null, null, null, null, new ErrorResponse(["InvalidInputValue", 'field' => "username"], 422)],
|
||||
[false, "/users/2", ['username' => "ook"], "ook", new ExceptionConflict("alreadyExists"), null, null, null, null, new ErrorResponse(["DuplicateUser", 'user' => "ook"], 409)],
|
||||
[false, "/users/2", ['password' => "ook"], null, null, "ook", "ook", null, null, new Response(array_merge($resp1, ['password' => "ook"]), 201)],
|
||||
[false, "/users/2", ['username' => "ook", 'password' => "ook"], "ook", true, "ook", "ook", null, null, new Response(array_merge($resp1, ['username' => "ook", 'password' => "ook"]), 201)],
|
||||
[true, "/users/1", ['theme' => "stark"], null, null, null, null, ['theme' => "stark"], $out2, new Response($resp2, 201)],
|
||||
[false, "/users/2", ['password' => "ook"], null, null, "ook", "ook", null, null, HTTP::respJson(array_merge($resp1, ['password' => "ook"]), 201)],
|
||||
[false, "/users/2", ['username' => "ook", 'password' => "ook"], "ook", true, "ook", "ook", null, null, HTTP::respJson(array_merge($resp1, ['username' => "ook", 'password' => "ook"]), 201)],
|
||||
[true, "/users/1", ['theme' => "stark"], null, null, null, null, ['theme' => "stark"], $out2, HTTP::respJson($resp2, 201)],
|
||||
[true, "/users/3", ['theme' => "stark"], null, null, null, null, null, null, new ErrorResponse("404", 404)],
|
||||
];
|
||||
}
|
||||
|
@ -367,7 +366,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
[['username' => "j:k", 'password' => "eek"], ["j:k", "eek"], new UserExceptionInput("invalidUsername"), null, null, new ErrorResponse(["InvalidInputValue", 'field' => "username"], 422)],
|
||||
[['username' => "ook", 'password' => "eek", 'timezone' => "ook"], ["ook", "eek"], "eek", ['tz' => "ook"], new UserExceptionInput("invalidTimezone"), new ErrorResponse(["InvalidInputValue", 'field' => "timezone"], 422)],
|
||||
[['username' => "ook", 'password' => "eek", 'entries_per_page' => -1], ["ook", "eek"], "eek", ['page_size' => -1], new UserExceptionInput("invalidNonZeroInteger"), new ErrorResponse(["InvalidInputValue", 'field' => "entries_per_page"], 422)],
|
||||
[['username' => "ook", 'password' => "eek", 'theme' => "default"], ["ook", "eek"], "eek", ['theme' => "default"], ['theme' => "default"], new Response($resp1, 201)],
|
||||
[['username' => "ook", 'password' => "eek", 'theme' => "default"], ["ook", "eek"], "eek", ['theme' => "default"], ['theme' => "default"], HTTP::respJson($resp1, 201)],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -406,7 +405,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 1, 'name' => "Science"],
|
||||
['id' => 20, 'name' => "Technology"],
|
||||
])));
|
||||
$exp = new Response([
|
||||
$exp = HTTP::respJson([
|
||||
['id' => 1, 'title' => "All", 'user_id' => 42],
|
||||
['id' => 2, 'title' => "Science", 'user_id' => 42],
|
||||
['id' => 21, 'title' => "Technology", 'user_id' => 42],
|
||||
|
@ -416,7 +415,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
// run test again with a renamed root folder
|
||||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("propertiesGet")->willReturn(['num' => 47, 'admin' => false, 'root_folder_name' => "Uncategorized"]);
|
||||
$exp = new Response([
|
||||
$exp = HTTP::respJson([
|
||||
['id' => 1, 'title' => "Uncategorized", 'user_id' => 47],
|
||||
['id' => 2, 'title' => "Science", 'user_id' => 47],
|
||||
['id' => 21, 'title' => "Technology", 'user_id' => 47],
|
||||
|
@ -440,7 +439,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function provideCategoryAdditions(): iterable {
|
||||
return [
|
||||
["New", new Response(['id' => 2112, 'title' => "New", 'user_id' => 42], 201)],
|
||||
["New", HTTP::respJson(['id' => 2112, 'title' => "New", 'user_id' => 42], 201)],
|
||||
["Duplicate", new ErrorResponse(["DuplicateCategory", 'title' => "Duplicate"], 409)],
|
||||
["", new ErrorResponse(["InvalidCategory", 'title' => ""], 422)],
|
||||
[" ", new ErrorResponse(["InvalidCategory", 'title' => " "], 422)],
|
||||
|
@ -467,14 +466,14 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function provideCategoryUpdates(): iterable {
|
||||
return [
|
||||
[3, "New", "subjectMissing", new ErrorResponse("404", 404)],
|
||||
[2, "New", true, new Response(['id' => 2, 'title' => "New", 'user_id' => 42], 201)],
|
||||
[2, "New", true, HTTP::respJson(['id' => 2, 'title' => "New", 'user_id' => 42], 201)],
|
||||
[2, "Duplicate", "constraintViolation", new ErrorResponse(["DuplicateCategory", 'title' => "Duplicate"], 409)],
|
||||
[2, "", "missing", new ErrorResponse(["InvalidCategory", 'title' => ""], 422)],
|
||||
[2, " ", "whitespace", new ErrorResponse(["InvalidCategory", 'title' => " "], 422)],
|
||||
[2, null, "missing", new ErrorResponse(["MissingInputValue", 'field' => "title"], 422)],
|
||||
[2, false, "subjectMissing", new ErrorResponse(["InvalidInputType", 'field' => "title", 'actual' => "boolean", 'expected' => "string"], 422)],
|
||||
[1, "New", true, new Response(['id' => 1, 'title' => "New", 'user_id' => 42], 201)],
|
||||
[1, "Duplicate", "constraintViolation", new Response(['id' => 1, 'title' => "Duplicate", 'user_id' => 42], 201)], // This is allowed because the name of the root folder is only a duplicate in circumstances where it is used
|
||||
[1, "New", true, HTTP::respJson(['id' => 1, 'title' => "New", 'user_id' => 42], 201)],
|
||||
[1, "Duplicate", "constraintViolation", HTTP::respJson(['id' => 1, 'title' => "Duplicate", 'user_id' => 42], 201)], // This is allowed because the name of the root folder is only a duplicate in circumstances where it is used
|
||||
[1, "", "missing", new ErrorResponse(["InvalidCategory", 'title' => ""], 422)],
|
||||
[1, " ", "whitespace", new ErrorResponse(["InvalidCategory", 'title' => " "], 422)],
|
||||
[1, null, "missing", new ErrorResponse(["MissingInputValue", 'field' => "title"], 422)],
|
||||
|
@ -510,20 +509,20 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testListFeeds(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
$exp = new Response(self::FEEDS_OUT);
|
||||
$exp = HTTP::respJson(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||
}
|
||||
|
||||
public function testListFeedsOfACategory(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
$exp = new Response(self::FEEDS_OUT);
|
||||
$exp = HTTP::respJson(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/2112/feeds"));
|
||||
$this->dbMock->subscriptionList->calledWith(Arsse::$user->id, 2111, true);
|
||||
}
|
||||
|
||||
public function testListFeedsOfTheRootCategory(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
$exp = new Response(self::FEEDS_OUT);
|
||||
$exp = HTTP::respJson(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/1/feeds"));
|
||||
$this->dbMock->subscriptionList->calledWith(Arsse::$user->id, 0, false);
|
||||
}
|
||||
|
@ -537,9 +536,9 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testGetAFeed(): void {
|
||||
$this->dbMock->subscriptionPropertiesGet->returns($this->v(self::FEEDS[0]))->returns($this->v(self::FEEDS[1]));
|
||||
$this->assertMessage(new Response(self::FEEDS_OUT[0]), $this->req("GET", "/feeds/1"));
|
||||
$this->assertMessage(HTTP::respJson(self::FEEDS_OUT[0]), $this->req("GET", "/feeds/1"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 1);
|
||||
$this->assertMessage(new Response(self::FEEDS_OUT[1]), $this->req("GET", "/feeds/55"));
|
||||
$this->assertMessage(HTTP::respJson(self::FEEDS_OUT[1]), $this->req("GET", "/feeds/55"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 55);
|
||||
}
|
||||
|
||||
|
@ -634,16 +633,16 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
[['feed_url' => "http://example.com/", 'category_id' => 1], new FeedException("unsupportedFeedFormat"), null, null, null, new ErrorResponse("FetchFormat", 502)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1], 2112, new ExceptionInput("constraintViolation"), null, null, new ErrorResponse("DuplicateFeed", 409)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1], 2112, 44, new ExceptionInput("idMissing"), null, new ErrorResponse("MissingCategory", 422)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1], 2112, 44, true, null, new Response(['feed_id' => 44], 201)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1, 'keeplist_rules' => "^A"], 2112, 44, true, true, new Response(['feed_id' => 44], 201)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1, 'blocklist_rules' => "A"], 2112, 44, true, true, new Response(['feed_id' => 44], 201)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1], 2112, 44, true, null, HTTP::respJson(['feed_id' => 44], 201)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1, 'keeplist_rules' => "^A"], 2112, 44, true, true, HTTP::respJson(['feed_id' => 44], 201)],
|
||||
[['feed_url' => "http://example.com/", 'category_id' => 1, 'blocklist_rules' => "A"], 2112, 44, true, true, HTTP::respJson(['feed_id' => 44], 201)],
|
||||
];
|
||||
}
|
||||
|
||||
/** @dataProvider provideFeedModifications */
|
||||
public function testModifyAFeed(array $in, array $data, $out, ResponseInterface $exp): void {
|
||||
$this->h = $this->partialMock(V1::class);
|
||||
$this->h->getFeed->returns(new Response(self::FEEDS_OUT[0]));
|
||||
$this->h->getFeed->returns(HTTP::respJson(self::FEEDS_OUT[0]));
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->subscriptionPropertiesSet->throws($out);
|
||||
} else {
|
||||
|
@ -655,7 +654,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function provideFeedModifications(): iterable {
|
||||
self::clearData();
|
||||
$success = new Response(self::FEEDS_OUT[0], 201);
|
||||
$success = HTTP::respJson(self::FEEDS_OUT[0], 201);
|
||||
return [
|
||||
[[], [], true, $success],
|
||||
[[], [], new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||
|
@ -672,9 +671,9 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testModifyAFeedWithNoBody(): void {
|
||||
$this->h = $this->partialMock(V1::class);
|
||||
$this->h->getFeed->returns(new Response(self::FEEDS_OUT[0]));
|
||||
$this->h->getFeed->returns(HTTP::respJson(self::FEEDS_OUT[0]));
|
||||
$this->dbMock->subscriptionPropertiesSet->returns(true);
|
||||
$this->assertMessage(new Response(self::FEEDS_OUT[0], 201), $this->req("PUT", "/feeds/2112", ""));
|
||||
$this->assertMessage(HTTP::respJson(self::FEEDS_OUT[0], 201), $this->req("PUT", "/feeds/2112", ""));
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith(Arsse::$user->id, 2112, []);
|
||||
}
|
||||
|
||||
|
@ -703,7 +702,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function provideIcons(): iterable {
|
||||
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/>"], HTTP::respJson(['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' => null, 'data' => "<svg/>"], new ErrorResponse("404", 404)],
|
||||
[['id' => 47, 'type' => null, 'data' => null], new ErrorResponse("404", 404)],
|
||||
|
@ -755,50 +754,50 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
["/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, $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?category_id=47", (clone $c)->folder(46), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?category_id=1", (clone $c)->folderShallow(0), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=unread", (clone $c)->unread(true)->hidden(false), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=read", (clone $c)->unread(false)->hidden(false), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed", (clone $c)->hidden(true), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=unread&status=read", (clone $c)->hidden(false), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=unread&status=removed", new UnionContext((clone $c)->unread(true), (clone $c)->hidden(true)), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed&status=read", new UnionContext((clone $c)->unread(false), (clone $c)->hidden(true)), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed&status=read&status=removed", new UnionContext((clone $c)->unread(false), (clone $c)->hidden(true)), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed&status=read&status=unread", $c, $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred", (clone $c)->starred(true), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred=", (clone $c)->starred(true), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred=true", (clone $c)->starred(true), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred=false", (clone $c)->starred(true), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?after=0", (clone $c)->modifiedRange(0, null), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before=0", $c, $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before=1", (clone $c)->modifiedRange(null, 1), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before=1&after=0", (clone $c)->modifiedRange(0, 1), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?after_entry_id=42", (clone $c)->articleRange(43, null), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before_entry_id=47", (clone $c)->articleRange(null, 46), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?search=alpha%20beta", (clone $c)->searchTerms(["alpha", "beta"]), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?limit=4", (clone $c)->limit(4), $o, self::ENTRIES, true, new Response(['total' => 2112, 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?offset=20", (clone $c)->offset(20), $o, [], true, new Response(['total' => 2112, 'entries' => []])],
|
||||
["/entries?direction=asc", $c, $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=id", $c, ["id"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=published_at", $c, ["modified_date"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_id", $c, ["top_folder"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_title", $c, ["top_folder_name"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=status", $c, ["hidden", "unread desc"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?direction=desc", $c, ["modified_date desc"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=id&direction=desc", $c, ["id desc"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=published_at&direction=desc", $c, ["modified_date desc"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_id&direction=desc", $c, ["top_folder desc"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_title&direction=desc", $c, ["top_folder_name desc"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=status&direction=desc", $c, ["hidden desc", "unread"], self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries", $c, $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?category_id=47", (clone $c)->folder(46), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?category_id=1", (clone $c)->folderShallow(0), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=unread", (clone $c)->unread(true)->hidden(false), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=read", (clone $c)->unread(false)->hidden(false), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed", (clone $c)->hidden(true), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=unread&status=read", (clone $c)->hidden(false), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=unread&status=removed", new UnionContext((clone $c)->unread(true), (clone $c)->hidden(true)), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed&status=read", new UnionContext((clone $c)->unread(false), (clone $c)->hidden(true)), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed&status=read&status=removed", new UnionContext((clone $c)->unread(false), (clone $c)->hidden(true)), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?status=removed&status=read&status=unread", $c, $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred", (clone $c)->starred(true), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred=", (clone $c)->starred(true), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred=true", (clone $c)->starred(true), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?starred=false", (clone $c)->starred(true), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?after=0", (clone $c)->modifiedRange(0, null), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before=0", $c, $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before=1", (clone $c)->modifiedRange(null, 1), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before=1&after=0", (clone $c)->modifiedRange(0, 1), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?after_entry_id=42", (clone $c)->articleRange(43, null), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?before_entry_id=47", (clone $c)->articleRange(null, 46), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?search=alpha%20beta", (clone $c)->searchTerms(["alpha", "beta"]), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?limit=4", (clone $c)->limit(4), $o, self::ENTRIES, true, HTTP::respJson(['total' => 2112, 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?offset=20", (clone $c)->offset(20), $o, [], true, HTTP::respJson(['total' => 2112, 'entries' => []])],
|
||||
["/entries?direction=asc", $c, $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=id", $c, ["id"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=published_at", $c, ["modified_date"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_id", $c, ["top_folder"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_title", $c, ["top_folder_name"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=status", $c, ["hidden", "unread desc"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?direction=desc", $c, ["modified_date desc"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=id&direction=desc", $c, ["id desc"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=published_at&direction=desc", $c, ["modified_date desc"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_id&direction=desc", $c, ["top_folder desc"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=category_title&direction=desc", $c, ["top_folder_name desc"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?order=status&direction=desc", $c, ["hidden desc", "unread"], self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/entries?category_id=2112", (clone $c)->folder(2111), $o, new ExceptionInput("idMissing"), false, new ErrorResponse("MissingCategory")],
|
||||
["/feeds/42/entries", (clone $c)->subscription(42), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/feeds/42/entries?category_id=47", (clone $c)->subscription(42)->folder(46), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/feeds/42/entries", (clone $c)->subscription(42), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/feeds/42/entries?category_id=47", (clone $c)->subscription(42)->folder(46), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/feeds/2112/entries", (clone $c)->subscription(2112), $o, new ExceptionInput("idMissing"), false, new ErrorResponse("404", 404)],
|
||||
["/categories/42/entries", (clone $c)->folder(41), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/42/entries?category_id=47", (clone $c)->folder(41), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/42/entries?starred", (clone $c)->folder(41)->starred(true), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/1/entries", (clone $c)->folderShallow(0), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/42/entries", (clone $c)->folder(41), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/42/entries?category_id=47", (clone $c)->folder(41), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/42/entries?starred", (clone $c)->folder(41)->starred(true), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/1/entries", (clone $c)->folderShallow(0), $o, self::ENTRIES, false, HTTP::respJson(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||
["/categories/2112/entries", (clone $c)->folder(2111), $o, new ExceptionInput("idMissing"), false, new ErrorResponse("404", 404)],
|
||||
];
|
||||
}
|
||||
|
@ -828,17 +827,17 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
$c = new Context;
|
||||
return [
|
||||
["/entries/42", (clone $c)->article(42), [self::ENTRIES[1]], new Response(self::ENTRIES_OUT[1])],
|
||||
["/entries/42", (clone $c)->article(42), [self::ENTRIES[1]], HTTP::respJson(self::ENTRIES_OUT[1])],
|
||||
["/entries/2112", (clone $c)->article(2112), new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||
["/feeds/47/entries/42", (clone $c)->subscription(47)->article(42), [self::ENTRIES[1]], new Response(self::ENTRIES_OUT[1])],
|
||||
["/feeds/47/entries/42", (clone $c)->subscription(47)->article(42), [self::ENTRIES[1]], HTTP::respJson(self::ENTRIES_OUT[1])],
|
||||
["/feeds/47/entries/44", (clone $c)->subscription(47)->article(44), [], new ErrorResponse("404", 404)],
|
||||
["/feeds/47/entries/2112", (clone $c)->subscription(47)->article(2112), new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||
["/feeds/2112/entries/47", (clone $c)->subscription(2112)->article(47), new ExceptionInput("idMissing"), new ErrorResponse("404", 404)],
|
||||
["/categories/47/entries/42", (clone $c)->folder(46)->article(42), [self::ENTRIES[1]], new Response(self::ENTRIES_OUT[1])],
|
||||
["/categories/47/entries/42", (clone $c)->folder(46)->article(42), [self::ENTRIES[1]], HTTP::respJson(self::ENTRIES_OUT[1])],
|
||||
["/categories/47/entries/44", (clone $c)->folder(46)->article(44), [], new ErrorResponse("404", 404)],
|
||||
["/categories/47/entries/2112", (clone $c)->folder(46)->article(2112), new ExceptionInput("subjectMissing"), new ErrorResponse("404", 404)],
|
||||
["/categories/2112/entries/47", (clone $c)->folder(2111)->article(47), new ExceptionInput("idMissing"), new ErrorResponse("404", 404)],
|
||||
["/categories/1/entries/42", (clone $c)->folderShallow(0)->article(42), [self::ENTRIES[1]], new Response(self::ENTRIES_OUT[1])],
|
||||
["/categories/1/entries/42", (clone $c)->folderShallow(0)->article(42), [self::ENTRIES[1]], HTTP::respJson(self::ENTRIES_OUT[1])],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -970,7 +969,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
[new ImportException("invalidFolderCopy"), new ErrorResponse("DuplicateImportCategory", 422)],
|
||||
[new ImportException("invalidTagName"), new ErrorResponse("InvalidImportLabel", 422)],
|
||||
[new FeedException("invalidUrl", ['url' => "http://example.com/"]), new ErrorResponse(["FailedImportFeed", 'url' => "http://example.com/", 'code' => 10502], 502)],
|
||||
[true, new Response(['message' => Arsse::$lang->msg("API.Miniflux.ImportSuccess")])],
|
||||
[true, HTTP::respJson(['message' => Arsse::$lang->msg("API.Miniflux.ImportSuccess")])],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ use JKingWeb\Arsse\Db\ExceptionInput;
|
|||
use JKingWeb\Arsse\Db\Transaction;
|
||||
use JKingWeb\Arsse\REST\NextcloudNews\V1_2;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\NextcloudNews\V1_2<extended> */
|
||||
class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -408,7 +407,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 12, 'name' => "Hardware"],
|
||||
];
|
||||
$this->dbMock->folderList->with($this->userId, null, false)->returns(new Result($this->v($list)));
|
||||
$exp = new Response(['folders' => $out]);
|
||||
$exp = HTTP::respJson(['folders' => $out]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/folders"));
|
||||
}
|
||||
|
||||
|
@ -432,10 +431,10 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function provideFolderCreations(): array {
|
||||
return [
|
||||
[['name' => "Software"], true, 1, new Response(['folders' => [['id' => 1, 'name' => "Software"]]])],
|
||||
[['name' => "Software"], false, 1, new Response(['folders' => [['id' => 1, 'name' => "Software"]]])],
|
||||
[['name' => "Hardware"], true, "2", new Response(['folders' => [['id' => 2, 'name' => "Hardware"]]])],
|
||||
[['name' => "Hardware"], false, "2", new Response(['folders' => [['id' => 2, 'name' => "Hardware"]]])],
|
||||
[['name' => "Software"], true, 1, HTTP::respJson(['folders' => [['id' => 1, 'name' => "Software"]]])],
|
||||
[['name' => "Software"], false, 1, HTTP::respJson(['folders' => [['id' => 1, 'name' => "Software"]]])],
|
||||
[['name' => "Hardware"], true, "2", HTTP::respJson(['folders' => [['id' => 2, 'name' => "Hardware"]]])],
|
||||
[['name' => "Hardware"], false, "2", HTTP::respJson(['folders' => [['id' => 2, 'name' => "Hardware"]]])],
|
||||
[['name' => "Software"], true, new ExceptionInput("constraintViolation"), HTTP::respEmpty(409)],
|
||||
[['name' => ""], true, new ExceptionInput("whitespace"), HTTP::respEmpty(422)],
|
||||
[['name' => " "], true, new ExceptionInput("whitespace"), HTTP::respEmpty(422)],
|
||||
|
@ -477,7 +476,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testRetrieveServerVersion(): void {
|
||||
$exp = new Response([
|
||||
$exp = HTTP::respJson([
|
||||
'version' => V1_2::VERSION,
|
||||
'arsse_version' => Arsse::VERSION,
|
||||
]);
|
||||
|
@ -497,9 +496,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->dbMock->subscriptionList->with($this->userId)->returns(new Result([]))->returns(new Result($this->v($this->feeds['db'])));
|
||||
$this->dbMock->articleStarred->with($this->userId)->returns($this->v(['total' => 0]))->returns($this->v(['total' => 5]));
|
||||
$this->dbMock->editionLatest->with($this->userId)->returns(0)->returns(4758915);
|
||||
$exp = new Response($exp1);
|
||||
$exp = HTTP::respJson($exp1);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||
$exp = new Response($exp2);
|
||||
$exp = HTTP::respJson($exp2);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||
}
|
||||
|
||||
|
@ -538,12 +537,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function provideNewSubscriptions(): array {
|
||||
$feedException = new \JKingWeb\Arsse\Feed\Exception("", [], new \PicoFeed\Reader\SubscriptionNotFoundException);
|
||||
return [
|
||||
[['url' => "http://example.com/news.atom", 'folderId' => 3], 2112, 0, $this->feeds['db'][0], new ExceptionInput("idMissing"), new Response(['feeds' => [$this->feeds['rest'][0]]])],
|
||||
[['url' => "http://example.org/news.atom", 'folderId' => 8], 42, 4758915, $this->feeds['db'][1], true, new Response(['feeds' => [$this->feeds['rest'][1]], 'newestItemId' => 4758915])],
|
||||
[['url' => "http://example.com/news.atom", 'folderId' => 3], 2112, 0, $this->feeds['db'][0], new ExceptionInput("idMissing"), HTTP::respJson(['feeds' => [$this->feeds['rest'][0]]])],
|
||||
[['url' => "http://example.org/news.atom", 'folderId' => 8], 42, 4758915, $this->feeds['db'][1], true, HTTP::respJson(['feeds' => [$this->feeds['rest'][1]], 'newestItemId' => 4758915])],
|
||||
[['url' => "http://example.com/news.atom", 'folderId' => 3], new ExceptionInput("constraintViolation"), 0, $this->feeds['db'][0], new ExceptionInput("idMissing"), HTTP::respEmpty(409)],
|
||||
[['url' => "http://example.org/news.atom", 'folderId' => 8], new ExceptionInput("constraintViolation"), 4758915, $this->feeds['db'][1], true, HTTP::respEmpty(409)],
|
||||
[[], $feedException, 0, [], false, HTTP::respEmpty(422)],
|
||||
[['url' => "http://example.net/news.atom", 'folderId' => -1], 47, 2112, $this->feeds['db'][2], new ExceptionInput("typeViolation"), new Response(['feeds' => [$this->feeds['rest'][2]], 'newestItemId' => 2112])],
|
||||
[['url' => "http://example.net/news.atom", 'folderId' => -1], 47, 2112, $this->feeds['db'][2], new ExceptionInput("typeViolation"), HTTP::respJson(['feeds' => [$this->feeds['rest'][2]], 'newestItemId' => 2112])],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -627,7 +626,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
],
|
||||
];
|
||||
$this->dbMock->feedListStale->returns($this->v(array_column($out, "id")));
|
||||
$exp = new Response(['feeds' => $out]);
|
||||
$exp = HTTP::respJson(['feeds' => $out]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds/all"));
|
||||
}
|
||||
|
||||
|
@ -683,7 +682,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$c = (new Context)->hidden(false);
|
||||
$t = Date::normalize(time());
|
||||
$out = new Result($this->v($this->articles['db']));
|
||||
$r200 = new Response(['items' => $this->articles['rest']]);
|
||||
$r200 = HTTP::respJson(['items' => $this->articles['rest']]);
|
||||
$r422 = HTTP::respEmpty(422);
|
||||
return [
|
||||
["/items", [], clone $c, $out, $r200],
|
||||
|
@ -854,7 +853,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
$arr2['warnings']['improperlyConfiguredCron'] = true;
|
||||
$arr2['warnings']['incorrectDbCharset'] = true;
|
||||
$exp = new Response($arr1);
|
||||
$exp = HTTP::respJson($arr1);
|
||||
$this->assertMessage($exp, $this->req("GET", "/status"));
|
||||
}
|
||||
|
||||
|
@ -888,10 +887,10 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testQueryTheUserStatus(): void {
|
||||
$act = $this->req("GET", "/user");
|
||||
$exp = new Response([
|
||||
$exp = HTTP::respJson([
|
||||
'userId' => $this->userId,
|
||||
'displayName' => $this->userId,
|
||||
'lastLoginTimestamp' => $this->approximateTime($act->getPayload()['lastLoginTimestamp'], new \DateTimeImmutable),
|
||||
'lastLoginTimestamp' => $this->approximateTime(json_decode((string) $act->getBody(), true)['lastLoginTimestamp'], new \DateTimeImmutable),
|
||||
'avatar' => null,
|
||||
]);
|
||||
$this->assertMessage($exp, $act);
|
||||
|
@ -906,7 +905,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->dbMock->folderAdd->with($this->anything(), $in)->returns(1);
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 1)->returns($this->v($out1));
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 2)->returns($this->v($out2));
|
||||
$exp = new Response(['folders' => [$out1]]);
|
||||
$exp = HTTP::respJson(['folders' => [$out1]]);
|
||||
$this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in)));
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\TestCase\REST\NextcloudNews;
|
|||
use JKingWeb\Arsse\Misc\HTTP;
|
||||
use JKingWeb\Arsse\REST\NextcloudNews\Versions;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\NextcloudNews\Versions */
|
||||
class TestVersions extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -25,7 +24,7 @@ class TestVersions extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testFetchVersionList(): void {
|
||||
$exp = new Response(['apiLevels' => ['v1-2']]);
|
||||
$exp = HTTP::respJson(['apiLevels' => ['v1-2']]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/"));
|
||||
$this->assertMessage($exp, $this->req("GET", "/"));
|
||||
$this->assertMessage($exp, $this->req("GET", "/"));
|
||||
|
|
|
@ -18,7 +18,6 @@ use JKingWeb\Arsse\Db\Transaction;
|
|||
use JKingWeb\Arsse\REST\TinyTinyRSS\API;
|
||||
use JKingWeb\Arsse\Feed\Exception as FeedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\API<extended>
|
||||
* @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Exception */
|
||||
|
@ -166,17 +165,17 @@ LONG_STRING;
|
|||
return $this->req($data, "POST", "", null, $user);
|
||||
}
|
||||
|
||||
protected function respGood($content = null, $seq = 0): Response {
|
||||
return new Response([
|
||||
protected function respGood($content = null, $seq = 0): ResponseInterface {
|
||||
return HTTP::respJson([
|
||||
'seq' => $seq,
|
||||
'status' => 0,
|
||||
'content' => $content,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function respErr(string $msg, $content = [], $seq = 0): Response {
|
||||
protected function respErr(string $msg, $content = [], $seq = 0): ResponseInterface {
|
||||
$err = ['error' => $msg];
|
||||
return new Response([
|
||||
return HTTP::respJson([
|
||||
'seq' => $seq,
|
||||
'status' => 1,
|
||||
'content' => array_merge($err, $content, $err),
|
||||
|
@ -1815,7 +1814,7 @@ LONG_STRING;
|
|||
]));
|
||||
}
|
||||
|
||||
protected function outputHeadlines(int $id): Response {
|
||||
protected function outputHeadlines(int $id): ResponseInterface {
|
||||
return $this->respGood([
|
||||
[
|
||||
'id' => $id,
|
||||
|
|
|
@ -19,12 +19,12 @@ use JKingWeb\Arsse\Factory;
|
|||
use JKingWeb\Arsse\Misc\Date;
|
||||
use JKingWeb\Arsse\Misc\ValueInfo;
|
||||
use JKingWeb\Arsse\Misc\URL;
|
||||
use JKingWeb\Arsse\Misc\HTTP;
|
||||
use Psr\Http\Message\MessageInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\Response\XmlResponse;
|
||||
|
||||
/** @coversNothing */
|
||||
|
@ -191,12 +191,13 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
$this->assertSame($exp->getMethod(), $act->getMethod(), $text);
|
||||
$this->assertSame($exp->getRequestTarget(), $act->getRequestTarget(), $text);
|
||||
}
|
||||
if ($exp instanceof JsonResponse) {
|
||||
$this->assertInstanceOf(JsonResponse::class, $act, $text);
|
||||
$this->assertEquals($exp->getPayload(), $act->getPayload(), $text);
|
||||
$this->assertSame($exp->getPayload(), $act->getPayload(), $text);
|
||||
} elseif ($exp instanceof XmlResponse) {
|
||||
$this->assertInstanceOf(XmlResponse::class, $act, $text);
|
||||
if ($exp instanceof ResponseInterface && HTTP::matchType($exp, "application/json", "text/json", "+json")) {
|
||||
$expBody = json_decode((string) $exp->getBody(), true);
|
||||
$actBody = json_decode((string) $act->getBody(), true);
|
||||
$this->assertSame(\JSON_ERROR_NONE, json_last_error(), "Response body is not valid JSON");
|
||||
$this->assertEquals($expBody, $actBody, $text);
|
||||
$this->assertSame($expBody, $actBody, $text);
|
||||
} elseif ($exp instanceof ResponseInterface && HTTP::matchType($exp, "application/xml", "text/xml", "+xml")) {
|
||||
$this->assertXmlStringEqualsXmlString((string) $exp->getBody(), (string) $act->getBody(), $text);
|
||||
} else {
|
||||
$this->assertSame((string) $exp->getBody(), (string) $act->getBody(), $text);
|
||||
|
|
Loading…
Reference in a new issue