Browse Source

Whitespace cleanup

microsub
J. King 6 years ago
parent
commit
f64f0c6a22
  1. 8
      dist/nginx.conf
  2. 2
      lib/Arsse.php
  3. 4
      lib/CLI.php
  4. 2
      lib/Conf.php
  5. 72
      lib/Database.php
  6. 2
      lib/Db/AbstractDriver.php
  7. 2
      lib/Db/Driver.php
  8. 2
      lib/Feed.php
  9. 36
      lib/Misc/Context.php
  10. 2
      lib/REST/AbstractHandler.php
  11. 12
      lib/REST/NextCloudNews/V1_2.php
  12. 2
      lib/REST/Target.php
  13. 6
      lib/REST/TinyTinyRSS/API.php
  14. 2
      lib/REST/TinyTinyRSS/Exception.php
  15. 4
      lib/Service.php
  16. 2
      lib/Service/Curl/Driver.php
  17. 4
      lib/Service/Forking/Driver.php
  18. 4
      lib/Service/Internal/Driver.php
  19. 4
      locale/en.php
  20. 4
      sql/SQLite3/0.sql
  21. 4
      tests/cases/Db/SQLite3/TestStatement.php
  22. 2
      tests/cases/Db/SQLite3PDO/TestStatement.php
  23. 8
      tests/cases/Feed/TestFeed.php
  24. 2
      tests/cases/Misc/TestValueInfo.php
  25. 2
      tests/cases/REST/NextCloudNews/TestV1_2.php
  26. 4
      tests/cases/REST/TestREST.php
  27. 34
      tests/cases/REST/TinyTinyRSS/TestAPI.php
  28. 2
      tests/cases/User/TestAuthorization.php
  29. 2
      tests/docroot/Feed/Fetching/Timeout.php
  30. 2
      tests/docroot/Feed/Fetching/TooLarge.php
  31. 2
      tests/docroot/Feed/NextFetch/NotModified.php
  32. 4
      tests/docroot/Feed/Parsing/XXEAttack.php
  33. 4
      tests/lib/Database/SeriesCleanup.php
  34. 2
      tests/lib/Database/SeriesFeed.php
  35. 20
      tests/lib/Database/SeriesUser.php
  36. 8
      www/tt-rss/images/README

8
dist/nginx.conf

@ -7,7 +7,7 @@ server {
#auth_basic "Advanced RSS Environment"; #auth_basic "Advanced RSS Environment";
root /usr/share/arsse/www; root /usr/share/arsse/www;
index index.html; index index.html;
location / { location / {
try_files $uri $uri/ =404; try_files $uri $uri/ =404;
} }
@ -22,11 +22,11 @@ server {
auth_basic off; auth_basic off;
include /usr/share/arsse/dist/nginx-fcgi.conf; include /usr/share/arsse/dist/nginx-fcgi.conf;
} }
# NextCloud News protocol # NextCloud News protocol
location /index.php/apps/news/api { location /index.php/apps/news/api {
try_files $uri @arsse_auth; try_files $uri @arsse_auth;
location ~ ^/index\.php/apps/news/api/?$ { location ~ ^/index\.php/apps/news/api/?$ {
try_files $uri @arsse_no_auth; try_files $uri @arsse_no_auth;
} }
@ -48,4 +48,4 @@ server {
root /usr/share/arsse/www; root /usr/share/arsse/www;
try_files $uri =404; try_files $uri =404;
} }
} }

2
lib/Arsse.php

@ -8,7 +8,7 @@ namespace JKingWeb\Arsse;
class Arsse { class Arsse {
const VERSION = "0.4.0"; const VERSION = "0.4.0";
/** @var Lang */ /** @var Lang */
public static $lang; public static $lang;
/** @var Conf */ /** @var Conf */

4
lib/CLI.php

@ -8,7 +8,7 @@ namespace JKingWeb\Arsse;
class CLI { class CLI {
protected $args = []; protected $args = [];
protected function usage(): string { protected function usage(): string {
$prog = basename($_SERVER['argv'][0]); $prog = basename($_SERVER['argv'][0]);
return <<<USAGE_TEXT return <<<USAGE_TEXT
@ -21,7 +21,7 @@ Usage:
$prog --help | -h $prog --help | -h
The Arsse command-line interface currently allows you to start the refresh The Arsse command-line interface currently allows you to start the refresh
daemon, refresh a specific feed by numeric ID, add a user, or save default daemon, refresh a specific feed by numeric ID, add a user, or save default
configuration to a sample file. configuration to a sample file.
USAGE_TEXT; USAGE_TEXT;
} }

2
lib/Conf.php

@ -56,7 +56,7 @@ class Conf {
public $serviceCurlUser = null; public $serviceCurlUser = null;
/** @var string The password to use when performing feed updates using cURL */ /** @var string The password to use when performing feed updates using cURL */
public $serviceCurlPassword = null; public $serviceCurlPassword = null;
/** @var integer Number of seconds to wait for data when fetching feeds from foreign servers */ /** @var integer Number of seconds to wait for data when fetching feeds from foreign servers */
public $fetchTimeout = 10; public $fetchTimeout = 10;
/** @var integer Maximum size, in bytes, of data when fetching feeds from foreign servers */ /** @var integer Maximum size, in bytes, of data when fetching feeds from foreign servers */

72
lib/Database.php

@ -21,7 +21,7 @@ class Database {
const LIST_CONSERVATIVE = 1; // base metadata plus anything that is not potentially large text const LIST_CONSERVATIVE = 1; // base metadata plus anything that is not potentially large text
const LIST_TYPICAL = 2; // conservative, with the addition of content const LIST_TYPICAL = 2; // conservative, with the addition of content
const LIST_FULL = 3; // all possible fields const LIST_FULL = 3; // all possible fields
/** @var Db\Driver */ /** @var Db\Driver */
public $db; public $db;
@ -37,7 +37,7 @@ class Database {
protected function caller(): string { protected function caller(): string {
return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function']; return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
} }
public static function driverList(): array { public static function driverList(): array {
$sep = \DIRECTORY_SEPARATOR; $sep = \DIRECTORY_SEPARATOR;
$path = __DIR__.$sep."Db".$sep; $path = __DIR__.$sep."Db".$sep;
@ -102,7 +102,7 @@ class Database {
public function metaGet(string $key) { public function metaGet(string $key) {
return $this->db->prepare("SELECT value from arsse_meta where key = ?", "str")->run($key)->getValue(); return $this->db->prepare("SELECT value from arsse_meta where key = ?", "str")->run($key)->getValue();
} }
public function metaSet(string $key, $value, string $type = "str"): bool { public function metaSet(string $key, $value, string $type = "str"): bool {
$out = $this->db->prepare("UPDATE arsse_meta set value = ? where key = ?", $type, "str")->run($value, $key)->changes(); $out = $this->db->prepare("UPDATE arsse_meta set value = ? where key = ?", $type, "str")->run($value, $key)->changes();
if (!$out) { if (!$out) {
@ -444,7 +444,7 @@ class Database {
target as (select ? as user, ? as source, ? as dest, ? as rename), target as (select ? as user, ? as source, ? as dest, ? as rename),
folders as (SELECT id from arsse_folders join target on owner = user and coalesce(parent,0) = source union select arsse_folders.id as id from arsse_folders join folders on arsse_folders.parent=folders.id) folders as (SELECT id from arsse_folders join target on owner = user and coalesce(parent,0) = source union select arsse_folders.id as id from arsse_folders join folders on arsse_folders.parent=folders.id)
". ".
"SELECT "SELECT
((select dest from target) is null or exists(select id from arsse_folders join target on owner = user and coalesce(id,0) = coalesce(dest,0))) as extant, ((select dest from target) is null or exists(select id from arsse_folders join target on owner = user and coalesce(id,0) = coalesce(dest,0))) as extant,
not exists(select id from folders where id = coalesce((select dest from target),0)) as valid, not exists(select id from folders where id = coalesce((select dest from target),0)) as valid,
not exists(select id from arsse_folders join target on coalesce(parent,0) = coalesce(dest,0) and name = coalesce((select rename from target),(select name from arsse_folders join target on id = source))) as available not exists(select id from arsse_folders join target on coalesce(parent,0) = coalesce(dest,0) and name = coalesce((select rename from target),(select name from arsse_folders join target on id = source))) as available
@ -524,16 +524,16 @@ class Database {
$folder = $this->folderValidateId($user, $folder)['id']; $folder = $this->folderValidateId($user, $folder)['id'];
// create a complex query // create a complex query
$q = new Query( $q = new Query(
"SELECT "SELECT
arsse_subscriptions.id as id, arsse_subscriptions.id as id,
feed,url,favicon,source,folder,pinned,err_count,err_msg,order_type,added, feed,url,favicon,source,folder,pinned,err_count,err_msg,order_type,added,
arsse_feeds.updated as updated, arsse_feeds.updated as updated,
topmost.top as top_folder, topmost.top as top_folder,
coalesce(arsse_subscriptions.title, arsse_feeds.title) as title, coalesce(arsse_subscriptions.title, arsse_feeds.title) as title,
(SELECT count(*) from arsse_articles where feed = arsse_subscriptions.feed) - (SELECT count(*) from arsse_marks where subscription = arsse_subscriptions.id and read = 1) as unread (SELECT count(*) from arsse_articles where feed = arsse_subscriptions.feed) - (SELECT count(*) from arsse_marks where subscription = arsse_subscriptions.id and read = 1) as unread
from arsse_subscriptions from arsse_subscriptions
join user on user = owner join user on user = owner
join arsse_feeds on feed = arsse_feeds.id join arsse_feeds on feed = arsse_feeds.id
left join topmost on folder=f_id" left join topmost on folder=f_id"
); );
$q->setOrder("pinned desc, title collate nocase"); $q->setOrder("pinned desc, title collate nocase");
@ -673,7 +673,7 @@ class Database {
$feeds = $this->db->query("SELECT id from arsse_feeds where next_fetch <= CURRENT_TIMESTAMP")->getAll(); $feeds = $this->db->query("SELECT id from arsse_feeds where next_fetch <= CURRENT_TIMESTAMP")->getAll();
return array_column($feeds, 'id'); return array_column($feeds, 'id');
} }
public function feedUpdate($feedID, bool $throwError = false): bool { public function feedUpdate($feedID, bool $throwError = false): bool {
// check to make sure the feed exists // check to make sure the feed exists
if (!ValueInfo::id($feedID)) { if (!ValueInfo::id($feedID)) {
@ -874,13 +874,13 @@ class Database {
$extraColumns .= ","; $extraColumns .= ",";
} }
$q = new Query( $q = new Query(
"SELECT "SELECT
$extraColumns $extraColumns
arsse_articles.id as id, arsse_articles.id as id,
arsse_articles.feed as feed, arsse_articles.feed as feed,
arsse_articles.modified as modified_date, arsse_articles.modified as modified_date,
max( max(
arsse_articles.modified, arsse_articles.modified,
coalesce((select modified from arsse_marks where article = arsse_articles.id and subscription in (select sub from subscribed_feeds)),''), coalesce((select modified from arsse_marks where article = arsse_articles.id and subscription in (select sub from subscribed_feeds)),''),
coalesce((select modified from arsse_label_members where article = arsse_articles.id and subscription in (select sub from subscribed_feeds)),'') coalesce((select modified from arsse_label_members where article = arsse_articles.id and subscription in (select sub from subscribed_feeds)),'')
) as marked_date, ) as marked_date,
@ -1137,17 +1137,17 @@ class Database {
]; ];
// the two queries we want to execute to make the requested changes // the two queries we want to execute to make the requested changes
$queries = [ $queries = [
"UPDATE arsse_marks "UPDATE arsse_marks
set set
read = case when (select honour_read from target_articles where target_articles.id = article) = 1 then (select read from target_values) else read end, read = case when (select honour_read from target_articles where target_articles.id = article) = 1 then (select read from target_values) else read end,
starred = coalesce((select starred from target_values),starred), starred = coalesce((select starred from target_values),starred),
note = coalesce((select note from target_values),note), note = coalesce((select note from target_values),note),
modified = CURRENT_TIMESTAMP modified = CURRENT_TIMESTAMP
WHERE WHERE
subscription in (select sub from subscribed_feeds) subscription in (select sub from subscribed_feeds)
and article in (select id from target_articles where to_insert = 0 and (honour_read = 1 or honour_star = 1 or (select note from target_values) is not null))", and article in (select id from target_articles where to_insert = 0 and (honour_read = 1 or honour_star = 1 or (select note from target_values) is not null))",
"INSERT INTO arsse_marks(subscription,article,read,starred,note) "INSERT INTO arsse_marks(subscription,article,read,starred,note)
select select
(select id from arsse_subscriptions join user on user = owner where arsse_subscriptions.feed = target_articles.feed), (select id from arsse_subscriptions join user on user = owner where arsse_subscriptions.feed = target_articles.feed),
id, id,
coalesce((select read from target_values) * honour_read,0), coalesce((select read from target_values) * honour_read,0),
@ -1238,18 +1238,18 @@ class Database {
public function articleCleanup(): bool { public function articleCleanup(): bool {
$query = $this->db->prepare( $query = $this->db->prepare(
"WITH target_feed(id,subs) as (". "WITH target_feed(id,subs) as (".
"SELECT "SELECT
id, (select count(*) from arsse_subscriptions where feed = arsse_feeds.id) as subs id, (select count(*) from arsse_subscriptions where feed = arsse_feeds.id) as subs
from arsse_feeds where id = ?". from arsse_feeds where id = ?".
"), excepted_articles(id,edition) as (". "), excepted_articles(id,edition) as (".
"SELECT "SELECT
arsse_articles.id, (select max(id) from arsse_editions where article = arsse_articles.id) as edition arsse_articles.id, (select max(id) from arsse_editions where article = arsse_articles.id) as edition
from arsse_articles from arsse_articles
join target_feed on arsse_articles.feed = target_feed.id join target_feed on arsse_articles.feed = target_feed.id
order by edition desc limit ?". order by edition desc limit ?".
") ". ") ".
"DELETE from arsse_articles where "DELETE from arsse_articles where
feed = (select max(id) from target_feed) feed = (select max(id) from target_feed)
and id not in (select id from excepted_articles) and id not in (select id from excepted_articles)
and (select count(*) from arsse_marks where article = arsse_articles.id and starred = 1) = 0 and (select count(*) from arsse_marks where article = arsse_articles.id and starred = 1) = 0
and ( and (
@ -1282,13 +1282,13 @@ class Database {
throw new Db\ExceptionInput("typeViolation", ["action" => $this->caller(), "field" => "article", 'type' => "int > 0"]); // @codeCoverageIgnore throw new Db\ExceptionInput("typeViolation", ["action" => $this->caller(), "field" => "article", 'type' => "int > 0"]); // @codeCoverageIgnore
} }
$out = $this->db->prepare( $out = $this->db->prepare(
"SELECT "SELECT
arsse_articles.id as article, arsse_articles.id as article,
(select max(id) from arsse_editions where article = arsse_articles.id) as edition (select max(id) from arsse_editions where article = arsse_articles.id) as edition
FROM arsse_articles FROM arsse_articles
join arsse_feeds on arsse_feeds.id = arsse_articles.feed join arsse_feeds on arsse_feeds.id = arsse_articles.feed
join arsse_subscriptions on arsse_subscriptions.feed = arsse_feeds.id join arsse_subscriptions on arsse_subscriptions.feed = arsse_feeds.id
WHERE WHERE
arsse_articles.id = ? and arsse_subscriptions.owner = ?", arsse_articles.id = ? and arsse_subscriptions.owner = ?",
"int", "int",
"str" "str"
@ -1304,15 +1304,15 @@ class Database {
throw new Db\ExceptionInput("typeViolation", ["action" => $this->caller(), "field" => "edition", 'type' => "int > 0"]); // @codeCoverageIgnore throw new Db\ExceptionInput("typeViolation", ["action" => $this->caller(), "field" => "edition", 'type' => "int > 0"]); // @codeCoverageIgnore
} }
$out = $this->db->prepare( $out = $this->db->prepare(
"SELECT "SELECT
arsse_editions.id as edition, arsse_editions.id as edition,
arsse_editions.article as article, arsse_editions.article as article,
(arsse_editions.id = (select max(id) from arsse_editions where article = arsse_editions.article)) as current (arsse_editions.id = (select max(id) from arsse_editions where article = arsse_editions.article)) as current
FROM arsse_editions FROM arsse_editions
join arsse_articles on arsse_editions.article = arsse_articles.id join arsse_articles on arsse_editions.article = arsse_articles.id
join arsse_feeds on arsse_feeds.id = arsse_articles.feed join arsse_feeds on arsse_feeds.id = arsse_articles.feed
join arsse_subscriptions on arsse_subscriptions.feed = arsse_feeds.id join arsse_subscriptions on arsse_subscriptions.feed = arsse_feeds.id
WHERE WHERE
edition = ? and arsse_subscriptions.owner = ?", edition = ? and arsse_subscriptions.owner = ?",
"int", "int",
"str" "str"
@ -1359,10 +1359,10 @@ class Database {
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
} }
return $this->db->prepare( return $this->db->prepare(
"SELECT "SELECT
id,name, id,name,
(select count(*) from arsse_label_members where label = id and assigned = 1) as articles, (select count(*) from arsse_label_members where label = id and assigned = 1) as articles,
(select count(*) from arsse_label_members (select count(*) from arsse_label_members
join arsse_marks on arsse_label_members.article = arsse_marks.article and arsse_label_members.subscription = arsse_marks.subscription join arsse_marks on arsse_label_members.article = arsse_marks.article and arsse_label_members.subscription = arsse_marks.subscription
where label = id and assigned = 1 and read = 1 where label = id and assigned = 1 and read = 1
) as read ) as read
@ -1395,10 +1395,10 @@ class Database {
$field = $byName ? "name" : "id"; $field = $byName ? "name" : "id";
$type = $byName ? "str" : "int"; $type = $byName ? "str" : "int";
$out = $this->db->prepare( $out = $this->db->prepare(
"SELECT "SELECT
id,name, id,name,
(select count(*) from arsse_label_members where label = id and assigned = 1) as articles, (select count(*) from arsse_label_members where label = id and assigned = 1) as articles,
(select count(*) from arsse_label_members (select count(*) from arsse_label_members
join arsse_marks on arsse_label_members.article = arsse_marks.article and arsse_label_members.subscription = arsse_marks.subscription join arsse_marks on arsse_label_members.article = arsse_marks.article and arsse_label_members.subscription = arsse_marks.subscription
where label = id and assigned = 1 and read = 1 where label = id and assigned = 1 and read = 1
) as read ) as read
@ -1484,11 +1484,11 @@ class Database {
$q->setWhere("not exists(select article from arsse_label_members where label = ? and article = arsse_articles.id)", "int", $id); $q->setWhere("not exists(select article from arsse_label_members where label = ? and article = arsse_articles.id)", "int", $id);
$q->pushCTE("target_articles"); $q->pushCTE("target_articles");
$q->setBody( $q->setBody(
"INSERT INTO "INSERT INTO
arsse_label_members(label,article,subscription) arsse_label_members(label,article,subscription)
SELECT SELECT
?,id, ?,id,
(select id from arsse_subscriptions join user on user = owner where arsse_subscriptions.feed = target_articles.feed) (select id from arsse_subscriptions join user on user = owner where arsse_subscriptions.feed = target_articles.feed)
FROM target_articles", FROM target_articles",
"int", "int",
$id $id

2
lib/Db/AbstractDriver.php

@ -76,7 +76,7 @@ abstract class AbstractDriver implements Driver {
public function begin(bool $lock = false): Transaction { public function begin(bool $lock = false): Transaction {
return new Transaction($this, $lock); return new Transaction($this, $lock);
} }
public function savepointCreate(bool $lock = false): int { public function savepointCreate(bool $lock = false): int {
if ($lock && !$this->transDepth) { if ($lock && !$this->transDepth) {
$this->lock(); $this->lock();

2
lib/Db/Driver.php

@ -12,7 +12,7 @@ interface Driver {
const TR_ROLLBACK = 2; const TR_ROLLBACK = 2;
const TR_PEND_COMMIT = -1; const TR_PEND_COMMIT = -1;
const TR_PEND_ROLLBACK = -2; const TR_PEND_ROLLBACK = -2;
public static function create(): Driver; public static function create(): Driver;
// returns a human-friendly name for the driver (for display in installer, for example) // returns a human-friendly name for the driver (for display in installer, for example)
public static function driverName(): string; public static function driverName(): string;

2
lib/Feed.php

@ -44,7 +44,7 @@ class Feed {
libxml_use_internal_errors(false); libxml_use_internal_errors(false);
return $out; return $out;
} }
public function __construct(int $feedID = null, string $url, string $lastModified = '', string $etag = '', string $username = '', string $password = '', bool $scrape = false) { public function __construct(int $feedID = null, string $url, string $lastModified = '', string $etag = '', string $username = '', string $password = '', bool $scrape = false) {
// fetch the feed // fetch the feed
$this->resource = self::download($url, $lastModified, $etag, $username, $password); $this->resource = self::download($url, $lastModified, $etag, $username, $password);

36
lib/Misc/Context.php

@ -58,79 +58,79 @@ class Context {
} }
return array_values(array_filter($spec)); return array_values(array_filter($spec));
} }
public function reverse(bool $spec = null) { public function reverse(bool $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function limit(int $spec = null) { public function limit(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function offset(int $spec = null) { public function offset(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function folder(int $spec = null) { public function folder(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function folderShallow(int $spec = null) { public function folderShallow(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function subscription(int $spec = null) { public function subscription(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function latestArticle(int $spec = null) { public function latestArticle(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function oldestArticle(int $spec = null) { public function oldestArticle(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function latestEdition(int $spec = null) { public function latestEdition(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function oldestEdition(int $spec = null) { public function oldestEdition(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function unread(bool $spec = null) { public function unread(bool $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function starred(bool $spec = null) { public function starred(bool $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function modifiedSince($spec = null) { public function modifiedSince($spec = null) {
$spec = Date::normalize($spec); $spec = Date::normalize($spec);
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function notModifiedSince($spec = null) { public function notModifiedSince($spec = null) {
$spec = Date::normalize($spec); $spec = Date::normalize($spec);
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function markedSince($spec = null) { public function markedSince($spec = null) {
$spec = Date::normalize($spec); $spec = Date::normalize($spec);
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function notMarkedSince($spec = null) { public function notMarkedSince($spec = null) {
$spec = Date::normalize($spec); $spec = Date::normalize($spec);
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function edition(int $spec = null) { public function edition(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }
public function article(int $spec = null) { public function article(int $spec = null) {
return $this->act(__FUNCTION__, func_num_args(), $spec); return $this->act(__FUNCTION__, func_num_args(), $spec);
} }

2
lib/REST/AbstractHandler.php

@ -24,7 +24,7 @@ abstract class AbstractHandler implements Handler {
} }
return $out; return $out;
} }
protected function fieldMapTypes(array $data, array $map, string $dateFormat = "sql"): array { protected function fieldMapTypes(array $data, array $map, string $dateFormat = "sql"): array {
foreach ($map as $key => $type) { foreach ($map as $key => $type) {
if (array_key_exists($key, $data)) { if (array_key_exists($key, $data)) {

12
lib/REST/NextCloudNews/V1_2.php

@ -74,7 +74,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
'/status' => ['GET' => "serverStatus"], '/status' => ['GET' => "serverStatus"],
'/user' => ['GET' => "userStatus"], '/user' => ['GET' => "userStatus"],
]; ];
public function __construct() { public function __construct() {
} }
@ -152,7 +152,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
$target->query = ""; $target->query = "";
return (string) $target; return (string) $target;
} }
protected function chooseCall(string $url, string $method): string { protected function chooseCall(string $url, string $method): string {
// // normalize the URL path: change any IDs to 1 for easier comparison // // normalize the URL path: change any IDs to 1 for easier comparison
$url = $this->normalizePathIds($url); $url = $this->normalizePathIds($url);
@ -282,7 +282,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
return new EmptyResponse(404); return new EmptyResponse(404);
} }
} }
// list folders // list folders
protected function folderList(array $url, array $data): ResponseInterface { protected function folderList(array $url, array $data): ResponseInterface {
$folders = []; $folders = [];
@ -362,7 +362,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
return new EmptyResponse(204); return new EmptyResponse(204);
} }
// return list of feeds which should be refreshed // return list of feeds which should be refreshed
protected function feedListStale(array $url, array $data): ResponseInterface { protected function feedListStale(array $url, array $data): ResponseInterface {
// function requires admin rights per spec // function requires admin rights per spec
@ -378,7 +378,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
return new Response(['feeds' => $out]); return new Response(['feeds' => $out]);
} }
// refresh a feed // refresh a feed
protected function feedUpdate(array $url, array $data): ResponseInterface { protected function feedUpdate(array $url, array $data): ResponseInterface {
// function requires admin rights per spec // function requires admin rights per spec
@ -431,7 +431,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
return new Response($out); return new Response($out);
} }
// return list of feeds for the logged-in user // return list of feeds for the logged-in user
protected function subscriptionList(array $url, array $data): ResponseInterface { protected function subscriptionList(array $url, array $data): ResponseInterface {
$subs = Arsse::$db->subscriptionList(Arsse::$user->id); $subs = Arsse::$db->subscriptionList(Arsse::$user->id);

2
lib/REST/Target.php

@ -14,7 +14,7 @@ class Target {
public $path = []; public $path = [];
public $query = ""; public $query = "";
public $fragment = ""; public $fragment = "";
public function __construct(string $target) { public function __construct(string $target) {
$target = $this->parseFragment($target); $target = $this->parseFragment($target);
$target = $this->parseQuery($target); $target = $this->parseQuery($target);

6
lib/REST/TinyTinyRSS/API.php

@ -87,7 +87,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
'status' => 1, 'status' => 1,
'content' => ['error' => "MALFORMED_INPUT"], 'content' => ['error' => "MALFORMED_INPUT"],
]; ];
public function __construct() { public function __construct() {
} }
@ -174,7 +174,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
public function opGetApiLevel(array $data): array { public function opGetApiLevel(array $data): array {
return ['level' => self::LEVEL]; return ['level' => self::LEVEL];
} }
public function opGetVersion(array $data): array { public function opGetVersion(array $data): array {
return [ return [
'version' => self::VERSION, 'version' => self::VERSION,
@ -186,7 +186,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
$user = $data['user'] ?? ""; $user = $data['user'] ?? "";
$pass = $data['password'] ?? ""; $pass = $data['password'] ?? "";
if (!Arsse::$conf->userSessionEnforced && isset(Arsse::$user->id)) { if (!Arsse::$conf->userSessionEnforced && isset(Arsse::$user->id)) {
// if HTTP authentication was previously successful and sessions // if HTTP authentication was previously successful and sessions
// are not enforced, create a session for the HTTP user regardless // are not enforced, create a session for the HTTP user regardless
// of which user the API call mentions // of which user the API call mentions
$id = Arsse::$db->sessionCreate(Arsse::$user->id); $id = Arsse::$db->sessionCreate(Arsse::$user->id);

2
lib/REST/TinyTinyRSS/Exception.php

@ -8,7 +8,7 @@ namespace JKingWeb\Arsse\REST\TinyTinyRSS;
class Exception extends \Exception { class Exception extends \Exception {
protected $data = []; protected $data = [];
public function __construct($msg = "UNSPECIFIED_ERROR", $data = [], $e = null) { public function __construct($msg = "UNSPECIFIED_ERROR", $data = [], $e = null) {
$this->data = $data; $this->data = $data;
parent::__construct($msg, 0, $e); parent::__construct($msg, 0, $e);

4
lib/Service.php

@ -9,7 +9,7 @@ namespace JKingWeb\Arsse;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
class Service { class Service {
/** @var Service\Driver */ /** @var Service\Driver */
protected $drv; protected $drv;
/** @var \DateInterval */ /** @var \DateInterval */
@ -26,7 +26,7 @@ class Service {
} }
return $classes; return $classes;
} }
public static function interval(): \DateInterval { public static function interval(): \DateInterval {
try { try {
return new \DateInterval(Arsse::$conf->serviceFrequency); return new \DateInterval(Arsse::$conf->serviceFrequency);

2
lib/Service/Curl/Driver.php

@ -12,7 +12,7 @@ class Driver implements \JKingWeb\Arsse\Service\Driver {
protected $options = []; protected $options = [];
protected $queue; protected $queue;
protected $handles = []; protected $handles = [];
public static function driverName(): string { public static function driverName(): string {
return Arsse::$lang->msg("Driver.Service.Curl.Name"); return Arsse::$lang->msg("Driver.Service.Curl.Name");
} }

4
lib/Service/Forking/Driver.php

@ -10,7 +10,7 @@ use JKingWeb\Arsse\Arsse;
class Driver implements \JKingWeb\Arsse\Service\Driver { class Driver implements \JKingWeb\Arsse\Service\Driver {
protected $queue = []; protected $queue = [];
public static function driverName(): string { public static function driverName(): string {
return Arsse::$lang->msg("Driver.Service.Forking.Name"); return Arsse::$lang->msg("Driver.Service.Forking.Name");
} }
@ -18,7 +18,7 @@ class Driver implements \JKingWeb\Arsse\Service\Driver {
public static function requirementsMet(): bool { public static function requirementsMet(): bool {
return function_exists("popen"); return function_exists("popen");
} }
public function __construct() { public function __construct() {
} }

4
lib/Service/Internal/Driver.php

@ -10,7 +10,7 @@ use JKingWeb\Arsse\Arsse;
class Driver implements \JKingWeb\Arsse\Service\Driver { class Driver implements \JKingWeb\Arsse\Service\Driver {
protected $queue = []; protected $queue = [];
public static function driverName(): string { public static function driverName(): string {
return Arsse::$lang->msg("Driver.Service.Internal.Name"); return Arsse::$lang->msg("Driver.Service.Internal.Name");
} }
@ -19,7 +19,7 @@ class Driver implements \JKingWeb\Arsse\Service\Driver {
// this driver has no requirements // this driver has no requirements
return true; return true;
} }
public function __construct() { public function __construct() {
} }

4
locale/en.php

@ -5,7 +5,7 @@
return [ return [
'API.TTRSS.Category.Uncategorized' => 'Uncategorized', 'API.TTRSS.Category.Uncategorized' => 'Uncategorized',
'API.TTRSS.Category.Special' => 'Special', 'API.TTRSS.Category.Special' => 'Special',
'API.TTRSS.Category.Labels' => 'Labels', 'API.TTRSS.Category.Labels' => 'Labels',
'API.TTRSS.Feed.All' => 'All articles', 'API.TTRSS.Feed.All' => 'All articles',
'API.TTRSS.Feed.Fresh' => 'Fresh articles', 'API.TTRSS.Feed.Fresh' => 'Fresh articles',
@ -181,4 +181,4 @@ return [
'Exception.JKingWeb/Arsse/Feed/Exception.xmlEntity' => 'Refused to parse feed "{url}" because it contains an XXE attack', 'Exception.JKingWeb/Arsse/Feed/Exception.xmlEntity' => 'Refused to parse feed "{url}" because it contains an XXE attack',
'Exception.JKingWeb/Arsse/Feed/Exception.subscriptionNotFound' => 'Unable to find a feed at location "{url}"', 'Exception.JKingWeb/Arsse/Feed/Exception.subscriptionNotFound' => 'Unable to find a feed at location "{url}"',
'Exception.JKingWeb/Arsse/Feed/Exception.unsupportedFeedFormat' => 'Feed "{url}" is of an unsupported format', 'Exception.JKingWeb/Arsse/Feed/Exception.unsupportedFeedFormat' => 'Feed "{url}" is of an unsupported format',
]; ];

4
sql/SQLite3/0.sql

@ -105,7 +105,7 @@ create table arsse_marks(
subscription integer not null references arsse_subscriptions(id) on delete cascade on update cascade, subscription integer not null references arsse_subscriptions(id) on delete cascade on update cascade,
read boolean not null default 0, read boolean not null default 0,
starred boolean not null default 0, starred boolean not null default 0,
modified text not null default CURRENT_TIMESTAMP, modified text not null default CURRENT_TIMESTAMP,
primary key(article,subscription) primary key(article,subscription)
); );
@ -124,4 +124,4 @@ create table arsse_categories(
-- set version marker -- set version marker
pragma user_version = 1; pragma user_version = 1;
insert into arsse_meta(key,value) values('schema_version','1'); insert into arsse_meta(key,value) values('schema_version','1');

4
tests/cases/Db/SQLite3/TestStatement.php

@ -49,7 +49,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$typeStr = "'".str_replace("'", "''", $type)."'"; $typeStr = "'".str_replace("'", "''", $type)."'";
$nativeStatement = $this->c->prepare( $nativeStatement = $this->c->prepare(
"SELECT ( "SELECT (
(CASE WHEN substr($typeStr, 0, 7) <> 'strict ' then null else 1 end) is null (CASE WHEN substr($typeStr, 0, 7) <> 'strict ' then null else 1 end) is null
and ? is null and ? is null
) or ( ) or (
$exp = ? $exp = ?
@ -250,7 +250,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
[$dateImmutable, "strict boolean", "1"], [$dateImmutable, "strict boolean", "1"],
]; ];
} }
public function testConstructStatement() { public function testConstructStatement() {
$nativeStatement = $this->c->prepare("SELECT ? as value"); $nativeStatement = $this->c->prepare("SELECT ? as value");
$this->assertInstanceOf(Statement::class, new \JKingWeb\Arsse\Db\SQLite3\Statement($this->c, $nativeStatement)); $this->assertInstanceOf(Statement::class, new \JKingWeb\Arsse\Db\SQLite3\Statement($this->c, $nativeStatement));

2
tests/cases/Db/SQLite3PDO/TestStatement.php

@ -50,7 +50,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$typeStr = "'".str_replace("'", "''", $type)."'"; $typeStr = "'".str_replace("'", "''", $type)."'";
$nativeStatement = $this->c->prepare( $nativeStatement = $this->c->prepare(
"SELECT ( "SELECT (
(CASE WHEN substr($typeStr, 0, 7) <> 'strict ' then null else 1 end) is null (CASE WHEN substr($typeStr, 0, 7) <> 'strict ' then null else 1 end) is null
and ? is null and ? is null
) or ( ) or (
$exp = ? $exp = ?

8
tests/cases/Feed/TestFeed.php

@ -172,7 +172,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertException("malformedXml", "Feed"); $this->assertException("malformedXml", "Feed");
new Feed(null, $this->base."Parsing/Malformed"); new Feed(null, $this->base."Parsing/Malformed");
} }
public function testDeduplicateFeedItems() { public function testDeduplicateFeedItems() {
// duplicates with dates lead to the newest match being kept // duplicates with dates lead to the newest match being kept
$t = strtotime("2002-05-19T15:21:36Z"); $t = strtotime("2002-05-19T15:21:36Z");
@ -245,7 +245,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$f = new Feed(null, $this->base."Caching/200None"); $f = new Feed(null, $this->base."Caching/200None");
$this->assertTime($t, $f->lastModified); $this->assertTime($t, $f->lastModified);
} }
public function testComputeNextFetchOnError() { public function testComputeNextFetchOnError() {
for ($a = 0; $a < 100; $a++) { for ($a = 0; $a < 100; $a++) {
if ($a < 3) { if ($a < 3) {
@ -257,7 +257,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
} }
public function testComputeNextFetchFrom304() { public function testComputeNextFetchFrom304() {
// if less than half an hour, check in 15 minutes // if less than half an hour, check in 15 minutes
$t = strtotime("now"); $t = strtotime("now");
@ -305,7 +305,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$exp = strtotime("now + 3 hours"); $exp = strtotime("now + 3 hours");
$this->assertTime($exp, $f->nextFetch); $this->assertTime($exp, $f->nextFetch);
} }
public function testComputeNextFetchFrom200() { public function testComputeNextFetchFrom200() {
// if less than half an hour, check in 15 minutes // if less than half an hour, check in 15 minutes
$f = new Feed(null, $this->base."NextFetch/30m"); $f = new Feed(null, $this->base."NextFetch/30m");

2
tests/cases/Misc/TestValueInfo.php

@ -16,7 +16,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() { public function setUp() {
$this->clearData(); $this->clearData();
} }
public function testGetIntegerInfo() { public function testGetIntegerInfo() {
$tests = [ $tests = [
[null, I::NULL], [null, I::NULL],

2
tests/cases/REST/NextCloudNews/TestV1_2.php

@ -934,7 +934,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$exp = new EmptyResponse(403); $exp = new EmptyResponse(403);
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
} }
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);

4
tests/cases/REST/TestREST.php

@ -60,7 +60,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
[$fake, "/full/url-not", []], [$fake, "/full/url-not", []],
]; ];
} }
/** @dataProvider provideAuthenticableRequests */ /** @dataProvider provideAuthenticableRequests */
public function testAuthenticateRequests(array $serverParams, array $expAttr) { public function testAuthenticateRequests(array $serverParams, array $expAttr) {
$r = new REST(); $r = new REST();
@ -105,7 +105,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
$act = $r->challenge($in); $act = $r->challenge($in);
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
} }
/** @dataProvider provideUnnormalizedOrigins */ /** @dataProvider provideUnnormalizedOrigins */
public function testNormalizeOrigins(string $origin, string $exp, array $ports = null) { public function testNormalizeOrigins(string $origin, string $exp, array $ports = null) {
$r = new REST(); $r = new REST();

34
tests/cases/REST/TinyTinyRSS/TestAPI.php

@ -105,21 +105,21 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
protected $richContent = <<<LONG_STRING protected $richContent = <<<LONG_STRING
<section> <section>
<p> <p>
<b>Pour</b> vous faire mieux <b>Pour</b> vous faire mieux
connaitre d’ou\u{300} vient connaitre d’ou\u{300} vient
l’erreur de ceux qui l’erreur de ceux qui
bla\u{302}ment la bla\u{302}ment la
volupte\u{301}, et qui louent volupte\u{301}, et qui louent
en quelque sorte la douleur, en quelque sorte la douleur,
je vais entrer dans une je vais entrer dans une
explication plus explication plus
e\u{301}tendue, et vous faire e\u{301}tendue, et vous faire
voir tout ce qui a voir tout ce qui a
e\u{301}te\u{301} dit e\u{301}te\u{301} dit
la\u{300}-dessus par la\u{300}-dessus par
l’inventeur de la l’inventeur de la
ve\u{301}rite\u{301}, et, pour ve\u{301}rite\u{301}, et, pour
ainsi dire, par l’architecte ainsi dire, par l’architecte
de la vie heureuse. de la vie heureuse.
</p> </p>
</section> </section>
@ -157,7 +157,7 @@ LONG_STRING;
protected function reqAuth($data, $user) { protected function reqAuth($data, $user) {
return $this->req($data, "POST", "", null, $user); return $this->req($data, "POST", "", null, $user);
} }
protected function respGood($content = null, $seq = 0): Response { protected function respGood($content = null, $seq = 0): Response {
return new Response([ return new Response([
'seq' => $seq, 'seq' => $seq,
@ -1551,7 +1551,7 @@ LONG_STRING;
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 0, 'mode' => 1], ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 0, 'mode' => 1],
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 0, 'mode' => 2], ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 0, 'mode' => 2],
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 0, 'mode' => 3], // invalid mode ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 0, 'mode' => 3], // invalid mode
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 1], // Published feed' no-op ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 1], // Published feed' no-op
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 1, 'mode' => 0], ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 1, 'mode' => 0],
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 1, 'mode' => 1], ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1", 'field' => 1, 'mode' => 1],

2
tests/cases/User/TestAuthorization.php

@ -83,7 +83,7 @@ class TestAuthorization extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertFalse(Arsse::$user->authorizationEnabled(true)); $this->assertFalse(Arsse::$user->authorizationEnabled(true));
$this->assertTrue(Arsse::$user->authorizationEnabled(true)); $this->assertTrue(Arsse::$user->authorizationEnabled(true));
} }
public function testSelfActionLogic() { public function testSelfActionLogic() {
foreach (array_keys(self::USERS) as $user) { foreach (array_keys(self::USERS) as $user) {
Arsse::$user->auth($user, ""); Arsse::$user->auth($user, "");

2
tests/docroot/Feed/Fetching/Timeout.php

@ -1,4 +1,4 @@
<?php <?php
usleep(1.05 * 1000000); usleep(1.05 * 1000000);
return [ return [
'code' => 404, 'code' => 404,

2
tests/docroot/Feed/Fetching/TooLarge.php

@ -1,4 +1,4 @@
<?php <?php
$item = ' $item = '
<item> <item>
<description>'.str_repeat("0", 1024).'</description> <description>'.str_repeat("0", 1024).'</description>

2
tests/docroot/Feed/NextFetch/NotModified.php

@ -1,4 +1,4 @@
<?php <?php
if (array_key_exists("t", $_GET)) { if (array_key_exists("t", $_GET)) {
return [ return [
'code' => 304, 'code' => 304,

4
tests/docroot/Feed/Parsing/XXEAttack.php

@ -1,8 +1,8 @@
<?php return [ <?php return [
'mime' => "application/rss+xml", 'mime' => "application/rss+xml",
'content' => <<<MESSAGE_BODY 'content' => <<<MESSAGE_BODY
<!DOCTYPE test [ <!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///etc/passwd"> <!ENTITY xxe SYSTEM "file:///etc/passwd">
]> ]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel> <channel>

4
tests/lib/Database/SeriesCleanup.php

@ -157,7 +157,7 @@ trait SeriesCleanup {
} }
$this->compareExpectations($state); $this->compareExpectations($state);
} }
public function testCleanUpOldArticlesWithUnlimitedReadRetention() { public function testCleanUpOldArticlesWithUnlimitedReadRetention() {
Arsse::$conf->purgeArticlesRead = ""; Arsse::$conf->purgeArticlesRead = "";
Arsse::$db->articleCleanup(); Arsse::$db->articleCleanup();
@ -169,7 +169,7 @@ trait SeriesCleanup {
} }
$this->compareExpectations($state); $this->compareExpectations($state);
} }
public function testCleanUpOldArticlesWithUnlimitedUnreadRetention() { public function testCleanUpOldArticlesWithUnlimitedUnreadRetention() {
Arsse::$conf->purgeArticlesUnread = ""; Arsse::$conf->purgeArticlesUnread = "";
Arsse::$db->articleCleanup(); Arsse::$db->articleCleanup();

2
tests/lib/Database/SeriesFeed.php

@ -30,7 +30,7 @@ trait SeriesFeed {
'title_content_hash' => '43b970ac6ec5f8a9647b2c7e4eed8b1d7f62e154a95eed748b0294c1256764ba', 'title_content_hash' => '43b970ac6ec5f8a9647b2c7e4eed8b1d7f62e154a95eed748b0294c1256764ba',
], ],
]; ];
public function setUpSeries() { public function setUpSeries() {
// set up the test data // set up the test data
$past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute")); $past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute"));

20
tests/lib/Database/SeriesUser.php

@ -58,7 +58,7 @@ trait SeriesUser {
$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->assertSame("", Arsse::$db->userAdd("john.doe@example.org", "")); $this->assertSame("", 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");
@ -99,7 +99,7 @@ trait SeriesUser {
$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");
@ -112,7 +112,7 @@ trait SeriesUser {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userRemove("john.doe@example.org"); Arsse::$db->userRemove("john.doe@example.org");
} }
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");
@ -130,13 +130,13 @@ trait SeriesUser {
$this->assertSame($users, Arsse::$db->userList("example.com")); $this->assertSame($users, Arsse::$db->userList("example.com"));
Phake::verify(Arsse::$user)->authorize("@example.com", "userList"); Phake::verify(Arsse::$user)->authorize("@example.com", "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();
} }
public function testListUsersOnADomainWithoutAuthority() { public function testListUsersOnADomainWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
@ -166,7 +166,7 @@ trait SeriesUser {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userPasswordSet("john.doe@example.org", "secret"); Arsse::$db->userPasswordSet("john.doe@example.org", "secret");
} }
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");
@ -188,7 +188,7 @@ trait SeriesUser {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userPropertiesGet("john.doe@example.org"); Arsse::$db->userPropertiesGet("john.doe@example.org");
} }
public function testGetUserPropertiesWithoutAuthority() { public function testGetUserPropertiesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
@ -223,7 +223,7 @@ trait SeriesUser {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userPropertiesSet("john.doe@example.org", $try); Arsse::$db->userPropertiesSet("john.doe@example.org", $try);
} }
public function testSetUserPropertiesWithoutAuthority() { public function testSetUserPropertiesWithoutAuthority() {
$try = ['name' => 'John Doe']; $try = ['name' => 'John Doe'];
Phake::when(Arsse::$user)->authorize->thenReturn(false); Phake::when(Arsse::$user)->authorize->thenReturn(false);
@ -244,7 +244,7 @@ trait SeriesUser {
$this->assertSame(UserDriver::RIGHTS_NONE, Arsse::$db->userRightsGet("john.doe@example.org")); $this->assertSame(UserDriver::RIGHTS_NONE, Arsse::$db->userRightsGet("john.doe@example.org"));
Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userRightsGet"); Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userRightsGet");
} }
public function testGetUserRightsWithoutAuthority() { public function testGetUserRightsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false); Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
@ -266,7 +266,7 @@ trait SeriesUser {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userRightsSet("john.doe@example.org", $rights); Arsse::$db->userRightsSet("john.doe@example.org", $rights);
} }
public function testSetUserRightsWithoutAuthority() { public function testSetUserRightsWithoutAuthority() {
$rights = UserDriver::RIGHTS_GLOBAL_ADMIN; $rights = UserDriver::RIGHTS_GLOBAL_ADMIN;
Phake::when(Arsse::$user)->authorize->thenReturn(false); Phake::when(Arsse::$user)->authorize->thenReturn(false);

8
www/tt-rss/images/README

@ -1,14 +1,14 @@
Silk icon set v1.3 Silk icon set v1.3
Copyright 2006, Mark James Copyright 2006, Mark James
http://www.famfamfam.com/lab/icons/silk/ http://www.famfamfam.com/lab/icons/silk/
Used under license: Used under license:
http://creativecommons.org/licenses/by/2.5/ http://creativecommons.org/licenses/by/2.5/
A minimal subset of the Silk icon set used by Tiny Tiny RSS is included here A minimal subset of the Silk icon set used by Tiny Tiny RSS is included here
to provide consistent results with certain API functions. to provide consistent results with certain API functions.
Note that TT-RSS renames some of the icons, and we use the modified names, Note that TT-RSS renames some of the icons, and we use the modified names,
again for consistency. Below is a table listing the source file names: again for consistency. Below is a table listing the source file names:
Modified Original Modified Original

Loading…
Cancel
Save