Browse Source

Move date formatting out of SQL and standardize on the DateFormatter trait

Fixes #56
microsub
J. King 7 years ago
parent
commit
17ec6cf669
  1. 38
      lib/Database.php
  2. 38
      lib/Db/AbstractStatement.php
  3. 26
      lib/Db/SQLite3/CustomFunctions.php
  4. 2
      lib/Db/SQLite3/Driver.php
  5. 8
      lib/Db/SQLite3/Statement.php
  6. 5
      lib/Db/Statement.php
  7. 6
      lib/Feed.php
  8. 44
      lib/Misc/DateFormatter.php
  9. 16
      lib/REST/AbstractHandler.php
  10. 14
      lib/REST/NextCloudNews/V1_2.php
  11. 16
      tests/Feed/TestFeed.php
  12. 4
      tests/REST/NextCloudNews/TestNCNV1_2.php
  13. 31
      tests/lib/Database/SeriesArticle.php
  14. 4
      tests/lib/Database/SeriesFeed.php
  15. 8
      tests/lib/Database/SeriesSubscription.php
  16. 54
      tests/lib/Db/BindingTests.php
  17. 4
      tests/lib/Tools.php

38
lib/Database.php

@ -6,6 +6,7 @@ use JKingWeb\Arsse\Misc\Query;
use JKingWeb\Arsse\Misc\Context;
class Database {
use Misc\DateFormatter;
const SCHEMA_VERSION = 1;
const FORMAT_TS = "Y-m-d h:i:s";
@ -13,7 +14,6 @@ class Database {
const FORMAT_TIME = "h:i:s";
public $db;
protected $dateFormatDefault = "sql";
public function __construct() {
$driver = Data::$conf->dbDriver;
@ -27,15 +27,6 @@ class Database {
protected function caller(): string {
return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
}
public function dateFormatDefault(string $set = null): string {
if(is_null($set)) return $this->dateFormatDefault;
$set = strtolower($set);
if(in_array($set, ["sql", "iso8601", "unix", "http"])) {
$this->dateFormatDefault = $set;
}
return $this->dateFormatDefault;
}
static public function listDrivers(): array {
$sep = \DIRECTORY_SEPARATOR;
@ -349,17 +340,14 @@ class Database {
$q = new Query(
"SELECT
arsse_subscriptions.id,
url,favicon,source,folder,pinned,err_count,err_msg,order_type,
DATEFORMAT(?, added) as added,
url,favicon,source,folder,pinned,err_count,err_msg,order_type,added,
topmost.top as top_folder,
coalesce(arsse_subscriptions.title, arsse_feeds.title) as title,
(SELECT count(*) from arsse_articles where feed is arsse_subscriptions.feed) - (SELECT count(*) from arsse_marks join user on user is owner join arsse_articles on article = arsse_articles.id where feed is arsse_feeds.id and read is 1) as unread
from arsse_subscriptions
join user on user is owner
join arsse_feeds on feed = arsse_feeds.id
left join topmost on folder=f_id",
"str", // where terms
$this->dateFormatDefault
left join topmost on folder=f_id"
);
$q->setOrder("pinned desc, title");
// define common table expressions
@ -444,13 +432,13 @@ class Database {
public function feedUpdate(int $feedID, bool $throwError = false): bool {
$tr = $this->db->begin();
// check to make sure the feed exists
$f = $this->db->prepare("SELECT url, username, password, DATEFORMAT('http', modified) AS lastmodified, etag, err_count FROM arsse_feeds where id is ?", "int")->run($feedID)->getRow();
$f = $this->db->prepare("SELECT url, username, password, modified, etag, err_count FROM arsse_feeds where id is ?", "int")->run($feedID)->getRow();
if(!$f) throw new Db\ExceptionInput("subjectMissing", ["action" => __FUNCTION__, "field" => "feed", 'id' => $feedID]);
// the Feed object throws an exception when there are problems, but that isn't ideal
// here. When an exception is thrown it should update the database with the
// error instead of failing; if other exceptions are thrown, we should simply roll back
try {
$feed = new Feed($feedID, $f['url'], (string)$f['lastmodified'], $f['etag'], $f['username'], $f['password']);
$feed = new Feed($feedID, $f['url'], $this->dateTransform($f['modified'], "http", "sql"), $f['etag'], $f['username'], $f['password']);
if(!$feed->modified) {
// if the feed hasn't changed, just compute the next fetch time and record it
$this->db->prepare("UPDATE arsse_feeds SET updated = CURRENT_TIMESTAMP, next_fetch = ? WHERE id is ?", 'datetime', 'int')->run($feed->nextFetch, $feedID);
@ -556,7 +544,7 @@ class Database {
public function feedMatchLatest(int $feedID, int $count): Db\Result {
return $this->db->prepare(
"SELECT id, DATEFORMAT('unix', edited) AS edited_date, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? ORDER BY modified desc, id desc limit ?",
"SELECT id, edited, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? ORDER BY modified desc, id desc limit ?",
'int', 'int'
)->run($feedID, $count);
}
@ -569,7 +557,7 @@ class Database {
list($cHashTC, $tHashTC) = $this->generateIn($hashesTC, "str");
// perform the query
return $articles = $this->db->prepare(
"SELECT id, DATEFORMAT('unix', edited) AS edited_date, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? and (guid in($cId) or url_title_hash in($cHashUT) or url_content_hash in($cHashUC) or title_content_hash in($cHashTC))",
"SELECT id, edited, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? and (guid in($cId) or url_title_hash in($cHashUT) or url_content_hash in($cHashUC) or title_content_hash in($cHashTC))",
'int', $tId, $tHashUT, $tHashUC, $tHashTC
)->run($feedID, $ids, $hashesUT, $hashesUC, $hashesTC);
}
@ -613,12 +601,12 @@ class Database {
arsse_articles.id as id,
arsse_articles.url as url,
title,author,content,guid,
DATEFORMAT(?, published) as published_date,
DATEFORMAT(?, edited) as edited_date,
DATEFORMAT(?, max(
published as published_date,
edited as edited_date,
max(
modified,
coalesce((select modified from arsse_marks join user on user is owner where article is arsse_articles.id),'')
)) as modified_date,
) as modified_date,
NOT (select count(*) from arsse_marks join user on user is owner where article is arsse_articles.id and read is 1) as unread,
(select count(*) from arsse_marks join user on user is owner where article is arsse_articles.id and starred is 1) as starred,
(select max(id) from arsse_editions where article is arsse_articles.id) as edition,
@ -629,9 +617,7 @@ class Database {
FROM arsse_articles
join subscribed_feeds on arsse_articles.feed is subscribed_feeds.id
left join arsse_enclosures on arsse_enclosures.article is arsse_articles.id
",
["str", "str", "str"],
[$this->dateFormatDefault, $this->dateFormatDefault, $this->dateFormatDefault]
"
);
$q->setOrder("edition".($context->reverse ? " desc" : ""));
$q->setLimit($context->limit, $context->offset);

38
lib/Db/AbstractStatement.php

@ -3,12 +3,13 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
abstract class AbstractStatement implements Statement {
use \JKingWeb\Arsse\Misc\DateFormatter;
protected $types = [];
protected $isNullable = [];
protected $values = ['pre' => [], 'post' => []];
abstract function runArray(array $values = []): Result;
abstract static function dateFormat(int $part = self::TS_BOTH): string;
public function run(...$values): Result {
return $this->runArray($values);
@ -44,13 +45,13 @@ abstract class AbstractStatement implements Statement {
switch($t) {
case "date":
if(is_null($v) && !$nullable) $v = 0;
return $this->formatDate($v, self::TS_DATE);
return $this->dateTransform($v, "date");
case "time":
if(is_null($v) && !$nullable) $v = 0;
return $this->formatDate($v, self::TS_TIME);
return $this->dateTransform($v, "time");
case "datetime":
if(is_null($v) && !$nullable) $v = 0;
return $this->formatDate($v, self::TS_BOTH);
return $this->dateTransform($v, "sql");
case "null":
case "integer":
case "float":
@ -65,9 +66,12 @@ abstract class AbstractStatement implements Statement {
// handle objects
$value = $v;
if($value instanceof \DateTimeInterface) {
$value = $value->getTimestamp();
if($t=="string") $value = $this->formatDate($value, self::TS_BOTH);
settype($value, $t);
if($t=="string") {
$value = $this->dateTransform($value, "sql");
} else {
$value = $value->getTimestamp();
settype($value, $t);
}
} else {
$value = null;
settype($value, $t);
@ -78,24 +82,4 @@ abstract class AbstractStatement implements Statement {
throw new Exception("paramTypeUnknown", $type);
}
}
protected function formatDate($date, int $part = self::TS_BOTH) {
// convert input to a Unix timestamp
if($date instanceof \DateTimeInterface) {
$time = $date->getTimestamp();
} else if(is_numeric($date)) {
$time = (int) $date;
} else if($date===null) {
return null;
} else if(is_string($date)) {
$time = strtotime($date);
if($time===false) return null;
} else if (is_bool($date)) {
return null;
} else {
$time = (int) $date;
}
// ISO 8601 with space in the middle instead of T.
return gmdate($this->dateFormat($part), $time);
}
}

26
lib/Db/SQLite3/CustomFunctions.php

@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
class CustomFunctions {
protected static $tz;
// Converts from SQL date format to a specified standard date format.
public static function dateFormat(string $format, $date) {
$format = strtolower($format);
if($format=="sql") return $date;
settype($date, "string");
if($date=="") return null;
if(is_null(self::$tz)) self::$tz = new \DateTimeZone("UTC");
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $date, self::$tz);
switch ($format) {
case 'unix':
return $date->getTimestamp();
case 'http':
return $date->format("D, d M Y H:i:s \G\M\T");
case 'iso8601':
default:
return $date->format(\DateTime::ATOM);
}
}
}

2
lib/Db/SQLite3/Driver.php

@ -40,8 +40,6 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
$this->db->enableExceptions(true);
$this->exec("PRAGMA journal_mode = wal");
$this->exec("PRAGMA foreign_keys = yes");
// Create custom functions
$this->db->createFunction('DATEFORMAT', [CustomFunctions::class, 'dateFormat'], 2);
} catch(\Exception $e) {
list($excClass, $excMsg, $excData) = $this->exceptionBuild();
throw new $excClass($excMsg, $excData);

8
lib/Db/SQLite3/Statement.php

@ -37,14 +37,6 @@ class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
unset($this->st);
}
public static function dateFormat(int $part = self::TS_BOTH): string {
return ([
self::TS_TIME => 'H:i:s',
self::TS_DATE => 'Y-m-d',
self::TS_BOTH => 'Y-m-d H:i:s',
])[$part];
}
public function runArray(array $values = []): \JKingWeb\Arsse\Db\Result {
$this->st->clear();
$this->bindValues($values);

5
lib/Db/Statement.php

@ -3,9 +3,6 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
interface Statement {
const TS_TIME = -1;
const TS_DATE = 0;
const TS_BOTH = 1;
const TYPES = [
"null" => "null",
"nil" => "null",
@ -30,8 +27,6 @@ interface Statement {
"bit" => "boolean",
];
static function dateFormat(int $part = self::TS_BOTH): string;
function run(...$values): Result;
function runArray(array $values = []): Result;
function rebind(...$bindings): bool;

6
lib/Feed.php

@ -7,6 +7,8 @@ use PicoFeed\Reader\Favicon;
use PicoFeed\Config\Config;
class Feed {
use Misc\DateFormatter;
public $data = null;
public $favicon;
public $parser;
@ -24,7 +26,7 @@ class Feed {
// format the HTTP Last-Modified date returned
$lastMod = $this->resource->getLastModified();
if(strlen($lastMod)) {
$this->lastModified = \DateTime::createFromFormat("!D, d M Y H:i:s e", $lastMod);
$this->lastModified = $this->dateNormalize($lastMod, "http");
}
$this->modified = $this->resource->isModified();
//parse the feed, if it has been modified
@ -229,7 +231,7 @@ class Feed {
($i->urlContentHash && $i->urlContentHash === $a['url_content_hash']) ||
($i->titleContentHash && $i->titleContentHash === $a['title_content_hash'])
) {
if($i->updatedDate && $i->updatedDate->getTimestamp() !== $a['edited_date']) {
if($i->updatedDate && $this->dateTransform($i->updatedDate, "sql") !== $a['edited']) {
// if the item has an edit timestamp and it doesn't match that of the article in the database, the the article has been edited
// we store the item index and database record ID as a key/value pair
$found = true;

44
lib/Misc/DateFormatter.php

@ -4,36 +4,46 @@ namespace JKingWeb\Arsse\Misc;
trait DateFormatter {
protected function dateTransform($date, string $format = "iso8601", bool $local = false) {
$date = $this->dateNormalize($date);
$format = strtolower($format);
if($format=="unix") return $date;
switch ($format) {
protected function dateTransform($date, string $outFormat = null, string $inFormat = null, bool $inLocal = false) {
$date = $this->dateNormalize($date, $inFormat, $inLocal);
if(is_null($date) || is_null($outFormat)) return $date;
$outFormat = strtolower($outFormat);
if($outFormat=="unix") return $date->getTimestamp();
switch ($outFormat) {
case 'http': $f = "D, d M Y H:i:s \G\M\T"; break;
case 'iso8601': $f = \DateTime::ATOM; break;
case 'iso8601': $f = "Y-m-dTH:i:s"; break;
case 'sql': $f = "Y-m-d H:i:s"; break;
case 'date': $f = "Y-m-d"; break;
case 'time': $f = "H:i:s"; break;
default: $f = \DateTime::ATOM; break;
}
if($local) {
return date($f, $date);
} else {
return gmdate($f, $date);
default: $f = $outFormat; break;
}
return $date->format($f);
}
protected function dateNormalize($date) {
protected function dateNormalize($date, string $inFormat = null, bool $inLocal = false) {
// convert input to a Unix timestamp
if($date instanceof \DateTimeInterface) {
$time = $date->getTimestamp();
return $date;
} else if(is_numeric($date)) {
$time = (int) $date;
} else if($date===null) {
return null;
} else if(is_string($date)) {
try {
$time = (new \DateTime($date, new \DateTimeZone("UTC")))->getTimestamp();
$tz = (!$inLocal) ? new \DateTimeZone("UTC") : null;
if(!is_null($inFormat)) {
switch($inFormat) {
case 'http': $f = "D, d M Y H:i:s \G\M\T"; break;
case 'iso8601': $f = "Y-m-dTH:i:sP"; break;
case 'sql': $f = "Y-m-d H:i:s"; break;
case 'date': $f = "Y-m-d"; break;
case 'time': $f = "H:i:s"; break;
default: $f = $inFormat; break;
}
return \DateTime::createFromFormat("!".$f, $date, $tz);
} else {
return new \DateTime($date, $tz);
}
} catch(\Throwable $e) {
return null;
}
@ -42,6 +52,8 @@ trait DateFormatter {
} else {
$time = (int) $date;
}
return $time;
$d = new \DateTime();
$d->setTimestamp($time);
return $d;
}
}

16
lib/REST/AbstractHandler.php

@ -3,6 +3,8 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\REST;
abstract class AbstractHandler implements Handler {
use \JKingWeb\Arsse\Misc\DateFormatter;
abstract function __construct();
abstract function dispatch(Request $req): Response;
@ -16,9 +18,15 @@ abstract class AbstractHandler implements Handler {
return $out;
}
protected function fieldMapTypes(array $data, array $map): array {
protected function fieldMapTypes(array $data, array $map, string $dateFormat = "sql"): array {
foreach($map as $key => $type) {
if(array_key_exists($key, $data)) settype($data[$key], $type);
if(array_key_exists($key, $data)) {
if($type=="datetime" && $dateFormat != "sql") {
$data[$key] = $this->dateTransform($data[$key], $dateFormat, "sql");
} else {
settype($data[$key], $type);
}
}
}
return $data;
}
@ -33,7 +41,7 @@ abstract class AbstractHandler implements Handler {
return ($ch1 === $ch2);
}
protected function NormalizeInput(array $data, array $types, string $dateFormat = "Y-m-d\TH:i:sP"): array {
protected function NormalizeInput(array $data, array $types, string $dateFormat = null): array {
$out = [];
foreach($data as $key => $value) {
if(!isset($types[$key])) {
@ -67,7 +75,7 @@ abstract class AbstractHandler implements Handler {
if(is_numeric($value)) $out[$key] = (float) $value;
break;
case "datetime":
$t = \DateTime::createFromFormat($dateFormat, (string) $value);
$t = $this->dateNormalize($value, $dateFormat);
if($t) $out[$key] = $t;
break;
default:

14
lib/REST/NextCloudNews/V1_2.php

@ -14,6 +14,8 @@ use JKingWeb\Arsse\REST\Exception405;
class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
const REALM = "NextCloud News API v1-2";
protected $dateFormat = "unix";
protected $validInput = [
'name' => "string",
'url' => "string",
@ -69,7 +71,6 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
if(!method_exists($this, $func)) return new Response(501);
// dispatch
try {
Data::$db->dateFormatDefault("unix");
return $this->$func($req->paths, $data);
} catch(Exception $e) {
// if there was a REST exception return 400
@ -169,7 +170,8 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
$feed = $this->fieldMapTypes($feed, [
'folderId' => "int",
'pinned' => "bool",
]);
'added' => "datetime",
], $this->dateFormat);
return $feed;
}
@ -194,9 +196,11 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
]);
// cast values
$article = $this->fieldMapTypes($article, [
'unread' => "bool",
'starred' => "bool",
]);
'unread' => "bool",
'starred' => "bool",
'pubDate' => "datetime",
'lastModified' => "datetime",
], $this->dateFormat);
return $article;
}

16
tests/Feed/TestFeed.php

@ -12,7 +12,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
protected $latest = [
[
'id' => 1,
'edited_date' => 946684800,
'edited' => '2000-01-01 00:00:00',
'guid' => 'e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda',
'url_title_hash' => 'f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6',
'url_content_hash' => 'fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4',
@ -20,7 +20,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
],
[
'id' => 2,
'edited_date' => 946771200,
'edited' => '2000-01-02 00:00:00',
'guid' => '5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7',
'url_title_hash' => '0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153',
'url_content_hash' => '13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9',
@ -28,7 +28,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
],
[
'id' => 3,
'edited_date' => 946857600,
'edited' => '2000-01-03 00:00:00',
'guid' => '31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92',
'url_title_hash' => 'f74b06b240bd08abf4d3fdfc20dba6a6f6eb8b4f1a00e9a617efd63a87180a4b',
'url_content_hash' => 'b278380e984cefe63f0e412b88ffc9cb0befdfa06fdc00bace1da99a8daff406',
@ -36,7 +36,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
],
[
'id' => 4,
'edited_date' => 946944000,
'edited' => '2000-01-04 00:00:00',
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
'url_title_hash' => 'f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8',
'url_content_hash' => 'f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3',
@ -44,7 +44,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
],
[
'id' => 5,
'edited_date' => 947030400,
'edited' => '2000-01-05 00:00:00',
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
'url_title_hash' => 'd40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022',
'url_content_hash' => '834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900',
@ -54,7 +54,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
protected $others = [
[
'id' => 6,
'edited_date' => 947116800,
'edited' => '2000-01-06 00:00:00',
'guid' => 'b3461ab8e8759eeb1d65a818c65051ec00c1dfbbb32a3c8f6999434e3e3b76ab',
'url_title_hash' => '91d051a8e6749d014506848acd45e959af50bf876427c4f0e3a1ec0f04777b51',
'url_content_hash' => '211d78b1a040d40d17e747a363cc283f58767b2e502630d8de9b8f1d5e941d18',
@ -62,7 +62,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
],
[
'id' => 7,
'edited_date' => 947203200,
'edited' => '2000-01-07 00:00:00',
'guid' => 'f4fae999d6531747523f4ff0c74f3f0c7c588b67e4f32d8f7dba5f6f36e8a45d',
'url_title_hash' => 'b92f805f0d0643dad1d6c0bb5cbaec24729f5f71b37b831cf7ad31f6c9403ac8',
'url_content_hash' => '4fc8789b787246e9be08ca1bac0d4a1ac4db1984f0db07f7142417598cf7211f',
@ -70,7 +70,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
],
[
'id' => 8,
'edited_date' => 947289600,
'edited' => '2000-01-08 00:00:00',
'guid' => 'b9d2d58e3172096b1d23b42a59961fabc89962836c3cd5de54f3d3a98ff08e6c',
'url_title_hash' => '53a6cbcfeb66b46d09cbb7b25035df0562da35786933319c83b04be29acfb6f4',
'url_content_hash' => 'c6f3722b4445b49d19d39c3bf5b11a7cf23dd69873e2a0a458aab662f1cd9438',

4
tests/REST/NextCloudNews/TestNCNV1_2.php

@ -256,8 +256,6 @@ class TestNCNV1_2 extends \PHPUnit\Framework\TestCase {
$this->assertEquals($exp, $this->h->dispatch(new Request("GET", "/feeds")));
$exp = new Response(200, $exp2);
$this->assertEquals($exp, $this->h->dispatch(new Request("GET", "/feeds")));
// make sure the correct date format is actually requested
Phake::verify(Data::$db, Phake::atLeast(1))->dateFormatDefault("unix");
}
function testAddASubscription() {
@ -295,8 +293,6 @@ class TestNCNV1_2 extends \PHPUnit\Framework\TestCase {
// try to add a bad feed
$exp = new Response(422);
$this->assertEquals($exp, $this->h->dispatch(new Request("POST", "/feeds", json_encode($in[2]), 'application/json')));
// make sure the correct date format is actually requested
Phake::verify(Data::$db, Phake::atLeast(1))->dateFormatDefault("unix");
}
function testRemoveASubscription() {

31
tests/lib/Database/SeriesArticle.php

@ -179,9 +179,9 @@ trait SeriesArticle {
'author' => '',
'content' => '<p>Article content 1</p>',
'guid' => 'e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda',
'published_date' => 946684800,
'edited_date' => 946684801,
'modified_date' => 946688400,
'published_date' => '2000-01-01 00:00:00',
'edited_date' => '2000-01-01 00:00:01',
'modified_date' => '2000-01-01 01:00:00',
'unread' => 1,
'starred' => 0,
'edition' => 101,
@ -197,9 +197,9 @@ trait SeriesArticle {
'author' => '',
'content' => '<p>Article content 2</p>',
'guid' => '5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7',
'published_date' => 946771200,
'edited_date' => 946771202,
'modified_date' => 946778400,
'published_date' => '2000-01-02 00:00:00',
'edited_date' => '2000-01-02 00:00:02',
'modified_date' => '2000-01-02 02:00:00',
'unread' => 0,
'starred' => 0,
'edition' => 202,
@ -215,9 +215,9 @@ trait SeriesArticle {
'author' => '',
'content' => '<p>Article content 3</p>',
'guid' => '31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92',
'published_date' => 946857600,
'edited_date' => 946857603,
'modified_date' => 946868400,
'published_date' => '2000-01-03 00:00:00',
'edited_date' => '2000-01-03 00:00:03',
'modified_date' => '2000-01-03 03:00:00',
'unread' => 1,
'starred' => 1,
'edition' => 203,
@ -233,9 +233,9 @@ trait SeriesArticle {
'author' => '',
'content' => '<p>Article content 4</p>',
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
'published_date' => 946944000,
'edited_date' => 946944004,
'modified_date' => 946958400,
'published_date' => '2000-01-04 00:00:00',
'edited_date' => '2000-01-04 00:00:04',
'modified_date' => '2000-01-04 04:00:00',
'unread' => 0,
'starred' => 1,
'edition' => 204,
@ -251,9 +251,9 @@ trait SeriesArticle {
'author' => '',
'content' => '<p>Article content 5</p>',
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
'published_date' => 947030400,
'edited_date' => 947030405,
'modified_date' => 947048400,
'published_date' => '2000-01-05 00:00:00',
'edited_date' => '2000-01-05 00:00:05',
'modified_date' => '2000-01-05 05:00:00',
'unread' => 1,
'starred' => 0,
'edition' => 305,
@ -340,7 +340,6 @@ trait SeriesArticle {
function testListArticlesCheckingProperties() {
$this->user = "john.doe@example.org";
Data::$db->dateFormatDefault("unix");
$this->assertResult($this->matches, Data::$db->articleList($this->user));
}

4
tests/lib/Database/SeriesFeed.php

@ -12,7 +12,7 @@ trait SeriesFeed {
protected $matches = [
[
'id' => 4,
'edited_date' => 946944000, // 2000-01-04T00:00:00Z
'edited' => '2000-01-04 00:00:00',
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
'url_title_hash' => 'f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8',
'url_content_hash' => 'f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3',
@ -20,7 +20,7 @@ trait SeriesFeed {
],
[
'id' => 5,
'edited_date' => 947030400, // 2000-01-05T00:00:00Z
'edited' => '2000-01-05 00:00:00',
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
'url_title_hash' => 'd40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022',
'url_content_hash' => '834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900',

8
tests/lib/Database/SeriesSubscription.php

@ -253,14 +253,6 @@ trait SeriesSubscription {
$this->assertResult($exp, Data::$db->subscriptionList($this->user, 2));
}
function testListSubscriptionsWithDifferentDateFormats() {
Data::$db->dateFormatDefault("iso8601");
$d1 = Data::$db->subscriptionList($this->user, 2)->getRow()['added'];
Data::$db->dateFormatDefault("http");
$d2 = Data::$db->subscriptionList($this->user, 2)->getRow()['added'];
$this->assertNotEquals($d1, $d2);
}
function testListSubscriptionsInAMissingFolder() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Data::$db->subscriptionList($this->user, 4);

54
tests/lib/Db/BindingTests.php

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Test\Db;
use JKingWeb\Arsse\Db\Statement;
trait BindingTests {
trait BindingTests {
function testBindNull() {
$input = null;
$exp = [
@ -24,9 +24,9 @@ trait BindingTests {
"null" => null,
"integer" => 0,
"float" => 0.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 0),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 0),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 0),
"date" => gmdate("Y-m-d", 0),
"time" => gmdate("H:i:s", 0),
"datetime" => gmdate("Y-m-d H:i:s", 0),
"binary" => "",
"string" => "",
"boolean" => 0,
@ -74,9 +74,9 @@ trait BindingTests {
"null" => null,
"integer" => 2112,
"float" => 2112.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 2112),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 2112),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 2112),
"date" => gmdate("Y-m-d", 2112),
"time" => gmdate("H:i:s", 2112),
"datetime" => gmdate("Y-m-d H:i:s", 2112),
"binary" => "2112",
"string" => "2112",
"boolean" => 1,
@ -91,9 +91,9 @@ trait BindingTests {
"null" => null,
"integer" => 0,
"float" => 0.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 0),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 0),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 0),
"date" => gmdate("Y-m-d", 0),
"time" => gmdate("H:i:s", 0),
"datetime" => gmdate("Y-m-d H:i:s", 0),
"binary" => "0",
"string" => "0",
"boolean" => 0,
@ -108,9 +108,9 @@ trait BindingTests {
"null" => null,
"integer" => 2112,
"float" => 2112.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 2112),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 2112),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 2112),
"date" => gmdate("Y-m-d", 2112),
"time" => gmdate("H:i:s", 2112),
"datetime" => gmdate("Y-m-d H:i:s", 2112),
"binary" => "2112",
"string" => "2112",
"boolean" => 1,
@ -125,9 +125,9 @@ trait BindingTests {
"null" => null,
"integer" => 0,
"float" => 0.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 0),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 0),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 0),
"date" => gmdate("Y-m-d", 0),
"time" => gmdate("H:i:s", 0),
"datetime" => gmdate("Y-m-d H:i:s", 0),
"binary" => "0",
"string" => "0",
"boolean" => 0,
@ -195,9 +195,9 @@ trait BindingTests {
"null" => null,
"integer" => 2017,
"float" => 2017.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), $time),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), $time),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
"date" => gmdate("Y-m-d", $time),
"time" => gmdate("H:i:s", $time),
"datetime" => gmdate("Y-m-d H:i:s", $time),
"binary" => $input,
"string" => $input,
"boolean" => 1,
@ -213,9 +213,9 @@ trait BindingTests {
"null" => null,
"integer" => 0,
"float" => 0.0,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), $time),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), $time),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
"date" => gmdate("Y-m-d", $time),
"time" => gmdate("H:i:s", $time),
"datetime" => gmdate("Y-m-d H:i:s", $time),
"binary" => $input,
"string" => $input,
"boolean" => 1,
@ -231,11 +231,11 @@ trait BindingTests {
"null" => null,
"integer" => $time,
"float" => (float) $time,
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), $time),
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), $time),
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
"binary" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
"string" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
"date" => gmdate("Y-m-d", $time),
"time" => gmdate("H:i:s", $time),
"datetime" => gmdate("Y-m-d H:i:s", $time),
"binary" => gmdate("Y-m-d H:i:s", $time),
"string" => gmdate("Y-m-d H:i:s", $time),
"boolean" => 1,
];
$this->checkBinding($input, $exp);

4
tests/lib/Tools.php

@ -20,8 +20,8 @@ trait Tools {
}
function assertTime($exp, $test) {
$exp = $this->dateTransform($exp);
$test = $this->dateTransform($test);
$exp = $this->dateTransform($exp, "unix");
$test = $this->dateTransform($test, "unix");
$this->assertSame($exp, $test);
}

Loading…
Cancel
Save