1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-23 09:02:41 +00:00

Merge branch 'urlnorm'

This commit is contained in:
J. King 2019-09-05 13:58:14 -04:00
commit b0517ddda1
70 changed files with 887 additions and 983 deletions

View file

@ -2,7 +2,6 @@
use Robo\Result; use Robo\Result;
const BASE = __DIR__.\DIRECTORY_SEPARATOR; const BASE = __DIR__.\DIRECTORY_SEPARATOR;
const BASE_TEST = BASE."tests".\DIRECTORY_SEPARATOR; const BASE_TEST = BASE."tests".\DIRECTORY_SEPARATOR;
define("IS_WIN", defined("PHP_WINDOWS_VERSION_MAJOR")); define("IS_WIN", defined("PHP_WINDOWS_VERSION_MAJOR"));

View file

@ -12,6 +12,7 @@ use JKingWeb\Arsse\Misc\Query;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Misc\ValueInfo; use JKingWeb\Arsse\Misc\ValueInfo;
use JKingWeb\Arsse\Misc\URL;
/** The high-level interface with the database /** The high-level interface with the database
* *
@ -992,6 +993,8 @@ class Database {
* @param boolean $discover Whether to perform newsfeed discovery if $url points to an HTML document * @param boolean $discover Whether to perform newsfeed discovery if $url points to an HTML document
*/ */
public function feedAdd(string $url, string $fetchUser = "", string $fetchPassword = "", bool $discover = true): int { public function feedAdd(string $url, string $fetchUser = "", string $fetchPassword = "", bool $discover = true): int {
// normalize the input URL
$url = URL::normalize($url);
// check to see if the feed already exists // check to see if the feed already exists
$check = $this->db->prepare("SELECT id from arsse_feeds where url = ? and username = ? and password = ?", "str", "str", "str"); $check = $this->db->prepare("SELECT id from arsse_feeds where url = ? and username = ? and password = ?", "str", "str", "str");
$feedID = $check->run($url, $fetchUser, $fetchPassword)->getValue(); $feedID = $check->run($url, $fetchUser, $fetchPassword)->getValue();

View file

@ -7,10 +7,7 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL; namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
use ExceptionBuilder; use ExceptionBuilder;

View file

@ -8,8 +8,6 @@ namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class PDODriver extends Driver { class PDODriver extends Driver {
use \JKingWeb\Arsse\Db\PDODriver; use \JKingWeb\Arsse\Db\PDODriver;

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL; namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Db\Exception;
class Result extends \JKingWeb\Arsse\Db\AbstractResult { class Result extends \JKingWeb\Arsse\Db\AbstractResult {
protected $st; protected $st;
protected $set; protected $set;

View file

@ -6,10 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL; namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement { class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
use ExceptionBuilder; use ExceptionBuilder;

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db; namespace JKingWeb\Arsse\Db;
use JKingWeb\Arsse\Db\Exception;
class PDOResult extends AbstractResult { class PDOResult extends AbstractResult {
protected $set; protected $set;
protected $db; protected $db;

View file

@ -7,10 +7,7 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL; namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
use Dispatch; use Dispatch;

View file

@ -8,8 +8,6 @@ namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class PDODriver extends Driver { class PDODriver extends Driver {
use \JKingWeb\Arsse\Db\PDODriver; use \JKingWeb\Arsse\Db\PDODriver;

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL; namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Db\Exception;
class Result extends \JKingWeb\Arsse\Db\AbstractResult { class Result extends \JKingWeb\Arsse\Db\AbstractResult {
protected $db; protected $db;
protected $r; protected $r;

View file

@ -6,10 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL; namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement { class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
use Dispatch; use Dispatch;

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db; namespace JKingWeb\Arsse\Db;
use JKingWeb\Arsse\Db\Exception;
class ResultAggregate extends AbstractResult { class ResultAggregate extends AbstractResult {
protected $data; protected $data;
protected $index = 0; protected $index = 0;

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db; namespace JKingWeb\Arsse\Db;
use JKingWeb\Arsse\Db\Exception;
class ResultEmpty extends AbstractResult { class ResultEmpty extends AbstractResult {
protected $changes = 0; protected $changes = 0;
protected $id = 0; protected $id = 0;

View file

@ -8,8 +8,6 @@ namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
use ExceptionBuilder; use ExceptionBuilder;

View file

@ -8,8 +8,6 @@ namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class PDODriver extends AbstractPDODriver { class PDODriver extends AbstractPDODriver {
protected $db; protected $db;

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3; namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Db\Exception;
class Result extends \JKingWeb\Arsse\Db\AbstractResult { class Result extends \JKingWeb\Arsse\Db\AbstractResult {
protected $st; protected $st;
protected $set; protected $set;

View file

@ -6,10 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3; namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Db\ExceptionTimeout;
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement { class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
use ExceptionBuilder; use ExceptionBuilder;

140
lib/Misc/URL.php Normal file
View file

@ -0,0 +1,140 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
/**
* A collection of functions for manipulating URLs
*/
class URL {
/** Normalizes a URL
*
* Normalizations performed are:
*
* - Lowercasing scheme
* - Lowercasing ASCII host names
* - IDN normalization
* - IPv6 address normalization
* - Resolution of relative path segments
* - Discarding empty path segments
* - Discarding empty queries
* - Generic percent-encoding normalization
* - Fragment discarding
*
* It does NOT drop trailing slashes from paths, nor does it perform Unicode normalization or context-aware percent-encoding normalization
*
* @param string $url The URL to normalize
* @param string $u Username to add to the URL, replacing any existing credentials
* @param string $p Password to add to the URL, if a username is specified
*/
public static function normalize(string $url, string $u = null, string $p = null): string {
extract(parse_url($url));
$out = "";
if (isset($scheme)) {
$out .= strtolower($scheme).":";
}
if (isset($host)) {
$out .= "//";
if (strlen($u ?? "")) {
$out .= self::normalizeEncoding(rawurlencode($u));
if (strlen($p ?? "")) {
$out .= ":".self::normalizeEncoding(rawurlencode($p));
}
$out .= "@";
} elseif (strlen($user ?? "")) {
$out .= self::normalizeEncoding($user);
if (strlen($pass ?? "")) {
$out .= ":".self::normalizeEncoding($pass);
}
$out .= "@";
}
$out .= self::normalizeHost($host);
$out .= isset($port) ? ":$port" : "";
}
$out .= self::normalizePath($path ?? "", isset($host));
if (isset($query) && strlen($query)) {
$out .= "?".self::normalizeEncoding($query);
}
return $out;
}
/** Perform percent-encoding normalization for a given URL component */
protected static function normalizeEncoding(string $part): string {
$pos = 0;
$end = strlen($part);
$out = "";
// process each character in sequence
while ($pos < $end) {
$c = $part[$pos];
if ($c === "%") {
// the % character signals an encoded character...
$d = substr($part, $pos+1, 2);
if (!preg_match("/^[0-9a-fA-F]{2}$/", $d)) {
// unless there are fewer than two characters left in the string or the two characters are not hex digits
$d = ord($c);
} else {
$d = hexdec($d);
$pos += 2;
}
} else {
$d = ord($c);
}
$dc = chr($d);
if ($d < 0x21 || $d > 0x7E || $d == 0x25) {
// these characters are always encoded
$out .= "%".strtoupper(dechex($d));
} elseif (preg_match("/[a-zA-Z0-9\._~-]/", $dc)) {
// these characters are never encoded
$out .= $dc;
} else {
// these characters are passed through as-is
if ($c === "%") {
$out .= "%".strtoupper(dechex($d));
} else {
$out .= $c;
}
}
$pos++;
}
return $out;
}
/** Normalizes a hostname per IDNA:2008 */
protected static function normalizeHost(string $host): string {
if ($host[0] === "[" && substr($host, -1) === "]") {
// normalize IPv6 addresses
$addr = @inet_pton(substr($host, 1, strlen($host) - 2));
if ($addr !== false) {
return "[".inet_ntop($addr)."]";
}
}
$idn = idn_to_ascii($host, \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46);
return $idn !== false ? idn_to_utf8($idn, \IDNA_NONTRANSITIONAL_TO_UNICODE, \INTL_IDNA_VARIANT_UTS46) : $host;
}
/** Normalizes the whole path segment to remove empty segments and relative segments */
protected static function normalizePath(string $path, bool $hasHost): string {
$parts = explode("/", self::normalizeEncoding($path));
$absolute = ($hasHost || $path[0] === "/");
$index = (substr($path, -1) === "/");
$out = [];
foreach ($parts as $p) {
switch ($p) {
case "":
case ".":
break;
case "..":
array_pop($out);
break;
default:
$out[] = $p;
}
}
$out = implode("/", $out);
$out = ($absolute ? "/" : "").$out.($index ? "/" : "");
return str_replace("//", "/", $out);
}
}

View file

@ -7,10 +7,10 @@ declare(strict_types=1);
namespace JKingWeb\Arsse; namespace JKingWeb\Arsse;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Misc\URL;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\ServerRequestFactory; use Zend\Diactoros\ServerRequestFactory;
use Zend\Diactoros\Response\EmptyResponse; use Zend\Diactoros\Response\EmptyResponse;
@ -103,7 +103,7 @@ class REST {
return (strlen($a['match']) <=> strlen($b['match'])) * -1; return (strlen($a['match']) <=> strlen($b['match'])) * -1;
}); });
// normalize the target URL // normalize the target URL
$url = REST\Target::normalize($url); $url = URL::normalize($url);
// find a match // find a match
foreach ($map as $id => $api) { foreach ($map as $id => $api) {
// first try a simple substring match // first try a simple substring match

View file

@ -7,17 +7,10 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\REST\Fever; namespace JKingWeb\Arsse\REST\Fever;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\User;
use JKingWeb\Arsse\Service;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Misc\ValueInfo as V; use JKingWeb\Arsse\Misc\ValueInfo as V;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\AbstractException;
use JKingWeb\Arsse\Db\ExceptionInput; use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\REST\Target;
use JKingWeb\Arsse\REST\Exception404;
use JKingWeb\Arsse\REST\Exception405;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -234,7 +227,6 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
} }
return $p; return $p;
} }
protected function logIn(string $hash): bool { protected function logIn(string $hash): bool {

View file

@ -7,15 +7,12 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\REST\NextCloudNews; namespace JKingWeb\Arsse\REST\NextCloudNews;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\User;
use JKingWeb\Arsse\Service; use JKingWeb\Arsse\Service;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Misc\ValueInfo; use JKingWeb\Arsse\Misc\ValueInfo;
use JKingWeb\Arsse\AbstractException; use JKingWeb\Arsse\AbstractException;
use JKingWeb\Arsse\Db\ExceptionInput; use JKingWeb\Arsse\Db\ExceptionInput;
use JKingWeb\Arsse\Feed\Exception as FeedException; use JKingWeb\Arsse\Feed\Exception as FeedException;
use JKingWeb\Arsse\REST\Target;
use JKingWeb\Arsse\REST\Exception404; use JKingWeb\Arsse\REST\Exception404;
use JKingWeb\Arsse\REST\Exception405; use JKingWeb\Arsse\REST\Exception405;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@ -85,11 +82,11 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} else { } else {
return new EmptyResponse(401); return new EmptyResponse(401);
} }
// explode and normalize the URL path // get the request path only; this is assumed to already be normalized
$target = new Target($req->getRequestTarget()); $target = parse_url($req->getRequestTarget())['path'] ?? "";
// handle HTTP OPTIONS requests // handle HTTP OPTIONS requests
if ($req->getMethod() === "OPTIONS") { if ($req->getMethod() === "OPTIONS") {
return $this->handleHTTPOptions((string) $target); return $this->handleHTTPOptions($target);
} }
// normalize the input // normalize the input
$data = (string) $req->getBody(); $data = (string) $req->getBody();
@ -115,7 +112,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
$data = $this->normalizeInput(array_merge($req->getQueryParams(), $data), $this->validInput, "unix"); $data = $this->normalizeInput(array_merge($req->getQueryParams(), $data), $this->validInput, "unix");
// check to make sure the requested function is implemented // check to make sure the requested function is implemented
try { try {
$func = $this->chooseCall((string) $target, $req->getMethod()); $func = $this->chooseCall($target, $req->getMethod());
} catch (Exception404 $e) { } catch (Exception404 $e) {
return new EmptyResponse(404); return new EmptyResponse(404);
} catch (Exception405 $e) { } catch (Exception405 $e) {
@ -126,7 +123,8 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
// dispatch // dispatch
try { try {
return $this->$func($target->path, $data); $path = explode("/", ltrim($target, "/"));
return $this->$func($path, $data);
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
} catch (Exception $e) { } catch (Exception $e) {
// if there was a REST exception return 400 // if there was a REST exception return 400
@ -139,18 +137,14 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
protected function normalizePathIds(string $url): string { protected function normalizePathIds(string $url): string {
// first parse the URL and perform syntactic normalization $path = explode("/", $url);
$target = new Target($url);
// any path components which are database IDs (integers greater than zero) should be replaced with "1", for easier comparison (we don't care about the specific ID) // any path components which are database IDs (integers greater than zero) should be replaced with "1", for easier comparison (we don't care about the specific ID)
for ($a = 0; $a < sizeof($target->path); $a++) { for ($a = 0; $a < sizeof($path); $a++) {
if (ValueInfo::id($target->path[$a])) { if (ValueInfo::id($path[$a])) {
$target->path[$a] = "1"; $path[$a] = "1";
} }
} }
// discard any fragment ID (there shouldn't be any) and query string (the query is available in the request itself) return implode("/", $path);
$target->fragment = "";
$target->query = "";
return (string) $target;
} }
protected function chooseCall(string $url, string $method): string { protected function chooseCall(string $url, string $method): string {

View file

@ -1,131 +0,0 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST;
use JKingWeb\Arsse\Misc\ValueInfo;
class Target {
public $relative = false;
public $index = false;
public $path = [];
public $query = "";
public $fragment = "";
public function __construct(string $target) {
$target = $this->parseFragment($target);
$target = $this->parseQuery($target);
$this->path = $this->parsePath($target);
}
public function __toString(): string {
$out = "";
$path = [];
foreach ($this->path as $segment) {
if (is_null($segment)) {
if (!$path) {
$path[] = "..";
} else {
continue;
}
} elseif ($segment === ".") {
$path[] = "%2E";
} elseif ($segment === "..") {
$path[] = "%2E%2E";
} else {
$path[] = rawurlencode(ValueInfo::normalize($segment, ValueInfo::T_STRING));
}
}
$path = implode("/", $path);
if (!$this->relative) {
$out .= "/";
}
$out .= $path;
if ($this->index && strlen($path)) {
$out .= "/";
}
if (strlen($this->query)) {
$out .= "?".$this->query;
}
if (strlen($this->fragment)) {
$out .= "#".rawurlencode($this->fragment);
}
return $out;
}
public static function normalize(string $target): string {
return (string) new self($target);
}
protected function parseFragment(string $target): string {
// store and strip off any fragment identifier and return the target without a fragment
$pos = strpos($target, "#");
if ($pos !== false) {
$this->fragment = rawurldecode(substr($target, $pos + 1));
$target = substr($target, 0, $pos);
}
return $target;
}
protected function parseQuery(string $target): string {
// store and strip off any query string and return the target without a query
// note that the function assumes any fragment identifier has already been stripped off
// unlike the other parts the query string is currently neither parsed nor normalized
$pos = strpos($target, "?");
if ($pos !== false) {
$this->query = substr($target, $pos + 1);
$target = substr($target, 0, $pos);
}
return $target;
}
protected function parsePath(string $target): array {
// note that the function assumes any fragment identifier or query has already been stripped off
// syntax-based normalization is applied to the path segments (see RFC 3986 sec. 6.2.2)
// duplicate slashes are NOT collapsed
if (substr($target, 0, 1) === "/") {
// if the path starts with a slash, strip it off
$target = substr($target, 1);
} else {
// otherwise this is a relative target
$this->relative = true;
}
if (!strlen($target)) {
// if the target is an empty string, this is an index target
$this->index = true;
} elseif (substr($target, -1, 1) === "/") {
// if the path ends in a slash, this is an index target and the slash should be stripped off
$this->index = true;
$target = substr($target, 0, strlen($target) -1);
}
// after stripping, explode the path parts
if (strlen($target)) {
$target = explode("/", $target);
$out = [];
// resolve relative path segments and decode each retained segment
foreach ($target as $index => $segment) {
if ($segment === ".") {
// self-referential segments can be ignored
continue;
} elseif ($segment === "..") {
if ($index == 0) {
// if the first path segment refers to its parent (which we don't know about) we cannot output a correct path, so we do the best we can
$out[] = null;
} else {
// for any other segments after the first we pop off the last stored segment
array_pop($out);
}
} else {
// any other segment is decoded and retained
$out[] = rawurldecode($segment);
}
}
return $out;
} else {
return [];
}
}
}

View file

@ -14,14 +14,13 @@ use JKingWeb\Arsse\Service;
use JKingWeb\Arsse\CLI; use JKingWeb\Arsse\CLI;
use JKingWeb\Arsse\REST\Fever\User as FeverUser; use JKingWeb\Arsse\REST\Fever\User as FeverUser;
use JKingWeb\Arsse\ImportExport\OPML; use JKingWeb\Arsse\ImportExport\OPML;
use Phake;
/** @covers \JKingWeb\Arsse\CLI */ /** @covers \JKingWeb\Arsse\CLI */
class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest { class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() { public function setUp() {
self::clearData(false); self::clearData(false);
$this->cli = Phake::partialMock(CLI::class); $this->cli = \Phake::partialMock(CLI::class);
Phake::when($this->cli)->logError->thenReturn(null); \Phake::when($this->cli)->logError->thenReturn(null);
} }
public function assertConsole(CLI $cli, string $command, int $exitStatus, string $output = "", bool $pattern = false) { public function assertConsole(CLI $cli, string $command, int $exitStatus, string $output = "", bool $pattern = false) {
@ -70,33 +69,33 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testStartTheDaemon() { public function testStartTheDaemon() {
$srv = Phake::mock(Service::class); $srv = \Phake::mock(Service::class);
Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable); \Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv); \Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv);
$this->assertConsole($this->cli, "arsse.php daemon", 0); $this->assertConsole($this->cli, "arsse.php daemon", 0);
$this->assertLoaded(true); $this->assertLoaded(true);
Phake::verify($srv)->watch(true); \Phake::verify($srv)->watch(true);
Phake::verify($this->cli)->getInstance(Service::class); \Phake::verify($this->cli)->getInstance(Service::class);
} }
public function testRefreshAllFeeds() { public function testRefreshAllFeeds() {
$srv = Phake::mock(Service::class); $srv = \Phake::mock(Service::class);
Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable); \Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv); \Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv);
$this->assertConsole($this->cli, "arsse.php feed refresh-all", 0); $this->assertConsole($this->cli, "arsse.php feed refresh-all", 0);
$this->assertLoaded(true); $this->assertLoaded(true);
Phake::verify($srv)->watch(false); \Phake::verify($srv)->watch(false);
Phake::verify($this->cli)->getInstance(Service::class); \Phake::verify($this->cli)->getInstance(Service::class);
} }
/** @dataProvider provideFeedUpdates */ /** @dataProvider provideFeedUpdates */
public function testRefreshAFeed(string $cmd, int $exitStatus, string $output) { public function testRefreshAFeed(string $cmd, int $exitStatus, string $output) {
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
Phake::when(Arsse::$db)->feedUpdate(1, true)->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate(1, true)->thenReturn(true);
Phake::when(Arsse::$db)->feedUpdate(2, true)->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/", new \PicoFeed\Client\InvalidUrlException)); \Phake::when(Arsse::$db)->feedUpdate(2, true)->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/", new \PicoFeed\Client\InvalidUrlException));
$this->assertConsole($this->cli, $cmd, $exitStatus, $output); $this->assertConsole($this->cli, $cmd, $exitStatus, $output);
$this->assertLoaded(true); $this->assertLoaded(true);
Phake::verify(Arsse::$db)->feedUpdate; \Phake::verify(Arsse::$db)->feedUpdate;
} }
public function provideFeedUpdates() { public function provideFeedUpdates() {
@ -108,14 +107,14 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideDefaultConfigurationSaves */ /** @dataProvider provideDefaultConfigurationSaves */
public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file) { public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file) {
$conf = Phake::mock(Conf::class); $conf = \Phake::mock(Conf::class);
Phake::when($conf)->exportFile("php://output", true)->thenReturn(true); \Phake::when($conf)->exportFile("php://output", true)->thenReturn(true);
Phake::when($conf)->exportFile("good.conf", true)->thenReturn(true); \Phake::when($conf)->exportFile("good.conf", true)->thenReturn(true);
Phake::when($conf)->exportFile("bad.conf", true)->thenThrow(new \JKingWeb\Arsse\Conf\Exception("fileUnwritable")); \Phake::when($conf)->exportFile("bad.conf", true)->thenThrow(new \JKingWeb\Arsse\Conf\Exception("fileUnwritable"));
Phake::when($this->cli)->getInstance(Conf::class)->thenReturn($conf); \Phake::when($this->cli)->getInstance(Conf::class)->thenReturn($conf);
$this->assertConsole($this->cli, $cmd, $exitStatus); $this->assertConsole($this->cli, $cmd, $exitStatus);
$this->assertLoaded(false); $this->assertLoaded(false);
Phake::verify($conf)->exportFile($file, true); \Phake::verify($conf)->exportFile($file, true);
} }
public function provideDefaultConfigurationSaves() { public function provideDefaultConfigurationSaves() {
@ -283,14 +282,14 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideOpmlExports */ /** @dataProvider provideOpmlExports */
public function testExportToOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat) { public function testExportToOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat) {
$opml = Phake::mock(OPML::class); $opml = \Phake::mock(OPML::class);
Phake::when($opml)->exportFile("php://output", $user, $flat)->thenReturn(true); \Phake::when($opml)->exportFile("php://output", $user, $flat)->thenReturn(true);
Phake::when($opml)->exportFile("good.opml", $user, $flat)->thenReturn(true); \Phake::when($opml)->exportFile("good.opml", $user, $flat)->thenReturn(true);
Phake::when($opml)->exportFile("bad.opml", $user, $flat)->thenThrow(new \JKingWeb\Arsse\ImportExport\Exception("fileUnwritable")); \Phake::when($opml)->exportFile("bad.opml", $user, $flat)->thenThrow(new \JKingWeb\Arsse\ImportExport\Exception("fileUnwritable"));
Phake::when($this->cli)->getInstance(OPML::class)->thenReturn($opml); \Phake::when($this->cli)->getInstance(OPML::class)->thenReturn($opml);
$this->assertConsole($this->cli, $cmd, $exitStatus); $this->assertConsole($this->cli, $cmd, $exitStatus);
$this->assertLoaded(true); $this->assertLoaded(true);
Phake::verify($opml)->exportFile($file, $user, $flat); \Phake::verify($opml)->exportFile($file, $user, $flat);
} }
public function provideOpmlExports() { public function provideOpmlExports() {
@ -324,14 +323,14 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideOpmlImports */ /** @dataProvider provideOpmlImports */
public function testImportFromOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat, bool $replace) { public function testImportFromOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat, bool $replace) {
$opml = Phake::mock(OPML::class); $opml = \Phake::mock(OPML::class);
Phake::when($opml)->importFile("php://input", $user, $flat, $replace)->thenReturn(true); \Phake::when($opml)->importFile("php://input", $user, $flat, $replace)->thenReturn(true);
Phake::when($opml)->importFile("good.opml", $user, $flat, $replace)->thenReturn(true); \Phake::when($opml)->importFile("good.opml", $user, $flat, $replace)->thenReturn(true);
Phake::when($opml)->importFile("bad.opml", $user, $flat, $replace)->thenThrow(new \JKingWeb\Arsse\ImportExport\Exception("fileUnreadable")); \Phake::when($opml)->importFile("bad.opml", $user, $flat, $replace)->thenThrow(new \JKingWeb\Arsse\ImportExport\Exception("fileUnreadable"));
Phake::when($this->cli)->getInstance(OPML::class)->thenReturn($opml); \Phake::when($this->cli)->getInstance(OPML::class)->thenReturn($opml);
$this->assertConsole($this->cli, $cmd, $exitStatus); $this->assertConsole($this->cli, $cmd, $exitStatus);
$this->assertLoaded(true); $this->assertLoaded(true);
Phake::verify($opml)->importFile($file, $user, $flat, $replace); \Phake::verify($opml)->importFile($file, $user, $flat, $replace);
} }
public function provideOpmlImports() { public function provideOpmlImports() {

View file

@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Test\Database; use JKingWeb\Arsse\Test\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\User; use JKingWeb\Arsse\User;
use Phake;
abstract class Base extends \JKingWeb\Arsse\Test\AbstractTest { abstract class Base extends \JKingWeb\Arsse\Test\AbstractTest {
use SeriesMiscellany; use SeriesMiscellany;
@ -73,8 +72,8 @@ abstract class Base extends \JKingWeb\Arsse\Test\AbstractTest {
Arsse::$db = new Database(static::$drv); Arsse::$db = new Database(static::$drv);
Arsse::$db->driverSchemaUpdate(); Arsse::$db->driverSchemaUpdate();
// create a mock user manager // create a mock user manager
Arsse::$user = Phake::mock(User::class); Arsse::$user = \Phake::mock(User::class);
Phake::when(Arsse::$user)->authorize->thenReturn(true); \Phake::when(Arsse::$user)->authorize->thenReturn(true);
// call the series-specific setup method // call the series-specific setup method
$setUp = "setUp".$this->series; $setUp = "setUp".$this->series;
$this->$setUp(); $this->$setUp();

View file

@ -11,7 +11,6 @@ use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Misc\ValueInfo; use JKingWeb\Arsse\Misc\ValueInfo;
use Phake;
trait SeriesArticle { trait SeriesArticle {
protected function setUpSeriesArticle() { protected function setUpSeriesArticle() {
@ -597,7 +596,7 @@ trait SeriesArticle {
} }
public function testListArticlesWithoutAuthority() { public function testListArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleList($this->user); Arsse::$db->articleList($this->user);
} }
@ -966,7 +965,7 @@ trait SeriesArticle {
} }
public function testMarkArticlesWithoutAuthority() { public function testMarkArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleMark($this->user, ['read'=>false]); Arsse::$db->articleMark($this->user, ['read'=>false]);
} }
@ -979,7 +978,7 @@ trait SeriesArticle {
} }
public function testCountArticlesWithoutAuthority() { public function testCountArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleCount($this->user); Arsse::$db->articleCount($this->user);
} }
@ -992,7 +991,7 @@ trait SeriesArticle {
} }
public function testFetchStarredCountsWithoutAuthority() { public function testFetchStarredCountsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleStarred($this->user); Arsse::$db->articleStarred($this->user);
} }
@ -1008,7 +1007,7 @@ trait SeriesArticle {
} }
public function testFetchLatestEditionWithoutAuthority() { public function testFetchLatestEditionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->editionLatest($this->user); Arsse::$db->editionLatest($this->user);
} }
@ -1028,7 +1027,7 @@ trait SeriesArticle {
} }
public function testListTheLabelsOfAnArticleWithoutAuthority() { public function testListTheLabelsOfAnArticleWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleLabelsGet("john.doe@example.com", 1); Arsse::$db->articleLabelsGet("john.doe@example.com", 1);
} }
@ -1048,7 +1047,7 @@ trait SeriesArticle {
} }
public function testListTheCategoriesOfAnArticleWithoutAuthority() { public function testListTheCategoriesOfAnArticleWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleCategoriesGet($this->user, 19); Arsse::$db->articleCategoriesGet($this->user, 19);
} }

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Database; namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use Phake;
trait SeriesCleanup { trait SeriesCleanup {
protected function setUpSeriesCleanup() { protected function setUpSeriesCleanup() {

View file

@ -7,9 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Database; namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Feed;
use JKingWeb\Arsse\Feed\Exception as FeedException;
use Phake;
trait SeriesFeed { trait SeriesFeed {
protected function setUpSeriesFeed() { protected function setUpSeriesFeed() {

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Database; namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use Phake;
trait SeriesFolder { trait SeriesFolder {
protected function setUpSeriesFolder() { protected function setUpSeriesFolder() {
@ -102,7 +101,7 @@ trait SeriesFolder {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$folderID = $this->nextID("arsse_folders"); $folderID = $this->nextID("arsse_folders");
$this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "Entertainment"])); $this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "Entertainment"]));
Phake::verify(Arsse::$user)->authorize($user, "folderAdd"); \Phake::verify(Arsse::$user)->authorize($user, "folderAdd");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
$state['arsse_folders']['rows'][] = [$folderID, $user, null, "Entertainment"]; $state['arsse_folders']['rows'][] = [$folderID, $user, null, "Entertainment"];
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -117,7 +116,7 @@ trait SeriesFolder {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$folderID = $this->nextID("arsse_folders"); $folderID = $this->nextID("arsse_folders");
$this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "GNOME", 'parent' => 2])); $this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "GNOME", 'parent' => 2]));
Phake::verify(Arsse::$user)->authorize($user, "folderAdd"); \Phake::verify(Arsse::$user)->authorize($user, "folderAdd");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
$state['arsse_folders']['rows'][] = [$folderID, $user, 2, "GNOME"]; $state['arsse_folders']['rows'][] = [$folderID, $user, 2, "GNOME"];
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -154,7 +153,7 @@ trait SeriesFolder {
} }
public function testAddAFolderWithoutAuthority() { public function testAddAFolderWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology"]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology"]);
} }
@ -171,9 +170,9 @@ trait SeriesFolder {
$this->assertResult($exp, Arsse::$db->folderList("jane.doe@example.com", null, false)); $this->assertResult($exp, Arsse::$db->folderList("jane.doe@example.com", null, false));
$exp = []; $exp = [];
$this->assertResult($exp, Arsse::$db->folderList("admin@example.net", null, false)); $this->assertResult($exp, Arsse::$db->folderList("admin@example.net", null, false));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderList"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderList");
Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList"); \Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList");
Phake::verify(Arsse::$user)->authorize("admin@example.net", "folderList"); \Phake::verify(Arsse::$user)->authorize("admin@example.net", "folderList");
} }
public function testListFoldersRecursively() { public function testListFoldersRecursively() {
@ -193,8 +192,8 @@ trait SeriesFolder {
$this->assertResult($exp, Arsse::$db->folderList("john.doe@example.com", 1, true)); $this->assertResult($exp, Arsse::$db->folderList("john.doe@example.com", 1, true));
$exp = []; $exp = [];
$this->assertResult($exp, Arsse::$db->folderList("jane.doe@example.com", 4, true)); $this->assertResult($exp, Arsse::$db->folderList("jane.doe@example.com", 4, true));
Phake::verify(Arsse::$user, Phake::times(2))->authorize("john.doe@example.com", "folderList"); \Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "folderList");
Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList"); \Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList");
} }
public function testListFoldersOfAMissingParent() { public function testListFoldersOfAMissingParent() {
@ -208,14 +207,14 @@ trait SeriesFolder {
} }
public function testListFoldersWithoutAuthority() { public function testListFoldersWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderList("john.doe@example.com"); Arsse::$db->folderList("john.doe@example.com");
} }
public function testRemoveAFolder() { public function testRemoveAFolder() {
$this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 6)); $this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 6));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
array_pop($state['arsse_folders']['rows']); array_pop($state['arsse_folders']['rows']);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -223,7 +222,7 @@ trait SeriesFolder {
public function testRemoveAFolderTree() { public function testRemoveAFolderTree() {
$this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 1)); $this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 1));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
foreach ([0,1,2,5] as $index) { foreach ([0,1,2,5] as $index) {
unset($state['arsse_folders']['rows'][$index]); unset($state['arsse_folders']['rows'][$index]);
@ -247,7 +246,7 @@ trait SeriesFolder {
} }
public function testRemoveAFolderWithoutAuthority() { public function testRemoveAFolderWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderRemove("john.doe@example.com", 1); Arsse::$db->folderRemove("john.doe@example.com", 1);
} }
@ -259,7 +258,7 @@ trait SeriesFolder {
'parent' => 2, 'parent' => 2,
]; ];
$this->assertArraySubset($exp, Arsse::$db->folderPropertiesGet("john.doe@example.com", 6)); $this->assertArraySubset($exp, Arsse::$db->folderPropertiesGet("john.doe@example.com", 6));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesGet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesGet");
} }
public function testGetThePropertiesOfAMissingFolder() { public function testGetThePropertiesOfAMissingFolder() {
@ -278,7 +277,7 @@ trait SeriesFolder {
} }
public function testGetThePropertiesOfAFolderWithoutAuthority() { public function testGetThePropertiesOfAFolderWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderPropertiesGet("john.doe@example.com", 1); Arsse::$db->folderPropertiesGet("john.doe@example.com", 1);
} }
@ -289,7 +288,7 @@ trait SeriesFolder {
public function testRenameAFolder() { public function testRenameAFolder() {
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => "Opinion"])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => "Opinion"]));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
$state['arsse_folders']['rows'][5][3] = "Opinion"; $state['arsse_folders']['rows'][5][3] = "Opinion";
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -316,7 +315,7 @@ trait SeriesFolder {
public function testMoveAFolder() { public function testMoveAFolder() {
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => 5])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => 5]));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
$state['arsse_folders']['rows'][5][2] = 5; // parent should have changed $state['arsse_folders']['rows'][5][2] = 5; // parent should have changed
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -373,7 +372,7 @@ trait SeriesFolder {
} }
public function testSetThePropertiesOfAFolderWithoutAuthority() { public function testSetThePropertiesOfAFolderWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => null]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => null]);
} }

View file

@ -9,8 +9,6 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Misc\Date;
use Phake;
trait SeriesLabel { trait SeriesLabel {
protected function setUpSeriesLabel() { protected function setUpSeriesLabel() {
@ -254,7 +252,7 @@ trait SeriesLabel {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$labelID = $this->nextID("arsse_labels"); $labelID = $this->nextID("arsse_labels");
$this->assertSame($labelID, Arsse::$db->labelAdd($user, ['name' => "Entertaining"])); $this->assertSame($labelID, Arsse::$db->labelAdd($user, ['name' => "Entertaining"]));
Phake::verify(Arsse::$user)->authorize($user, "labelAdd"); \Phake::verify(Arsse::$user)->authorize($user, "labelAdd");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
$state['arsse_labels']['rows'][] = [$labelID, $user, "Entertaining"]; $state['arsse_labels']['rows'][] = [$labelID, $user, "Entertaining"];
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -281,7 +279,7 @@ trait SeriesLabel {
} }
public function testAddALabelWithoutAuthority() { public function testAddALabelWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Boring"]); Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Boring"]);
} }
@ -299,18 +297,18 @@ trait SeriesLabel {
$this->assertResult($exp, Arsse::$db->labelList("jane.doe@example.com")); $this->assertResult($exp, Arsse::$db->labelList("jane.doe@example.com"));
$exp = []; $exp = [];
$this->assertResult($exp, Arsse::$db->labelList("jane.doe@example.com", false)); $this->assertResult($exp, Arsse::$db->labelList("jane.doe@example.com", false));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelList"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelList");
} }
public function testListLabelsWithoutAuthority() { public function testListLabelsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelList("john.doe@example.com"); Arsse::$db->labelList("john.doe@example.com");
} }
public function testRemoveALabel() { public function testRemoveALabel() {
$this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", 1)); $this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", 1));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
array_shift($state['arsse_labels']['rows']); array_shift($state['arsse_labels']['rows']);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -318,7 +316,7 @@ trait SeriesLabel {
public function testRemoveALabelByName() { public function testRemoveALabelByName() {
$this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", "Interesting", true)); $this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", "Interesting", true));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
array_shift($state['arsse_labels']['rows']); array_shift($state['arsse_labels']['rows']);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -345,7 +343,7 @@ trait SeriesLabel {
} }
public function testRemoveALabelWithoutAuthority() { public function testRemoveALabelWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelRemove("john.doe@example.com", 1); Arsse::$db->labelRemove("john.doe@example.com", 1);
} }
@ -359,7 +357,7 @@ trait SeriesLabel {
]; ];
$this->assertArraySubset($exp, Arsse::$db->labelPropertiesGet("john.doe@example.com", 2)); $this->assertArraySubset($exp, Arsse::$db->labelPropertiesGet("john.doe@example.com", 2));
$this->assertArraySubset($exp, Arsse::$db->labelPropertiesGet("john.doe@example.com", "Fascinating", true)); $this->assertArraySubset($exp, Arsse::$db->labelPropertiesGet("john.doe@example.com", "Fascinating", true));
Phake::verify(Arsse::$user, Phake::times(2))->authorize("john.doe@example.com", "labelPropertiesGet"); \Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "labelPropertiesGet");
} }
public function testGetThePropertiesOfAMissingLabel() { public function testGetThePropertiesOfAMissingLabel() {
@ -383,7 +381,7 @@ trait SeriesLabel {
} }
public function testGetThePropertiesOfALabelWithoutAuthority() { public function testGetThePropertiesOfALabelWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelPropertiesGet("john.doe@example.com", 1); Arsse::$db->labelPropertiesGet("john.doe@example.com", 1);
} }
@ -394,7 +392,7 @@ trait SeriesLabel {
public function testRenameALabel() { public function testRenameALabel() {
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"])); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
$state['arsse_labels']['rows'][0][2] = "Curious"; $state['arsse_labels']['rows'][0][2] = "Curious";
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -402,7 +400,7 @@ trait SeriesLabel {
public function testRenameALabelByName() { public function testRenameALabelByName() {
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true)); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
$state['arsse_labels']['rows'][0][2] = "Curious"; $state['arsse_labels']['rows'][0][2] = "Curious";
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -449,7 +447,7 @@ trait SeriesLabel {
} }
public function testSetThePropertiesOfALabelWithoutAuthority() { public function testSetThePropertiesOfALabelWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]); Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]);
} }
@ -477,7 +475,7 @@ trait SeriesLabel {
} }
public function testListLabelledArticlesWithoutAuthority() { public function testListLabelledArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelArticlesGet("john.doe@example.com", 1); Arsse::$db->labelArticlesGet("john.doe@example.com", 1);
} }
@ -543,7 +541,7 @@ trait SeriesLabel {
} }
public function testApplyALabelToArticlesWithoutAuthority() { public function testApplyALabelToArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5])); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]));
} }

View file

@ -8,7 +8,6 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use Phake;
trait SeriesSession { trait SeriesSession {
protected function setUpSeriesSession() { protected function setUpSeriesSession() {
@ -71,7 +70,7 @@ trait SeriesSession {
$state['arsse_sessions']['rows'][3][2] = Date::transform(Date::add(Arsse::$conf->userSessionTimeout, $now), "sql"); $state['arsse_sessions']['rows'][3][2] = Date::transform(Date::add(Arsse::$conf->userSessionTimeout, $now), "sql");
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
// session resumption should not check authorization // session resumption should not check authorization
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertArraySubset($exp1, Arsse::$db->sessionResume("80fa94c1a11f11e78667001e673b2560")); $this->assertArraySubset($exp1, Arsse::$db->sessionResume("80fa94c1a11f11e78667001e673b2560"));
} }
@ -100,7 +99,7 @@ trait SeriesSession {
} }
public function testCreateASessionWithoutAuthority() { public function testCreateASessionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->sessionCreate("jane.doe@example.com"); Arsse::$db->sessionCreate("jane.doe@example.com");
} }
@ -133,7 +132,7 @@ trait SeriesSession {
} }
public function testDestroyASessionWithoutAuthority() { public function testDestroyASessionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->sessionDestroy("jane.doe@example.com", "80fa94c1a11f11e78667001e673b2560"); Arsse::$db->sessionDestroy("jane.doe@example.com", "80fa94c1a11f11e78667001e673b2560");
} }

View file

@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Test\Database; use JKingWeb\Arsse\Test\Database;
use JKingWeb\Arsse\Feed\Exception as FeedException; use JKingWeb\Arsse\Feed\Exception as FeedException;
use Phake;
trait SeriesSubscription { trait SeriesSubscription {
public function setUpSeriesSubscription() { public function setUpSeriesSubscription() {
@ -140,7 +139,7 @@ trait SeriesSubscription {
[3,"http://example.com/feed3", "Ack", "", "",strtotime("now + 1 hour"),strtotime("now + 1 hour"),''], [3,"http://example.com/feed3", "Ack", "", "",strtotime("now + 1 hour"),strtotime("now + 1 hour"),''],
]; ];
// initialize a partial mock of the Database object to later manipulate the feedUpdate method // initialize a partial mock of the Database object to later manipulate the feedUpdate method
Arsse::$db = Phake::partialMock(Database::class, static::$drv); Arsse::$db = \Phake::partialMock(Database::class, static::$drv);
$this->user = "john.doe@example.com"; $this->user = "john.doe@example.com";
} }
@ -151,10 +150,10 @@ trait SeriesSubscription {
public function testAddASubscriptionToAnExistingFeed() { public function testAddASubscriptionToAnExistingFeed() {
$url = "http://example.com/feed1"; $url = "http://example.com/feed1";
$subID = $this->nextID("arsse_subscriptions"); $subID = $this->nextID("arsse_subscriptions");
Phake::when(Arsse::$db)->feedUpdate->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url)); $this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url));
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd");
Phake::verify(Arsse::$db, Phake::times(0))->feedUpdate(1, true); \Phake::verify(Arsse::$db, \Phake::times(0))->feedUpdate(1, true);
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_feeds' => ['id','url','username','password'], 'arsse_feeds' => ['id','url','username','password'],
'arsse_subscriptions' => ['id','owner','feed'], 'arsse_subscriptions' => ['id','owner','feed'],
@ -167,10 +166,10 @@ trait SeriesSubscription {
$url = "http://example.org/feed1"; $url = "http://example.org/feed1";
$feedID = $this->nextID("arsse_feeds"); $feedID = $this->nextID("arsse_feeds");
$subID = $this->nextID("arsse_subscriptions"); $subID = $this->nextID("arsse_subscriptions");
Phake::when(Arsse::$db)->feedUpdate->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", false)); $this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", false));
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd");
Phake::verify(Arsse::$db)->feedUpdate($feedID, true); \Phake::verify(Arsse::$db)->feedUpdate($feedID, true);
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_feeds' => ['id','url','username','password'], 'arsse_feeds' => ['id','url','username','password'],
'arsse_subscriptions' => ['id','owner','feed'], 'arsse_subscriptions' => ['id','owner','feed'],
@ -185,10 +184,10 @@ trait SeriesSubscription {
$discovered = "http://localhost:8000/Feed/Discovery/Feed"; $discovered = "http://localhost:8000/Feed/Discovery/Feed";
$feedID = $this->nextID("arsse_feeds"); $feedID = $this->nextID("arsse_feeds");
$subID = $this->nextID("arsse_subscriptions"); $subID = $this->nextID("arsse_subscriptions");
Phake::when(Arsse::$db)->feedUpdate->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", true)); $this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", true));
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd");
Phake::verify(Arsse::$db)->feedUpdate($feedID, true); \Phake::verify(Arsse::$db)->feedUpdate($feedID, true);
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_feeds' => ['id','url','username','password'], 'arsse_feeds' => ['id','url','username','password'],
'arsse_subscriptions' => ['id','owner','feed'], 'arsse_subscriptions' => ['id','owner','feed'],
@ -201,19 +200,18 @@ trait SeriesSubscription {
public function testAddASubscriptionToAnInvalidFeed() { public function testAddASubscriptionToAnInvalidFeed() {
$url = "http://example.org/feed1"; $url = "http://example.org/feed1";
$feedID = $this->nextID("arsse_feeds"); $feedID = $this->nextID("arsse_feeds");
Phake::when(Arsse::$db)->feedUpdate->thenThrow(new FeedException($url, new \PicoFeed\Client\InvalidUrlException())); \Phake::when(Arsse::$db)->feedUpdate->thenThrow(new FeedException($url, new \PicoFeed\Client\InvalidUrlException()));
$this->assertException("invalidUrl", "Feed");
try { try {
Arsse::$db->subscriptionAdd($this->user, $url, "", "", false); Arsse::$db->subscriptionAdd($this->user, $url, "", "", false);
} catch (FeedException $e) { } finally {
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionAdd");
Phake::verify(Arsse::$db)->feedUpdate($feedID, true); \Phake::verify(Arsse::$db)->feedUpdate($feedID, true);
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_feeds' => ['id','url','username','password'], 'arsse_feeds' => ['id','url','username','password'],
'arsse_subscriptions' => ['id','owner','feed'], 'arsse_subscriptions' => ['id','owner','feed'],
]); ]);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
$this->assertException("invalidUrl", "Feed");
throw $e;
} }
} }
@ -223,6 +221,12 @@ trait SeriesSubscription {
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
} }
public function testAddADuplicateSubscriptionWithEquivalentUrl() {
$url = "http://EXAMPLE.COM/feed2";
$this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionAdd($this->user, $url);
}
public function testAddADuplicateSubscriptionViaRedirection() { public function testAddADuplicateSubscriptionViaRedirection() {
$url = "http://localhost:8000/Feed/Parsing/Valid"; $url = "http://localhost:8000/Feed/Parsing/Valid";
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
@ -233,14 +237,14 @@ trait SeriesSubscription {
public function testAddASubscriptionWithoutAuthority() { public function testAddASubscriptionWithoutAuthority() {
$url = "http://example.com/feed1"; $url = "http://example.com/feed1";
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
} }
public function testRemoveASubscription() { public function testRemoveASubscription() {
$this->assertTrue(Arsse::$db->subscriptionRemove($this->user, 1)); $this->assertTrue(Arsse::$db->subscriptionRemove($this->user, 1));
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionRemove"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionRemove");
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_feeds' => ['id','url','username','password'], 'arsse_feeds' => ['id','url','username','password'],
'arsse_subscriptions' => ['id','owner','feed'], 'arsse_subscriptions' => ['id','owner','feed'],
@ -266,7 +270,7 @@ trait SeriesSubscription {
} }
public function testRemoveASubscriptionWithoutAuthority() { public function testRemoveASubscriptionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionRemove($this->user, 1); Arsse::$db->subscriptionRemove($this->user, 1);
} }
@ -293,9 +297,9 @@ trait SeriesSubscription {
], ],
]; ];
$this->assertResult($exp, Arsse::$db->subscriptionList($this->user)); $this->assertResult($exp, Arsse::$db->subscriptionList($this->user));
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionList"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionList");
$this->assertArraySubset($exp[0], Arsse::$db->subscriptionPropertiesGet($this->user, 1)); $this->assertArraySubset($exp[0], Arsse::$db->subscriptionPropertiesGet($this->user, 1));
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionPropertiesGet"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionPropertiesGet");
$this->assertArraySubset($exp[1], Arsse::$db->subscriptionPropertiesGet($this->user, 3)); $this->assertArraySubset($exp[1], Arsse::$db->subscriptionPropertiesGet($this->user, 3));
} }
@ -335,7 +339,7 @@ trait SeriesSubscription {
} }
public function testListSubscriptionsWithoutAuthority() { public function testListSubscriptionsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionList($this->user); Arsse::$db->subscriptionList($this->user);
} }
@ -351,7 +355,7 @@ trait SeriesSubscription {
} }
public function testCountSubscriptionsWithoutAuthority() { public function testCountSubscriptionsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionCount($this->user); Arsse::$db->subscriptionCount($this->user);
} }
@ -367,7 +371,7 @@ trait SeriesSubscription {
} }
public function testGetThePropertiesOfASubscriptionWithoutAuthority() { public function testGetThePropertiesOfASubscriptionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionPropertiesGet($this->user, 1); Arsse::$db->subscriptionPropertiesGet($this->user, 1);
} }
@ -379,7 +383,7 @@ trait SeriesSubscription {
'pinned' => false, 'pinned' => false,
'order_type' => 0, 'order_type' => 0,
]); ]);
Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionPropertiesSet"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionPropertiesSet");
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_feeds' => ['id','url','username','password','title'], 'arsse_feeds' => ['id','url','username','password','title'],
'arsse_subscriptions' => ['id','owner','feed','title','folder','pinned','order_type'], 'arsse_subscriptions' => ['id','owner','feed','title','folder','pinned','order_type'],
@ -440,7 +444,7 @@ trait SeriesSubscription {
} }
public function testSetThePropertiesOfASubscriptionWithoutAuthority() { public function testSetThePropertiesOfASubscriptionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => null]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => null]);
} }
@ -452,7 +456,7 @@ trait SeriesSubscription {
$this->assertSame('', Arsse::$db->subscriptionFavicon(3)); $this->assertSame('', Arsse::$db->subscriptionFavicon(3));
$this->assertSame('', Arsse::$db->subscriptionFavicon(4)); $this->assertSame('', Arsse::$db->subscriptionFavicon(4));
// authorization shouldn't have any bearing on this function // authorization shouldn't have any bearing on this function
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(1)); $this->assertSame($exp, Arsse::$db->subscriptionFavicon(1));
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(2)); $this->assertSame($exp, Arsse::$db->subscriptionFavicon(2));
$this->assertSame('', Arsse::$db->subscriptionFavicon(3)); $this->assertSame('', Arsse::$db->subscriptionFavicon(3));
@ -478,7 +482,7 @@ trait SeriesSubscription {
public function testRetrieveTheFaviconOfASubscriptionWithUserWithoutAuthority() { public function testRetrieveTheFaviconOfASubscriptionWithUserWithoutAuthority() {
$exp = "http://example.com/favicon.ico"; $exp = "http://example.com/favicon.ico";
$user = "john.doe@example.com"; $user = "john.doe@example.com";
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionFavicon(-2112, $user); Arsse::$db->subscriptionFavicon(-2112, $user);
} }
@ -496,7 +500,7 @@ trait SeriesSubscription {
} }
public function testListTheTagsOfASubscriptionWithoutAuthority() { public function testListTheTagsOfASubscriptionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1); Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1);
} }
@ -513,7 +517,7 @@ trait SeriesSubscription {
} }
public function testGetRefreshTimeOfASubscriptionWithoutAuthority() { public function testGetRefreshTimeOfASubscriptionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com")); $this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com"));
} }

View file

@ -8,8 +8,6 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Misc\Date;
use Phake;
trait SeriesTag { trait SeriesTag {
protected function setUpSeriesTag() { protected function setUpSeriesTag() {
@ -114,7 +112,7 @@ trait SeriesTag {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$tagID = $this->nextID("arsse_tags"); $tagID = $this->nextID("arsse_tags");
$this->assertSame($tagID, Arsse::$db->tagAdd($user, ['name' => "Entertaining"])); $this->assertSame($tagID, Arsse::$db->tagAdd($user, ['name' => "Entertaining"]));
Phake::verify(Arsse::$user)->authorize($user, "tagAdd"); \Phake::verify(Arsse::$user)->authorize($user, "tagAdd");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
$state['arsse_tags']['rows'][] = [$tagID, $user, "Entertaining"]; $state['arsse_tags']['rows'][] = [$tagID, $user, "Entertaining"];
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -141,7 +139,7 @@ trait SeriesTag {
} }
public function testAddATagWithoutAuthority() { public function testAddATagWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Boring"]); Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Boring"]);
} }
@ -159,18 +157,18 @@ trait SeriesTag {
$this->assertResult($exp, Arsse::$db->tagList("jane.doe@example.com")); $this->assertResult($exp, Arsse::$db->tagList("jane.doe@example.com"));
$exp = []; $exp = [];
$this->assertResult($exp, Arsse::$db->tagList("jane.doe@example.com", false)); $this->assertResult($exp, Arsse::$db->tagList("jane.doe@example.com", false));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagList"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagList");
} }
public function testListTagsWithoutAuthority() { public function testListTagsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagList("john.doe@example.com"); Arsse::$db->tagList("john.doe@example.com");
} }
public function testRemoveATag() { public function testRemoveATag() {
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", 1)); $this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", 1));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
array_shift($state['arsse_tags']['rows']); array_shift($state['arsse_tags']['rows']);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -178,7 +176,7 @@ trait SeriesTag {
public function testRemoveATagByName() { public function testRemoveATagByName() {
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", "Interesting", true)); $this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", "Interesting", true));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
array_shift($state['arsse_tags']['rows']); array_shift($state['arsse_tags']['rows']);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -205,7 +203,7 @@ trait SeriesTag {
} }
public function testRemoveATagWithoutAuthority() { public function testRemoveATagWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagRemove("john.doe@example.com", 1); Arsse::$db->tagRemove("john.doe@example.com", 1);
} }
@ -217,7 +215,7 @@ trait SeriesTag {
]; ];
$this->assertArraySubset($exp, Arsse::$db->tagPropertiesGet("john.doe@example.com", 2)); $this->assertArraySubset($exp, Arsse::$db->tagPropertiesGet("john.doe@example.com", 2));
$this->assertArraySubset($exp, Arsse::$db->tagPropertiesGet("john.doe@example.com", "Fascinating", true)); $this->assertArraySubset($exp, Arsse::$db->tagPropertiesGet("john.doe@example.com", "Fascinating", true));
Phake::verify(Arsse::$user, Phake::times(2))->authorize("john.doe@example.com", "tagPropertiesGet"); \Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "tagPropertiesGet");
} }
public function testGetThePropertiesOfAMissingTag() { public function testGetThePropertiesOfAMissingTag() {
@ -241,7 +239,7 @@ trait SeriesTag {
} }
public function testGetThePropertiesOfATagWithoutAuthority() { public function testGetThePropertiesOfATagWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagPropertiesGet("john.doe@example.com", 1); Arsse::$db->tagPropertiesGet("john.doe@example.com", 1);
} }
@ -252,7 +250,7 @@ trait SeriesTag {
public function testRenameATag() { public function testRenameATag() {
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"])); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
$state['arsse_tags']['rows'][0][2] = "Curious"; $state['arsse_tags']['rows'][0][2] = "Curious";
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -260,7 +258,7 @@ trait SeriesTag {
public function testRenameATagByName() { public function testRenameATagByName() {
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true)); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
$state['arsse_tags']['rows'][0][2] = "Curious"; $state['arsse_tags']['rows'][0][2] = "Curious";
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -307,7 +305,7 @@ trait SeriesTag {
} }
public function testSetThePropertiesOfATagWithoutAuthority() { public function testSetThePropertiesOfATagWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]); Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]);
} }
@ -335,7 +333,7 @@ trait SeriesTag {
} }
public function testListTaggedSubscriptionsWithoutAuthority() { public function testListTaggedSubscriptionsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1); Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1);
} }
@ -401,7 +399,7 @@ trait SeriesTag {
} }
public function testApplyATagToSubscriptionsWithoutAuthority() { public function testApplyATagToSubscriptionsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]);
} }
@ -418,7 +416,7 @@ trait SeriesTag {
} }
public function testSummarizeTagsWithoutAuthority() { public function testSummarizeTagsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagSummarize("john.doe@example.com"); Arsse::$db->tagSummarize("john.doe@example.com");
} }

View file

@ -7,8 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Database; namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Misc\Date;
use Phake;
trait SeriesToken { trait SeriesToken {
protected function setUpSeriesToken() { protected function setUpSeriesToken() {
@ -69,7 +67,7 @@ trait SeriesToken {
$this->assertArraySubset($exp2, Arsse::$db->tokenLookup("class.class", "da772f8fa13c11e78667001e673b2560")); $this->assertArraySubset($exp2, Arsse::$db->tokenLookup("class.class", "da772f8fa13c11e78667001e673b2560"));
$this->assertArraySubset($exp3, Arsse::$db->tokenLookup("class.class", "ab3b3eb8a13311e78667001e673b2560")); $this->assertArraySubset($exp3, Arsse::$db->tokenLookup("class.class", "ab3b3eb8a13311e78667001e673b2560"));
// token lookup should not check authorization // token lookup should not check authorization
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertArraySubset($exp1, Arsse::$db->tokenLookup("fever.login", "80fa94c1a11f11e78667001e673b2560")); $this->assertArraySubset($exp1, Arsse::$db->tokenLookup("fever.login", "80fa94c1a11f11e78667001e673b2560"));
} }
@ -108,7 +106,7 @@ trait SeriesToken {
} }
public function testCreateATokenWithoutAuthority() { public function testCreateATokenWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tokenCreate("fever.login", "jane.doe@example.com"); Arsse::$db->tokenCreate("fever.login", "jane.doe@example.com");
} }
@ -139,7 +137,7 @@ trait SeriesToken {
} }
public function testRevokeATokenWithoutAuthority() { public function testRevokeATokenWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tokenRevoke("jane.doe@example.com", "fever.login"); Arsse::$db->tokenRevoke("jane.doe@example.com", "fever.login");
} }

View file

@ -7,8 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Database; namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\User\Driver as UserDriver;
use Phake;
trait SeriesUser { trait SeriesUser {
protected function setUpSeriesUser() { protected function setUpSeriesUser() {
@ -34,13 +32,13 @@ trait SeriesUser {
public function testCheckThatAUserExists() { public function testCheckThatAUserExists() {
$this->assertTrue(Arsse::$db->userExists("jane.doe@example.com")); $this->assertTrue(Arsse::$db->userExists("jane.doe@example.com"));
$this->assertFalse(Arsse::$db->userExists("jane.doe@example.org")); $this->assertFalse(Arsse::$db->userExists("jane.doe@example.org"));
Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "userExists"); \Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "userExists");
Phake::verify(Arsse::$user)->authorize("jane.doe@example.org", "userExists"); \Phake::verify(Arsse::$user)->authorize("jane.doe@example.org", "userExists");
$this->compareExpectations(static::$drv, $this->data); $this->compareExpectations(static::$drv, $this->data);
} }
public function testCheckThatAUserExistsWithoutAuthority() { public function testCheckThatAUserExistsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userExists("jane.doe@example.com"); Arsse::$db->userExists("jane.doe@example.com");
} }
@ -48,7 +46,7 @@ trait SeriesUser {
public function testGetAPassword() { public function testGetAPassword() {
$hash = Arsse::$db->userPasswordGet("admin@example.net"); $hash = Arsse::$db->userPasswordGet("admin@example.net");
$this->assertSame('$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', $hash); $this->assertSame('$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', $hash);
Phake::verify(Arsse::$user)->authorize("admin@example.net", "userPasswordGet"); \Phake::verify(Arsse::$user)->authorize("admin@example.net", "userPasswordGet");
$this->assertTrue(password_verify("secret", $hash)); $this->assertTrue(password_verify("secret", $hash));
} }
@ -58,14 +56,14 @@ trait SeriesUser {
} }
public function testGetAPasswordWithoutAuthority() { public function testGetAPasswordWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userPasswordGet("admin@example.net"); Arsse::$db->userPasswordGet("admin@example.net");
} }
public function testAddANewUser() { public function testAddANewUser() {
$this->assertTrue(Arsse::$db->userAdd("john.doe@example.org", "")); $this->assertTrue(Arsse::$db->userAdd("john.doe@example.org", ""));
Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userAdd"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userAdd");
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]); $state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
$state['arsse_users']['rows'][] = ["john.doe@example.org"]; $state['arsse_users']['rows'][] = ["john.doe@example.org"];
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -77,14 +75,14 @@ trait SeriesUser {
} }
public function testAddANewUserWithoutAuthority() { public function testAddANewUserWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userAdd("john.doe@example.org", ""); Arsse::$db->userAdd("john.doe@example.org", "");
} }
public function testRemoveAUser() { public function testRemoveAUser() {
$this->assertTrue(Arsse::$db->userRemove("admin@example.net")); $this->assertTrue(Arsse::$db->userRemove("admin@example.net"));
Phake::verify(Arsse::$user)->authorize("admin@example.net", "userRemove"); \Phake::verify(Arsse::$user)->authorize("admin@example.net", "userRemove");
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]); $state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
array_shift($state['arsse_users']['rows']); array_shift($state['arsse_users']['rows']);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
@ -96,7 +94,7 @@ trait SeriesUser {
} }
public function testRemoveAUserWithoutAuthority() { public function testRemoveAUserWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userRemove("admin@example.net"); Arsse::$db->userRemove("admin@example.net");
} }
@ -104,11 +102,11 @@ trait SeriesUser {
public function testListAllUsers() { public function testListAllUsers() {
$users = ["admin@example.net", "jane.doe@example.com", "john.doe@example.com"]; $users = ["admin@example.net", "jane.doe@example.com", "john.doe@example.com"];
$this->assertSame($users, Arsse::$db->userList()); $this->assertSame($users, Arsse::$db->userList());
Phake::verify(Arsse::$user)->authorize("", "userList"); \Phake::verify(Arsse::$user)->authorize("", "userList");
} }
public function testListAllUsersWithoutAuthority() { public function testListAllUsersWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userList(); Arsse::$db->userList();
} }
@ -123,7 +121,7 @@ trait SeriesUser {
$this->assertTrue(Arsse::$db->userPasswordSet($user, $pass)); $this->assertTrue(Arsse::$db->userPasswordSet($user, $pass));
$hash = Arsse::$db->userPasswordGet($user); $hash = Arsse::$db->userPasswordGet($user);
$this->assertNotEquals("", $hash); $this->assertNotEquals("", $hash);
Phake::verify(Arsse::$user)->authorize($user, "userPasswordSet"); \Phake::verify(Arsse::$user)->authorize($user, "userPasswordSet");
$this->assertTrue(password_verify($pass, $hash), "Failed verifying password of $user '$pass' against hash '$hash'."); $this->assertTrue(password_verify($pass, $hash), "Failed verifying password of $user '$pass' against hash '$hash'.");
} }
@ -140,7 +138,7 @@ trait SeriesUser {
} }
public function testSetAPasswordWithoutAuthority() { public function testSetAPasswordWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userPasswordSet("john.doe@example.com", "secret"); Arsse::$db->userPasswordSet("john.doe@example.com", "secret");
} }

View file

@ -8,7 +8,6 @@ namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Db\Statement; use JKingWeb\Arsse\Db\Statement;
use JKingWeb\Arsse\Db\Result; use JKingWeb\Arsse\Db\Result;
use JKingWeb\Arsse\Test\DatabaseInformation;
abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest { abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
protected static $insertDefaultValues = "INSERT INTO arsse_test default values"; protected static $insertDefaultValues = "INSERT INTO arsse_test default values";

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db; namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Db\Result; use JKingWeb\Arsse\Db\Result;
use JKingWeb\Arsse\Test\DatabaseInformation;
abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest { abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
protected static $insertDefault = "INSERT INTO arsse_test default values"; protected static $insertDefault = "INSERT INTO arsse_test default values";

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db; namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Db\Statement; use JKingWeb\Arsse\Db\Statement;
use JKingWeb\Arsse\Test\DatabaseInformation;
abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest { abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
protected static $interface; protected static $interface;

View file

@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use JKingWeb\Arsse\Test\DatabaseInformation;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest { class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {

View file

@ -6,7 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\MySQL; namespace JKingWeb\Arsse\TestCase\Db\MySQL;
use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\MySQL\Driver as Driver; use JKingWeb\Arsse\Db\MySQL\Driver as Driver;
/** /**

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\MySQL; namespace JKingWeb\Arsse\TestCase\Db\MySQL;
use JKingWeb\Arsse\Test\DatabaseInformation;
/** /**
* @group slow * @group slow
* @covers \JKingWeb\Arsse\Db\MySQL\Result<extended> * @covers \JKingWeb\Arsse\Db\MySQL\Result<extended>

View file

@ -6,7 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\MySQLPDO; namespace JKingWeb\Arsse\TestCase\Db\MySQLPDO;
use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\MySQL\PDODriver as Driver; use JKingWeb\Arsse\Db\MySQL\PDODriver as Driver;
/** /**

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\MySQLPDO; namespace JKingWeb\Arsse\TestCase\Db\MySQLPDO;
use JKingWeb\Arsse\Test\DatabaseInformation;
/** /**
* @group slow * @group slow
* @covers \JKingWeb\Arsse\Db\PDOResult<extended> * @covers \JKingWeb\Arsse\Db\PDOResult<extended>

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\PostgreSQL; namespace JKingWeb\Arsse\TestCase\Db\PostgreSQL;
use JKingWeb\Arsse\Test\DatabaseInformation;
/** /**
* @group slow * @group slow
* @covers \JKingWeb\Arsse\Db\PostgreSQL\Result<extended> * @covers \JKingWeb\Arsse\Db\PostgreSQL\Result<extended>

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\PostgreSQLPDO; namespace JKingWeb\Arsse\TestCase\Db\PostgreSQLPDO;
use JKingWeb\Arsse\Test\DatabaseInformation;
/** /**
* @group slow * @group slow
* @covers \JKingWeb\Arsse\Db\PDOResult<extended> * @covers \JKingWeb\Arsse\Db\PDOResult<extended>

View file

@ -7,10 +7,8 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\SQLite3; namespace JKingWeb\Arsse\TestCase\Db\SQLite3;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Db\SQLite3\Driver; use JKingWeb\Arsse\Db\SQLite3\Driver;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use Phake;
/** /**
* @covers \JKingWeb\Arsse\Db\SQLite3\Driver<extended> * @covers \JKingWeb\Arsse\Db\SQLite3\Driver<extended>

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\SQLite3; namespace JKingWeb\Arsse\TestCase\Db\SQLite3;
use JKingWeb\Arsse\Test\DatabaseInformation;
/** /**
* @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended> * @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended>
*/ */

View file

@ -7,10 +7,8 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\SQLite3PDO; namespace JKingWeb\Arsse\TestCase\Db\SQLite3PDO;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Db\SQLite3\PDODriver as Driver; use JKingWeb\Arsse\Db\SQLite3\PDODriver as Driver;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use Phake;
/** /**
* @covers \JKingWeb\Arsse\Db\SQLite3\PDODriver<extended> * @covers \JKingWeb\Arsse\Db\SQLite3\PDODriver<extended>

View file

@ -6,8 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\SQLite3PDO; namespace JKingWeb\Arsse\TestCase\Db\SQLite3PDO;
use JKingWeb\Arsse\Test\DatabaseInformation;
/** /**
* @covers \JKingWeb\Arsse\Db\PDOResult<extended> * @covers \JKingWeb\Arsse\Db\PDOResult<extended>
*/ */

View file

@ -8,7 +8,6 @@ namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Db\Transaction; use JKingWeb\Arsse\Db\Transaction;
use JKingWeb\Arsse\Db\Exception; use JKingWeb\Arsse\Db\Exception;
use Phake;
/** /**
* @covers \JKingWeb\Arsse\Db\Transaction */ * @covers \JKingWeb\Arsse\Db\Transaction */
@ -17,23 +16,23 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() { public function setUp() {
self::clearData(); self::clearData();
$drv = Phake::mock(\JKingWeb\Arsse\Db\SQLite3\Driver::class); $drv = \Phake::mock(\JKingWeb\Arsse\Db\SQLite3\Driver::class);
Phake::when($drv)->savepointRelease->thenReturn(true); \Phake::when($drv)->savepointRelease->thenReturn(true);
Phake::when($drv)->savepointUndo->thenReturn(true); \Phake::when($drv)->savepointUndo->thenReturn(true);
Phake::when($drv)->savepointCreate->thenReturn(1)->thenReturn(2); \Phake::when($drv)->savepointCreate->thenReturn(1)->thenReturn(2);
$this->drv = $drv; $this->drv = $drv;
} }
public function testManipulateTransactions() { public function testManipulateTransactions() {
$tr1 = new Transaction($this->drv); $tr1 = new Transaction($this->drv);
$tr2 = new Transaction($this->drv); $tr2 = new Transaction($this->drv);
Phake::verify($this->drv, Phake::times(2))->savepointCreate; \Phake::verify($this->drv, \Phake::times(2))->savepointCreate;
$this->assertSame(1, $tr1->getIndex()); $this->assertSame(1, $tr1->getIndex());
$this->assertSame(2, $tr2->getIndex()); $this->assertSame(2, $tr2->getIndex());
unset($tr1); unset($tr1);
Phake::verify($this->drv)->savepointUndo(1); \Phake::verify($this->drv)->savepointUndo(1);
unset($tr2); unset($tr2);
Phake::verify($this->drv)->savepointUndo(2); \Phake::verify($this->drv)->savepointUndo(2);
} }
public function testCloseTransactions() { public function testCloseTransactions() {
@ -44,19 +43,19 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
$tr1->commit(); $tr1->commit();
$this->assertFalse($tr1->isPending()); $this->assertFalse($tr1->isPending());
$this->assertTrue($tr2->isPending()); $this->assertTrue($tr2->isPending());
Phake::verify($this->drv)->savepointRelease(1); \Phake::verify($this->drv)->savepointRelease(1);
$tr2->rollback(); $tr2->rollback();
$this->assertFalse($tr1->isPending()); $this->assertFalse($tr1->isPending());
$this->assertFalse($tr2->isPending()); $this->assertFalse($tr2->isPending());
Phake::verify($this->drv)->savepointUndo(2); \Phake::verify($this->drv)->savepointUndo(2);
} }
public function testIgnoreRollbackErrors() { public function testIgnoreRollbackErrors() {
Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale")); \Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale"));
$tr1 = new Transaction($this->drv); $tr1 = new Transaction($this->drv);
$tr2 = new Transaction($this->drv); $tr2 = new Transaction($this->drv);
unset($tr1, $tr2); // no exception should bubble up unset($tr1, $tr2); // no exception should bubble up
Phake::verify($this->drv)->savepointUndo(1); \Phake::verify($this->drv)->savepointUndo(1);
Phake::verify($this->drv)->savepointUndo(2); \Phake::verify($this->drv)->savepointUndo(2);
} }
} }

View file

@ -10,21 +10,20 @@ use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Lang; use JKingWeb\Arsse\Lang;
use JKingWeb\Arsse\Exception; use JKingWeb\Arsse\Exception;
use JKingWeb\Arsse\Lang\Exception as LangException; use JKingWeb\Arsse\Lang\Exception as LangException;
use Phake;
/** @covers \JKingWeb\Arsse\AbstractException */ /** @covers \JKingWeb\Arsse\AbstractException */
class TestException extends \JKingWeb\Arsse\Test\AbstractTest { class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() { public function setUp() {
self::clearData(false); self::clearData(false);
// create a mock Lang object so as not to create a dependency loop // create a mock Lang object so as not to create a dependency loop
Arsse::$lang = Phake::mock(Lang::class); Arsse::$lang = \Phake::mock(Lang::class);
Phake::when(Arsse::$lang)->msg->thenReturn(""); \Phake::when(Arsse::$lang)->msg->thenReturn("");
} }
public function tearDown() { public function tearDown() {
// verify calls to the mock Lang object // verify calls to the mock Lang object
Phake::verify(Arsse::$lang, Phake::atLeast(0))->msg($this->isType("string"), $this->anything()); \Phake::verify(Arsse::$lang, \Phake::atLeast(0))->msg($this->isType("string"), $this->anything());
Phake::verifyNoOtherInteractions(Arsse::$lang); \Phake::verifyNoOtherInteractions(Arsse::$lang);
// clean up // clean up
self::clearData(true); self::clearData(true);
} }

View file

@ -7,12 +7,10 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Feed; namespace JKingWeb\Arsse\TestCase\Feed;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Feed; use JKingWeb\Arsse\Feed;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Test\Result; use JKingWeb\Arsse\Test\Result;
use Phake;
/** /**
* @covers \JKingWeb\Arsse\Feed * @covers \JKingWeb\Arsse\Feed
@ -97,7 +95,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->base = self::$host."Feed/"; $this->base = self::$host."Feed/";
self::clearData(); self::clearData();
self::setConf(); self::setConf();
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
} }
public function testParseAFeed() { public function testParseAFeed() {
@ -315,7 +313,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testMatchLatestArticles() { public function testMatchLatestArticles() {
Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest)); \Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
$f = new Feed(1, $this->base."Matching/1"); $f = new Feed(1, $this->base."Matching/1");
$this->assertCount(0, $f->newItems); $this->assertCount(0, $f->newItems);
$this->assertCount(0, $f->changedItems); $this->assertCount(0, $f->changedItems);
@ -331,8 +329,8 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testMatchHistoricalArticles() { public function testMatchHistoricalArticles() {
Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest)); \Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
Phake::when(Arsse::$db)->feedMatchIds(1, $this->anything(), $this->anything(), $this->anything(), $this->anything())->thenReturn(new Result($this->others)); \Phake::when(Arsse::$db)->feedMatchIds(1, $this->anything(), $this->anything(), $this->anything(), $this->anything())->thenReturn(new Result($this->others));
$f = new Feed(1, $this->base."Matching/5"); $f = new Feed(1, $this->base."Matching/5");
$this->assertCount(0, $f->newItems); $this->assertCount(0, $f->newItems);
$this->assertCount(0, $f->changedItems); $this->assertCount(0, $f->changedItems);

View file

@ -7,9 +7,7 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Feed; namespace JKingWeb\Arsse\TestCase\Feed;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Feed; use JKingWeb\Arsse\Feed;
use Phake;
/** /**
* @covers \JKingWeb\Arsse\Feed * @covers \JKingWeb\Arsse\Feed

View file

@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\TestCase\ImportExport;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\SQLite3\Driver; use JKingWeb\Arsse\Db\SQLite3\Driver;
use JKingWeb\Arsse\ImportExport\AbstractImportExport; use JKingWeb\Arsse\ImportExport\AbstractImportExport;
use JKingWeb\Arsse\ImportExport\Exception;
use JKingWeb\Arsse\Test\Database; use JKingWeb\Arsse\Test\Database;
/** @covers \JKingWeb\Arsse\ImportExport\AbstractImportExport */ /** @covers \JKingWeb\Arsse\ImportExport\AbstractImportExport */

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Lang; namespace JKingWeb\Arsse\TestCase\Lang;
use JKingWeb\Arsse\Lang as TestClass; use JKingWeb\Arsse\Lang as TestClass;
use org\bovigo\vfs\vfsStream;
/** @covers \JKingWeb\Arsse\Lang */ /** @covers \JKingWeb\Arsse\Lang */
class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest { class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Lang; namespace JKingWeb\Arsse\TestCase\Lang;
use JKingWeb\Arsse\Lang as TestClass; use JKingWeb\Arsse\Lang as TestClass;
use org\bovigo\vfs\vfsStream;
/** @covers \JKingWeb\Arsse\Lang */ /** @covers \JKingWeb\Arsse\Lang */
class TestErrors extends \JKingWeb\Arsse\Test\AbstractTest { class TestErrors extends \JKingWeb\Arsse\Test\AbstractTest {

View file

@ -7,7 +7,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Lang; namespace JKingWeb\Arsse\TestCase\Lang;
use JKingWeb\Arsse\Lang as TestClass; use JKingWeb\Arsse\Lang as TestClass;
use org\bovigo\vfs\vfsStream;
/** @covers \JKingWeb\Arsse\Lang */ /** @covers \JKingWeb\Arsse\Lang */
class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest { class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {

View file

@ -0,0 +1,78 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Misc;
use JKingWeb\Arsse\Misc\URL;
/** @covers \JKingWeb\Arsse\Misc\URL */
class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() {
self::clearData();
}
/** @dataProvider provideNormalizations */
public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null) {
$this->assertSame($exp, URL::normalize($url, $user, $pass));
}
public function provideNormalizations() {
return [
["http://example.com/", "http://example.com/"],
["HTTP://example.com/", "http://example.com/"],
["http://example.com", "http://example.com/"],
["http://example.com:/", "http://example.com/"],
["HTTP://example.com:80/", "http://example.com:80/"],
["HTTP://example.com:80", "http://example.com:80/"],
["http://example.com/?", "http://example.com/"],
["http://example.com?", "http://example.com/"],
["http://example.com/#fragment", "http://example.com/"],
["http://example.com#fragment", "http://example.com/"],
["http://example.com?#", "http://example.com/"],
["http://example.com/?key=value", "http://example.com/?key=value"],
["http://example.com/", "http://user:pass@example.com/", "user", "pass"],
["http://example.com/", "http://user@example.com/", "user"],
["http://user:pass@example.com/", "http://user:pass@example.com/"],
["http://user@example.com/", "http://user@example.com/"],
["http://user:pass@example.com/", "http://u:p@example.com/", "u", "p"],
["http://user:pass@example.com/", "http://u@example.com/", "u"],
["http://user:pass@example.com/", "http://user:pass@example.com/", "", "p"],
["http://example.com/", "http://example.com/", "", "p"],
["http://example.com/path", "http://example.com/path"],
["http://example.com/PATH", "http://example.com/PATH"],
["http://example.com/path/", "http://example.com/path/"],
["http://example.com/path/.", "http://example.com/path"],
["http://example.com/path/./", "http://example.com/path/"],
["http://example.com/path/..", "http://example.com/"],
["http://example.com/path/../", "http://example.com/"],
["http://example.com/a/b/..", "http://example.com/a"],
["http://example.com/a/b/../", "http://example.com/a/"],
["http://example.com/../", "http://example.com/"],
["http://example.com////", "http://example.com/"],
["http://example.com/a/./b/", "http://example.com/a/b/"],
["http://example.com/a/../b/", "http://example.com/b/"],
["http://example.com/.a/", "http://example.com/.a/"],
["http://example.com/..a/", "http://example.com/..a/"],
["http://日本.example.com/", "http://日本.example.com/"],
["http://EXAMPLE.COM/", "http://example.com/"],
["http://É.example.com/", "http://é.example.com/"],
["http://[::1]/", "http://[::1]/"],
["http://[0::1]/", "http://[::1]/"],
["http://[Z]/", "http://[z]/"],
["http://example.com/ ?%61=%3d", "http://example.com/%20?a=%3D"],
["http://example.com/%", "http://example.com/%25"],
["http://example.com/%a", "http://example.com/%25a"],
["http://example.com/%za", "http://example.com/%25za"],
["//EXAMPLE.COM/", "//example.com/"],
["//EXAMPLE.COM/", "//u:p@example.com/", "u", "p"],
["/ ", "/%20"],
["/ ", "/%20", "u", "p"],
["EXAMPLE.COM/", "EXAMPLE.COM/"],
["EXAMPLE.COM", "EXAMPLE.COM"],
[" ", "%20"],
];
}
}

View file

@ -6,7 +6,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Misc; namespace JKingWeb\Arsse\TestCase\Misc;
use JKingWeb\Arsse\ExceptionType;
use JKingWeb\Arsse\Misc\ValueInfo as I; use JKingWeb\Arsse\Misc\ValueInfo as I;
use JKingWeb\Arsse\Test\Misc\StrClass; use JKingWeb\Arsse\Test\Misc\StrClass;
use JKingWeb\Arsse\Test\Result; use JKingWeb\Arsse\Test\Result;

View file

@ -7,10 +7,8 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\REST\NextCloudNews; namespace JKingWeb\Arsse\TestCase\REST\NextCloudNews;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\User; use JKingWeb\Arsse\User;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Service;
use JKingWeb\Arsse\Test\Result; use JKingWeb\Arsse\Test\Result;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
@ -21,7 +19,6 @@ use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\Response\JsonResponse as Response; use Zend\Diactoros\Response\JsonResponse as Response;
use Zend\Diactoros\Response\EmptyResponse; use Zend\Diactoros\Response\EmptyResponse;
use Phake;
/** @covers \JKingWeb\Arsse\REST\NextCloudNews\V1_2<extended> */ /** @covers \JKingWeb\Arsse\REST\NextCloudNews\V1_2<extended> */
class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest { class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
@ -342,12 +339,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
self::setConf(); self::setConf();
// create a mock user manager // create a mock user manager
Arsse::$user = Phake::mock(User::class); Arsse::$user = \Phake::mock(User::class);
Phake::when(Arsse::$user)->auth->thenReturn(true); \Phake::when(Arsse::$user)->auth->thenReturn(true);
Arsse::$user->id = "john.doe@example.com"; Arsse::$user->id = "john.doe@example.com";
// create a mock database interface // create a mock database interface
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(Transaction::class)); \Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
$this->h = new V1_2(); $this->h = new V1_2();
} }
@ -360,7 +357,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testSendAuthenticationChallenge() { public function testSendAuthenticationChallenge() {
Phake::when(Arsse::$user)->auth->thenReturn(false); \Phake::when(Arsse::$user)->auth->thenReturn(false);
$exp = new EmptyResponse(401); $exp = new EmptyResponse(401);
$this->assertMessage($exp, $this->req("GET", "/")); $this->assertMessage($exp, $this->req("GET", "/"));
} }
@ -448,7 +445,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['id' => 1, 'name' => "Software"], ['id' => 1, 'name' => "Software"],
['id' => 12, 'name' => "Hardware"], ['id' => 12, 'name' => "Hardware"],
]; ];
Phake::when(Arsse::$db)->folderList(Arsse::$user->id, null, false)->thenReturn(new Result([]))->thenReturn(new Result($this->v($list))); \Phake::when(Arsse::$db)->folderList(Arsse::$user->id, null, false)->thenReturn(new Result([]))->thenReturn(new Result($this->v($list)));
$exp = new Response(['folders' => []]); $exp = new Response(['folders' => []]);
$this->assertMessage($exp, $this->req("GET", "/folders")); $this->assertMessage($exp, $this->req("GET", "/folders"));
$exp = new Response(['folders' => $out]); $exp = new Response(['folders' => $out]);
@ -469,24 +466,24 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['id' => 2, 'name' => "Hardware"], ['id' => 2, 'name' => "Hardware"],
]; ];
// set of various mocks for testing // set of various mocks for testing
Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenThrow(new \Exception); \Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenThrow(new \Exception);
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $in[0])->thenReturn(1)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $in[0])->thenReturn(1)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $in[1])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $in[1])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v($db[0])); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v($db[0]));
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2)->thenReturn($this->v($db[1])); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2)->thenReturn($this->v($db[1]));
// set up mocks that produce errors // set up mocks that produce errors
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => ""])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => ""])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => " "])->thenThrow(new ExceptionInput("whitespace")); \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => " "])->thenThrow(new ExceptionInput("whitespace"));
// correctly add two folders, using different means // correctly add two folders, using different means
$exp = new Response(['folders' => [$out[0]]]); $exp = new Response(['folders' => [$out[0]]]);
$this->assertMessage($exp, $this->req("POST", "/folders", json_encode($in[0]))); $this->assertMessage($exp, $this->req("POST", "/folders", json_encode($in[0])));
$exp = new Response(['folders' => [$out[1]]]); $exp = new Response(['folders' => [$out[1]]]);
$this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware")); $this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware"));
Phake::verify(Arsse::$db)->folderAdd(Arsse::$user->id, $in[0]); \Phake::verify(Arsse::$db)->folderAdd(Arsse::$user->id, $in[0]);
Phake::verify(Arsse::$db)->folderAdd(Arsse::$user->id, $in[1]); \Phake::verify(Arsse::$db)->folderAdd(Arsse::$user->id, $in[1]);
Phake::verify(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1); \Phake::verify(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1);
Phake::verify(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2); \Phake::verify(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2);
// test bad folder names // test bad folder names
$exp = new EmptyResponse(422); $exp = new EmptyResponse(422);
$this->assertMessage($exp, $this->req("POST", "/folders")); $this->assertMessage($exp, $this->req("POST", "/folders"));
@ -501,13 +498,13 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testRemoveAFolder() { public function testRemoveAFolder() {
Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("DELETE", "/folders/1")); $this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
// fail on the second invocation because it no longer exists // fail on the second invocation because it no longer exists
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
$this->assertMessage($exp, $this->req("DELETE", "/folders/1")); $this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
Phake::verify(Arsse::$db, Phake::times(2))->folderRemove(Arsse::$user->id, 1); \Phake::verify(Arsse::$db, \Phake::times(2))->folderRemove(Arsse::$user->id, 1);
} }
public function testRenameAFolder() { public function testRenameAFolder() {
@ -518,12 +515,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
["name" => " "], ["name" => " "],
[], [],
]; ];
Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[0])->thenReturn(true); \Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[0])->thenReturn(true);
Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 2, $in[1])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 2, $in[1])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[2])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[2])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[3])->thenThrow(new ExceptionInput("whitespace")); \Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[3])->thenThrow(new ExceptionInput("whitespace"));
Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[4])->thenReturn(true); // this should be stopped by the handler before the request gets to the database \Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 1, $in[4])->thenReturn(true); // this should be stopped by the handler before the request gets to the database
Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 3, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); // folder ID 3 does not exist \Phake::when(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, 3, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); // folder ID 3 does not exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/folders/1", json_encode($in[0]))); $this->assertMessage($exp, $this->req("PUT", "/folders/1", json_encode($in[0])));
$exp = new EmptyResponse(409); $exp = new EmptyResponse(409);
@ -556,9 +553,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
'starredCount' => 5, 'starredCount' => 5,
'newestItemId' => 4758915, 'newestItemId' => 4758915,
]; ];
Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result([]))->thenReturn(new Result($this->v($this->feeds['db']))); \Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result([]))->thenReturn(new Result($this->v($this->feeds['db'])));
Phake::when(Arsse::$db)->articleStarred(Arsse::$user->id)->thenReturn($this->v(['total' => 0]))->thenReturn($this->v(['total' => 5])); \Phake::when(Arsse::$db)->articleStarred(Arsse::$user->id)->thenReturn($this->v(['total' => 0]))->thenReturn($this->v(['total' => 5]));
Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id)->thenReturn(0)->thenReturn(4758915); \Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id)->thenReturn(0)->thenReturn(4758915);
$exp = new Response($exp1); $exp = new Response($exp1);
$this->assertMessage($exp, $this->req("GET", "/feeds")); $this->assertMessage($exp, $this->req("GET", "/feeds"));
$exp = new Response($exp2); $exp = new Response($exp2);
@ -579,20 +576,20 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['feeds' => [$this->feeds['rest'][2]], 'newestItemId' => 2112], ['feeds' => [$this->feeds['rest'][2]], 'newestItemId' => 2112],
]; ];
// set up the necessary mocks // set up the necessary mocks
Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "http://example.com/news.atom")->thenReturn(2112)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "http://example.com/news.atom")->thenReturn(2112)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "http://example.org/news.atom")->thenReturn(42)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "http://example.org/news.atom")->thenReturn(42)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "")->thenThrow(new \JKingWeb\Arsse\Feed\Exception("", new \PicoFeed\Reader\SubscriptionNotFoundException)); \Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "")->thenThrow(new \JKingWeb\Arsse\Feed\Exception("", new \PicoFeed\Reader\SubscriptionNotFoundException));
Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 2112)->thenReturn($this->v($this->feeds['db'][0])); \Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 2112)->thenReturn($this->v($this->feeds['db'][0]));
Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 42)->thenReturn($this->v($this->feeds['db'][1])); \Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 42)->thenReturn($this->v($this->feeds['db'][1]));
Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 47)->thenReturn($this->v($this->feeds['db'][2])); \Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 47)->thenReturn($this->v($this->feeds['db'][2]));
Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription(2112))->thenReturn(0); \Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription(2112))->thenReturn(0);
Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription(42))->thenReturn(4758915); \Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription(42))->thenReturn(4758915);
Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription(47))->thenReturn(2112); \Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription(47))->thenReturn(2112);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 2112, ['folder' => 3])->thenThrow(new ExceptionInput("idMissing")); // folder ID 3 does not exist \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 2112, ['folder' => 3])->thenThrow(new ExceptionInput("idMissing")); // folder ID 3 does not exist
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, ['folder' => 8])->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, ['folder' => 8])->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 47, ['folder' => -1])->thenThrow(new ExceptionInput("typeViolation")); // folder ID -1 is invalid \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 47, ['folder' => -1])->thenThrow(new ExceptionInput("typeViolation")); // folder ID -1 is invalid
// set up a mock for a bad feed which succeeds the second time // set up a mock for a bad feed which succeeds the second time
Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "http://example.net/news.atom")->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.net/news.atom", new \PicoFeed\Client\InvalidUrlException()))->thenReturn(47); \Phake::when(Arsse::$db)->subscriptionAdd(Arsse::$user->id, "http://example.net/news.atom")->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.net/news.atom", new \PicoFeed\Client\InvalidUrlException()))->thenReturn(47);
// add the subscriptions // add the subscriptions
$exp = new Response($out[0]); $exp = new Response($out[0]);
$this->assertMessage($exp, $this->req("POST", "/feeds", json_encode($in[0]))); $this->assertMessage($exp, $this->req("POST", "/feeds", json_encode($in[0])));
@ -614,13 +611,13 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testRemoveASubscription() { public function testRemoveASubscription() {
Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1")); $this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
// fail on the second invocation because it no longer exists // fail on the second invocation because it no longer exists
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1")); $this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
Phake::verify(Arsse::$db, Phake::times(2))->subscriptionRemove(Arsse::$user->id, 1); \Phake::verify(Arsse::$db, \Phake::times(2))->subscriptionRemove(Arsse::$user->id, 1);
} }
public function testMoveASubscription() { public function testMoveASubscription() {
@ -632,11 +629,11 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['folderId' => -1], ['folderId' => -1],
[], [],
]; ];
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => 42])->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => 42])->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => null])->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => null])->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => 2112])->thenThrow(new ExceptionInput("idMissing")); // folder does not exist \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => 2112])->thenThrow(new ExceptionInput("idMissing")); // folder does not exist
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => -1])->thenThrow(new ExceptionInput("typeViolation")); // folder is invalid \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => -1])->thenThrow(new ExceptionInput("typeViolation")); // folder is invalid
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); // subscription does not exist \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); // subscription does not exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[0]))); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[0])));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
@ -661,12 +658,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['feedTitle' => "Feed does not exist"], ['feedTitle' => "Feed does not exist"],
[], [],
]; ];
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => null]))->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => null]))->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => "Ook"]))->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => "Ook"]))->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => " "]))->thenThrow(new ExceptionInput("whitespace")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => " "]))->thenThrow(new ExceptionInput("whitespace"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => ""]))->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => ""]))->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => false]))->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => false]))->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing"));
$exp = new EmptyResponse(422); $exp = new EmptyResponse(422);
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[0]))); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[0])));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
@ -692,7 +689,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
'userId' => "", 'userId' => "",
], ],
]; ];
Phake::when(Arsse::$db)->feedListStale->thenReturn($this->v(array_column($out, "id"))); \Phake::when(Arsse::$db)->feedListStale->thenReturn($this->v(array_column($out, "id")));
$exp = new Response(['feeds' => $out]); $exp = new Response(['feeds' => $out]);
$this->assertMessage($exp, $this->req("GET", "/feeds/all")); $this->assertMessage($exp, $this->req("GET", "/feeds/all"));
} }
@ -705,9 +702,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['feedId' => -1], // invalid ID ['feedId' => -1], // invalid ID
['feed' => 42], // invalid input ['feed' => 42], // invalid input
]; ];
Phake::when(Arsse::$db)->feedUpdate(42)->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate(42)->thenReturn(true);
Phake::when(Arsse::$db)->feedUpdate(2112)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->feedUpdate(2112)->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->feedUpdate($this->lessThan(1))->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->feedUpdate($this->lessThan(1))->thenThrow(new ExceptionInput("typeViolation"));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[0]))); $this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[0])));
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
@ -734,11 +731,11 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['lastModified' => $t->getTimestamp()], ['lastModified' => $t->getTimestamp()],
['oldestFirst' => false, 'batchSize' => 5, 'offset' => 0], // offset=0 should not set the latestEdition context ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 0], // offset=0 should not set the latestEdition context
]; ];
Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v($this->articles['db']))); \Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v($this->articles['db'])));
Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(42), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("idMissing")); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(42), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("idMissing"));
Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(2112), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("idMissing")); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(2112), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("idMissing"));
Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(-1), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(-1), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(-1), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(-1), $this->anything(), ["edition desc"])->thenThrow(new ExceptionInput("typeViolation"));
$exp = new Response(['items' => $this->articles['rest']]); $exp = new Response(['items' => $this->articles['rest']]);
// check the contents of the response // check the contents of the response
$this->assertMessage($exp, $this->req("GET", "/items")); // first instance of base context $this->assertMessage($exp, $this->req("GET", "/items")); // first instance of base context
@ -759,24 +756,24 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->req("GET", "/items", json_encode($in[10])); $this->req("GET", "/items", json_encode($in[10]));
$this->req("GET", "/items", json_encode($in[11])); $this->req("GET", "/items", json_encode($in[11]));
// perform method verifications // perform method verifications
Phake::verify(Arsse::$db, Phake::times(4))->articleList(Arsse::$user->id, new Context, $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db, \Phake::times(4))->articleList(Arsse::$user->id, new Context, $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(42), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(42), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(2112), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(2112), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(-1), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->subscription(-1), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(-1), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->folder(-1), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(10)->oldestEdition(6), $this->anything(), ["edition"]); // offset is one more than specified \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(10)->oldestEdition(6), $this->anything(), ["edition"]); // offset is one more than specified
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5)->latestEdition(4), $this->anything(), ["edition desc"]); // offset is one less than specified \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5)->latestEdition(4), $this->anything(), ["edition desc"]); // offset is one less than specified
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $this->equalTo((new Context)->markedSince($t), 2), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $this->equalTo((new Context)->markedSince($t), 2), $this->anything(), ["edition desc"]);
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5), $this->anything(), ["edition desc"]);
} }
public function testMarkAFolderRead() { public function testMarkAFolderRead() {
$read = ['read' => true]; $read = ['read' => true];
$in = json_encode(['newestItemId' => 2112]); $in = json_encode(['newestItemId' => 2112]);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(1)->latestEdition(2112))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(1)->latestEdition(2112))->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(42)->latestEdition(2112))->thenThrow(new ExceptionInput("idMissing")); // folder doesn't exist \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(42)->latestEdition(2112))->thenThrow(new ExceptionInput("idMissing")); // folder doesn't exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in));
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112")); $this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112"));
@ -790,8 +787,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMarkASubscriptionRead() { public function testMarkASubscriptionRead() {
$read = ['read' => true]; $read = ['read' => true];
$in = json_encode(['newestItemId' => 2112]); $in = json_encode(['newestItemId' => 2112]);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(1)->latestEdition(2112))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(1)->latestEdition(2112))->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(42)->latestEdition(2112))->thenThrow(new ExceptionInput("idMissing")); // subscription doesn't exist \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(42)->latestEdition(2112))->thenThrow(new ExceptionInput("idMissing")); // subscription doesn't exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in));
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112")); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112"));
@ -805,7 +802,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMarkAllItemsRead() { public function testMarkAllItemsRead() {
$read = ['read' => true]; $read = ['read' => true];
$in = json_encode(['newestItemId' => 2112]); $in = json_encode(['newestItemId' => 2112]);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->latestEdition(2112))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->latestEdition(2112))->thenReturn(42);
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/items/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/items/read", $in));
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112")); $this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112"));
@ -819,14 +816,14 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$unread = ['read' => false]; $unread = ['read' => false];
$star = ['starred' => true]; $star = ['starred' => true];
$unstar = ['starred' => false]; $unstar = ['starred' => false];
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->edition(1))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->edition(1))->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->edition(42))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->edition(42))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unread, (new Context)->edition(2))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unread, (new Context)->edition(2))->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unread, (new Context)->edition(47))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unread, (new Context)->edition(47))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $star, (new Context)->article(3))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $star, (new Context)->article(3))->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $star, (new Context)->article(2112))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $star, (new Context)->article(2112))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->article(4))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->article(4))->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->article(1337))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->article(1337))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/items/1/read")); $this->assertMessage($exp, $this->req("PUT", "/items/1/read"));
$this->assertMessage($exp, $this->req("PUT", "/items/2/unread")); $this->assertMessage($exp, $this->req("PUT", "/items/2/unread"));
@ -837,7 +834,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/items/47/unread")); $this->assertMessage($exp, $this->req("PUT", "/items/47/unread"));
$this->assertMessage($exp, $this->req("PUT", "/items/1/2112/star")); $this->assertMessage($exp, $this->req("PUT", "/items/1/2112/star"));
$this->assertMessage($exp, $this->req("PUT", "/items/4400/1337/unstar")); $this->assertMessage($exp, $this->req("PUT", "/items/4400/1337/unstar"));
Phake::verify(Arsse::$db, Phake::times(8))->articleMark(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(8))->articleMark(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testChangeMarksOfMultipleArticles() { public function testChangeMarksOfMultipleArticles() {
@ -855,9 +852,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$inStar[$a][$b] = ['feedId' => 2112, 'guidHash' => $inStar[$a][$b]]; $inStar[$a][$b] = ['feedId' => 2112, 'guidHash' => $inStar[$a][$b]];
} }
} }
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), $this->anything())->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), $this->anything())->thenReturn(42);
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->editions([]))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->editions([]))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->articles([]))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->articles([]))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/items/read/multiple")); $this->assertMessage($exp, $this->req("PUT", "/items/read/multiple"));
$this->assertMessage($exp, $this->req("PUT", "/items/unread/multiple")); $this->assertMessage($exp, $this->req("PUT", "/items/unread/multiple"));
@ -880,27 +877,27 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/items/star/multiple", json_encode(['items' => $inStar[1]]))); $this->assertMessage($exp, $this->req("PUT", "/items/star/multiple", json_encode(['items' => $inStar[1]])));
$this->assertMessage($exp, $this->req("PUT", "/items/unstar/multiple", json_encode(['items' => $inStar[1]]))); $this->assertMessage($exp, $this->req("PUT", "/items/unstar/multiple", json_encode(['items' => $inStar[1]])));
// ensure the data model was queried appropriately for read/unread // ensure the data model was queried appropriately for read/unread
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions([])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions([]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions($in[0])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions($in[0]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions($in[1])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions($in[1]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions([])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions([]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions($in[0])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions($in[0]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions($in[1])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions($in[1]));
// ensure the data model was queried appropriately for star/unstar // ensure the data model was queried appropriately for star/unstar
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles([])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles([]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles($in[0])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles($in[0]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles($in[1])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles($in[1]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles([])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles([]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[0])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[0]));
Phake::verify(Arsse::$db, Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[1])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[1]));
} }
public function testQueryTheServerStatus() { public function testQueryTheServerStatus() {
$interval = Arsse::$conf->serviceFrequency; $interval = Arsse::$conf->serviceFrequency;
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval); $valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
$invalid = $valid->sub($interval)->sub($interval); $invalid = $valid->sub($interval)->sub($interval);
Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql")); \Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
Phake::when(Arsse::$db)->driverCharsetAcceptable->thenReturn(true)->thenReturn(false); \Phake::when(Arsse::$db)->driverCharsetAcceptable->thenReturn(true)->thenReturn(false);
$arr1 = $arr2 = [ $arr1 = $arr2 = [
'version' => V1_2::VERSION, 'version' => V1_2::VERSION,
'arsse_version' => Arsse::VERSION, 'arsse_version' => Arsse::VERSION,
@ -916,17 +913,17 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testCleanUpBeforeUpdate() { public function testCleanUpBeforeUpdate() {
Phake::when(Arsse::$db)->feedCleanup()->thenReturn(true); \Phake::when(Arsse::$db)->feedCleanup()->thenReturn(true);
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
Phake::verify(Arsse::$db)->feedCleanup(); \Phake::verify(Arsse::$db)->feedCleanup();
} }
public function testCleanUpAfterUpdate() { public function testCleanUpAfterUpdate() {
Phake::when(Arsse::$db)->articleCleanup()->thenReturn(true); \Phake::when(Arsse::$db)->articleCleanup()->thenReturn(true);
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("GET", "/cleanup/after-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/after-update"));
Phake::verify(Arsse::$db)->articleCleanup(); \Phake::verify(Arsse::$db)->articleCleanup();
} }
public function testQueryTheUserStatus() { public function testQueryTheUserStatus() {
@ -945,10 +942,10 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$url = "/folders?name=Hardware"; $url = "/folders?name=Hardware";
$out1 = ['id' => 1, 'name' => "Software"]; $out1 = ['id' => 1, 'name' => "Software"];
$out2 = ['id' => 2, 'name' => "Hardware"]; $out2 = ['id' => 2, 'name' => "Hardware"];
Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenReturn(2); \Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenReturn(2);
Phake::when(Arsse::$db)->folderAdd($this->anything(), $in)->thenReturn(1); \Phake::when(Arsse::$db)->folderAdd($this->anything(), $in)->thenReturn(1);
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v($out1)); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v($out1));
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2)->thenReturn($this->v($out2)); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2)->thenReturn($this->v($out2));
$exp = new Response(['folders' => [$out1]]); $exp = new Response(['folders' => [$out1]]);
$this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in))); $this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in)));
} }
@ -956,8 +953,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMeldJsonAndQueryParameters() { public function testMeldJsonAndQueryParameters() {
$in = ['oldestFirst' => true]; $in = ['oldestFirst' => true];
$url = "/items?type=2"; $url = "/items?type=2";
Phake::when(Arsse::$db)->articleList->thenReturn(new Result([])); \Phake::when(Arsse::$db)->articleList->thenReturn(new Result([]));
$this->req("GET", $url, json_encode($in)); $this->req("GET", $url, json_encode($in));
Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true), $this->anything(), ["edition"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true), $this->anything(), ["edition"]);
} }
} }

View file

@ -20,7 +20,6 @@ use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\Response\TextResponse; use Zend\Diactoros\Response\TextResponse;
use Zend\Diactoros\Response\EmptyResponse; use Zend\Diactoros\Response\EmptyResponse;
use Phake;
/** @covers \JKingWeb\Arsse\REST */ /** @covers \JKingWeb\Arsse\REST */
class TestREST extends \JKingWeb\Arsse\Test\AbstractTest { class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
@ -65,11 +64,11 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
public function testAuthenticateRequests(array $serverParams, array $expAttr) { public function testAuthenticateRequests(array $serverParams, array $expAttr) {
$r = new REST(); $r = new REST();
// create a mock user manager // create a mock user manager
Arsse::$user = Phake::mock(User::class); Arsse::$user = \Phake::mock(User::class);
Phake::when(Arsse::$user)->auth->thenReturn(false); \Phake::when(Arsse::$user)->auth->thenReturn(false);
Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true); \Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
Phake::when(Arsse::$user)->auth("john.doe@example.com", "")->thenReturn(true); \Phake::when(Arsse::$user)->auth("john.doe@example.com", "")->thenReturn(true);
Phake::when(Arsse::$user)->auth("someone.else@example.com", "")->thenReturn(true); \Phake::when(Arsse::$user)->auth("someone.else@example.com", "")->thenReturn(true);
// create an input server request // create an input server request
$req = new ServerRequest($serverParams); $req = new ServerRequest($serverParams);
// create the expected output // create the expected output
@ -152,8 +151,8 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideCorsNegotiations */ /** @dataProvider provideCorsNegotiations */
public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null) { public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null) {
self::setConf(); self::setConf();
$r = Phake::partialMock(REST::class); $r = \Phake::partialMock(REST::class);
Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function($origin) { \Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function($origin) {
return $origin; return $origin;
}); });
$headers = isset($origin) ? ['Origin' => $origin] : []; $headers = isset($origin) ? ['Origin' => $origin] : [];
@ -253,12 +252,12 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideUnnormalizedResponses */ /** @dataProvider provideUnnormalizedResponses */
public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null) { public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null) {
$r = Phake::partialMock(REST::class); $r = \Phake::partialMock(REST::class);
Phake::when($r)->corsNegotiate->thenReturn(true); \Phake::when($r)->corsNegotiate->thenReturn(true);
Phake::when($r)->challenge->thenReturnCallback(function($res) { \Phake::when($r)->challenge->thenReturnCallback(function($res) {
return $res->withHeader("WWW-Authenticate", "Fake Value"); return $res->withHeader("WWW-Authenticate", "Fake Value");
}); });
Phake::when($r)->corsApply->thenReturnCallback(function($res) { \Phake::when($r)->corsApply->thenReturnCallback(function($res) {
return $res; return $res;
}); });
$act = $r->normalizeResponse($res, $req); $act = $r->normalizeResponse($res, $req);
@ -297,30 +296,30 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideMockRequests */ /** @dataProvider provideMockRequests */
public function testDispatchRequests(ServerRequest $req, string $method, bool $called, string $class = "", string $target ="") { public function testDispatchRequests(ServerRequest $req, string $method, bool $called, string $class = "", string $target ="") {
$r = Phake::partialMock(REST::class); $r = \Phake::partialMock(REST::class);
Phake::when($r)->normalizeResponse->thenReturnCallback(function($res) { \Phake::when($r)->normalizeResponse->thenReturnCallback(function($res) {
return $res; return $res;
}); });
Phake::when($r)->authenticateRequest->thenReturnCallback(function($req) { \Phake::when($r)->authenticateRequest->thenReturnCallback(function($req) {
return $req; return $req;
}); });
if ($called) { if ($called) {
$h = Phake::mock($class); $h = \Phake::mock($class);
Phake::when($r)->getHandler($class)->thenReturn($h); \Phake::when($r)->getHandler($class)->thenReturn($h);
Phake::when($h)->dispatch->thenReturn(new EmptyResponse(204)); \Phake::when($h)->dispatch->thenReturn(new EmptyResponse(204));
} }
$out = $r->dispatch($req); $out = $r->dispatch($req);
$this->assertInstanceOf(ResponseInterface::class, $out); $this->assertInstanceOf(ResponseInterface::class, $out);
if ($called) { if ($called) {
Phake::verify($r)->authenticateRequest; \Phake::verify($r)->authenticateRequest;
Phake::verify($h)->dispatch(Phake::capture($in)); \Phake::verify($h)->dispatch(\Phake::capture($in));
$this->assertSame($method, $in->getMethod()); $this->assertSame($method, $in->getMethod());
$this->assertSame($target, $in->getRequestTarget()); $this->assertSame($target, $in->getRequestTarget());
} else { } else {
$this->assertSame(501, $out->getStatusCode()); $this->assertSame(501, $out->getStatusCode());
} }
Phake::verify($r)->apiMatch; \Phake::verify($r)->apiMatch;
Phake::verify($r)->normalizeResponse; \Phake::verify($r)->normalizeResponse;
} }
public function provideMockRequests() { public function provideMockRequests() {

View file

@ -1,66 +0,0 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\REST;
use JKingWeb\Arsse\REST\Target;
/** @covers \JKingWeb\Arsse\REST\Target */
class TestTarget extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideTargetUrls */
public function testParseTargetUrl(string $target, array $path, bool $relative, bool $index, string $query, string $fragment, string $normalized) {
$test = new Target($target);
$this->assertEquals($path, $test->path, "Path does not match");
$this->assertSame($path, $test->path, "Path does not match exactly");
$this->assertSame($relative, $test->relative, "Relative flag does not match");
$this->assertSame($index, $test->index, "Index flag does not match");
$this->assertSame($query, $test->query, "Query does not match");
$this->assertSame($fragment, $test->fragment, "Fragment does not match");
}
/** @dataProvider provideTargetUrls */
public function testNormalizeTargetUrl(string $target, array $path, bool $relative, bool $index, string $query, string $fragment, string $normalized) {
$test = new Target("");
$test->path = $path;
$test->relative = $relative;
$test->index = $index;
$test->query = $query;
$test->fragment = $fragment;
$this->assertSame($normalized, (string) $test);
$this->assertSame($normalized, Target::normalize($target));
}
public function provideTargetUrls() {
return [
["/", [], false, true, "", "", "/"],
["", [], true, true, "", "", ""],
["/index.php", ["index.php"], false, false, "", "", "/index.php"],
["index.php", ["index.php"], true, false, "", "", "index.php"],
["/ook/", ["ook"], false, true, "", "", "/ook/"],
["ook/", ["ook"], true, true, "", "", "ook/"],
["/eek/../ook/", ["ook"], false, true, "", "", "/ook/"],
["eek/../ook/", ["ook"], true, true, "", "", "ook/"],
["/./ook/", ["ook"], false, true, "", "", "/ook/"],
["./ook/", ["ook"], true, true, "", "", "ook/"],
["/../ook/", [null,"ook"], false, true, "", "", "/../ook/"],
["../ook/", [null,"ook"], true, true, "", "", "../ook/"],
["0", ["0"], true, false, "", "", "0"],
["%6f%6F%6b", ["ook"], true, false, "", "", "ook"],
["%2e%2E%2f%2E%2Fook%2f", [".././ook/"], true, false, "", "", "..%2F.%2Fook%2F"],
["%2e%2E/%2E/ook%2f", ["..",".","ook/"], true, false, "", "", "%2E%2E/%2E/ook%2F"],
["...", ["..."], true, false, "", "", "..."],
["%2e%2e%2e", ["..."], true, false, "", "", "..."],
["/?", [], false, true, "", "", "/"],
["/#", [], false, true, "", "", "/"],
["/?#", [], false, true, "", "", "/"],
["#%2e", [], true, true, "", ".", "#."],
["?%2e", [], true, true, "%2e", "", "?%2e"],
["?%2e#%2f", [], true, true, "%2e", "/", "?%2e#%2F"],
["#%2e?%2f", [], true, true, "", ".?/", "#.%3F%2F"],
];
}
}

View file

@ -7,11 +7,8 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\REST\TinyTinyRSS; namespace JKingWeb\Arsse\TestCase\REST\TinyTinyRSS;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\User; use JKingWeb\Arsse\User;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Service;
use JKingWeb\Arsse\REST\Request;
use JKingWeb\Arsse\Test\Result; use JKingWeb\Arsse\Test\Result;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
@ -22,7 +19,6 @@ use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\Response\JsonResponse as Response; use Zend\Diactoros\Response\JsonResponse as Response;
use Zend\Diactoros\Response\EmptyResponse; use Zend\Diactoros\Response\EmptyResponse;
use Phake;
/** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\API<extended> /** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\API<extended>
* @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Exception */ * @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Exception */
@ -179,14 +175,14 @@ LONG_STRING;
self::clearData(); self::clearData();
self::setConf(); self::setConf();
// create a mock user manager // create a mock user manager
Arsse::$user = Phake::mock(User::class); Arsse::$user = \Phake::mock(User::class);
Phake::when(Arsse::$user)->auth->thenReturn(true); \Phake::when(Arsse::$user)->auth->thenReturn(true);
Arsse::$user->id = "john.doe@example.com"; Arsse::$user->id = "john.doe@example.com";
// create a mock database interface // create a mock database interface
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(Transaction::class)); \Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
Phake::when(Arsse::$db)->sessionResume->thenThrow(new \JKingWeb\Arsse\User\ExceptionSession("invalid")); \Phake::when(Arsse::$db)->sessionResume->thenThrow(new \JKingWeb\Arsse\User\ExceptionSession("invalid"));
Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([ \Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
'id' => "PriestsOfSyrinx", 'id' => "PriestsOfSyrinx",
'created' => "2000-01-01 00:00:00", 'created' => "2000-01-01 00:00:00",
'expires' => "2112-12-21 21:12:00", 'expires' => "2112-12-21 21:12:00",
@ -226,11 +222,11 @@ LONG_STRING;
public function testLogIn(array $conf, $httpUser, array $data, $sessions) { public function testLogIn(array $conf, $httpUser, array $data, $sessions) {
Arsse::$user->id = null; Arsse::$user->id = null;
self::setConf($conf); self::setConf($conf);
Phake::when(Arsse::$user)->auth->thenReturn(false); \Phake::when(Arsse::$user)->auth->thenReturn(false);
Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true); \Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true); \Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true);
Phake::when(Arsse::$db)->sessionCreate("john.doe@example.com")->thenReturn("PriestsOfSyrinx")->thenReturn("SolarFederation"); \Phake::when(Arsse::$db)->sessionCreate("john.doe@example.com")->thenReturn("PriestsOfSyrinx")->thenReturn("SolarFederation");
Phake::when(Arsse::$db)->sessionCreate("jane.doe@example.com")->thenReturn("ClockworkAngels")->thenReturn("SevenCitiesOfGold"); \Phake::when(Arsse::$db)->sessionCreate("jane.doe@example.com")->thenReturn("ClockworkAngels")->thenReturn("SevenCitiesOfGold");
if ($sessions instanceof EmptyResponse) { if ($sessions instanceof EmptyResponse) {
$exp1 = $sessions; $exp1 = $sessions;
$exp2 = $sessions; $exp2 = $sessions;
@ -249,7 +245,7 @@ LONG_STRING;
} }
$this->assertMessage($exp2, $this->reqAuth($data, $httpUser)); $this->assertMessage($exp2, $this->reqAuth($data, $httpUser));
// logging in should never try to resume a session // logging in should never try to resume a session
Phake::verify(Arsse::$db, Phake::times(0))->sessionResume($this->anything()); \Phake::verify(Arsse::$db, \Phake::times(0))->sessionResume($this->anything());
} }
public function provideLoginRequests() { public function provideLoginRequests() {
@ -260,13 +256,13 @@ LONG_STRING;
public function testValidateASession(array $conf, $httpUser, string $data, $result) { public function testValidateASession(array $conf, $httpUser, string $data, $result) {
Arsse::$user->id = null; Arsse::$user->id = null;
self::setConf($conf); self::setConf($conf);
Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([ \Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
'id' => "PriestsOfSyrinx", 'id' => "PriestsOfSyrinx",
'created' => "2000-01-01 00:00:00", 'created' => "2000-01-01 00:00:00",
'expires' => "2112-12-21 21:12:00", 'expires' => "2112-12-21 21:12:00",
'user' => "john.doe@example.com", 'user' => "john.doe@example.com",
]); ]);
Phake::when(Arsse::$db)->sessionResume("ClockworkAngels")->thenReturn([ \Phake::when(Arsse::$db)->sessionResume("ClockworkAngels")->thenReturn([
'id' => "ClockworkAngels", 'id' => "ClockworkAngels",
'created' => "2000-01-01 00:00:00", 'created' => "2000-01-01 00:00:00",
'expires' => "2112-12-21 21:12:00", 'expires' => "2112-12-21 21:12:00",
@ -542,7 +538,7 @@ LONG_STRING;
} }
public function testHandleGenericError() { public function testHandleGenericError() {
Phake::when(Arsse::$user)->auth(Arsse::$user->id, $this->anything())->thenThrow(new \JKingWeb\Arsse\Db\ExceptionTimeout("general")); \Phake::when(Arsse::$user)->auth(Arsse::$user->id, $this->anything())->thenThrow(new \JKingWeb\Arsse\Db\ExceptionTimeout("general"));
$data = [ $data = [
'op' => "login", 'op' => "login",
'user' => Arsse::$user->id, 'user' => Arsse::$user->id,
@ -553,14 +549,14 @@ LONG_STRING;
} }
public function testLogOut() { public function testLogOut() {
Phake::when(Arsse::$db)->sessionDestroy->thenReturn(true); \Phake::when(Arsse::$db)->sessionDestroy->thenReturn(true);
$data = [ $data = [
'op' => "logout", 'op' => "logout",
'sid' => "PriestsOfSyrinx", 'sid' => "PriestsOfSyrinx",
]; ];
$exp = $this->respGood(['status' => "OK"]); $exp = $this->respGood(['status' => "OK"]);
$this->assertMessage($exp, $this->req($data)); $this->assertMessage($exp, $this->req($data));
Phake::verify(Arsse::$db)->sessionDestroy(Arsse::$user->id, "PriestsOfSyrinx"); \Phake::verify(Arsse::$db)->sessionDestroy(Arsse::$user->id, "PriestsOfSyrinx");
} }
public function testHandleUnknownMethods() { public function testHandleUnknownMethods() {
@ -628,15 +624,15 @@ LONG_STRING;
['id' => 1, 'name' => "Politics", 'parent' => null], ['id' => 1, 'name' => "Politics", 'parent' => null],
]; ];
// set of various mocks for testing // set of various mocks for testing
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $db[0])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $db[0])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $db[1])->thenReturn(3)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $db[1])->thenReturn(3)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->folderList(Arsse::$user->id, null, false)->thenReturn(new Result($this->v([$out[0], $out[2]]))); \Phake::when(Arsse::$db)->folderList(Arsse::$user->id, null, false)->thenReturn(new Result($this->v([$out[0], $out[2]])));
Phake::when(Arsse::$db)->folderList(Arsse::$user->id, 1, false)->thenReturn(new Result($this->v([$out[1]]))); \Phake::when(Arsse::$db)->folderList(Arsse::$user->id, 1, false)->thenReturn(new Result($this->v([$out[1]])));
// set up mocks that produce errors // set up mocks that produce errors
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $db[2])->thenThrow(new ExceptionInput("idMissing")); // parent folder does not exist \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, $db[2])->thenThrow(new ExceptionInput("idMissing")); // parent folder does not exist
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => "", 'parent' => null])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => "", 'parent' => null])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => " ", 'parent' => null])->thenThrow(new ExceptionInput("whitespace")); \Phake::when(Arsse::$db)->folderAdd(Arsse::$user->id, ['name' => " ", 'parent' => null])->thenThrow(new ExceptionInput("whitespace"));
// correctly add two folders // correctly add two folders
$exp = $this->respGood("2"); $exp = $this->respGood("2");
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -647,8 +643,8 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
$exp = $this->respGood("3"); $exp = $this->respGood("3");
$this->assertMessage($exp, $this->req($in[1])); $this->assertMessage($exp, $this->req($in[1]));
Phake::verify(Arsse::$db)->folderList(Arsse::$user->id, null, false); \Phake::verify(Arsse::$db)->folderList(Arsse::$user->id, null, false);
Phake::verify(Arsse::$db)->folderList(Arsse::$user->id, 1, false); \Phake::verify(Arsse::$db)->folderList(Arsse::$user->id, 1, false);
// add a folder to a missing parent (silently fails) // add a folder to a missing parent (silently fails)
$exp = $this->respGood(false); $exp = $this->respGood(false);
$this->assertMessage($exp, $this->req($in[2])); $this->assertMessage($exp, $this->req($in[2]));
@ -665,8 +661,8 @@ LONG_STRING;
['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112], ['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112],
['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => -1], ['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => -1],
]; ];
Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 42)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 42)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
// succefully delete a folder // succefully delete a folder
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -679,7 +675,7 @@ LONG_STRING;
// delete an invalid folder (causes an error) // delete an invalid folder (causes an error)
$exp = $this->respErr("INCORRECT_USAGE"); $exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[2])); $this->assertMessage($exp, $this->req($in[2]));
Phake::verify(Arsse::$db, Phake::times(3))->folderRemove(Arsse::$user->id, $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(3))->folderRemove(Arsse::$user->id, $this->anything());
} }
public function testMoveACategory() { public function testMoveACategory() {
@ -705,15 +701,15 @@ LONG_STRING;
[Arsse::$user->id, 0, ['parent' => -1]], [Arsse::$user->id, 0, ['parent' => -1]],
[Arsse::$user->id, 0, ['parent' => 0]], [Arsse::$user->id, 0, ['parent' => 0]],
]; ];
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[0])->thenReturn(true); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[0])->thenReturn(true);
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("idMissing")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("idMissing"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[4])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[4])->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[5])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[5])->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[6])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[6])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[7])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[7])->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[8])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[8])->thenThrow(new ExceptionInput("typeViolation"));
// succefully move a folder // succefully move a folder
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -731,7 +727,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[5])); $this->assertMessage($exp, $this->req($in[5]));
$this->assertMessage($exp, $this->req($in[7])); $this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8])); $this->assertMessage($exp, $this->req($in[8]));
Phake::verify(Arsse::$db, Phake::times(5))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(5))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testRenameACategory() { public function testRenameACategory() {
@ -751,9 +747,9 @@ LONG_STRING;
[Arsse::$user->id, 2112, ['name' => "Eek"]], [Arsse::$user->id, 2112, ['name' => "Eek"]],
[Arsse::$user->id, 42, ['name' => "Eek"]], [Arsse::$user->id, 42, ['name' => "Eek"]],
]; ];
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[0])->thenReturn(true); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[0])->thenReturn(true);
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->folderPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->folderPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
// succefully rename a folder // succefully rename a folder
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -771,7 +767,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[6])); $this->assertMessage($exp, $this->req($in[6]));
$this->assertMessage($exp, $this->req($in[7])); $this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8])); $this->assertMessage($exp, $this->req($in[8]));
Phake::verify(Arsse::$db, Phake::times(3))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(3))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testAddASubscription() { public function testAddASubscription() {
@ -822,22 +818,22 @@ LONG_STRING;
['id' => 3, 'url' => "http://example.com/3"], ['id' => 3, 'url' => "http://example.com/3"],
['id' => 4, 'url' => "http://example.com/9"], ['id' => 4, 'url' => "http://example.com/9"],
]; ];
Phake::when(Arsse::$db)->subscriptionAdd(...$db[0])->thenReturn(2); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[0])->thenReturn(2);
Phake::when(Arsse::$db)->subscriptionAdd(...$db[1])->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/1", new \PicoFeed\Client\UnauthorizedException())); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[1])->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/1", new \PicoFeed\Client\UnauthorizedException()));
Phake::when(Arsse::$db)->subscriptionAdd(...$db[2])->thenReturn(2); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[2])->thenReturn(2);
Phake::when(Arsse::$db)->subscriptionAdd(...$db[3])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[3])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->subscriptionAdd(...$db[4])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[4])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->subscriptionAdd(...$db[5])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[5])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->subscriptionAdd(...$db[6])->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/6", new \PicoFeed\Client\InvalidUrlException())); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[6])->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/6", new \PicoFeed\Client\InvalidUrlException()));
Phake::when(Arsse::$db)->subscriptionAdd(...$db[7])->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/7", new \PicoFeed\Parser\MalformedXmlException())); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[7])->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/7", new \PicoFeed\Parser\MalformedXmlException()));
Phake::when(Arsse::$db)->subscriptionAdd(...$db[8])->thenReturn(4); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[8])->thenReturn(4);
Phake::when(Arsse::$db)->subscriptionAdd(...$db[9])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionAdd(...$db[9])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 42)->thenReturn($this->v(['id' => 42])); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 42)->thenReturn($this->v(['id' => 42]));
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 47)->thenReturn($this->v(['id' => 47])); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 47)->thenReturn($this->v(['id' => 47]));
Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2112)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2112)->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything())->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything())->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 4, $this->anything())->thenThrow(new ExceptionInput("idMissing")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 4, $this->anything())->thenThrow(new ExceptionInput("idMissing"));
Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v($list))); \Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v($list)));
for ($a = 0; $a < (sizeof($in) - 4); $a++) { for ($a = 0; $a < (sizeof($in) - 4); $a++) {
$exp = $this->respGood($out[$a]); $exp = $this->respGood($out[$a]);
$this->assertMessage($exp, $this->req($in[$a]), "Failed test $a"); $this->assertMessage($exp, $this->req($in[$a]), "Failed test $a");
@ -846,7 +842,7 @@ LONG_STRING;
for ($a = (sizeof($in) - 4); $a < sizeof($in); $a++) { for ($a = (sizeof($in) - 4); $a < sizeof($in); $a++) {
$this->assertMessage($exp, $this->req($in[$a]), "Failed test $a"); $this->assertMessage($exp, $this->req($in[$a]), "Failed test $a");
} }
Phake::verify(Arsse::$db, Phake::times(0))->subscriptionPropertiesSet(Arsse::$user->id, 4, ['folder' => 1]); \Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet(Arsse::$user->id, 4, ['folder' => 1]);
} }
public function testRemoveASubscription() { public function testRemoveASubscription() {
@ -856,9 +852,9 @@ LONG_STRING;
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1], ['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1],
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx"], ['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx"],
]; ];
Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 2112)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 2112)->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 42)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 42)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
// succefully delete a folder // succefully delete a folder
$exp = $this->respGood(['status' => "OK"]); $exp = $this->respGood(['status' => "OK"]);
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -868,7 +864,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[1])); $this->assertMessage($exp, $this->req($in[1]));
$this->assertMessage($exp, $this->req($in[2])); $this->assertMessage($exp, $this->req($in[2]));
$this->assertMessage($exp, $this->req($in[3])); $this->assertMessage($exp, $this->req($in[3]));
Phake::verify(Arsse::$db, Phake::times(5))->subscriptionRemove(Arsse::$user->id, $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(5))->subscriptionRemove(Arsse::$user->id, $this->anything());
} }
public function testMoveASubscription() { public function testMoveASubscription() {
@ -889,10 +885,10 @@ LONG_STRING;
[Arsse::$user->id, 42, ['folder' => 0]], [Arsse::$user->id, 42, ['folder' => 0]],
[Arsse::$user->id, 42, ['folder' => 47]], [Arsse::$user->id, 42, ['folder' => 47]],
]; ];
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[0])->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[0])->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("constraintViolation"));
// succefully move a subscription // succefully move a subscription
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -910,7 +906,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[6])); $this->assertMessage($exp, $this->req($in[6]));
$this->assertMessage($exp, $this->req($in[7])); $this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8])); $this->assertMessage($exp, $this->req($in[8]));
Phake::verify(Arsse::$db, Phake::times(4))->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(4))->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testRenameASubscription() { public function testRenameASubscription() {
@ -930,9 +926,9 @@ LONG_STRING;
[Arsse::$user->id, 2112, ['title' => "Eek"]], [Arsse::$user->id, 2112, ['title' => "Eek"]],
[Arsse::$user->id, 42, ['title' => "Eek"]], [Arsse::$user->id, 42, ['title' => "Eek"]],
]; ];
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[0])->thenReturn(true); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[0])->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
// succefully rename a subscription // succefully rename a subscription
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -950,14 +946,14 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[6])); $this->assertMessage($exp, $this->req($in[6]));
$this->assertMessage($exp, $this->req($in[7])); $this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8])); $this->assertMessage($exp, $this->req($in[8]));
Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[0]); \Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[0]);
Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[1]); \Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[1]);
Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[2]); \Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[2]);
} }
public function testRetrieveTheGlobalUnreadCount() { public function testRetrieveTheGlobalUnreadCount() {
$in = ['op' => "getUnread", 'sid' => "PriestsOfSyrinx"]; $in = ['op' => "getUnread", 'sid' => "PriestsOfSyrinx"];
Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v([ \Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v([
['id' => 1, 'unread' => 2112], ['id' => 1, 'unread' => 2112],
['id' => 2, 'unread' => 42], ['id' => 2, 'unread' => 42],
['id' => 3, 'unread' => 47], ['id' => 3, 'unread' => 47],
@ -971,8 +967,8 @@ LONG_STRING;
$interval = Arsse::$conf->serviceFrequency; $interval = Arsse::$conf->serviceFrequency;
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval); $valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
$invalid = $valid->sub($interval)->sub($interval); $invalid = $valid->sub($interval)->sub($interval);
Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql")); \Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
Phake::when(Arsse::$db)->subscriptionCount(Arsse::$user->id)->thenReturn(12)->thenReturn(2); \Phake::when(Arsse::$db)->subscriptionCount(Arsse::$user->id)->thenReturn(12)->thenReturn(2);
$exp = [ $exp = [
['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => true, 'num_feeds' => 12], ['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => true, 'num_feeds' => 12],
['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => false, 'num_feeds' => 2], ['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => false, 'num_feeds' => 2],
@ -988,12 +984,12 @@ LONG_STRING;
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1], ['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1],
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx"], ['op' => "updateFeed", 'sid' => "PriestsOfSyrinx"],
]; ];
Phake::when(Arsse::$db)->feedUpdate(11)->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate(11)->thenReturn(true);
Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v(['id' => 1, 'feed' => 11])); \Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v(['id' => 1, 'feed' => 11]));
Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 2)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 2)->thenThrow(new ExceptionInput("subjectMissing"));
$exp = $this->respGood(['status' => "OK"]); $exp = $this->respGood(['status' => "OK"]);
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
Phake::verify(Arsse::$db)->feedUpdate(11); \Phake::verify(Arsse::$db)->feedUpdate(11);
$exp = $this->respErr("FEED_NOT_FOUND"); $exp = $this->respErr("FEED_NOT_FOUND");
$this->assertMessage($exp, $this->req($in[1])); $this->assertMessage($exp, $this->req($in[1]));
$exp = $this->respErr("INCORRECT_USAGE"); $exp = $this->respErr("INCORRECT_USAGE");
@ -1019,14 +1015,14 @@ LONG_STRING;
['id' => 1, 'name' => "Politics"], ['id' => 1, 'name' => "Politics"],
]; ];
// set of various mocks for testing // set of various mocks for testing
Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[0])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[0])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[1])->thenReturn(3)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call \Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[1])->thenReturn(3)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
Phake::when(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true)->thenReturn($this->v($out[0])); \Phake::when(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true)->thenReturn($this->v($out[0]));
Phake::when(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true)->thenReturn($this->v($out[1])); \Phake::when(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true)->thenReturn($this->v($out[1]));
// set up mocks that produce errors // set up mocks that produce errors
Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => ""])->thenThrow(new ExceptionInput("missing")); \Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => ""])->thenThrow(new ExceptionInput("missing"));
Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => " "])->thenThrow(new ExceptionInput("whitespace")); \Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => " "])->thenThrow(new ExceptionInput("whitespace"));
// correctly add two labels // correctly add two labels
$exp = $this->respGood((-1 * API::LABEL_OFFSET) - 2); $exp = $this->respGood((-1 * API::LABEL_OFFSET) - 2);
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -1037,8 +1033,8 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
$exp = $this->respGood((-1 * API::LABEL_OFFSET) - 3); $exp = $this->respGood((-1 * API::LABEL_OFFSET) - 3);
$this->assertMessage($exp, $this->req($in[1])); $this->assertMessage($exp, $this->req($in[1]));
Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true); \Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true);
Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true); \Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true);
// add some invalid labels // add some invalid labels
$exp = $this->respErr("INCORRECT_USAGE"); $exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[2])); $this->assertMessage($exp, $this->req($in[2]));
@ -1054,8 +1050,8 @@ LONG_STRING;
['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => 0], ['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => 0],
['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -10], ['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -10],
]; ];
Phake::when(Arsse::$db)->labelRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->labelRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->labelRemove(Arsse::$user->id, 18)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->labelRemove(Arsse::$user->id, 18)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
// succefully delete a label // succefully delete a label
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -1070,8 +1066,8 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[2])); $this->assertMessage($exp, $this->req($in[2]));
$this->assertMessage($exp, $this->req($in[3])); $this->assertMessage($exp, $this->req($in[3]));
$this->assertMessage($exp, $this->req($in[4])); $this->assertMessage($exp, $this->req($in[4]));
Phake::verify(Arsse::$db, Phake::times(2))->labelRemove(Arsse::$user->id, 18); \Phake::verify(Arsse::$db, \Phake::times(2))->labelRemove(Arsse::$user->id, 18);
Phake::verify(Arsse::$db)->labelRemove(Arsse::$user->id, 1088); \Phake::verify(Arsse::$db)->labelRemove(Arsse::$user->id, 1088);
} }
public function testRenameALabel() { public function testRenameALabel() {
@ -1094,12 +1090,12 @@ LONG_STRING;
[Arsse::$user->id, 18, ['name' => " "]], [Arsse::$user->id, 18, ['name' => " "]],
[Arsse::$user->id, 18, ['name' => ""]], [Arsse::$user->id, 18, ['name' => ""]],
]; ];
Phake::when(Arsse::$db)->labelPropertiesSet(...$db[0])->thenReturn(true); \Phake::when(Arsse::$db)->labelPropertiesSet(...$db[0])->thenReturn(true);
Phake::when(Arsse::$db)->labelPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->labelPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->labelPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation")); \Phake::when(Arsse::$db)->labelPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
Phake::when(Arsse::$db)->labelPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->labelPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->labelPropertiesSet(...$db[4])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->labelPropertiesSet(...$db[4])->thenThrow(new ExceptionInput("typeViolation"));
Phake::when(Arsse::$db)->labelPropertiesSet(...$db[5])->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->labelPropertiesSet(...$db[5])->thenThrow(new ExceptionInput("typeViolation"));
// succefully rename a label // succefully rename a label
$exp = $this->respGood(); $exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
@ -1117,7 +1113,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[6])); $this->assertMessage($exp, $this->req($in[6]));
$this->assertMessage($exp, $this->req($in[7])); $this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8])); $this->assertMessage($exp, $this->req($in[8]));
Phake::verify(Arsse::$db, Phake::times(6))->labelPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(6))->labelPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testRetrieveCategoryLists() { public function testRetrieveCategoryLists() {
@ -1129,12 +1125,12 @@ LONG_STRING;
['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'enable_nested' => true], ['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'enable_nested' => true],
['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'enable_nested' => true, 'unread_only' => true], ['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'enable_nested' => true, 'unread_only' => true],
]; ];
Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders))); \Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders)));
Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->topFolders))); \Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->topFolders)));
Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions))); \Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7); \Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred)); \Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
$exp = [ $exp = [
[ [
['id' => "5", 'title' => "Local", 'unread' => 10, 'order_id' => 1], ['id' => "5", 'title' => "Local", 'unread' => 10, 'order_id' => 1],
@ -1194,11 +1190,11 @@ LONG_STRING;
public function testRetrieveCounterList() { public function testRetrieveCounterList() {
$in = ['op' => "getCounters", 'sid' => "PriestsOfSyrinx"]; $in = ['op' => "getCounters", 'sid' => "PriestsOfSyrinx"];
Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders))); \Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders)));
Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions))); \Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels))); \Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7); \Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred)); \Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
$exp = [ $exp = [
['id' => "global-unread", 'counter' => 35], ['id' => "global-unread", 'counter' => 35],
['id' => "subscribed-feeds", 'counter' => 6], ['id' => "subscribed-feeds", 'counter' => 6],
@ -1235,11 +1231,11 @@ LONG_STRING;
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 3], ['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 3],
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 4], ['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 4],
]; ];
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 1)->thenReturn($this->v([1,3])); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 1)->thenReturn($this->v([1,3]));
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2)->thenReturn($this->v([3])); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2)->thenReturn($this->v([3]));
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 3)->thenReturn([]); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 3)->thenReturn([]);
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 4)->thenThrow(new ExceptionInput("idMissing")); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 4)->thenThrow(new ExceptionInput("idMissing"));
$exp = [ $exp = [
[ [
['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => false], ['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
@ -1287,20 +1283,20 @@ LONG_STRING;
['op' => "setArticleLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => 0], ['op' => "setArticleLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => 0],
['op' => "setArticleLabel", 'sid' => "PriestsOfSyrinx"], ['op' => "setArticleLabel", 'sid' => "PriestsOfSyrinx"],
]; ];
Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, $this->anything(), (new Context)->articles([]), $this->anything())->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples \Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, $this->anything(), (new Context)->articles([]), $this->anything())->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, $this->anything(), (new Context)->articles($list[0]), $this->anything())->thenThrow(new ExceptionInput("tooLong")); // data model function limited to 50 items for multiples \Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, $this->anything(), (new Context)->articles($list[0]), $this->anything())->thenThrow(new ExceptionInput("tooLong")); // data model function limited to 50 items for multiples
Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_REMOVE)->thenReturn(42); \Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_REMOVE)->thenReturn(42);
Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_REMOVE)->thenReturn(47); \Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_REMOVE)->thenReturn(47);
Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_ADD)->thenReturn(5); \Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_ADD)->thenReturn(5);
Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_ADD)->thenReturn(2); \Phake::when(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_ADD)->thenReturn(2);
$exp = $this->respGood(['status' => "OK", 'updated' => 89]); $exp = $this->respGood(['status' => "OK", 'updated' => 89]);
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_REMOVE); \Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_REMOVE);
Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_REMOVE); \Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_REMOVE);
$exp = $this->respGood(['status' => "OK", 'updated' => 7]); $exp = $this->respGood(['status' => "OK", 'updated' => 7]);
$this->assertMessage($exp, $this->req($in[1])); $this->assertMessage($exp, $this->req($in[1]));
Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_ADD); \Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[1]), Database::ASSOC_ADD);
Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_ADD); \Phake::verify(Arsse::$db)->labelArticlesSet(Arsse::$user->id, 1088, (new Context)->articles($list[2]), Database::ASSOC_ADD);
$exp = $this->respGood(['status' => "OK", 'updated' => 0]); $exp = $this->respGood(['status' => "OK", 'updated' => 0]);
$this->assertMessage($exp, $this->req($in[2])); $this->assertMessage($exp, $this->req($in[2]));
$exp = $this->respErr("INCORRECT_USAGE"); $exp = $this->respErr("INCORRECT_USAGE");
@ -1315,11 +1311,11 @@ LONG_STRING;
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx", 'include_empty' => true], ['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx", 'include_empty' => true],
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx"], ['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx"],
]; ];
Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders))); \Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders)));
Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions))); \Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
Phake::when(Arsse::$db)->labelList($this->anything(), true)->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything(), true)->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7); \Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred)); \Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
// the expectations are packed tightly since they're very verbose; one can use var_export() (or convert to JSON) to pretty-print them // the expectations are packed tightly since they're very verbose; one can use var_export() (or convert to JSON) to pretty-print them
$exp = ['categories'=>['identifier'=>'id','label'=>'name','items'=>[['name'=>'Special','id'=>'CAT:-1','bare_id'=>-1,'type'=>'category','unread'=>0,'items'=>[['name'=>'All articles','id'=>'FEED:-4','bare_id'=>-4,'icon'=>'images/folder.png','unread'=>35,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Fresh articles','id'=>'FEED:-3','bare_id'=>-3,'icon'=>'images/fresh.png','unread'=>7,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Starred articles','id'=>'FEED:-1','bare_id'=>-1,'icon'=>'images/star.png','unread'=>4,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Published articles','id'=>'FEED:-2','bare_id'=>-2,'icon'=>'images/feed.png','unread'=>0,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Archived articles','id'=>'FEED:0','bare_id'=>0,'icon'=>'images/archive.png','unread'=>0,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Recently read','id'=>'FEED:-6','bare_id'=>-6,'icon'=>'images/time.png','unread'=>0,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],],],['name'=>'Labels','id'=>'CAT:-2','bare_id'=>-2,'type'=>'category','unread'=>6,'items'=>[['name'=>'Fascinating','id'=>'FEED:-1027','bare_id'=>-1027,'unread'=>0,'icon'=>'images/label.png','type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'','fg_color'=>'','bg_color'=>'',],['name'=>'Interesting','id'=>'FEED:-1029','bare_id'=>-1029,'unread'=>0,'icon'=>'images/label.png','type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'','fg_color'=>'','bg_color'=>'',],['name'=>'Logical','id'=>'FEED:-1025','bare_id'=>-1025,'unread'=>0,'icon'=>'images/label.png','type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'','fg_color'=>'','bg_color'=>'',],],],['name'=>'Photography','id'=>'CAT:4','bare_id'=>4,'parent_id'=>null,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(0 feeds)','items'=>[],],['name'=>'Politics','id'=>'CAT:3','bare_id'=>3,'parent_id'=>null,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(3 feeds)','items'=>[['name'=>'Local','id'=>'CAT:5','bare_id'=>5,'parent_id'=>3,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(1 feed)','items'=>[['name'=>'Toronto Star','id'=>'FEED:2','bare_id'=>2,'icon'=>'feed-icons/2.ico','error'=>'oops','param'=>'2011-11-11T11:11:11Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],['name'=>'National','id'=>'CAT:6','bare_id'=>6,'parent_id'=>3,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(2 feeds)','items'=>[['name'=>'CBC News','id'=>'FEED:4','bare_id'=>4,'icon'=>'feed-icons/4.ico','error'=>'','param'=>'2017-10-09T15:58:34Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],['name'=>'Ottawa Citizen','id'=>'FEED:5','bare_id'=>5,'icon'=>false,'error'=>'','param'=>'2017-07-07T17:07:17Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],],],['name'=>'Science','id'=>'CAT:1','bare_id'=>1,'parent_id'=>null,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(2 feeds)','items'=>[['name'=>'Rocketry','id'=>'CAT:2','bare_id'=>2,'parent_id'=>1,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(1 feed)','items'=>[['name'=>'NASA JPL','id'=>'FEED:1','bare_id'=>1,'icon'=>false,'error'=>'','param'=>'2017-09-15T22:54:16Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],['name'=>'Ars Technica','id'=>'FEED:3','bare_id'=>3,'icon'=>'feed-icons/3.ico','error'=>'argh','param'=>'2016-05-23T06:40:02Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],['name'=>'Uncategorized','id'=>'CAT:0','bare_id'=>0,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'parent_id'=>null,'param'=>'(1 feed)','items'=>[['name'=>'Eurogamer','id'=>'FEED:6','bare_id'=>6,'icon'=>'feed-icons/6.ico','error'=>'','param'=>'2010-02-12T20:08:47Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],],],]; $exp = ['categories'=>['identifier'=>'id','label'=>'name','items'=>[['name'=>'Special','id'=>'CAT:-1','bare_id'=>-1,'type'=>'category','unread'=>0,'items'=>[['name'=>'All articles','id'=>'FEED:-4','bare_id'=>-4,'icon'=>'images/folder.png','unread'=>35,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Fresh articles','id'=>'FEED:-3','bare_id'=>-3,'icon'=>'images/fresh.png','unread'=>7,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Starred articles','id'=>'FEED:-1','bare_id'=>-1,'icon'=>'images/star.png','unread'=>4,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Published articles','id'=>'FEED:-2','bare_id'=>-2,'icon'=>'images/feed.png','unread'=>0,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Archived articles','id'=>'FEED:0','bare_id'=>0,'icon'=>'images/archive.png','unread'=>0,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],['name'=>'Recently read','id'=>'FEED:-6','bare_id'=>-6,'icon'=>'images/time.png','unread'=>0,'type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'',],],],['name'=>'Labels','id'=>'CAT:-2','bare_id'=>-2,'type'=>'category','unread'=>6,'items'=>[['name'=>'Fascinating','id'=>'FEED:-1027','bare_id'=>-1027,'unread'=>0,'icon'=>'images/label.png','type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'','fg_color'=>'','bg_color'=>'',],['name'=>'Interesting','id'=>'FEED:-1029','bare_id'=>-1029,'unread'=>0,'icon'=>'images/label.png','type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'','fg_color'=>'','bg_color'=>'',],['name'=>'Logical','id'=>'FEED:-1025','bare_id'=>-1025,'unread'=>0,'icon'=>'images/label.png','type'=>'feed','auxcounter'=>0,'error'=>'','updated'=>'','fg_color'=>'','bg_color'=>'',],],],['name'=>'Photography','id'=>'CAT:4','bare_id'=>4,'parent_id'=>null,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(0 feeds)','items'=>[],],['name'=>'Politics','id'=>'CAT:3','bare_id'=>3,'parent_id'=>null,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(3 feeds)','items'=>[['name'=>'Local','id'=>'CAT:5','bare_id'=>5,'parent_id'=>3,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(1 feed)','items'=>[['name'=>'Toronto Star','id'=>'FEED:2','bare_id'=>2,'icon'=>'feed-icons/2.ico','error'=>'oops','param'=>'2011-11-11T11:11:11Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],['name'=>'National','id'=>'CAT:6','bare_id'=>6,'parent_id'=>3,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(2 feeds)','items'=>[['name'=>'CBC News','id'=>'FEED:4','bare_id'=>4,'icon'=>'feed-icons/4.ico','error'=>'','param'=>'2017-10-09T15:58:34Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],['name'=>'Ottawa Citizen','id'=>'FEED:5','bare_id'=>5,'icon'=>false,'error'=>'','param'=>'2017-07-07T17:07:17Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],],],['name'=>'Science','id'=>'CAT:1','bare_id'=>1,'parent_id'=>null,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(2 feeds)','items'=>[['name'=>'Rocketry','id'=>'CAT:2','bare_id'=>2,'parent_id'=>1,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'param'=>'(1 feed)','items'=>[['name'=>'NASA JPL','id'=>'FEED:1','bare_id'=>1,'icon'=>false,'error'=>'','param'=>'2017-09-15T22:54:16Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],['name'=>'Ars Technica','id'=>'FEED:3','bare_id'=>3,'icon'=>'feed-icons/3.ico','error'=>'argh','param'=>'2016-05-23T06:40:02Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],['name'=>'Uncategorized','id'=>'CAT:0','bare_id'=>0,'type'=>'category','auxcounter'=>0,'unread'=>0,'child_unread'=>0,'checkbox'=>false,'parent_id'=>null,'param'=>'(1 feed)','items'=>[['name'=>'Eurogamer','id'=>'FEED:6','bare_id'=>6,'icon'=>'feed-icons/6.ico','error'=>'','param'=>'2010-02-12T20:08:47Z','unread'=>0,'auxcounter'=>0,'checkbox'=>false,],],],],],];
$this->assertMessage($this->respGood($exp), $this->req($in[0])); $this->assertMessage($this->respGood($exp), $this->req($in[0]));
@ -1352,30 +1348,30 @@ LONG_STRING;
// this one has a tricky time-based context // this one has a tricky time-based context
['op' => "catchupFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3], ['op' => "catchupFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3],
]; ];
Phake::when(Arsse::$db)->articleMark->thenThrow(new ExceptionInput("typeViolation")); \Phake::when(Arsse::$db)->articleMark->thenThrow(new ExceptionInput("typeViolation"));
$exp = $this->respGood(['status' => "OK"]); $exp = $this->respGood(['status' => "OK"]);
// verify the above are in fact no-ops // verify the above are in fact no-ops
for ($a = 0; $a < sizeof($in1); $a++) { for ($a = 0; $a < sizeof($in1); $a++) {
$this->assertMessage($exp, $this->req($in1[$a]), "Test $a failed"); $this->assertMessage($exp, $this->req($in1[$a]), "Test $a failed");
} }
Phake::verify(Arsse::$db, Phake::times(0))->articleMark; \Phake::verify(Arsse::$db, \Phake::times(0))->articleMark;
// verify the simple contexts // verify the simple contexts
for ($a = 0; $a < sizeof($in2); $a++) { for ($a = 0; $a < sizeof($in2); $a++) {
$this->assertMessage($exp, $this->req($in2[$a]), "Test $a failed"); $this->assertMessage($exp, $this->req($in2[$a]), "Test $a failed");
} }
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], new Context); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], new Context);
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->starred(true)); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->starred(true));
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->label(1088)); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->label(1088));
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->subscription(2112)); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->subscription(2112));
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folder(42)); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folder(42));
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folderShallow(0)); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->folderShallow(0));
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->labelled(true)); \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->labelled(true));
// verify the time-based mock // verify the time-based mock
$t = Date::sub("PT24H"); $t = Date::sub("PT24H");
for ($a = 0; $a < sizeof($in3); $a++) { for ($a = 0; $a < sizeof($in3); $a++) {
$this->assertMessage($exp, $this->req($in3[$a]), "Test $a failed"); $this->assertMessage($exp, $this->req($in3[$a]), "Test $a failed");
} }
Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], $this->equalTo((new Context)->modifiedSince($t), 2)); // within two seconds \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], $this->equalTo((new Context)->modifiedSince($t), 2)); // within two seconds
} }
public function testRetrieveFeedList() { public function testRetrieveFeedList() {
@ -1404,24 +1400,24 @@ LONG_STRING;
['op' => "getFeeds", 'sid' => "PriestsOfSyrinx", 'cat_id' => 6, 'offset' => 2], ['op' => "getFeeds", 'sid' => "PriestsOfSyrinx", 'cat_id' => 6, 'offset' => 2],
]; ];
// statistical mocks // statistical mocks
Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred)); \Phake::when(Arsse::$db)->articleStarred($this->anything())->thenReturn($this->v($this->starred));
Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7); \Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->modifiedSince(Date::sub("PT24H")), 2))->thenReturn(7);
Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(35); \Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(35);
// label mocks // label mocks
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels))); \Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
// subscription and folder list and unread count mocks // subscription and folder list and unread count mocks
Phake::when(Arsse::$db)->folderList->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->folderList->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->subscriptionList->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->subscriptionList->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders))); \Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders)));
Phake::when(Arsse::$db)->subscriptionList($this->anything(), null, true)->thenReturn(new Result($this->v($this->subscriptions))); \Phake::when(Arsse::$db)->subscriptionList($this->anything(), null, true)->thenReturn(new Result($this->v($this->subscriptions)));
Phake::when(Arsse::$db)->subscriptionList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterSubs(null)))); \Phake::when(Arsse::$db)->subscriptionList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterSubs(null))));
Phake::when(Arsse::$db)->folderList($this->anything(), null)->thenReturn(new Result($this->v($this->folders))); \Phake::when(Arsse::$db)->folderList($this->anything(), null)->thenReturn(new Result($this->v($this->folders)));
Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterFolders(null)))); \Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterFolders(null))));
foreach ($this->folders as $f) { foreach ($this->folders as $f) {
Phake::when(Arsse::$db)->folderList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterFolders($f['id'])))); \Phake::when(Arsse::$db)->folderList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterFolders($f['id']))));
Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true)->folder($f['id']))->thenReturn($this->reduceFolders($f['id'])); \Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true)->folder($f['id']))->thenReturn($this->reduceFolders($f['id']));
Phake::when(Arsse::$db)->subscriptionList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterSubs($f['id'])))); \Phake::when(Arsse::$db)->subscriptionList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterSubs($f['id']))));
} }
$exp = [ $exp = [
[ [
@ -1573,21 +1569,21 @@ LONG_STRING;
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 4], // invalid field ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 4], // invalid field
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "0, -1", 'field' => 3], // no valid IDs ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "0, -1", 'field' => 3], // no valid IDs
]; ];
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->starred(true), $this->anything())->thenReturn(new Result($this->v([['id' => 42]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->starred(true), $this->anything())->thenReturn(new Result($this->v([['id' => 42]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->starred(false), $this->anything())->thenReturn(new Result($this->v([['id' => 2112]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->starred(false), $this->anything())->thenReturn(new Result($this->v([['id' => 2112]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->unread(true), $this->anything())->thenReturn(new Result($this->v([['id' => 42]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->unread(true), $this->anything())->thenReturn(new Result($this->v([['id' => 42]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->unread(false), $this->anything())->thenReturn(new Result($this->v([['id' => 2112]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([42, 2112])->unread(false), $this->anything())->thenReturn(new Result($this->v([['id' => 2112]])));
Phake::when(Arsse::$db)->articleMark->thenReturn(1); \Phake::when(Arsse::$db)->articleMark->thenReturn(1);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => false], (new Context)->articles([42, 2112]))->thenReturn(2); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => false], (new Context)->articles([42, 2112]))->thenReturn(2);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => true], (new Context)->articles([42, 2112]))->thenReturn(4); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => true], (new Context)->articles([42, 2112]))->thenReturn(4);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => false], (new Context)->articles([42]))->thenReturn(8); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => false], (new Context)->articles([42]))->thenReturn(8);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => true], (new Context)->articles([2112]))->thenReturn(16); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['starred' => true], (new Context)->articles([2112]))->thenReturn(16);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->articles([42, 2112]))->thenReturn(32); // false is read for TT-RSS \Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->articles([42, 2112]))->thenReturn(32); // false is read for TT-RSS
Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => false], (new Context)->articles([42, 2112]))->thenReturn(64); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => false], (new Context)->articles([42, 2112]))->thenReturn(64);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->articles([42]))->thenReturn(128); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => true], (new Context)->articles([42]))->thenReturn(128);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => false], (new Context)->articles([2112]))->thenReturn(256); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['read' => false], (new Context)->articles([2112]))->thenReturn(256);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['note' => ""], (new Context)->articles([42, 2112]))->thenReturn(512); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['note' => ""], (new Context)->articles([42, 2112]))->thenReturn(512);
Phake::when(Arsse::$db)->articleMark($this->anything(), ['note' => "eh"], (new Context)->articles([42, 2112]))->thenReturn(1024); \Phake::when(Arsse::$db)->articleMark($this->anything(), ['note' => "eh"], (new Context)->articles([42, 2112]))->thenReturn(1024);
$out = [ $out = [
$this->respErr("INCORRECT_USAGE"), $this->respErr("INCORRECT_USAGE"),
$this->respGood(['status' => "OK", 'updated' => 2]), $this->respGood(['status' => "OK", 'updated' => 2]),
@ -1637,13 +1633,13 @@ LONG_STRING;
['op' => "getArticle", 'sid' => "PriestsOfSyrinx", 'article_id' => "101"], ['op' => "getArticle", 'sid' => "PriestsOfSyrinx", 'article_id' => "101"],
['op' => "getArticle", 'sid' => "PriestsOfSyrinx", 'article_id' => "102"], ['op' => "getArticle", 'sid' => "PriestsOfSyrinx", 'article_id' => "102"],
]; ];
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels))); \Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 101)->thenReturn([]); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 101)->thenReturn([]);
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 102)->thenReturn($this->v([1,3])); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 102)->thenReturn($this->v([1,3]));
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([101, 102]), $this->anything())->thenReturn(new Result($this->v($this->articles))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([101, 102]), $this->anything())->thenReturn(new Result($this->v($this->articles)));
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([101]), $this->anything())->thenReturn(new Result($this->v([$this->articles[0]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([101]), $this->anything())->thenReturn(new Result($this->v([$this->articles[0]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([102]), $this->anything())->thenReturn(new Result($this->v([$this->articles[1]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->articles([102]), $this->anything())->thenReturn(new Result($this->v([$this->articles[1]])));
$exp = $this->respErr("INCORRECT_USAGE"); $exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[0])); $this->assertMessage($exp, $this->req($in[0]));
$this->assertMessage($exp, $this->req($in[1])); $this->assertMessage($exp, $this->req($in[1]));
@ -1709,8 +1705,8 @@ LONG_STRING;
$this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5])); $this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5]));
$this->assertMessage($this->respGood([$exp[1]]), $this->req($in[6])); $this->assertMessage($this->respGood([$exp[1]]), $this->req($in[6]));
// test the special case when labels are not used // test the special case when labels are not used
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result([])); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result([]));
Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result([])); \Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result([]));
$this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5])); $this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5]));
} }
@ -1746,22 +1742,22 @@ LONG_STRING;
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3], ['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3],
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'view_mode' => "marked"], ['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'view_mode' => "marked"],
]; ];
Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v([['id' => 0]]))); \Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v([['id' => 0]])));
Phake::when(Arsse::$db)->articleCount->thenReturn(0); \Phake::when(Arsse::$db)->articleCount->thenReturn(0);
Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1); \Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1);
$c = (new Context); $c = (new Context);
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(2112), ["id"], ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(2112), ["id"], ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->articleList($this->anything(), $c, ["id"], ["edited_date desc"])->thenReturn(new Result($this->v($this->articles))); \Phake::when(Arsse::$db)->articleList($this->anything(), $c, ["id"], ["edited_date desc"])->thenReturn(new Result($this->v($this->articles)));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->starred(true), ["id"], ["marked_date desc"])->thenReturn(new Result($this->v([['id' => 1]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->starred(true), ["id"], ["marked_date desc"])->thenReturn(new Result($this->v([['id' => 1]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 2]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 2]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->unread(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 3]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->unread(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 3]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088)->unread(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 4]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088)->unread(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 4]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->starred(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 5]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->starred(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 5]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->annotated(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 6]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->annotated(true), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 6]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 7]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 7]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->offset(2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 8]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->offset(2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 8]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5)->offset(2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 9]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5)->offset(2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 9]])));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->oldestArticle(48), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 10]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->oldestArticle(48), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 10]])));
$out1 = [ $out1 = [
$this->respErr("INCORRECT_USAGE"), $this->respErr("INCORRECT_USAGE"),
$this->respGood([]), $this->respGood([]),
@ -1793,9 +1789,9 @@ LONG_STRING;
$this->assertMessage($out1[$a], $this->req($in1[$a]), "Test $a failed"); $this->assertMessage($out1[$a], $this->req($in1[$a]), "Test $a failed");
} }
for ($a = 0; $a < sizeof($in2); $a++) { for ($a = 0; $a < sizeof($in2); $a++) {
Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(false)->markedSince(Date::sub("PT24H")), 2), ["id"], ["marked_date desc"])->thenReturn(new Result($this->v([['id' => 1001]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(false)->markedSince(Date::sub("PT24H")), 2), ["id"], ["marked_date desc"])->thenReturn(new Result($this->v([['id' => 1001]])));
Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H")), 2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 1002]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H")), 2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 1002]])));
Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H"))->starred(true), 2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 1003]]))); \Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H"))->starred(true), 2), ["id"], ["edited_date desc"])->thenReturn(new Result($this->v([['id' => 1003]])));
$this->assertMessage($out2[$a], $this->req($in2[$a]), "Test $a failed"); $this->assertMessage($out2[$a], $this->req($in2[$a]), "Test $a failed");
} }
} }
@ -1844,34 +1840,34 @@ LONG_STRING;
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3], ['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'view_mode' => "marked"], ['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -3, 'view_mode' => "marked"],
]; ];
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels))); \Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]); \Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]);
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3])); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3]));
Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]); \Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]);
Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]); \Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]);
Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(0)); \Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(0));
Phake::when(Arsse::$db)->articleCount->thenReturn(0); \Phake::when(Arsse::$db)->articleCount->thenReturn(0);
Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1); \Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1);
$c = (new Context)->limit(200); $c = (new Context)->limit(200);
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(2112), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(2112), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->starred(true), $this->anything(), ["marked_date desc"])->thenReturn($this->generateHeadlines(1)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->starred(true), $this->anything(), ["marked_date desc"])->thenReturn($this->generateHeadlines(1));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(2)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(2));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->unread(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(3)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->unread(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(3));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088)->unread(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(4)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->label(1088)->unread(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(4));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->starred(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(5)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->starred(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(5));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->annotated(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(6)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->annotated(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(6));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(7)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(7));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->offset(2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(8)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->offset(2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(8));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5)->offset(2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(9)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->limit(5)->offset(2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(9));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->oldestArticle(48), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(10)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->oldestArticle(48), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(10));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(11)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(11));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->labelled(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(12)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->labelled(true), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(12));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(0), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(13)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(0), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(13));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(14)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(14));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folder(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(15)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folder(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(15));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c), $this->anything(), ["edited_date"])->thenReturn($this->generateHeadlines(16)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c), $this->anything(), ["edited_date"])->thenReturn($this->generateHeadlines(16));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->searchTerms(["interesting"]), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(17)); \Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->searchTerms(["interesting"]), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(17));
$out2 = [ $out2 = [
$this->respErr("INCORRECT_USAGE"), $this->respErr("INCORRECT_USAGE"),
$this->outputHeadlines(11), $this->outputHeadlines(11),
@ -1909,9 +1905,9 @@ LONG_STRING;
$this->assertMessage($out2[$a], $this->req($in2[$a]), "Test $a failed"); $this->assertMessage($out2[$a], $this->req($in2[$a]), "Test $a failed");
} }
for ($a = 0; $a < sizeof($in3); $a++) { for ($a = 0; $a < sizeof($in3); $a++) {
Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(false)->markedSince(Date::sub("PT24H")), 2), $this->anything(), ["marked_date desc"])->thenReturn($this->generateHeadlines(1001)); \Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(false)->markedSince(Date::sub("PT24H")), 2), $this->anything(), ["marked_date desc"])->thenReturn($this->generateHeadlines(1001));
Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H")), 2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1002)); \Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H")), 2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1002));
Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H"))->starred(true), 2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1003)); \Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((clone $c)->unread(true)->modifiedSince(Date::sub("PT24H"))->starred(true), 2), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1003));
$this->assertMessage($out3[$a], $this->req($in3[$a]), "Test $a failed"); $this->assertMessage($out3[$a], $this->req($in3[$a]), "Test $a failed");
} }
} }
@ -1931,15 +1927,15 @@ LONG_STRING;
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'skip' => 47, 'include_header' => true, 'order_by' => "date_reverse"], ['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'skip' => 47, 'include_header' => true, 'order_by' => "date_reverse"],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'show_excerpt' => true], ['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'show_excerpt' => true],
]; ];
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels))); \Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels))); \Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]); \Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]);
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3])); \Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3]));
Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]); \Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]);
Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]); \Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]);
Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(1)); \Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(1));
Phake::when(Arsse::$db)->articleCount->thenReturn(0); \Phake::when(Arsse::$db)->articleCount->thenReturn(0);
Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1); \Phake::when(Arsse::$db)->articleCount($this->anything(), (new Context)->unread(true))->thenReturn(1);
// sanity check; this makes sure extra fields are not included in default situations // sanity check; this makes sure extra fields are not included in default situations
$test = $this->req($in[0]); $test = $this->req($in[0]);
$this->assertMessage($this->outputHeadlines(1), $test); $this->assertMessage($this->outputHeadlines(1), $test);
@ -1990,7 +1986,7 @@ LONG_STRING;
]); ]);
$this->assertMessage($exp, $test); $this->assertMessage($exp, $test);
// test 'include_header' with an erroneous result // test 'include_header' with an erroneous result
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(200)->subscription(2112), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing")); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(200)->subscription(2112), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
$test = $this->req($in[6]); $test = $this->req($in[6]);
$exp = $this->respGood([ $exp = $this->respGood([
['id' => 2112, 'is_cat' => false, 'first_id' => 0], ['id' => 2112, 'is_cat' => false, 'first_id' => 0],
@ -2005,7 +2001,7 @@ LONG_STRING;
]); ]);
$this->assertMessage($exp, $test); $this->assertMessage($exp, $test);
// test 'include_header' with skip // test 'include_header' with skip
Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(1)->subscription(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1867)); \Phake::when(Arsse::$db)->articleList($this->anything(), (new Context)->limit(1)->subscription(42), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1867));
$test = $this->req($in[8]); $test = $this->req($in[8]);
$exp = $this->respGood([ $exp = $this->respGood([
['id' => 42, 'is_cat' => false, 'first_id' => 1867], ['id' => 42, 'is_cat' => false, 'first_id' => 1867],

View file

@ -7,15 +7,12 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\REST\TinyTinyRSS; namespace JKingWeb\Arsse\TestCase\REST\TinyTinyRSS;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\User; use JKingWeb\Arsse\User;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\REST\TinyTinyRSS\Icon; use JKingWeb\Arsse\REST\TinyTinyRSS\Icon;
use JKingWeb\Arsse\REST\Request;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\Response\EmptyResponse as Response; use Zend\Diactoros\Response\EmptyResponse as Response;
use Phake;
/** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Icon<extended> */ /** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Icon<extended> */
class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest { class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
@ -26,9 +23,9 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
self::setConf(); self::setConf();
// create a mock user manager // create a mock user manager
Arsse::$user = Phake::mock(User::class); Arsse::$user = \Phake::mock(User::class);
// create a mock database interface // create a mock database interface
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
$this->h = new Icon(); $this->h = new Icon();
} }
@ -63,10 +60,10 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testRetrieveFavion() { public function testRetrieveFavion() {
Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn(""); \Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn("");
Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->anything())->thenReturn("http://example.com/favicon.ico"); \Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->anything())->thenReturn("http://example.com/favicon.ico");
Phake::when(Arsse::$db)->subscriptionFavicon(2112, $this->anything())->thenReturn("http://example.net/logo.png"); \Phake::when(Arsse::$db)->subscriptionFavicon(2112, $this->anything())->thenReturn("http://example.net/logo.png");
Phake::when(Arsse::$db)->subscriptionFavicon(1337, $this->anything())->thenReturn("http://example.org/icon.gif\r\nLocation: http://bad.example.com/"); \Phake::when(Arsse::$db)->subscriptionFavicon(1337, $this->anything())->thenReturn("http://example.org/icon.gif\r\nLocation: http://bad.example.com/");
// these requests should succeed // these requests should succeed
$exp = new Response(301, ['Location' => "http://example.com/favicon.ico"]); $exp = new Response(301, ['Location' => "http://example.com/favicon.ico"]);
$this->assertMessage($exp, $this->req("42.ico")); $this->assertMessage($exp, $this->req("42.ico"));
@ -87,13 +84,13 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
public function testRetrieveFavionWithHttpAuthentication() { public function testRetrieveFavionWithHttpAuthentication() {
$url = "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"; $url = "http://example.org/icon.gif\r\nLocation: http://bad.example.com/";
Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn(""); \Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn("");
Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->user)->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->user)->thenReturn($url);
Phake::when(Arsse::$db)->subscriptionFavicon(2112, "jane.doe")->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(2112, "jane.doe")->thenReturn($url);
Phake::when(Arsse::$db)->subscriptionFavicon(1337, $this->user)->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(1337, $this->user)->thenReturn($url);
Phake::when(Arsse::$db)->subscriptionFavicon(42, null)->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(42, null)->thenReturn($url);
Phake::when(Arsse::$db)->subscriptionFavicon(2112, null)->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(2112, null)->thenReturn($url);
Phake::when(Arsse::$db)->subscriptionFavicon(1337, null)->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(1337, null)->thenReturn($url);
// these requests should succeed // these requests should succeed
$exp = new Response(301, ['Location' => "http://example.org/icon.gif"]); $exp = new Response(301, ['Location' => "http://example.org/icon.gif"]);
$this->assertMessage($exp, $this->req("42.ico")); $this->assertMessage($exp, $this->req("42.ico"));

View file

@ -7,11 +7,9 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Service; namespace JKingWeb\Arsse\TestCase\Service;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Service; use JKingWeb\Arsse\Service;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
use Phake;
/** @covers \JKingWeb\Arsse\Service */ /** @covers \JKingWeb\Arsse\Service */
class TestService extends \JKingWeb\Arsse\Test\AbstractTest { class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
@ -20,14 +18,14 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() { public function setUp() {
self::clearData(); self::clearData();
self::setConf(); self::setConf();
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
$this->srv = new Service(); $this->srv = new Service();
} }
public function testCheckIn() { public function testCheckIn() {
$now = time(); $now = time();
$this->srv->checkIn(); $this->srv->checkIn();
Phake::verify(Arsse::$db)->metaSet("service_last_checkin", Phake::capture($then), "datetime"); \Phake::verify(Arsse::$db)->metaSet("service_last_checkin", \Phake::capture($then), "datetime");
$this->assertTime($now, $then); $this->assertTime($now, $then);
} }
@ -37,7 +35,7 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
$interval = Arsse::$conf->serviceFrequency; $interval = Arsse::$conf->serviceFrequency;
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval); $valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
$invalid = $valid->sub($interval)->sub($interval); $invalid = $valid->sub($interval)->sub($interval);
Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql")); \Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
$this->assertTrue(Service::hasCheckedIn()); $this->assertTrue(Service::hasCheckedIn());
$this->assertFalse(Service::hasCheckedIn()); $this->assertFalse(Service::hasCheckedIn());
} }

View file

@ -7,13 +7,9 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\User; namespace JKingWeb\Arsse\TestCase\User;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\User;
use JKingWeb\Arsse\AbstractException as Exception;
use JKingWeb\Arsse\User\Driver as DriverInterface; use JKingWeb\Arsse\User\Driver as DriverInterface;
use JKingWeb\Arsse\User\Internal\Driver; use JKingWeb\Arsse\User\Internal\Driver;
use Phake;
/** @covers \JKingWeb\Arsse\User\Internal\Driver */ /** @covers \JKingWeb\Arsse\User\Internal\Driver */
class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest { class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
@ -21,8 +17,8 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
self::setConf(); self::setConf();
// create a mock database interface // create a mock database interface
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class)); \Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
} }
public function testConstruct() { public function testConstruct() {
@ -39,13 +35,13 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
*/ */
public function testAuthenticateAUser(bool $authorized, string $user, $password, bool $exp) { public function testAuthenticateAUser(bool $authorized, string $user, $password, bool $exp) {
if ($authorized) { if ($authorized) {
Phake::when(Arsse::$db)->userPasswordGet("john.doe@example.com")->thenReturn('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret" \Phake::when(Arsse::$db)->userPasswordGet("john.doe@example.com")->thenReturn('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret"
Phake::when(Arsse::$db)->userPasswordGet("jane.doe@example.com")->thenReturn('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman" \Phake::when(Arsse::$db)->userPasswordGet("jane.doe@example.com")->thenReturn('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman"
Phake::when(Arsse::$db)->userPasswordGet("owen.hardy@example.com")->thenReturn(""); \Phake::when(Arsse::$db)->userPasswordGet("owen.hardy@example.com")->thenReturn("");
Phake::when(Arsse::$db)->userPasswordGet("kira.nerys@example.com")->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when(Arsse::$db)->userPasswordGet("kira.nerys@example.com")->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
Phake::when(Arsse::$db)->userPasswordGet("007@example.com")->thenReturn(null); \Phake::when(Arsse::$db)->userPasswordGet("007@example.com")->thenReturn(null);
} else { } else {
Phake::when(Arsse::$db)->userPasswordGet->thenThrow(new \JKingWeb\Arsse\User\ExceptionAuthz("notAuthorized")); \Phake::when(Arsse::$db)->userPasswordGet->thenThrow(new \JKingWeb\Arsse\User\ExceptionAuthz("notAuthorized"));
} }
$this->assertSame($exp, (new Driver)->auth($user, $password)); $this->assertSame($exp, (new Driver)->auth($user, $password));
} }
@ -79,62 +75,62 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testAuthorizeAnAction() { public function testAuthorizeAnAction() {
Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertTrue((new Driver)->authorize("someone", "something")); $this->assertTrue((new Driver)->authorize("someone", "something"));
} }
public function testListUsers() { public function testListUsers() {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
$jane = "jane.doe@example.com"; $jane = "jane.doe@example.com";
Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]); \Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]);
$driver = new Driver; $driver = new Driver;
$this->assertSame([$john, $jane], $driver->userList()); $this->assertSame([$john, $jane], $driver->userList());
$this->assertSame([$jane, $john], $driver->userList()); $this->assertSame([$jane, $john], $driver->userList());
Phake::verify(Arsse::$db, Phake::times(2))->userList; \Phake::verify(Arsse::$db, \Phake::times(2))->userList;
} }
public function testCheckThatAUserExists() { public function testCheckThatAUserExists() {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
$jane = "jane.doe@example.com"; $jane = "jane.doe@example.com";
Phake::when(Arsse::$db)->userExists($john)->thenReturn(true); \Phake::when(Arsse::$db)->userExists($john)->thenReturn(true);
Phake::when(Arsse::$db)->userExists($jane)->thenReturn(false); \Phake::when(Arsse::$db)->userExists($jane)->thenReturn(false);
$driver = new Driver; $driver = new Driver;
$this->assertTrue($driver->userExists($john)); $this->assertTrue($driver->userExists($john));
Phake::verify(Arsse::$db)->userExists($john); \Phake::verify(Arsse::$db)->userExists($john);
$this->assertFalse($driver->userExists($jane)); $this->assertFalse($driver->userExists($jane));
Phake::verify(Arsse::$db)->userExists($jane); \Phake::verify(Arsse::$db)->userExists($jane);
} }
public function testAddAUser() { public function testAddAUser() {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) { \Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) {
return $pass; return $pass;
}); });
$driver = new Driver; $driver = new Driver;
$this->assertNull($driver->userAdd($john)); $this->assertNull($driver->userAdd($john));
$this->assertNull($driver->userAdd($john, null)); $this->assertNull($driver->userAdd($john, null));
$this->assertSame("secret", $driver->userAdd($john, "secret")); $this->assertSame("secret", $driver->userAdd($john, "secret"));
Phake::verify(Arsse::$db)->userAdd($john, "secret"); \Phake::verify(Arsse::$db)->userAdd($john, "secret");
Phake::verify(Arsse::$db)->userAdd; \Phake::verify(Arsse::$db)->userAdd;
} }
public function testRemoveAUser() { public function testRemoveAUser() {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
$driver = new Driver; $driver = new Driver;
$this->assertTrue($driver->userRemove($john)); $this->assertTrue($driver->userRemove($john));
Phake::verify(Arsse::$db, Phake::times(1))->userRemove($john); \Phake::verify(Arsse::$db, \Phake::times(1))->userRemove($john);
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
try { try {
$this->assertFalse($driver->userRemove($john)); $this->assertFalse($driver->userRemove($john));
} finally { } finally {
Phake::verify(Arsse::$db, Phake::times(2))->userRemove($john); \Phake::verify(Arsse::$db, \Phake::times(2))->userRemove($john);
} }
} }
public function testSetAPassword() { public function testSetAPassword() {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertSame("superman", (new Driver)->userPasswordSet($john, "superman")); $this->assertSame("superman", (new Driver)->userPasswordSet($john, "superman"));
$this->assertSame(null, (new Driver)->userPasswordSet($john, null)); $this->assertSame(null, (new Driver)->userPasswordSet($john, null));
} }
@ -142,14 +138,14 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
public function testUnsetAPassword() { public function testUnsetAPassword() {
$drv = \Phake::partialMock(Driver::class); $drv = \Phake::partialMock(Driver::class);
\Phake::when($drv)->userExists->thenReturn(true); \Phake::when($drv)->userExists->thenReturn(true);
Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertTrue($drv->userPasswordUnset("john.doe@example.com")); $this->assertTrue($drv->userPasswordUnset("john.doe@example.com"));
} }
public function testUnsetAPasswordForAMssingUser() { public function testUnsetAPasswordForAMssingUser() {
$drv = \Phake::partialMock(Driver::class); $drv = \Phake::partialMock(Driver::class);
\Phake::when($drv)->userExists->thenReturn(false); \Phake::when($drv)->userExists->thenReturn(false);
Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
$drv->userPasswordUnset("john.doe@example.com"); $drv->userPasswordUnset("john.doe@example.com");
} }

View file

@ -7,13 +7,10 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\User; namespace JKingWeb\Arsse\TestCase\User;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Conf;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\User; use JKingWeb\Arsse\User;
use JKingWeb\Arsse\AbstractException as Exception; use JKingWeb\Arsse\AbstractException as Exception;
use JKingWeb\Arsse\User\Driver; use JKingWeb\Arsse\User\Driver;
use JKingWeb\Arsse\User\Internal\Driver as InternalDriver;
use Phake;
/** @covers \JKingWeb\Arsse\User */ /** @covers \JKingWeb\Arsse\User */
class TestUser extends \JKingWeb\Arsse\Test\AbstractTest { class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
@ -21,10 +18,10 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
self::setConf(); self::setConf();
// create a mock database interface // create a mock database interface
Arsse::$db = Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class)); \Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
// create a mock user driver // create a mock user driver
$this->drv = Phake::mock(Driver::class); $this->drv = \Phake::mock(Driver::class);
} }
public function testListDrivers() { public function testListDrivers() {
@ -50,17 +47,17 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideAuthentication */ /** @dataProvider provideAuthentication */
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp) { public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp) {
Arsse::$conf->userPreAuth = $preAuth; Arsse::$conf->userPreAuth = $preAuth;
Phake::when($this->drv)->auth->thenReturn(false); \Phake::when($this->drv)->auth->thenReturn(false);
Phake::when($this->drv)->auth("john.doe@example.com", "secret")->thenReturn(true); \Phake::when($this->drv)->auth("john.doe@example.com", "secret")->thenReturn(true);
Phake::when($this->drv)->auth("jane.doe@example.com", "superman")->thenReturn(true); \Phake::when($this->drv)->auth("jane.doe@example.com", "superman")->thenReturn(true);
Phake::when(Arsse::$db)->userExists("john.doe@example.com")->thenReturn(true); \Phake::when(Arsse::$db)->userExists("john.doe@example.com")->thenReturn(true);
Phake::when(Arsse::$db)->userExists("jane.doe@example.com")->thenReturn(false); \Phake::when(Arsse::$db)->userExists("jane.doe@example.com")->thenReturn(false);
Phake::when(Arsse::$db)->userAdd->thenReturn(""); \Phake::when(Arsse::$db)->userAdd->thenReturn("");
$u = new User($this->drv); $u = new User($this->drv);
$this->assertSame($exp, $u->auth($user, $password)); $this->assertSame($exp, $u->auth($user, $password));
$this->assertNull($u->id); $this->assertNull($u->id);
Phake::verify(Arsse::$db, Phake::times($exp ? 1 : 0))->userExists($user); \Phake::verify(Arsse::$db, \Phake::times($exp ? 1 : 0))->userExists($user);
Phake::verify(Arsse::$db, Phake::times($exp && $user === "jane.doe@example.com" ? 1 : 0))->userAdd($user, $password); \Phake::verify(Arsse::$db, \Phake::times($exp && $user === "jane.doe@example.com" ? 1 : 0))->userAdd($user, $password);
} }
public function provideAuthentication() { public function provideAuthentication() {
@ -81,8 +78,8 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideUserList */ /** @dataProvider provideUserList */
public function testListUsers(bool $authorized, $exp) { public function testListUsers(bool $authorized, $exp) {
$u = new User($this->drv); $u = new User($this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userList->thenReturn(["john.doe@example.com", "jane.doe@example.com"]); \Phake::when($this->drv)->userList->thenReturn(["john.doe@example.com", "jane.doe@example.com"]);
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
} }
@ -101,9 +98,9 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideExistence */ /** @dataProvider provideExistence */
public function testCheckThatAUserExists(bool $authorized, string $user, $exp) { public function testCheckThatAUserExists(bool $authorized, string $user, $exp) {
$u = new User($this->drv); $u = new User($this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userExists("john.doe@example.com")->thenReturn(true); \Phake::when($this->drv)->userExists("john.doe@example.com")->thenReturn(true);
Phake::when($this->drv)->userExists("jane.doe@example.com")->thenReturn(false); \Phake::when($this->drv)->userExists("jane.doe@example.com")->thenReturn(false);
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
} }
@ -124,9 +121,9 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideAdditions */ /** @dataProvider provideAdditions */
public function testAddAUser(bool $authorized, string $user, $password, $exp) { public function testAddAUser(bool $authorized, string $user, $password, $exp) {
$u = new User($this->drv); $u = new User($this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userAdd("john.doe@example.com", $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("alreadyExists")); \Phake::when($this->drv)->userAdd("john.doe@example.com", $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("alreadyExists"));
Phake::when($this->drv)->userAdd("jane.doe@example.com", $this->anything())->thenReturnCallback(function($user, $pass) { \Phake::when($this->drv)->userAdd("jane.doe@example.com", $this->anything())->thenReturnCallback(function($user, $pass) {
return $pass ?? "random password"; return $pass ?? "random password";
}); });
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
@ -141,11 +138,11 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideAdditions */ /** @dataProvider provideAdditions */
public function testAddAUserWithARandomPassword(bool $authorized, string $user, $password, $exp) { public function testAddAUserWithARandomPassword(bool $authorized, string $user, $password, $exp) {
$u = Phake::partialMock(User::class, $this->drv); $u = \Phake::partialMock(User::class, $this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userAdd($this->anything(), $this->isNull())->thenReturn(null); \Phake::when($this->drv)->userAdd($this->anything(), $this->isNull())->thenReturn(null);
Phake::when($this->drv)->userAdd("john.doe@example.com", $this->logicalNot($this->isNull()))->thenThrow(new \JKingWeb\Arsse\User\Exception("alreadyExists")); \Phake::when($this->drv)->userAdd("john.doe@example.com", $this->logicalNot($this->isNull()))->thenThrow(new \JKingWeb\Arsse\User\Exception("alreadyExists"));
Phake::when($this->drv)->userAdd("jane.doe@example.com", $this->logicalNot($this->isNull()))->thenReturnCallback(function($user, $pass) { \Phake::when($this->drv)->userAdd("jane.doe@example.com", $this->logicalNot($this->isNull()))->thenReturnCallback(function($user, $pass) {
return $pass; return $pass;
}); });
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
@ -164,8 +161,8 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
$pass2 = $u->add($user, null); $pass2 = $u->add($user, null);
$this->assertNotEquals($pass1, $pass2); $this->assertNotEquals($pass1, $pass2);
} finally { } finally {
Phake::verify($this->drv, Phake::times($calls))->userAdd; \Phake::verify($this->drv, \Phake::times($calls))->userAdd;
Phake::verify($u, Phake::times($calls / 2))->generatePassword; \Phake::verify($u, \Phake::times($calls / 2))->generatePassword;
} }
} }
@ -184,11 +181,11 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideRemovals */ /** @dataProvider provideRemovals */
public function testRemoveAUser(bool $authorized, string $user, bool $exists, $exp) { public function testRemoveAUser(bool $authorized, string $user, bool $exists, $exp) {
$u = new User($this->drv); $u = new User($this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userRemove("john.doe@example.com")->thenReturn(true); \Phake::when($this->drv)->userRemove("john.doe@example.com")->thenReturn(true);
Phake::when($this->drv)->userRemove("jane.doe@example.com")->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when($this->drv)->userRemove("jane.doe@example.com")->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
Phake::when(Arsse::$db)->userExists->thenReturn($exists); \Phake::when(Arsse::$db)->userExists->thenReturn($exists);
Phake::when(Arsse::$db)->userRemove->thenReturn(true); \Phake::when(Arsse::$db)->userRemove->thenReturn(true);
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
if ($exp instanceof \JKingWeb\Arsse\User\ExceptionAuthz) { if ($exp instanceof \JKingWeb\Arsse\User\ExceptionAuthz) {
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
@ -199,8 +196,8 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
try { try {
$this->assertSame($exp, $u->remove($user)); $this->assertSame($exp, $u->remove($user));
} finally { } finally {
Phake::verify(Arsse::$db, Phake::times((int) $authorized))->userExists($user); \Phake::verify(Arsse::$db, \Phake::times((int) $authorized))->userExists($user);
Phake::verify(Arsse::$db, Phake::times((int) ($authorized && $exists)))->userRemove($user); \Phake::verify(Arsse::$db, \Phake::times((int) ($authorized && $exists)))->userRemove($user);
} }
} }
@ -222,12 +219,12 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider providePasswordChanges */ /** @dataProvider providePasswordChanges */
public function testChangeAPassword(bool $authorized, string $user, $password, bool $exists, $exp) { public function testChangeAPassword(bool $authorized, string $user, $password, bool $exists, $exp) {
$u = new User($this->drv); $u = new User($this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userPasswordSet("john.doe@example.com", $this->anything(), $this->anything())->thenReturnCallback(function($user, $pass, $old) { \Phake::when($this->drv)->userPasswordSet("john.doe@example.com", $this->anything(), $this->anything())->thenReturnCallback(function($user, $pass, $old) {
return $pass ?? "random password"; return $pass ?? "random password";
}); });
Phake::when($this->drv)->userPasswordSet("jane.doe@example.com", $this->anything(), $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when($this->drv)->userPasswordSet("jane.doe@example.com", $this->anything(), $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
Phake::when(Arsse::$db)->userExists->thenReturn($exists); \Phake::when(Arsse::$db)->userExists->thenReturn($exists);
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
if ($exp instanceof \JKingWeb\Arsse\User\ExceptionAuthz) { if ($exp instanceof \JKingWeb\Arsse\User\ExceptionAuthz) {
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
@ -241,21 +238,21 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
try { try {
$this->assertSame($exp, $u->passwordSet($user, $password)); $this->assertSame($exp, $u->passwordSet($user, $password));
} finally { } finally {
Phake::verify(Arsse::$db, Phake::times($calls))->userExists($user); \Phake::verify(Arsse::$db, \Phake::times($calls))->userExists($user);
Phake::verify(Arsse::$db, Phake::times($exists ? $calls : 0))->userPasswordSet($user, $password ?? "random password", null); \Phake::verify(Arsse::$db, \Phake::times($exists ? $calls : 0))->userPasswordSet($user, $password ?? "random password", null);
} }
} }
/** @dataProvider providePasswordChanges */ /** @dataProvider providePasswordChanges */
public function testChangeAPasswordToARandomPassword(bool $authorized, string $user, $password, bool $exists, $exp) { public function testChangeAPasswordToARandomPassword(bool $authorized, string $user, $password, bool $exists, $exp) {
$u = Phake::partialMock(User::class, $this->drv); $u = \Phake::partialMock(User::class, $this->drv);
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userPasswordSet($this->anything(), $this->isNull(), $this->anything())->thenReturn(null); \Phake::when($this->drv)->userPasswordSet($this->anything(), $this->isNull(), $this->anything())->thenReturn(null);
Phake::when($this->drv)->userPasswordSet("john.doe@example.com", $this->logicalNot($this->isNull()), $this->anything())->thenReturnCallback(function($user, $pass, $old) { \Phake::when($this->drv)->userPasswordSet("john.doe@example.com", $this->logicalNot($this->isNull()), $this->anything())->thenReturnCallback(function($user, $pass, $old) {
return $pass ?? "random password"; return $pass ?? "random password";
}); });
Phake::when($this->drv)->userPasswordSet("jane.doe@example.com", $this->logicalNot($this->isNull()), $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when($this->drv)->userPasswordSet("jane.doe@example.com", $this->logicalNot($this->isNull()), $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
Phake::when(Arsse::$db)->userExists->thenReturn($exists); \Phake::when(Arsse::$db)->userExists->thenReturn($exists);
if ($exp instanceof Exception) { if ($exp instanceof Exception) {
if ($exp instanceof \JKingWeb\Arsse\User\ExceptionAuthz) { if ($exp instanceof \JKingWeb\Arsse\User\ExceptionAuthz) {
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
@ -272,14 +269,14 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
$pass2 = $u->passwordSet($user, null); $pass2 = $u->passwordSet($user, null);
$this->assertNotEquals($pass1, $pass2); $this->assertNotEquals($pass1, $pass2);
} finally { } finally {
Phake::verify($this->drv, Phake::times($calls))->userPasswordSet; \Phake::verify($this->drv, \Phake::times($calls))->userPasswordSet;
Phake::verify($u, Phake::times($calls / 2))->generatePassword; \Phake::verify($u, \Phake::times($calls / 2))->generatePassword;
Phake::verify(Arsse::$db, Phake::times($calls == 4 ? 2 : 0))->userExists($user); \Phake::verify(Arsse::$db, \Phake::times($calls == 4 ? 2 : 0))->userExists($user);
if ($calls == 4) { if ($calls == 4) {
Phake::verify(Arsse::$db, Phake::times($exists ? 1 : 0))->userPasswordSet($user, $pass1, null); \Phake::verify(Arsse::$db, \Phake::times($exists ? 1 : 0))->userPasswordSet($user, $pass1, null);
Phake::verify(Arsse::$db, Phake::times($exists ? 1 : 0))->userPasswordSet($user, $pass2, null); \Phake::verify(Arsse::$db, \Phake::times($exists ? 1 : 0))->userPasswordSet($user, $pass2, null);
} else { } else {
Phake::verify(Arsse::$db, Phake::times(0))->userPasswordSet; \Phake::verify(Arsse::$db, \Phake::times(0))->userPasswordSet;
} }
} }
} }
@ -300,10 +297,10 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider providePasswordClearings */ /** @dataProvider providePasswordClearings */
public function testClearAPassword(bool $authorized, bool $exists, string $user, $exp) { public function testClearAPassword(bool $authorized, bool $exists, string $user, $exp) {
Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
Phake::when($this->drv)->userPasswordUnset->thenReturn(true); \Phake::when($this->drv)->userPasswordUnset->thenReturn(true);
Phake::when($this->drv)->userPasswordUnset("jane.doe@example.net", null)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when($this->drv)->userPasswordUnset("jane.doe@example.net", null)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
Phake::when(Arsse::$db)->userExists->thenReturn($exists); \Phake::when(Arsse::$db)->userExists->thenReturn($exists);
$u = new User($this->drv); $u = new User($this->drv);
try { try {
if ($exp instanceof \JKingWeb\Arsse\AbstractException) { if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
@ -313,7 +310,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $u->passwordUnset($user)); $this->assertSame($exp, $u->passwordUnset($user));
} }
} finally { } finally {
Phake::verify(Arsse::$db, Phake::times((int) ($authorized && $exists && is_bool($exp))))->userPasswordSet($user, null); \Phake::verify(Arsse::$db, \Phake::times((int) ($authorized && $exists && is_bool($exp))))->userPasswordSet($user, null);
} }
} }

View file

@ -9,7 +9,6 @@ namespace JKingWeb\Arsse\Test\Lang;
use JKingWeb\Arsse\Lang; use JKingWeb\Arsse\Lang;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use Phake;
trait Setup { trait Setup {
public function setUp() { public function setUp() {
@ -40,8 +39,8 @@ trait Setup {
$this->l = new TestLang($this->path); $this->l = new TestLang($this->path);
// create a mock Lang object so as not to create a dependency loop // create a mock Lang object so as not to create a dependency loop
self::clearData(false); self::clearData(false);
Arsse::$lang = Phake::mock(Lang::class); Arsse::$lang = \Phake::mock(Lang::class);
Phake::when(Arsse::$lang)->msg->thenReturn(""); \Phake::when(Arsse::$lang)->msg->thenReturn("");
// call the additional setup method if it exists // call the additional setup method if it exists
if (method_exists($this, "setUpSeries")) { if (method_exists($this, "setUpSeries")) {
$this->setUpSeries(); $this->setUpSeries();
@ -50,8 +49,8 @@ trait Setup {
public function tearDown() { public function tearDown() {
// verify calls to the mock Lang object // verify calls to the mock Lang object
Phake::verify(Arsse::$lang, Phake::atLeast(0))->msg($this->isType("string"), $this->anything()); \Phake::verify(Arsse::$lang, \Phake::atLeast(0))->msg($this->isType("string"), $this->anything());
Phake::verifyNoOtherInteractions(Arsse::$lang); \Phake::verifyNoOtherInteractions(Arsse::$lang);
// clean up // clean up
self::clearData(true); self::clearData(true);
// call the additional teardiwn method if it exists // call the additional teardiwn method if it exists

View file

@ -46,6 +46,7 @@
<file>cases/Misc/TestValueInfo.php</file> <file>cases/Misc/TestValueInfo.php</file>
<file>cases/Misc/TestDate.php</file> <file>cases/Misc/TestDate.php</file>
<file>cases/Misc/TestContext.php</file> <file>cases/Misc/TestContext.php</file>
<file>cases/Misc/TestURL.php</file>
</testsuite> </testsuite>
<testsuite name="User management"> <testsuite name="User management">
<file>cases/User/TestInternal.php</file> <file>cases/User/TestInternal.php</file>
@ -105,7 +106,6 @@
<file>cases/Db/MySQLPDO/TestDatabase.php</file> <file>cases/Db/MySQLPDO/TestDatabase.php</file>
</testsuite> </testsuite>
<testsuite name="REST"> <testsuite name="REST">
<file>cases/REST/TestTarget.php</file>
<file>cases/REST/TestREST.php</file> <file>cases/REST/TestREST.php</file>
</testsuite> </testsuite>
<testsuite name="NCNv1"> <testsuite name="NCNv1">