mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Merge branch 'php7.1'
This commit is contained in:
commit
670fb61299
109 changed files with 2022 additions and 1299 deletions
|
@ -1,3 +1,10 @@
|
|||
Version 0.8.3 (2020-??-??)
|
||||
==========================
|
||||
|
||||
Changes:
|
||||
- Officially require PHP 7.1 (accidentally required since version 0.8.0)
|
||||
- Various internal changes pursuant to use of PHP 7.1
|
||||
|
||||
Version 0.8.2 (2019-12-07)
|
||||
==========================
|
||||
|
||||
|
|
14
UPGRADING
14
UPGRADING
|
@ -11,6 +11,20 @@ usually prudent:
|
|||
`composer install -o --no-dev`
|
||||
|
||||
|
||||
Upgrading from 0.8.2 to 0.8.3
|
||||
=============================
|
||||
|
||||
- PHP 7.1 is now required
|
||||
- The following Composer dependencies have been added:
|
||||
- nicolus/picofeed
|
||||
- laminas/laminas-diactoros
|
||||
- laminas/laminas-httphandlerrunner
|
||||
- The following Composer dependencies have been removed:
|
||||
- p3k/picofeed
|
||||
- zendframework/zend-diactoros
|
||||
- zendframework/zend-httphandlerrunner
|
||||
|
||||
|
||||
Upgrading from 0.8.1 to 0.8.2
|
||||
=============================
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ if (\PHP_SAPI === "cli") {
|
|||
$conf = file_exists(BASE."config.php") ? new Conf(BASE."config.php") : new Conf;
|
||||
Arsse::load($conf);
|
||||
// handle Web requests
|
||||
$emitter = new \Zend\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
$emitter = new \Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
$response = (new REST)->dispatch();
|
||||
$emitter->emit($response);
|
||||
}
|
||||
|
|
|
@ -18,21 +18,26 @@
|
|||
|
||||
],
|
||||
"require": {
|
||||
"php": "7.*",
|
||||
"php": "^7.1",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-dom": "*",
|
||||
"p3k/picofeed": "0.1.*",
|
||||
"nicolus/picofeed": "dev-master#0ebdf92852a4725f4807c200dd49bf9fff3905b7",
|
||||
"hosteurope/password-generator": "1.*",
|
||||
"docopt/docopt": "1.*",
|
||||
"jkingweb/druuid": "3.*",
|
||||
"zendframework/zend-diactoros": "2.*",
|
||||
"zendframework/zend-httphandlerrunner": "1.*"
|
||||
"laminas/laminas-diactoros": "2.*",
|
||||
"laminas/laminas-httphandlerrunner": "1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "*"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.1.33"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": ["@composer bin all install"],
|
||||
"post-update-cmd": ["@composer bin all update"]
|
||||
|
|
778
composer.lock
generated
778
composer.lock
generated
|
@ -4,20 +4,20 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c2b0698669d89268ffb995a5e1d6667a",
|
||||
"content-hash": "1d03b34d159fbf69097aa783994f9cfa",
|
||||
"packages": [
|
||||
{
|
||||
"name": "docopt/docopt",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/docopt/docopt.php.git",
|
||||
"reference": "d2ee65c2fe4be78f945a48edd02be45843b39423"
|
||||
"reference": "bf3683a16e09fa1665e493eb4d5a29469e132a4f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/docopt/docopt.php/zipball/d2ee65c2fe4be78f945a48edd02be45843b39423",
|
||||
"reference": "d2ee65c2fe4be78f945a48edd02be45843b39423",
|
||||
"url": "https://api.github.com/repos/docopt/docopt.php/zipball/bf3683a16e09fa1665e493eb4d5a29469e132a4f",
|
||||
"reference": "bf3683a16e09fa1665e493eb4d5a29469e132a4f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -44,13 +44,202 @@
|
|||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Port of Python's docopt for PHP 5.3",
|
||||
"description": "Port of Python's docopt for PHP >=5.3",
|
||||
"homepage": "http://github.com/docopt/docopt.php",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"docs"
|
||||
],
|
||||
"time": "2015-10-30T03:21:23+00:00"
|
||||
"time": "2019-12-03T02:48:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82",
|
||||
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.0",
|
||||
"guzzlehttp/psr7": "^1.6.1",
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
|
||||
"psr/log": "^1.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
|
||||
"psr/log": "Required for using the Log middleware"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle is a PHP HTTP client library",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"client",
|
||||
"curl",
|
||||
"framework",
|
||||
"http",
|
||||
"http client",
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2019-12-23T11:57:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "v1.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/promises.git",
|
||||
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Promise\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle promises library",
|
||||
"keywords": [
|
||||
"promise"
|
||||
],
|
||||
"time": "2016-12-20T10:07:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "239400de7a173fe9901b9ac7c06497751f00727a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
|
||||
"reference": "239400de7a173fe9901b9ac7c06497751f00727a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"psr/http-message": "~1.0",
|
||||
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-zlib": "*",
|
||||
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Psr7\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"description": "PSR-7 message implementation that also provides common utility methods",
|
||||
"keywords": [
|
||||
"http",
|
||||
"message",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"stream",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2019-07-01T23:21:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hosteurope/password-generator",
|
||||
|
@ -138,17 +327,337 @@
|
|||
"time": "2017-02-09T14:17:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "p3k/picofeed",
|
||||
"version": "v0.1.38",
|
||||
"name": "kevinrob/guzzle-cache-middleware",
|
||||
"version": "v2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aaronpk/picoFeed.git",
|
||||
"reference": "989c0bcf2eac016a4104abce1aadff791fc287ab"
|
||||
"url": "https://github.com/Kevinrob/guzzle-cache-middleware.git",
|
||||
"reference": "6952064f7747756b0be7b4c234c0fd7535ea4c8c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aaronpk/picoFeed/zipball/989c0bcf2eac016a4104abce1aadff791fc287ab",
|
||||
"reference": "989c0bcf2eac016a4104abce1aadff791fc287ab",
|
||||
"url": "https://api.github.com/repos/Kevinrob/guzzle-cache-middleware/zipball/6952064f7747756b0be7b4c234c0fd7535ea4c8c",
|
||||
"reference": "6952064f7747756b0be7b4c234c0fd7535ea4c8c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/array-adapter": "^0.4",
|
||||
"doctrine/cache": "^1.0",
|
||||
"guzzlehttp/guzzle": "^6.0",
|
||||
"illuminate/cache": "^5.0",
|
||||
"league/flysystem": "^1.0",
|
||||
"phpunit/phpunit": "^4.0 || ^5.0",
|
||||
"psr/cache": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/cache": "This library have a lot of ready-to-use cache storage (to be use with Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage)",
|
||||
"guzzlehttp/guzzle": "For using this library. It was created for Guzzle6. (but you can use it with any PSR-7 HTTP Client)",
|
||||
"laravel/framework": "To be use with Kevinrob\\GuzzleCache\\Storage\\LaravelCacheStorage",
|
||||
"league/flysystem": "To be use with Kevinrob\\GuzzleCache\\Storage\\FlysystemStorage",
|
||||
"psr/cache": "To be use with Kevinrob\\GuzzleCache\\Storage\\Psr6CacheStorage"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kevinrob\\GuzzleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kevin Robatel",
|
||||
"email": "kevinrob2@gmail.com",
|
||||
"homepage": "https://github.com/Kevinrob"
|
||||
}
|
||||
],
|
||||
"description": "A HTTP/1.1 Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack. (RFC 7234)",
|
||||
"homepage": "https://github.com/Kevinrob/guzzle-cache-middleware",
|
||||
"keywords": [
|
||||
"Etag",
|
||||
"Flysystem",
|
||||
"Guzzle",
|
||||
"cache",
|
||||
"cache-control",
|
||||
"doctrine",
|
||||
"expiration",
|
||||
"guzzle6",
|
||||
"handler",
|
||||
"http",
|
||||
"http 1.1",
|
||||
"middleware",
|
||||
"performance",
|
||||
"php",
|
||||
"promise",
|
||||
"psr6",
|
||||
"psr7",
|
||||
"rfc7234",
|
||||
"validation"
|
||||
],
|
||||
"time": "2017-08-17T12:23:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-diactoros",
|
||||
"version": "2.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-diactoros.git",
|
||||
"reference": "95178c4751d737cdf9ab0a9f70a42754ac860e7b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/95178c4751d737cdf9ab0a9f70a42754ac860e7b",
|
||||
"reference": "95178c4751d737cdf9ab0a9f70a42754ac860e7b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laminas/laminas-zendframework-bridge": "^1.0",
|
||||
"php": "^7.1",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpspec/prophecy": "<1.9.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-factory-implementation": "1.0",
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"replace": {
|
||||
"zendframework/zend-diactoros": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"http-interop/http-factory-tests": "^0.5.0",
|
||||
"laminas/laminas-coding-standard": "~1.0.0",
|
||||
"php-http/psr7-integration-tests": "dev-master",
|
||||
"phpunit/phpunit": "^7.5.18"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1.x-dev",
|
||||
"dev-develop": "2.2.x-dev",
|
||||
"dev-release-1.8": "1.8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions/create_uploaded_file.php",
|
||||
"src/functions/marshal_headers_from_sapi.php",
|
||||
"src/functions/marshal_method_from_sapi.php",
|
||||
"src/functions/marshal_protocol_version_from_sapi.php",
|
||||
"src/functions/marshal_uri_from_sapi.php",
|
||||
"src/functions/normalize_server.php",
|
||||
"src/functions/normalize_uploaded_files.php",
|
||||
"src/functions/parse_cookie_header.php",
|
||||
"src/functions/create_uploaded_file.legacy.php",
|
||||
"src/functions/marshal_headers_from_sapi.legacy.php",
|
||||
"src/functions/marshal_method_from_sapi.legacy.php",
|
||||
"src/functions/marshal_protocol_version_from_sapi.legacy.php",
|
||||
"src/functions/marshal_uri_from_sapi.legacy.php",
|
||||
"src/functions/normalize_server.legacy.php",
|
||||
"src/functions/normalize_uploaded_files.legacy.php",
|
||||
"src/functions/parse_cookie_header.legacy.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Laminas\\Diactoros\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "PSR HTTP Message implementations",
|
||||
"homepage": "https://laminas.dev",
|
||||
"keywords": [
|
||||
"http",
|
||||
"laminas",
|
||||
"psr",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2020-01-07T19:39:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-httphandlerrunner",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-httphandlerrunner.git",
|
||||
"reference": "296f5ff35074dd981d1570a66b95596c81808087"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/296f5ff35074dd981d1570a66b95596c81808087",
|
||||
"reference": "296f5ff35074dd981d1570a66b95596c81808087",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laminas/laminas-zendframework-bridge": "^1.0",
|
||||
"php": "^7.1",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-message-implementation": "^1.0",
|
||||
"psr/http-server-handler": "^1.0"
|
||||
},
|
||||
"replace": {
|
||||
"zendframework/zend-httphandlerrunner": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"laminas/laminas-coding-standard": "~1.0.0",
|
||||
"laminas/laminas-diactoros": "^1.7 || ^2.1.1",
|
||||
"phpunit/phpunit": "^7.0.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev",
|
||||
"dev-develop": "1.2.x-dev"
|
||||
},
|
||||
"laminas": {
|
||||
"config-provider": "Laminas\\HttpHandlerRunner\\ConfigProvider"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laminas\\HttpHandlerRunner\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Execute PSR-15 RequestHandlerInterface instances and emit responses they generate.",
|
||||
"homepage": "https://laminas.dev",
|
||||
"keywords": [
|
||||
"components",
|
||||
"laminas",
|
||||
"mezzio",
|
||||
"psr-15",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2019-12-31T17:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-xml",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-xml.git",
|
||||
"reference": "879cc66d1bba6a37705e98074f52a6960c220020"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-xml/zipball/879cc66d1bba6a37705e98074f52a6960c220020",
|
||||
"reference": "879cc66d1bba6a37705e98074f52a6960c220020",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laminas/laminas-zendframework-bridge": "^1.0",
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"replace": {
|
||||
"zendframework/zendxml": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"laminas/laminas-coding-standard": "~1.0.0",
|
||||
"phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev",
|
||||
"dev-develop": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laminas\\Xml\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Utility library for XML usage, best practices, and security in PHP",
|
||||
"homepage": "https://laminas.dev",
|
||||
"keywords": [
|
||||
"laminas",
|
||||
"security",
|
||||
"xml"
|
||||
],
|
||||
"time": "2019-12-31T18:05:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-zendframework-bridge",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-zendframework-bridge.git",
|
||||
"reference": "0fb9675b84a1666ab45182b6c5b29956921e818d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/0fb9675b84a1666ab45182b6c5b29956921e818d",
|
||||
"reference": "0fb9675b84a1666ab45182b6c5b29956921e818d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev",
|
||||
"dev-develop": "1.1.x-dev"
|
||||
},
|
||||
"laminas": {
|
||||
"module": "Laminas\\ZendFrameworkBridge"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/autoload.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Laminas\\ZendFrameworkBridge\\": "src//"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Alias legacy ZF class names to Laminas Project equivalents.",
|
||||
"keywords": [
|
||||
"ZendFramework",
|
||||
"autoloading",
|
||||
"laminas",
|
||||
"zf"
|
||||
],
|
||||
"time": "2020-01-07T22:58:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nicolus/picofeed",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nicolus/picoFeed.git",
|
||||
"reference": "0ebdf92852a4725f4807c200dd49bf9fff3905b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nicolus/picoFeed/zipball/0ebdf92852a4725f4807c200dd49bf9fff3905b7",
|
||||
"reference": "0ebdf92852a4725f4807c200dd49bf9fff3905b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -157,16 +666,22 @@
|
|||
"ext-libxml": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"php": ">=5.3.0",
|
||||
"zendframework/zendxml": "^1.0"
|
||||
"guzzlehttp/guzzle": "~6.0",
|
||||
"kevinrob/guzzle-cache-middleware": "^2.1",
|
||||
"laminas/laminas-xml": "^1.0",
|
||||
"php": ">=7.1",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"blastcloud/guzzler": "^1.5",
|
||||
"monolog/monolog": "^1.23",
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"phpdocumentor/reflection-docblock": "2.0.4",
|
||||
"phpunit/phpunit": "4.8.26",
|
||||
"symfony/yaml": "2.8.7"
|
||||
"phpunit/phpunit": "^7.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "PicoFeed will use cURL if present"
|
||||
"ext-curl": "PicoFeed will use cURL if present",
|
||||
"monolog/monolog": "You can set a monolog Logger to get debug information from PicoFeed"
|
||||
},
|
||||
"bin": [
|
||||
"picofeed"
|
||||
|
@ -184,11 +699,14 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Frédéric Guillot"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Bailly"
|
||||
}
|
||||
],
|
||||
"description": "Modern library to handle RSS/Atom feeds",
|
||||
"homepage": "https://github.com/miniflux/picoFeed",
|
||||
"time": "2017-11-30T00:16:58+00:00"
|
||||
"description": "RSS/Atom parsing library",
|
||||
"homepage": "https://github.com/nicolus/picoFeed",
|
||||
"time": "2020-02-13T06:43:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
|
@ -346,172 +864,91 @@
|
|||
"time": "2018-10-30T16:46:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-diactoros",
|
||||
"version": "2.1.5",
|
||||
"name": "psr/log",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/zend-diactoros.git",
|
||||
"reference": "6dcf9e760a6b476f3e9d80abbc9ce9c4aa921f9c"
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/6dcf9e760a6b476f3e9d80abbc9ce9c4aa921f9c",
|
||||
"reference": "6dcf9e760a6b476f3e9d80abbc9ce9c4aa921f9c",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
|
||||
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-factory-implementation": "1.0",
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"http-interop/http-factory-tests": "^0.5.0",
|
||||
"php-http/psr7-integration-tests": "dev-master",
|
||||
"phpunit/phpunit": "^7.0.2",
|
||||
"zendframework/zend-coding-standard": "~1.0.0"
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1.x-dev",
|
||||
"dev-develop": "2.2.x-dev",
|
||||
"dev-release-1.8": "1.8.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "Psr/Log/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2019-11-01T11:05:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"phpunit/phpunit": "^5 || ^6.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions/create_uploaded_file.php",
|
||||
"src/functions/marshal_headers_from_sapi.php",
|
||||
"src/functions/marshal_method_from_sapi.php",
|
||||
"src/functions/marshal_protocol_version_from_sapi.php",
|
||||
"src/functions/marshal_uri_from_sapi.php",
|
||||
"src/functions/normalize_server.php",
|
||||
"src/functions/normalize_uploaded_files.php",
|
||||
"src/functions/parse_cookie_header.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Zend\\Diactoros\\": "src/"
|
||||
}
|
||||
"src/getallheaders.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
"MIT"
|
||||
],
|
||||
"description": "PSR HTTP Message implementations",
|
||||
"keywords": [
|
||||
"http",
|
||||
"psr",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2019-10-10T17:38:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-httphandlerrunner",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/zend-httphandlerrunner.git",
|
||||
"reference": "75fb12751fe9d6e392cce1ee0d687dacae2db787"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-httphandlerrunner/zipball/75fb12751fe9d6e392cce1ee0d687dacae2db787",
|
||||
"reference": "75fb12751fe9d6e392cce1ee0d687dacae2db787",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-message-implementation": "^1.0",
|
||||
"psr/http-server-handler": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0.2",
|
||||
"zendframework/zend-coding-standard": "~1.0.0",
|
||||
"zendframework/zend-diactoros": "^1.7 || ^2.1.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev",
|
||||
"dev-develop": "1.2.x-dev"
|
||||
},
|
||||
"zf": {
|
||||
"config-provider": "Zend\\HttpHandlerRunner\\ConfigProvider"
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ralph Khattar",
|
||||
"email": "ralph.khattar@gmail.com"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Zend\\HttpHandlerRunner\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Execute PSR-15 RequestHandlerInterface instances and emit responses they generate.",
|
||||
"keywords": [
|
||||
"ZendFramework",
|
||||
"components",
|
||||
"expressive",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"zf"
|
||||
],
|
||||
"time": "2019-02-19T18:20:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zendxml",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/ZendXml.git",
|
||||
"reference": "eceab37a591c9e140772a1470338258857339e00"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/ZendXml/zipball/eceab37a591c9e140772a1470338258857339e00",
|
||||
"reference": "eceab37a591c9e140772a1470338258857339e00",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4",
|
||||
"zendframework/zend-coding-standard": "~1.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev",
|
||||
"dev-develop": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ZendXml\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Utility library for XML usage, best practices, and security in PHP",
|
||||
"keywords": [
|
||||
"ZendFramework",
|
||||
"security",
|
||||
"xml",
|
||||
"zf"
|
||||
],
|
||||
"time": "2019-01-22T19:42:14+00:00"
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"time": "2019-03-08T08:55:37+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -557,15 +994,20 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"nicolus/picofeed": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "7.*",
|
||||
"php": "^7.1",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-dom": "*"
|
||||
},
|
||||
"platform-dev": []
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "7.1.33"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
The Arsse has the following requirements:
|
||||
|
||||
- A Linux server running Nginx or Apache 2.4 (tested on Ubuntu 16.04 and 18.04)
|
||||
- PHP 7.0.7 or later with the following extensions:
|
||||
- A Linux server running Nginx or Apache 2.4
|
||||
- PHP 7.1.0 or later with the following extensions:
|
||||
- [intl](http://php.net/manual/en/book.intl.php), [json](http://php.net/manual/en/book.json.php), [hash](http://php.net/manual/en/book.hash.php), and [dom](http://php.net/manual/en/book.dom.php)
|
||||
- [simplexml](http://php.net/manual/en/book.simplexml.php), and [iconv](http://php.net/manual/en/book.iconv.php)
|
||||
- One of:
|
||||
- [sqlite3](http://php.net/manual/en/book.sqlite3.php) or [pdo_sqlite](http://php.net/manual/en/ref.pdo-sqlite.php) for SQLite databases
|
||||
- [pgsql](http://php.net/manual/en/book.pgsql.php) or [pdo_pgsql](http://php.net/manual/en/ref.pdo-pgsql.php) for PostgreSQL 10 or later databases
|
||||
- [mysqli](http://php.net/manual/en/book.mysqli.php) or [pdo_mysql](http://php.net/manual/en/ref.pdo-mysql.php) for MySQL/Percona 8.0.11 or later databases
|
||||
- [curl](http://php.net/manual/en/book.curl.php) (optional)
|
||||
- Privileges either to create and run systemd services, or to run cron jobs
|
||||
|
||||
Instructions for how to satisfy the PHP extension requirements for Debian systems are included in the next section.
|
||||
|
|
|
@ -75,6 +75,7 @@ abstract class AbstractException extends \Exception {
|
|||
"User/Exception.authFailed" => 10412,
|
||||
"User/ExceptionAuthz.notAuthorized" => 10421,
|
||||
"User/ExceptionSession.invalid" => 10431,
|
||||
"Feed/Exception.internalError" => 10500,
|
||||
"Feed/Exception.invalidCertificate" => 10501,
|
||||
"Feed/Exception.invalidUrl" => 10502,
|
||||
"Feed/Exception.maxRedirect" => 10503,
|
||||
|
@ -82,6 +83,8 @@ abstract class AbstractException extends \Exception {
|
|||
"Feed/Exception.timeout" => 10505,
|
||||
"Feed/Exception.forbidden" => 10506,
|
||||
"Feed/Exception.unauthorized" => 10507,
|
||||
"Feed/Exception.transmissionError" => 10508,
|
||||
"Feed/Exception.connectionFailed" => 10509,
|
||||
"Feed/Exception.malformedXml" => 10511,
|
||||
"Feed/Exception.xmlEntity" => 10512,
|
||||
"Feed/Exception.subscriptionNotFound" => 10521,
|
||||
|
|
|
@ -18,7 +18,7 @@ class Arsse {
|
|||
/** @var User */
|
||||
public static $user;
|
||||
|
||||
public static function load(Conf $conf) {
|
||||
public static function load(Conf $conf): void {
|
||||
static::$lang = static::$lang ?? new Lang;
|
||||
static::$conf = $conf;
|
||||
static::$lang->set($conf->lang);
|
||||
|
|
|
@ -160,7 +160,7 @@ USAGE_TEXT;
|
|||
return ($file === "-" ? null : $file) ?? $stdinOrStdout;
|
||||
}
|
||||
|
||||
public function dispatch(array $argv = null) {
|
||||
public function dispatch(array $argv = null): int {
|
||||
$argv = $argv ?? $_SERVER['argv'];
|
||||
$argv0 = array_shift($argv);
|
||||
$args = \Docopt::handle($this->usage($argv0), [
|
||||
|
@ -210,7 +210,7 @@ USAGE_TEXT;
|
|||
} // @codeCoverageIgnore
|
||||
|
||||
/** @codeCoverageIgnore */
|
||||
protected function logError(string $msg) {
|
||||
protected function logError(string $msg): void {
|
||||
fwrite(STDERR, $msg.\PHP_EOL);
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ class Database {
|
|||
}
|
||||
|
||||
/** Retrieve a value from the metadata table. If the key is not set null is returned */
|
||||
public function metaGet(string $key) {
|
||||
public function metaGet(string $key): ?string {
|
||||
return $this->db->prepare("SELECT value from arsse_meta where \"key\" = ?", "str")->run($key)->getValue();
|
||||
}
|
||||
|
||||
|
@ -284,7 +284,7 @@ class Database {
|
|||
}
|
||||
|
||||
/** Retrieves the hashed password of a user */
|
||||
public function userPasswordGet(string $user) {
|
||||
public function userPasswordGet(string $user): ?string {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
} elseif (!$this->userExists($user)) {
|
||||
|
@ -617,7 +617,7 @@ class Database {
|
|||
}
|
||||
|
||||
/** Ensures an operation to rename and/or move a folder does not result in a conflict or circular dependence, and raises an exception otherwise */
|
||||
protected function folderValidateMove(string $user, $id = null, $parent = null, string $name = null) {
|
||||
protected function folderValidateMove(string $user, $id = null, $parent = null, string $name = null): ?int {
|
||||
$errData = ["action" => $this->caller(), "field" => "parent", 'id' => $parent];
|
||||
if (!$id) {
|
||||
// the root cannot be moved
|
||||
|
@ -932,7 +932,7 @@ class Database {
|
|||
}
|
||||
|
||||
/** Returns the time at which any of a user's subscriptions (or a specific subscription) was last refreshed, as a DateTimeImmutable object */
|
||||
public function subscriptionRefreshed(string $user, int $id = null) {
|
||||
public function subscriptionRefreshed(string $user, int $id = null): ?\DateTimeImmutable {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ abstract class AbstractResult implements Result {
|
|||
}
|
||||
}
|
||||
|
||||
public function getRow() {
|
||||
public function getRow(): ?array {
|
||||
if ($this->valid()) {
|
||||
$out = $this->cur;
|
||||
$this->next();
|
||||
|
|
|
@ -158,7 +158,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
return class_exists("mysqli");
|
||||
}
|
||||
|
||||
protected function makeConnection(string $db, string $user, string $password, string $host, int $port, string $socket) {
|
||||
protected function makeConnection(string $db, string $user, string $password, string $host, int $port, string $socket): void {
|
||||
$this->db = mysqli_init();
|
||||
$this->db->options(\MYSQLI_OPT_CONNECT_TIMEOUT, ceil(Arsse::$conf->dbTimeoutConnect));
|
||||
@$this->db->real_connect($host, $user, $password, $db, $port, $socket);
|
||||
|
|
|
@ -18,7 +18,7 @@ class PDODriver extends Driver {
|
|||
return class_exists("PDO") && in_array("mysql", \PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
protected function makeConnection(string $db, string $user, string $password, string $host, int $port, string $socket) {
|
||||
protected function makeConnection(string $db, string $user, string $password, string $host, int $port, string $socket): void {
|
||||
$dsn = "mysql:".implode(";", [
|
||||
"charset=utf8mb4",
|
||||
"dbname=$db",
|
||||
|
|
|
@ -181,7 +181,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
return \extension_loaded("pgsql");
|
||||
}
|
||||
|
||||
protected function makeConnection(string $user, string $pass, string $db, string $host, int $port, string $service) {
|
||||
protected function makeConnection(string $user, string $pass, string $db, string $host, int $port, string $service): void {
|
||||
$dsn = $this->makeconnectionString(false, $user, $pass, $db, $host, $port, $service);
|
||||
set_error_handler(function(int $code, string $msg) {
|
||||
$msg = substr($msg, 62);
|
||||
|
|
|
@ -18,7 +18,7 @@ class PDODriver extends Driver {
|
|||
return class_exists("PDO") && in_array("pgsql", \PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
protected function makeConnection(string $user, string $pass, string $db, string $host, int $port, string $service) {
|
||||
protected function makeConnection(string $user, string $pass, string $db, string $host, int $port, string $service): void {
|
||||
$dsn = $this->makeconnectionString(true, $user, $pass, $db, $host, $port, $service);
|
||||
try {
|
||||
$this->db = new \PDO("pgsql:$dsn", $user, $pass, [
|
||||
|
|
|
@ -69,13 +69,13 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
return class_exists("SQLite3");
|
||||
}
|
||||
|
||||
protected function makeConnection(string $file, string $key) {
|
||||
protected function makeConnection(string $file, string $key): void {
|
||||
$this->db = new \SQLite3($file, \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE, $key);
|
||||
// enable exceptions
|
||||
$this->db->enableExceptions(true);
|
||||
}
|
||||
|
||||
protected function setTimeout(int $msec) {
|
||||
protected function setTimeout(int $msec): void {
|
||||
$this->exec("PRAGMA busy_timeout = $msec");
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class PDODriver extends AbstractPDODriver {
|
|||
return class_exists("PDO") && in_array("sqlite", \PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
protected function makeConnection(string $file, string $key) {
|
||||
protected function makeConnection(string $file, string $key): void {
|
||||
$this->db = new \PDO("sqlite:".$file, "", "", [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
]);
|
||||
|
|
12
lib/Feed.php
12
lib/Feed.php
|
@ -50,7 +50,7 @@ class Feed {
|
|||
$this->resource = self::download($url, $lastModified, $etag, $username, $password);
|
||||
// format the HTTP Last-Modified date returned
|
||||
$lastMod = $this->resource->getLastModified();
|
||||
if (strlen($lastMod)) {
|
||||
if (strlen($lastMod ?? "")) {
|
||||
$this->lastModified = Date::normalize($lastMod, "http");
|
||||
}
|
||||
$this->modified = $this->resource->isModified();
|
||||
|
@ -100,6 +100,8 @@ class Feed {
|
|||
$client->reader = $reader;
|
||||
return $client;
|
||||
} catch (PicoFeedException $e) {
|
||||
throw new Feed\Exception($url, $e); // @codeCoverageIgnore
|
||||
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
|
||||
throw new Feed\Exception($url, $e);
|
||||
}
|
||||
}
|
||||
|
@ -115,12 +117,10 @@ class Feed {
|
|||
// Some feeds might use a different domain (eg: feedburner), so the site url is
|
||||
// used instead of the feed's url.
|
||||
$this->favicon = (new Favicon)->find($feed->siteUrl);
|
||||
// work around a PicoFeed memory leak
|
||||
libxml_use_internal_errors(false);
|
||||
} catch (PicoFeedException $e) {
|
||||
// work around a PicoFeed memory leak
|
||||
libxml_use_internal_errors(false);
|
||||
throw new Feed\Exception($this->resource->getUrl(), $e);
|
||||
} catch (\GuzzleHttp\Exception\GuzzleException $e) { // @codeCoverageIgnore
|
||||
throw new Feed\Exception($this->resource->getUrl(), $e); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// PicoFeed does not provide valid ids when there is no id element. Its solution
|
||||
|
@ -390,7 +390,7 @@ class Feed {
|
|||
return $offset;
|
||||
}
|
||||
|
||||
protected function computeLastModified() {
|
||||
protected function computeLastModified(): ?\DateTimeImmutable {
|
||||
if (!$this->modified) {
|
||||
return $this->lastModified; // @codeCoverageIgnore
|
||||
}
|
||||
|
|
|
@ -6,13 +6,39 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\Feed;
|
||||
|
||||
use GuzzleHttp\Exception\BadResponseException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\TooManyRedirectsException;
|
||||
use PicoFeed\PicoFeedException;
|
||||
|
||||
class Exception extends \JKingWeb\Arsse\AbstractException {
|
||||
const CURL_ERROR_MAP = [1=>"invalidUrl",3=>"invalidUrl",5=>"transmissionError","connectionFailed","connectionFailed","transmissionError","forbidden","unauthorized","transmissionError","transmissionError","transmissionError","transmissionError","connectionFailed","connectionFailed","transmissionError","transmissionError","transmissionError","transmissionError","transmissionError","invalidUrl","transmissionError","transmissionError","transmissionError","transmissionError",28=>"timeout","transmissionError","transmissionError","transmissionError","transmissionError","transmissionError",35=>"invalidCertificate","transmissionError","transmissionError","transmissionError","transmissionError",45=>"transmissionError","unauthorized","maxRedirect",52=>"transmissionError","invalidCertificate","invalidCertificate","transmissionError","transmissionError",58=>"invalidCertificate","invalidCertificate","invalidCertificate","transmissionError","invalidUrl","transmissionError","invalidCertificate","transmissionError","invalidCertificate","forbidden","invalidUrl","forbidden","transmissionError",73=>"transmissionError","transmissionError",77=>"invalidCertificate","invalidUrl",90=>"invalidCertificate","invalidCertificate","transmissionError",94=>"unauthorized","transmissionError","connectionFailed"];
|
||||
const HTTP_ERROR_MAP = [401=>"unauthorized",403=>"forbidden",404=>"invalidUrl",408=>"timeout",410=>"invalidUrl",414=>"invalidUrl",451=>"invalidUrl"];
|
||||
|
||||
public function __construct($url, \Throwable $e) {
|
||||
$className = get_class($e);
|
||||
// Convert the exception thrown by PicoFeed to the one to be thrown here.
|
||||
$msgID = preg_replace('/^PicoFeed\\\(?:Client|Parser|Reader)\\\([A-Za-z]+)Exception$/', '$1', $className);
|
||||
// If the message ID doesn't change then it's unknown.
|
||||
$msgID = ($msgID !== $className) ? lcfirst($msgID) : '';
|
||||
if ($e instanceof BadResponseException) {
|
||||
$msgID = self::HTTP_ERROR_MAP[$e->getCode()] ?? "transmissionError";
|
||||
} elseif ($e instanceof TooManyRedirectsException) {
|
||||
$msgID = "maxRedirect";
|
||||
} elseif ($e instanceof GuzzleException) {
|
||||
$msg = $e->getMessage();
|
||||
if (preg_match("/^Error creating resource:/", $msg)) {
|
||||
// PHP stream error; the class of error is ambiguous
|
||||
$msgID = "transmissionError";
|
||||
} elseif (preg_match("/^cURL error (\d+):/", $msg, $match)) {
|
||||
$msgID = self::CURL_ERROR_MAP[(int) $match[1]] ?? "internalError";
|
||||
} else {
|
||||
$msgID = "internalError";
|
||||
}
|
||||
} elseif ($e instanceof PicoFeedException) {
|
||||
$className = get_class($e);
|
||||
// Convert the exception thrown by PicoFeed to the one to be thrown here.
|
||||
$msgID = preg_replace('/^PicoFeed\\\(?:Client|Parser|Reader)\\\([A-Za-z]+)Exception$/', '$1', $className);
|
||||
// If the message ID doesn't change then it's unknown.
|
||||
$msgID = ($msgID !== $className) ? lcfirst($msgID) : "internalError";
|
||||
} else {
|
||||
$msgID = "internalError";
|
||||
}
|
||||
parent::__construct($msgID, ['url' => $url], $e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,19 +21,19 @@ class Date {
|
|||
return $out;
|
||||
}
|
||||
|
||||
public static function normalize($date, string $inFormat = null) {
|
||||
public static function normalize($date, string $inFormat = null): ?\DateTimeImmutable {
|
||||
return ValueInfo::normalize($date, ValueInfo::T_DATE, $inFormat);
|
||||
}
|
||||
|
||||
public static function add($interval, $date = "now") {
|
||||
public static function add($interval, $date = "now"): ?\DateTimeImmutable {
|
||||
return self::modify("add", $interval, $date);
|
||||
}
|
||||
|
||||
public static function sub($interval, $date = "now") {
|
||||
public static function sub($interval, $date = "now"): ?\DateTimeImmutable {
|
||||
return self::modify("sub", $interval, $date);
|
||||
}
|
||||
|
||||
protected static function modify(string $func, $interval, $date) {
|
||||
protected static function modify(string $func, $interval, $date): ?\DateTimeImmutable {
|
||||
$date = self::normalize($date);
|
||||
$interval = (!$interval instanceof \DateInterval) ? ValueInfo::normalize($interval, ValueInfo::T_INTERVAL) : $interval;
|
||||
return $date ? $date->$func($interval) : null;
|
||||
|
|
|
@ -499,7 +499,7 @@ class ValueInfo {
|
|||
}
|
||||
}
|
||||
|
||||
public static function bool($value, bool $default = null) {
|
||||
public static function bool($value, bool $default = null): ?bool {
|
||||
if (is_null($value) || ValueInfo::str($value) & ValueInfo::WHITE) {
|
||||
return $default;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ use JKingWeb\Arsse\Misc\URL;
|
|||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\ServerRequestFactory;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\ServerRequestFactory;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class REST {
|
||||
const API_LIST = [
|
||||
|
|
|
@ -14,9 +14,9 @@ use JKingWeb\Arsse\Db\ExceptionInput;
|
|||
use JKingWeb\Arsse\Misc\HTTP;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
use Zend\Diactoros\Response\XmlResponse;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\Response\XmlResponse;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const LEVEL = 3;
|
||||
|
@ -306,7 +306,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
return $listSaved;
|
||||
}
|
||||
|
||||
protected function setUnread() {
|
||||
protected function setUnread(): void {
|
||||
$lastUnread = Arsse::$db->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->getValue();
|
||||
if (!$lastUnread) {
|
||||
// there are no articles
|
||||
|
@ -322,7 +322,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
Arsse::$db->articleMark(Arsse::$user->id, ['read' => false], $c);
|
||||
}
|
||||
|
||||
protected function getRefreshTime() {
|
||||
protected function getRefreshTime(): ?int {
|
||||
return Date::transform(Arsse::$db->subscriptionRefreshed(Arsse::$user->id), "unix");
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ use JKingWeb\Arsse\REST\Exception404;
|
|||
use JKingWeb\Arsse\REST\Exception405;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse as Response;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const REALM = "Nextcloud News API v1-2";
|
||||
|
|
|
@ -8,8 +8,8 @@ namespace JKingWeb\Arsse\REST\NextcloudNews;
|
|||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse as Response;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class Versions implements \JKingWeb\Arsse\REST\Handler {
|
||||
public function __construct() {
|
||||
|
|
|
@ -20,8 +20,8 @@ use JKingWeb\Arsse\Db\ResultEmpty;
|
|||
use JKingWeb\Arsse\Feed\Exception as FeedException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse as Response;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const LEVEL = 14; // emulated API level
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\REST\TinyTinyRSS;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\EmptyResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse as Response;
|
||||
|
||||
class Icon extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
public function __construct() {
|
||||
|
|
|
@ -32,7 +32,7 @@ class Search {
|
|||
"" => "searchTerms",
|
||||
];
|
||||
|
||||
public static function parse(string $search, Context $context = null) {
|
||||
public static function parse(string $search, Context $context = null): ?Context {
|
||||
// normalize the input
|
||||
$search = strtolower(trim(preg_replace("<\s+>", " ", $search)));
|
||||
// set initial state
|
||||
|
|
|
@ -40,7 +40,7 @@ class Driver implements \JKingWeb\Arsse\User\Driver {
|
|||
return Arsse::$db->userExists($user);
|
||||
}
|
||||
|
||||
public function userAdd(string $user, string $password = null) {
|
||||
public function userAdd(string $user, string $password = null): ?string {
|
||||
if (isset($password)) {
|
||||
// only add the user if the password is not null; the user manager will retry with a generated password if null is returned
|
||||
Arsse::$db->userAdd($user, $password);
|
||||
|
@ -56,7 +56,7 @@ class Driver implements \JKingWeb\Arsse\User\Driver {
|
|||
return Arsse::$db->userList();
|
||||
}
|
||||
|
||||
public function userPasswordSet(string $user, string $newPassword = null, string $oldPassword = null) {
|
||||
public function userPasswordSet(string $user, string $newPassword = null, string $oldPassword = null): ?string {
|
||||
// do nothing: the internal database is updated regardless of what the driver does (assuming it does not throw an exception)
|
||||
return $newPassword;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ class Driver implements \JKingWeb\Arsse\User\Driver {
|
|||
}
|
||||
}
|
||||
|
||||
protected function userPasswordGet(string $user) {
|
||||
protected function userPasswordGet(string $user): ?string {
|
||||
return Arsse::$db->userPasswordGet($user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ return [
|
|||
other {Authenticated user is not authorized to perform the action "{action}" on behalf of {user}}
|
||||
}',
|
||||
'Exception.JKingWeb/Arsse/User/ExceptionSession.invalid' => 'Session with ID {0} does not exist',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.internalError' => 'Could not download feed "{url}" because of an internal error which is probably a bug',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.invalidCertificate' => 'Could not download feed "{url}" because its server is serving an invalid SSL certificate',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.invalidUrl' => 'Feed URL "{url}" is invalid',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.maxRedirect' => 'Could not download feed "{url}" because its server reached its maximum number of HTTP redirections',
|
||||
|
@ -151,6 +152,8 @@ return [
|
|||
'Exception.JKingWeb/Arsse/Feed/Exception.timeout' => 'Could not download feed "{url}" because its server timed out',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.forbidden' => 'Could not download feed "{url}" because you do not have permission to access it',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.unauthorized' => 'Could not download feed "{url}" because you provided insufficient or invalid credentials',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.transmissionError' => 'Could not download feed "{url}" because of a network error',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.connectionFailed' => 'Could not download feed "{url}" because its server could not be reached',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.malformedXml' => 'Could not parse feed "{url}" because it is malformed',
|
||||
'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}"',
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\TestCase\CLI;
|
||||
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Conf;
|
||||
use JKingWeb\Arsse\User;
|
||||
|
@ -24,7 +25,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::when($this->cli)->loadConf->thenReturn(true);
|
||||
}
|
||||
|
||||
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): void {
|
||||
$argv = \Clue\Arguments\split($command);
|
||||
$output = strlen($output) ? $output.\PHP_EOL : "";
|
||||
if ($pattern) {
|
||||
|
@ -35,13 +36,13 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($exitStatus, $cli->dispatch($argv));
|
||||
}
|
||||
|
||||
public function testPrintVersion() {
|
||||
public function testPrintVersion(): void {
|
||||
$this->assertConsole($this->cli, "arsse.php --version", 0, Arsse::VERSION);
|
||||
\Phake::verify($this->cli, \Phake::times(0))->loadConf;
|
||||
}
|
||||
|
||||
/** @dataProvider provideHelpText */
|
||||
public function testPrintHelp(string $cmd, string $name) {
|
||||
public function testPrintHelp(string $cmd, string $name): void {
|
||||
$this->assertConsole($this->cli, $cmd, 0, str_replace("arsse.php", $name, CLI::USAGE));
|
||||
\Phake::verify($this->cli, \Phake::times(0))->loadConf;
|
||||
}
|
||||
|
@ -57,7 +58,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testStartTheDaemon() {
|
||||
public function testStartTheDaemon(): void {
|
||||
$srv = \Phake::mock(Service::class);
|
||||
\Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
|
||||
\Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv);
|
||||
|
@ -67,7 +68,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify($this->cli)->getInstance(Service::class);
|
||||
}
|
||||
|
||||
public function testRefreshAllFeeds() {
|
||||
public function testRefreshAllFeeds(): void {
|
||||
$srv = \Phake::mock(Service::class);
|
||||
\Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
|
||||
\Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv);
|
||||
|
@ -78,10 +79,10 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideFeedUpdates */
|
||||
public function testRefreshAFeed(string $cmd, int $exitStatus, string $output) {
|
||||
public function testRefreshAFeed(string $cmd, int $exitStatus, string $output): void {
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\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/", $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
\Phake::verify($this->cli)->loadConf;
|
||||
\Phake::verify(Arsse::$db)->feedUpdate;
|
||||
|
@ -95,7 +96,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideDefaultConfigurationSaves */
|
||||
public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file) {
|
||||
public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file): void {
|
||||
$conf = \Phake::mock(Conf::class);
|
||||
\Phake::when($conf)->exportFile("php://output", true)->thenReturn(true);
|
||||
\Phake::when($conf)->exportFile("good.conf", true)->thenReturn(true);
|
||||
|
@ -116,7 +117,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserList */
|
||||
public function testListUsers(string $cmd, array $list, int $exitStatus, string $output) {
|
||||
public function testListUsers(string $cmd, array $list, int $exitStatus, string $output): void {
|
||||
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
|
||||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("list")->willReturn($list);
|
||||
|
@ -135,7 +136,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserAdditions */
|
||||
public function testAddAUser(string $cmd, int $exitStatus, string $output) {
|
||||
public function testAddAUser(string $cmd, int $exitStatus, string $output): void {
|
||||
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
|
||||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("add")->will($this->returnCallback(function($user, $pass = null) {
|
||||
|
@ -158,7 +159,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserAuthentication */
|
||||
public function testAuthenticateAUser(string $cmd, int $exitStatus, string $output) {
|
||||
public function testAuthenticateAUser(string $cmd, int $exitStatus, string $output): void {
|
||||
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
|
||||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("auth")->will($this->returnCallback(function($user, $pass) {
|
||||
|
@ -192,7 +193,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserRemovals */
|
||||
public function testRemoveAUser(string $cmd, int $exitStatus, string $output) {
|
||||
public function testRemoveAUser(string $cmd, int $exitStatus, string $output): void {
|
||||
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
|
||||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("remove")->will($this->returnCallback(function($user) {
|
||||
|
@ -212,7 +213,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserPasswordChanges */
|
||||
public function testChangeAUserPassword(string $cmd, int $exitStatus, string $output) {
|
||||
public function testChangeAUserPassword(string $cmd, int $exitStatus, string $output): void {
|
||||
$passwordChange = function($user, $pass = null) {
|
||||
switch ($user) {
|
||||
case "jane.doe@example.com":
|
||||
|
@ -242,7 +243,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserPasswordClearings */
|
||||
public function testClearAUserPassword(string $cmd, int $exitStatus, string $output) {
|
||||
public function testClearAUserPassword(string $cmd, int $exitStatus, string $output): void {
|
||||
$passwordClear = function($user) {
|
||||
switch ($user) {
|
||||
case "jane.doe@example.com":
|
||||
|
@ -270,7 +271,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @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): void {
|
||||
$opml = \Phake::mock(OPML::class);
|
||||
\Phake::when($opml)->exportFile("php://output", $user, $flat)->thenReturn(true);
|
||||
\Phake::when($opml)->exportFile("good.opml", $user, $flat)->thenReturn(true);
|
||||
|
@ -311,7 +312,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @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): void {
|
||||
$opml = \Phake::mock(OPML::class);
|
||||
\Phake::when($opml)->importFile("php://input", $user, $flat, $replace)->thenReturn(true);
|
||||
\Phake::when($opml)->importFile("good.opml", $user, $flat, $replace)->thenReturn(true);
|
||||
|
|
|
@ -38,12 +38,12 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testLoadDefaultValues() {
|
||||
public function testLoadDefaultValues(): void {
|
||||
$this->assertInstanceOf(Conf::class, new Conf);
|
||||
}
|
||||
|
||||
/** @depends testLoadDefaultValues */
|
||||
public function testImportFromArray() {
|
||||
public function testImportFromArray(): void {
|
||||
$arr = [
|
||||
'lang' => "xx",
|
||||
'purgeFeeds' => "P2D",
|
||||
|
@ -54,7 +54,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @depends testImportFromArray */
|
||||
public function testImportFromFile() {
|
||||
public function testImportFromFile(): void {
|
||||
$conf = new Conf;
|
||||
$conf->importFile(self::$path."confGood");
|
||||
$this->assertEquals("xx", $conf->lang);
|
||||
|
@ -63,43 +63,43 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @depends testImportFromFile */
|
||||
public function testImportFromMissingFile() {
|
||||
public function testImportFromMissingFile(): void {
|
||||
$this->assertException("fileMissing", "Conf");
|
||||
$conf = new Conf(self::$path."confMissing");
|
||||
}
|
||||
|
||||
/** @depends testImportFromFile */
|
||||
public function testImportFromEmptyFile() {
|
||||
public function testImportFromEmptyFile(): void {
|
||||
$this->assertException("fileCorrupt", "Conf");
|
||||
$conf = new Conf(self::$path."confEmpty");
|
||||
}
|
||||
|
||||
/** @depends testImportFromFile */
|
||||
public function testImportFromFileWithoutReadPermission() {
|
||||
public function testImportFromFileWithoutReadPermission(): void {
|
||||
$this->assertException("fileUnreadable", "Conf");
|
||||
$conf = new Conf(self::$path."confUnreadable");
|
||||
}
|
||||
|
||||
/** @depends testImportFromFile */
|
||||
public function testImportFromFileWhichIsNotAnArray() {
|
||||
public function testImportFromFileWhichIsNotAnArray(): void {
|
||||
$this->assertException("fileCorrupt", "Conf");
|
||||
$conf = new Conf(self::$path."confNotArray");
|
||||
}
|
||||
|
||||
/** @depends testImportFromFile */
|
||||
public function testImportFromFileWhichIsNotPhp() {
|
||||
public function testImportFromFileWhichIsNotPhp(): void {
|
||||
$this->assertException("fileCorrupt", "Conf");
|
||||
// this should not print the output of the non-PHP file
|
||||
$conf = new Conf(self::$path."confNotPHP");
|
||||
}
|
||||
|
||||
/** @depends testImportFromFile */
|
||||
public function testImportFromCorruptFile() {
|
||||
public function testImportFromCorruptFile(): void {
|
||||
$this->assertException("fileCorrupt", "Conf");
|
||||
$conf = new Conf(self::$path."confCorrupt");
|
||||
}
|
||||
|
||||
public function testImportBogusValue() {
|
||||
public function testImportBogusValue(): void {
|
||||
$arr = [
|
||||
'dbAutoUpdate' => "yes, please",
|
||||
];
|
||||
|
@ -108,7 +108,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$conf->import($arr);
|
||||
}
|
||||
|
||||
public function testImportBogusDriver() {
|
||||
public function testImportBogusDriver(): void {
|
||||
$arr = [
|
||||
'dbDriver' => "this driver does not exist",
|
||||
];
|
||||
|
@ -117,7 +117,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$conf->import($arr);
|
||||
}
|
||||
|
||||
public function testExportToArray() {
|
||||
public function testExportToArray(): void {
|
||||
$conf = new Conf;
|
||||
$conf->lang = ["en", "fr"]; // should not be exported: not scalar
|
||||
$conf->dbSQLite3File = "test.db"; // should be exported: value changed
|
||||
|
@ -138,7 +138,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @depends testExportToArray
|
||||
* @depends testImportFromFile */
|
||||
public function testExportToFile() {
|
||||
public function testExportToFile(): void {
|
||||
$conf = new Conf;
|
||||
$conf->lang = ["en", "fr"]; // should not be exported: not scalar
|
||||
$conf->dbSQLite3File = "test.db"; // should be exported: value changed
|
||||
|
@ -159,19 +159,19 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @depends testExportToFile */
|
||||
public function testExportToStdout() {
|
||||
public function testExportToStdout(): void {
|
||||
$conf = new Conf(self::$path."confGood");
|
||||
$conf->exportFile(self::$path."confGood");
|
||||
$this->expectOutputString(file_get_contents(self::$path."confGood"));
|
||||
$conf->exportFile("php://output");
|
||||
}
|
||||
|
||||
public function testExportToFileWithoutWritePermission() {
|
||||
public function testExportToFileWithoutWritePermission(): void {
|
||||
$this->assertException("fileUnwritable", "Conf");
|
||||
(new Conf)->exportFile(self::$path."confUnreadable");
|
||||
}
|
||||
|
||||
public function testExportToFileWithoutCreatePermission() {
|
||||
public function testExportToFileWithoutCreatePermission(): void {
|
||||
$this->assertException("fileUncreatable", "Conf");
|
||||
(new Conf)->exportFile(self::$path."confForbidden/conf");
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use JKingWeb\Arsse\Misc\Date;
|
|||
use JKingWeb\Arsse\Misc\ValueInfo;
|
||||
|
||||
trait SeriesArticle {
|
||||
protected function setUpSeriesArticle() {
|
||||
protected function setUpSeriesArticle(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
|
@ -408,12 +408,12 @@ trait SeriesArticle {
|
|||
$this->user = "john.doe@example.net";
|
||||
}
|
||||
|
||||
protected function tearDownSeriesArticle() {
|
||||
protected function tearDownSeriesArticle(): void {
|
||||
unset($this->data, $this->matches, $this->fields, $this->checkTables, $this->user);
|
||||
}
|
||||
|
||||
/** @dataProvider provideContextMatches */
|
||||
public function testListArticlesCheckingContext(Context $c, array $exp) {
|
||||
public function testListArticlesCheckingContext(Context $c, array $exp): void {
|
||||
$ids = array_column($ids = Arsse::$db->articleList("john.doe@example.com", $c, ["id"], ["id"])->getAll(), "id");
|
||||
sort($ids);
|
||||
sort($exp);
|
||||
|
@ -516,7 +516,7 @@ trait SeriesArticle {
|
|||
];
|
||||
}
|
||||
|
||||
public function testRetrieveArticleIdsForEditions() {
|
||||
public function testRetrieveArticleIdsForEditions(): void {
|
||||
$exp = [
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
|
@ -553,17 +553,17 @@ trait SeriesArticle {
|
|||
$this->assertEquals($exp, Arsse::$db->editionArticle(...range(1, 1001)));
|
||||
}
|
||||
|
||||
public function testListArticlesOfAMissingFolder() {
|
||||
public function testListArticlesOfAMissingFolder(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleList($this->user, (new Context)->folder(1));
|
||||
}
|
||||
|
||||
public function testListArticlesOfAMissingSubscription() {
|
||||
public function testListArticlesOfAMissingSubscription(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleList($this->user, (new Context)->subscription(1));
|
||||
}
|
||||
|
||||
public function testListArticlesCheckingProperties() {
|
||||
public function testListArticlesCheckingProperties(): void {
|
||||
$this->user = "john.doe@example.org";
|
||||
// check that the different fieldset groups return the expected columns
|
||||
foreach ($this->fields as $column) {
|
||||
|
@ -577,7 +577,7 @@ trait SeriesArticle {
|
|||
}
|
||||
|
||||
/** @dataProvider provideOrderedLists */
|
||||
public function testListArticlesCheckingOrder(array $sortCols, array $exp) {
|
||||
public function testListArticlesCheckingOrder(array $sortCols, array $exp): void {
|
||||
$act = ValueInfo::normalize(array_column(iterator_to_array(Arsse::$db->articleList("john.doe@example.com", null, ["id"], $sortCols)), "id"), ValueInfo::T_INT | ValueInfo::M_ARRAY);
|
||||
$this->assertSame($exp, $act);
|
||||
}
|
||||
|
@ -595,17 +595,17 @@ trait SeriesArticle {
|
|||
];
|
||||
}
|
||||
|
||||
public function testListArticlesWithoutAuthority() {
|
||||
public function testListArticlesWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleList($this->user);
|
||||
}
|
||||
|
||||
public function testMarkNothing() {
|
||||
public function testMarkNothing(): void {
|
||||
$this->assertSame(0, Arsse::$db->articleMark($this->user, []));
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnread() {
|
||||
public function testMarkAllArticlesUnread(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -616,7 +616,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesRead() {
|
||||
public function testMarkAllArticlesRead(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -631,7 +631,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnstarred() {
|
||||
public function testMarkAllArticlesUnstarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>false]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -642,7 +642,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesStarred() {
|
||||
public function testMarkAllArticlesStarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -657,7 +657,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnreadAndUnstarred() {
|
||||
public function testMarkAllArticlesUnreadAndUnstarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -671,7 +671,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesReadAndStarred() {
|
||||
public function testMarkAllArticlesReadAndStarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>true]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -689,7 +689,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnreadAndStarred() {
|
||||
public function testMarkAllArticlesUnreadAndStarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -707,7 +707,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesReadAndUnstarred() {
|
||||
public function testMarkAllArticlesReadAndUnstarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>false]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -725,7 +725,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testSetNoteForAllArticles() {
|
||||
public function testSetNoteForAllArticles(): void {
|
||||
Arsse::$db->articleMark($this->user, ['note'=>"New note"]);
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -744,7 +744,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkATreeFolder() {
|
||||
public function testMarkATreeFolder(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(7));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -755,7 +755,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkALeafFolder() {
|
||||
public function testMarkALeafFolder(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(8));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -764,12 +764,12 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAMissingFolder() {
|
||||
public function testMarkAMissingFolder(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(42));
|
||||
}
|
||||
|
||||
public function testMarkASubscription() {
|
||||
public function testMarkASubscription(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->subscription(13));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -778,12 +778,12 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAMissingSubscription() {
|
||||
public function testMarkAMissingSubscription(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(2112));
|
||||
}
|
||||
|
||||
public function testMarkAnArticle() {
|
||||
public function testMarkAnArticle(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(20));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -792,7 +792,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleArticles() {
|
||||
public function testMarkMultipleArticles(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->articles([2,4,7,20]));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -802,7 +802,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleArticlessUnreadAndStarred() {
|
||||
public function testMarkMultipleArticlessUnreadAndStarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles([2,4,7,20]));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -815,16 +815,16 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkTooManyMultipleArticles() {
|
||||
public function testMarkTooManyMultipleArticles(): void {
|
||||
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
|
||||
}
|
||||
|
||||
public function testMarkAMissingArticle() {
|
||||
public function testMarkAMissingArticle(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(1));
|
||||
}
|
||||
|
||||
public function testMarkAnEdition() {
|
||||
public function testMarkAnEdition(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(1001));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -833,7 +833,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditions() {
|
||||
public function testMarkMultipleEditions(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([2,4,7,20]));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -843,13 +843,13 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleMissingEditions() {
|
||||
public function testMarkMultipleMissingEditions(): void {
|
||||
$this->assertSame(0, Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([500,501])));
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditionsUnread() {
|
||||
public function testMarkMultipleEditionsUnread(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,1001]));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -860,7 +860,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditionsUnreadWithStale() {
|
||||
public function testMarkMultipleEditionsUnreadWithStale(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,20]));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -869,7 +869,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditionsUnreadAndStarredWithStale() {
|
||||
public function testMarkMultipleEditionsUnreadAndStarredWithStale(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions([2,4,7,20]));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -881,17 +881,17 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkTooManyMultipleEditions() {
|
||||
public function testMarkTooManyMultipleEditions(): void {
|
||||
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions(range(1, 51))));
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionUnread() {
|
||||
public function testMarkAStaleEditionUnread(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->edition(20)); // no changes occur
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionStarred() {
|
||||
public function testMarkAStaleEditionStarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(20));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -900,7 +900,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionUnreadAndStarred() {
|
||||
public function testMarkAStaleEditionUnreadAndStarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->edition(20)); // only starred is changed
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -909,18 +909,18 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionUnreadAndUnstarred() {
|
||||
public function testMarkAStaleEditionUnreadAndUnstarred(): void {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false], (new Context)->edition(20)); // no changes occur
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAMissingEdition() {
|
||||
public function testMarkAMissingEdition(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(2));
|
||||
}
|
||||
|
||||
public function testMarkByOldestEdition() {
|
||||
public function testMarkByOldestEdition(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->oldestEdition(19));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -931,7 +931,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkByLatestEdition() {
|
||||
public function testMarkByLatestEdition(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->latestEdition(20));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -944,7 +944,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkByLastMarked() {
|
||||
public function testMarkByLastMarked(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->markedSince('2017-01-01T00:00:00Z'));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -955,7 +955,7 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkByNotLastMarked() {
|
||||
public function testMarkByNotLastMarked(): void {
|
||||
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->notMarkedSince('2000-01-01T00:00:00Z'));
|
||||
$now = Date::transform(time(), "sql");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
|
@ -964,55 +964,55 @@ trait SeriesArticle {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkArticlesWithoutAuthority() {
|
||||
public function testMarkArticlesWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false]);
|
||||
}
|
||||
|
||||
public function testCountArticles() {
|
||||
public function testCountArticles(): void {
|
||||
$this->assertSame(2, Arsse::$db->articleCount("john.doe@example.com", (new Context)->starred(true)));
|
||||
$this->assertSame(4, Arsse::$db->articleCount("john.doe@example.com", (new Context)->folder(1)));
|
||||
$this->assertSame(0, Arsse::$db->articleCount("jane.doe@example.com", (new Context)->starred(true)));
|
||||
$this->assertSame(10, Arsse::$db->articleCount("john.doe@example.com", (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
|
||||
}
|
||||
|
||||
public function testCountArticlesWithoutAuthority() {
|
||||
public function testCountArticlesWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleCount($this->user);
|
||||
}
|
||||
|
||||
public function testFetchStarredCounts() {
|
||||
public function testFetchStarredCounts(): void {
|
||||
$exp1 = ['total' => 2, 'unread' => 1, 'read' => 1];
|
||||
$exp2 = ['total' => 0, 'unread' => 0, 'read' => 0];
|
||||
$this->assertEquals($exp1, Arsse::$db->articleStarred("john.doe@example.com"));
|
||||
$this->assertEquals($exp2, Arsse::$db->articleStarred("jane.doe@example.com"));
|
||||
}
|
||||
|
||||
public function testFetchStarredCountsWithoutAuthority() {
|
||||
public function testFetchStarredCountsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleStarred($this->user);
|
||||
}
|
||||
|
||||
public function testFetchLatestEdition() {
|
||||
public function testFetchLatestEdition(): void {
|
||||
$this->assertSame(1001, Arsse::$db->editionLatest($this->user));
|
||||
$this->assertSame(4, Arsse::$db->editionLatest($this->user, (new Context)->subscription(12)));
|
||||
}
|
||||
|
||||
public function testFetchLatestEditionOfMissingSubscription() {
|
||||
public function testFetchLatestEditionOfMissingSubscription(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->editionLatest($this->user, (new Context)->subscription(1));
|
||||
}
|
||||
|
||||
public function testFetchLatestEditionWithoutAuthority() {
|
||||
public function testFetchLatestEditionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->editionLatest($this->user);
|
||||
}
|
||||
|
||||
public function testListTheLabelsOfAnArticle() {
|
||||
public function testListTheLabelsOfAnArticle(): void {
|
||||
$this->assertEquals([1,2], Arsse::$db->articleLabelsGet("john.doe@example.com", 1));
|
||||
$this->assertEquals([2], Arsse::$db->articleLabelsGet("john.doe@example.com", 5));
|
||||
$this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2));
|
||||
|
@ -1021,18 +1021,18 @@ trait SeriesArticle {
|
|||
$this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2, true));
|
||||
}
|
||||
|
||||
public function testListTheLabelsOfAMissingArticle() {
|
||||
public function testListTheLabelsOfAMissingArticle(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleLabelsGet($this->user, 101);
|
||||
}
|
||||
|
||||
public function testListTheLabelsOfAnArticleWithoutAuthority() {
|
||||
public function testListTheLabelsOfAnArticleWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleLabelsGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testListTheCategoriesOfAnArticle() {
|
||||
public function testListTheCategoriesOfAnArticle(): void {
|
||||
$exp = ["Fascinating", "Logical"];
|
||||
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 19));
|
||||
$exp = ["Interesting", "Logical"];
|
||||
|
@ -1041,19 +1041,19 @@ trait SeriesArticle {
|
|||
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 4));
|
||||
}
|
||||
|
||||
public function testListTheCategoriesOfAMissingArticle() {
|
||||
public function testListTheCategoriesOfAMissingArticle(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleCategoriesGet($this->user, 101);
|
||||
}
|
||||
|
||||
public function testListTheCategoriesOfAnArticleWithoutAuthority() {
|
||||
public function testListTheCategoriesOfAnArticleWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleCategoriesGet($this->user, 19);
|
||||
}
|
||||
|
||||
/** @dataProvider provideArrayContextOptions */
|
||||
public function testUseTooFewValuesInArrayContext(string $option) {
|
||||
public function testUseTooFewValuesInArrayContext(string $option): void {
|
||||
$this->assertException("tooShort", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleList($this->user, (new Context)->$option([]));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SeriesCleanup {
|
||||
protected function setUpSeriesCleanup() {
|
||||
protected function setUpSeriesCleanup(): void {
|
||||
// set up the configuration
|
||||
Arsse::$conf->import([
|
||||
'userSessionTimeout' => "PT1H",
|
||||
|
@ -147,11 +147,11 @@ trait SeriesCleanup {
|
|||
];
|
||||
}
|
||||
|
||||
protected function tearDownSeriesCleanup() {
|
||||
protected function tearDownSeriesCleanup(): void {
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
public function testCleanUpOrphanedFeeds() {
|
||||
public function testCleanUpOrphanedFeeds(): void {
|
||||
Arsse::$db->feedCleanup();
|
||||
$now = gmdate("Y-m-d H:i:s");
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
|
@ -163,7 +163,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOrphanedFeedsWithUnlimitedRetention() {
|
||||
public function testCleanUpOrphanedFeedsWithUnlimitedRetention(): void {
|
||||
Arsse::$conf->import([
|
||||
'purgeFeeds' => null,
|
||||
]);
|
||||
|
@ -177,7 +177,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithStandardRetention() {
|
||||
public function testCleanUpOldArticlesWithStandardRetention(): void {
|
||||
Arsse::$db->articleCleanup();
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_articles' => ["id"]
|
||||
|
@ -188,7 +188,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithUnlimitedReadRetention() {
|
||||
public function testCleanUpOldArticlesWithUnlimitedReadRetention(): void {
|
||||
Arsse::$conf->import([
|
||||
'purgeArticlesRead' => null,
|
||||
]);
|
||||
|
@ -202,7 +202,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithUnlimitedUnreadRetention() {
|
||||
public function testCleanUpOldArticlesWithUnlimitedUnreadRetention(): void {
|
||||
Arsse::$conf->import([
|
||||
'purgeArticlesUnread' => null,
|
||||
]);
|
||||
|
@ -216,7 +216,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithUnlimitedRetention() {
|
||||
public function testCleanUpOldArticlesWithUnlimitedRetention(): void {
|
||||
Arsse::$conf->import([
|
||||
'purgeArticlesRead' => null,
|
||||
'purgeArticlesUnread' => null,
|
||||
|
@ -228,7 +228,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpExpiredSessions() {
|
||||
public function testCleanUpExpiredSessions(): void {
|
||||
Arsse::$db->sessionCleanup();
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_sessions' => ["id"]
|
||||
|
@ -239,7 +239,7 @@ trait SeriesCleanup {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpExpiredTokens() {
|
||||
public function testCleanUpExpiredTokens(): void {
|
||||
Arsse::$db->tokenCleanup();
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_tokens' => ["id", "class"]
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SeriesFeed {
|
||||
protected function setUpSeriesFeed() {
|
||||
protected function setUpSeriesFeed(): void {
|
||||
// set up the test data
|
||||
$past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute"));
|
||||
$future = gmdate("Y-m-d H:i:s", strtotime("now + 1 minute"));
|
||||
|
@ -160,15 +160,15 @@ trait SeriesFeed {
|
|||
];
|
||||
}
|
||||
|
||||
protected function tearDownSeriesFeed() {
|
||||
protected function tearDownSeriesFeed(): void {
|
||||
unset($this->data, $this->matches);
|
||||
}
|
||||
|
||||
public function testListLatestItems() {
|
||||
public function testListLatestItems(): void {
|
||||
$this->assertResult($this->matches, Arsse::$db->feedMatchLatest(1, 2));
|
||||
}
|
||||
|
||||
public function testMatchItemsById() {
|
||||
public function testMatchItemsById(): void {
|
||||
$this->assertResult($this->matches, Arsse::$db->feedMatchIds(1, ['804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180','db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41']));
|
||||
foreach ($this->matches as $m) {
|
||||
$exp = [$m];
|
||||
|
@ -179,7 +179,7 @@ trait SeriesFeed {
|
|||
$this->assertResult([['id' => 1]], Arsse::$db->feedMatchIds(1, ['e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda'])); // this ID appears in both feed 1 and feed 2; only one result should be returned
|
||||
}
|
||||
|
||||
public function testUpdateAFeed() {
|
||||
public function testUpdateAFeed(): void {
|
||||
// update a valid feed with both new and changed items
|
||||
Arsse::$db->feedUpdate(1);
|
||||
$now = gmdate("Y-m-d H:i:s");
|
||||
|
@ -219,22 +219,22 @@ trait SeriesFeed {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testUpdateAMissingFeed() {
|
||||
public function testUpdateAMissingFeed(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->feedUpdate(2112);
|
||||
}
|
||||
|
||||
public function testUpdateAnInvalidFeed() {
|
||||
public function testUpdateAnInvalidFeed(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->feedUpdate(-1);
|
||||
}
|
||||
|
||||
public function testUpdateAFeedThrowingExceptions() {
|
||||
public function testUpdateAFeedThrowingExceptions(): void {
|
||||
$this->assertException("invalidUrl", "Feed");
|
||||
Arsse::$db->feedUpdate(3, true);
|
||||
}
|
||||
|
||||
public function testUpdateAFeedWithEnclosuresAndCategories() {
|
||||
public function testUpdateAFeedWithEnclosuresAndCategories(): void {
|
||||
Arsse::$db->feedUpdate(5);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_enclosures' => ["url","type"],
|
||||
|
@ -254,7 +254,7 @@ trait SeriesFeed {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testListStaleFeeds() {
|
||||
public function testListStaleFeeds(): void {
|
||||
$this->assertEquals([1,3,4], Arsse::$db->feedListStale());
|
||||
Arsse::$db->feedUpdate(3);
|
||||
Arsse::$db->feedUpdate(4);
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SeriesFolder {
|
||||
protected function setUpSeriesFolder() {
|
||||
protected function setUpSeriesFolder(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
|
@ -93,11 +93,11 @@ trait SeriesFolder {
|
|||
];
|
||||
}
|
||||
|
||||
protected function tearDownSeriesFolder() {
|
||||
protected function tearDownSeriesFolder(): void {
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
public function testAddARootFolder() {
|
||||
public function testAddARootFolder(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$folderID = $this->nextID("arsse_folders");
|
||||
$this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "Entertainment"]));
|
||||
|
@ -107,12 +107,12 @@ trait SeriesFolder {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddADuplicateRootFolder() {
|
||||
public function testAddADuplicateRootFolder(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Politics"]);
|
||||
}
|
||||
|
||||
public function testAddANestedFolder() {
|
||||
public function testAddANestedFolder(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$folderID = $this->nextID("arsse_folders");
|
||||
$this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "GNOME", 'parent' => 2]));
|
||||
|
@ -122,43 +122,43 @@ trait SeriesFolder {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddANestedFolderToAMissingParent() {
|
||||
public function testAddANestedFolderToAMissingParent(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => 2112]);
|
||||
}
|
||||
|
||||
public function testAddANestedFolderToAnInvalidParent() {
|
||||
public function testAddANestedFolderToAnInvalidParent(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => "stringFolderId"]);
|
||||
}
|
||||
|
||||
public function testAddANestedFolderForTheWrongOwner() {
|
||||
public function testAddANestedFolderForTheWrongOwner(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => 4]); // folder ID 4 belongs to Jane
|
||||
}
|
||||
|
||||
public function testAddAFolderWithAMissingName() {
|
||||
public function testAddAFolderWithAMissingName(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", []);
|
||||
}
|
||||
|
||||
public function testAddAFolderWithABlankName() {
|
||||
public function testAddAFolderWithABlankName(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => ""]);
|
||||
}
|
||||
|
||||
public function testAddAFolderWithAWhitespaceName() {
|
||||
public function testAddAFolderWithAWhitespaceName(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => " "]);
|
||||
}
|
||||
|
||||
public function testAddAFolderWithoutAuthority() {
|
||||
public function testAddAFolderWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology"]);
|
||||
}
|
||||
|
||||
public function testListRootFolders() {
|
||||
public function testListRootFolders(): void {
|
||||
$exp = [
|
||||
['id' => 5, 'name' => "Politics", 'parent' => null, 'children' => 0, 'feeds' => 2],
|
||||
['id' => 1, 'name' => "Technology", 'parent' => null, 'children' => 2, 'feeds' => 1],
|
||||
|
@ -175,7 +175,7 @@ trait SeriesFolder {
|
|||
\Phake::verify(Arsse::$user)->authorize("admin@example.net", "folderList");
|
||||
}
|
||||
|
||||
public function testListFoldersRecursively() {
|
||||
public function testListFoldersRecursively(): void {
|
||||
$exp = [
|
||||
['id' => 5, 'name' => "Politics", 'parent' => null, 'children' => 0, 'feeds' => 2],
|
||||
['id' => 6, 'name' => "Politics", 'parent' => 2, 'children' => 0, 'feeds' => 1],
|
||||
|
@ -196,23 +196,23 @@ trait SeriesFolder {
|
|||
\Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList");
|
||||
}
|
||||
|
||||
public function testListFoldersOfAMissingParent() {
|
||||
public function testListFoldersOfAMissingParent(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderList("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testListFoldersOfTheWrongOwner() {
|
||||
public function testListFoldersOfTheWrongOwner(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderList("john.doe@example.com", 4); // folder ID 4 belongs to Jane
|
||||
}
|
||||
|
||||
public function testListFoldersWithoutAuthority() {
|
||||
public function testListFoldersWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->folderList("john.doe@example.com");
|
||||
}
|
||||
|
||||
public function testRemoveAFolder() {
|
||||
public function testRemoveAFolder(): void {
|
||||
$this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 6));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
|
@ -220,7 +220,7 @@ trait SeriesFolder {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAFolderTree() {
|
||||
public function testRemoveAFolderTree(): void {
|
||||
$this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 1));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
|
@ -230,28 +230,28 @@ trait SeriesFolder {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingFolder() {
|
||||
public function testRemoveAMissingFolder(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderRemove("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testRemoveAnInvalidFolder() {
|
||||
public function testRemoveAnInvalidFolder(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderRemove("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testRemoveAFolderOfTheWrongOwner() {
|
||||
public function testRemoveAFolderOfTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderRemove("john.doe@example.com", 4); // folder ID 4 belongs to Jane
|
||||
}
|
||||
|
||||
public function testRemoveAFolderWithoutAuthority() {
|
||||
public function testRemoveAFolderWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->folderRemove("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAFolder() {
|
||||
public function testGetThePropertiesOfAFolder(): void {
|
||||
$exp = [
|
||||
'id' => 6,
|
||||
'name' => "Politics",
|
||||
|
@ -261,32 +261,32 @@ trait SeriesFolder {
|
|||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesGet");
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAMissingFolder() {
|
||||
public function testGetThePropertiesOfAMissingFolder(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesGet("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAnInvalidFolder() {
|
||||
public function testGetThePropertiesOfAnInvalidFolder(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesGet("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAFolderOfTheWrongOwner() {
|
||||
public function testGetThePropertiesOfAFolderOfTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesGet("john.doe@example.com", 4); // folder ID 4 belongs to Jane
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAFolderWithoutAuthority() {
|
||||
public function testGetThePropertiesOfAFolderWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->folderPropertiesGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testMakeNoChangesToAFolder() {
|
||||
public function testMakeNoChangesToAFolder(): void {
|
||||
$this->assertFalse(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, []));
|
||||
}
|
||||
|
||||
public function testRenameAFolder() {
|
||||
public function testRenameAFolder(): void {
|
||||
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => "Opinion"]));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
|
@ -294,26 +294,26 @@ trait SeriesFolder {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameTheRootFolder() {
|
||||
public function testRenameTheRootFolder(): void {
|
||||
$this->assertFalse(Arsse::$db->folderPropertiesSet("john.doe@example.com", null, ['name' => "Opinion"]));
|
||||
}
|
||||
|
||||
public function testRenameAFolderToTheEmptyString() {
|
||||
public function testRenameAFolderToTheEmptyString(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => ""]));
|
||||
}
|
||||
|
||||
public function testRenameAFolderToWhitespaceOnly() {
|
||||
public function testRenameAFolderToWhitespaceOnly(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => " "]));
|
||||
}
|
||||
|
||||
public function testRenameAFolderToAnInvalidValue() {
|
||||
public function testRenameAFolderToAnInvalidValue(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => []]));
|
||||
}
|
||||
|
||||
public function testMoveAFolder() {
|
||||
public function testMoveAFolder(): void {
|
||||
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => 5]));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
|
@ -321,57 +321,57 @@ trait SeriesFolder {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMoveTheRootFolder() {
|
||||
public function testMoveTheRootFolder(): void {
|
||||
$this->assertException("circularDependence", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 0, ['parent' => 1]);
|
||||
}
|
||||
|
||||
public function testMoveAFolderToItsDescendant() {
|
||||
public function testMoveAFolderToItsDescendant(): void {
|
||||
$this->assertException("circularDependence", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 3]);
|
||||
}
|
||||
|
||||
public function testMoveAFolderToItself() {
|
||||
public function testMoveAFolderToItself(): void {
|
||||
$this->assertException("circularDependence", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 1]);
|
||||
}
|
||||
|
||||
public function testMoveAFolderToAMissingParent() {
|
||||
public function testMoveAFolderToAMissingParent(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 2112]);
|
||||
}
|
||||
|
||||
public function testMoveAFolderToAnInvalidParent() {
|
||||
public function testMoveAFolderToAnInvalidParent(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => "ThisFolderDoesNotExist"]);
|
||||
}
|
||||
|
||||
public function testCauseAFolderCollision() {
|
||||
public function testCauseAFolderCollision(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => null]);
|
||||
}
|
||||
|
||||
public function testCauseACompoundFolderCollision() {
|
||||
public function testCauseACompoundFolderCollision(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 3, ['parent' => null, 'name' => "Technology"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAMissingFolder() {
|
||||
public function testSetThePropertiesOfAMissingFolder(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 2112, ['parent' => null]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAnInvalidFolder() {
|
||||
public function testSetThePropertiesOfAnInvalidFolder(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", -1, ['parent' => null]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAFolderForTheWrongOwner() {
|
||||
public function testSetThePropertiesOfAFolderForTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 4, ['parent' => null]); // folder ID 4 belongs to Jane
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAFolderWithoutAuthority() {
|
||||
public function testSetThePropertiesOfAFolderWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => null]);
|
||||
|
|
|
@ -11,7 +11,7 @@ use JKingWeb\Arsse\Database;
|
|||
use JKingWeb\Arsse\Context\Context;
|
||||
|
||||
trait SeriesLabel {
|
||||
protected function setUpSeriesLabel() {
|
||||
protected function setUpSeriesLabel(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
|
@ -244,11 +244,11 @@ trait SeriesLabel {
|
|||
$this->user = "john.doe@example.com";
|
||||
}
|
||||
|
||||
protected function tearDownSeriesLabel() {
|
||||
protected function tearDownSeriesLabel(): void {
|
||||
unset($this->data, $this->checkLabels, $this->checkMembers, $this->user);
|
||||
}
|
||||
|
||||
public function testAddALabel() {
|
||||
public function testAddALabel(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$labelID = $this->nextID("arsse_labels");
|
||||
$this->assertSame($labelID, Arsse::$db->labelAdd($user, ['name' => "Entertaining"]));
|
||||
|
@ -258,33 +258,33 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddADuplicateLabel() {
|
||||
public function testAddADuplicateLabel(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Interesting"]);
|
||||
}
|
||||
|
||||
public function testAddALabelWithAMissingName() {
|
||||
public function testAddALabelWithAMissingName(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelAdd("john.doe@example.com", []);
|
||||
}
|
||||
|
||||
public function testAddALabelWithABlankName() {
|
||||
public function testAddALabelWithABlankName(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelAdd("john.doe@example.com", ['name' => ""]);
|
||||
}
|
||||
|
||||
public function testAddALabelWithAWhitespaceName() {
|
||||
public function testAddALabelWithAWhitespaceName(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelAdd("john.doe@example.com", ['name' => " "]);
|
||||
}
|
||||
|
||||
public function testAddALabelWithoutAuthority() {
|
||||
public function testAddALabelWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Boring"]);
|
||||
}
|
||||
|
||||
public function testListLabels() {
|
||||
public function testListLabels(): void {
|
||||
$exp = [
|
||||
['id' => 2, 'name' => "Fascinating", 'articles' => 3, 'read' => 1],
|
||||
['id' => 1, 'name' => "Interesting", 'articles' => 2, 'read' => 2],
|
||||
|
@ -300,13 +300,13 @@ trait SeriesLabel {
|
|||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelList");
|
||||
}
|
||||
|
||||
public function testListLabelsWithoutAuthority() {
|
||||
public function testListLabelsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelList("john.doe@example.com");
|
||||
}
|
||||
|
||||
public function testRemoveALabel() {
|
||||
public function testRemoveALabel(): void {
|
||||
$this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", 1));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
|
@ -314,7 +314,7 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveALabelByName() {
|
||||
public function testRemoveALabelByName(): void {
|
||||
$this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", "Interesting", true));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
|
@ -322,33 +322,33 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingLabel() {
|
||||
public function testRemoveAMissingLabel(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelRemove("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testRemoveAnInvalidLabel() {
|
||||
public function testRemoveAnInvalidLabel(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelRemove("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testRemoveAnInvalidLabelByName() {
|
||||
public function testRemoveAnInvalidLabelByName(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelRemove("john.doe@example.com", [], true);
|
||||
}
|
||||
|
||||
public function testRemoveALabelOfTheWrongOwner() {
|
||||
public function testRemoveALabelOfTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelRemove("john.doe@example.com", 3); // label ID 3 belongs to Jane
|
||||
}
|
||||
|
||||
public function testRemoveALabelWithoutAuthority() {
|
||||
public function testRemoveALabelWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelRemove("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfALabel() {
|
||||
public function testGetThePropertiesOfALabel(): void {
|
||||
$exp = [
|
||||
'id' => 2,
|
||||
'name' => "Fascinating",
|
||||
|
@ -360,37 +360,37 @@ trait SeriesLabel {
|
|||
\Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "labelPropertiesGet");
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAMissingLabel() {
|
||||
public function testGetThePropertiesOfAMissingLabel(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesGet("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAnInvalidLabel() {
|
||||
public function testGetThePropertiesOfAnInvalidLabel(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesGet("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAnInvalidLabelByName() {
|
||||
public function testGetThePropertiesOfAnInvalidLabelByName(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesGet("john.doe@example.com", [], true);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfALabelOfTheWrongOwner() {
|
||||
public function testGetThePropertiesOfALabelOfTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesGet("john.doe@example.com", 3); // label ID 3 belongs to Jane
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfALabelWithoutAuthority() {
|
||||
public function testGetThePropertiesOfALabelWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelPropertiesGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testMakeNoChangesToALabel() {
|
||||
public function testMakeNoChangesToALabel(): void {
|
||||
$this->assertFalse(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, []));
|
||||
}
|
||||
|
||||
public function testRenameALabel() {
|
||||
public function testRenameALabel(): void {
|
||||
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
|
@ -398,7 +398,7 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameALabelByName() {
|
||||
public function testRenameALabelByName(): void {
|
||||
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
|
@ -406,53 +406,53 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameALabelToTheEmptyString() {
|
||||
public function testRenameALabelToTheEmptyString(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => ""]));
|
||||
}
|
||||
|
||||
public function testRenameALabelToWhitespaceOnly() {
|
||||
public function testRenameALabelToWhitespaceOnly(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => " "]));
|
||||
}
|
||||
|
||||
public function testRenameALabelToAnInvalidValue() {
|
||||
public function testRenameALabelToAnInvalidValue(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => []]));
|
||||
}
|
||||
|
||||
public function testCauseALabelCollision() {
|
||||
public function testCauseALabelCollision(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAMissingLabel() {
|
||||
public function testSetThePropertiesOfAMissingLabel(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAnInvalidLabel() {
|
||||
public function testSetThePropertiesOfAnInvalidLabel(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAnInvalidLabelByName() {
|
||||
public function testSetThePropertiesOfAnInvalidLabelByName(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfALabelForTheWrongOwner() {
|
||||
public function testSetThePropertiesOfALabelForTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // label ID 3 belongs to Jane
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfALabelWithoutAuthority() {
|
||||
public function testSetThePropertiesOfALabelWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]);
|
||||
}
|
||||
|
||||
public function testListLabelledArticles() {
|
||||
public function testListLabelledArticles(): void {
|
||||
$exp = [1,19];
|
||||
$this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", 1));
|
||||
$this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", "Interesting", true));
|
||||
|
@ -464,23 +464,23 @@ trait SeriesLabel {
|
|||
$this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", "Lonely", true));
|
||||
}
|
||||
|
||||
public function testListLabelledArticlesForAMissingLabel() {
|
||||
public function testListLabelledArticlesForAMissingLabel(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelArticlesGet("john.doe@example.com", 3);
|
||||
}
|
||||
|
||||
public function testListLabelledArticlesForAnInvalidLabel() {
|
||||
public function testListLabelledArticlesForAnInvalidLabel(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->labelArticlesGet("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testListLabelledArticlesWithoutAuthority() {
|
||||
public function testListLabelledArticlesWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelArticlesGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testApplyALabelToArticles() {
|
||||
public function testApplyALabelToArticles(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]));
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][4][3] = 1;
|
||||
|
@ -488,14 +488,14 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearALabelFromArticles() {
|
||||
public function testClearALabelFromArticles(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([1,5]), Database::ASSOC_REMOVE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyALabelToArticlesByName() {
|
||||
public function testApplyALabelToArticlesByName(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([2,5]), Database::ASSOC_ADD, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][4][3] = 1;
|
||||
|
@ -503,26 +503,26 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearALabelFromArticlesByName() {
|
||||
public function testClearALabelFromArticlesByName(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([1,5]), Database::ASSOC_REMOVE, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyALabelToNoArticles() {
|
||||
public function testApplyALabelToNoArticles(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]));
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearALabelFromNoArticles() {
|
||||
public function testClearALabelFromNoArticles(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REMOVE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testReplaceArticlesOfALabel() {
|
||||
public function testReplaceArticlesOfALabel(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]), Database::ASSOC_REPLACE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
|
@ -532,7 +532,7 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testPurgeArticlesOfALabel() {
|
||||
public function testPurgeArticlesOfALabel(): void {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REPLACE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
|
@ -540,7 +540,7 @@ trait SeriesLabel {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyALabelToArticlesWithoutAuthority() {
|
||||
public function testApplyALabelToArticlesWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]));
|
||||
|
|
|
@ -10,7 +10,7 @@ use JKingWeb\Arsse\Test\Database;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SeriesMeta {
|
||||
protected function setUpSeriesMeta() {
|
||||
protected function setUpSeriesMeta(): void {
|
||||
$dataBare = [
|
||||
'arsse_meta' => [
|
||||
'columns' => [
|
||||
|
@ -31,18 +31,18 @@ trait SeriesMeta {
|
|||
$this->primeDatabase(static::$drv, $dataBare);
|
||||
}
|
||||
|
||||
protected function tearDownSeriesMeta() {
|
||||
protected function tearDownSeriesMeta(): void {
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
public function testAddANewValue() {
|
||||
public function testAddANewValue(): void {
|
||||
$this->assertTrue(Arsse::$db->metaSet("favourite", "Cygnus X-1"));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
|
||||
$state['arsse_meta']['rows'][] = ["favourite","Cygnus X-1"];
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddANewTypedValue() {
|
||||
public function testAddANewTypedValue(): void {
|
||||
$this->assertTrue(Arsse::$db->metaSet("answer", 42, "int"));
|
||||
$this->assertTrue(Arsse::$db->metaSet("true", true, "bool"));
|
||||
$this->assertTrue(Arsse::$db->metaSet("false", false, "bool"));
|
||||
|
@ -55,14 +55,14 @@ trait SeriesMeta {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testChangeAnExistingValue() {
|
||||
public function testChangeAnExistingValue(): void {
|
||||
$this->assertTrue(Arsse::$db->metaSet("album", "Hemispheres"));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
|
||||
$state['arsse_meta']['rows'][1][1] = "Hemispheres";
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAValue() {
|
||||
public function testRemoveAValue(): void {
|
||||
$this->assertTrue(Arsse::$db->metaRemove("album"));
|
||||
$this->assertFalse(Arsse::$db->metaRemove("album"));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
|
||||
|
@ -70,7 +70,7 @@ trait SeriesMeta {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRetrieveAValue() {
|
||||
public function testRetrieveAValue(): void {
|
||||
$this->assertSame("".Database::SCHEMA_VERSION, Arsse::$db->metaGet("schema_version"));
|
||||
$this->assertSame("A Farewell to Kings", Arsse::$db->metaGet("album"));
|
||||
$this->assertSame(null, Arsse::$db->metaGet("this_key_does_not_exist"));
|
||||
|
|
|
@ -10,22 +10,22 @@ use JKingWeb\Arsse\Arsse;
|
|||
use JKingWeb\Arsse\Database;
|
||||
|
||||
trait SeriesMiscellany {
|
||||
protected function setUpSeriesMiscellany() {
|
||||
protected function setUpSeriesMiscellany(): void {
|
||||
static::setConf([
|
||||
'dbDriver' => static::$dbDriverClass,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function tearDownSeriesMiscellany() {
|
||||
protected function tearDownSeriesMiscellany(): void {
|
||||
}
|
||||
|
||||
public function testInitializeDatabase() {
|
||||
public function testInitializeDatabase(): void {
|
||||
static::dbRaze(static::$drv);
|
||||
$d = new Database(true);
|
||||
$this->assertSame(Database::SCHEMA_VERSION, $d->driverSchemaVersion());
|
||||
}
|
||||
|
||||
public function testManuallyInitializeDatabase() {
|
||||
public function testManuallyInitializeDatabase(): void {
|
||||
static::dbRaze(static::$drv);
|
||||
$d = new Database(false);
|
||||
$this->assertSame(0, $d->driverSchemaVersion());
|
||||
|
@ -34,11 +34,11 @@ trait SeriesMiscellany {
|
|||
$this->assertFalse($d->driverSchemaUpdate());
|
||||
}
|
||||
|
||||
public function testCheckCharacterSetAcceptability() {
|
||||
public function testCheckCharacterSetAcceptability(): void {
|
||||
$this->assertIsBool(Arsse::$db->driverCharsetAcceptable());
|
||||
}
|
||||
|
||||
public function testPerformMaintenance() {
|
||||
public function testPerformMaintenance(): void {
|
||||
$this->assertTrue(Arsse::$db->driverMaintenance());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use JKingWeb\Arsse\Arsse;
|
|||
use JKingWeb\Arsse\Misc\Date;
|
||||
|
||||
trait SeriesSession {
|
||||
protected function setUpSeriesSession() {
|
||||
protected function setUpSeriesSession(): void {
|
||||
// set up the configuration
|
||||
static::setConf([
|
||||
'userSessionTimeout' => "PT1H",
|
||||
|
@ -49,11 +49,11 @@ trait SeriesSession {
|
|||
];
|
||||
}
|
||||
|
||||
protected function tearDownSeriesSession() {
|
||||
protected function tearDownSeriesSession(): void {
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
public function testResumeAValidSession() {
|
||||
public function testResumeAValidSession(): void {
|
||||
$exp1 = [
|
||||
'id' => "80fa94c1a11f11e78667001e673b2560",
|
||||
'user' => "jane.doe@example.com"
|
||||
|
@ -74,22 +74,22 @@ trait SeriesSession {
|
|||
$this->assertArraySubset($exp1, Arsse::$db->sessionResume("80fa94c1a11f11e78667001e673b2560"));
|
||||
}
|
||||
|
||||
public function testResumeAMissingSession() {
|
||||
public function testResumeAMissingSession(): void {
|
||||
$this->assertException("invalid", "User", "ExceptionSession");
|
||||
Arsse::$db->sessionResume("thisSessionDoesNotExist");
|
||||
}
|
||||
|
||||
public function testResumeAnExpiredSession() {
|
||||
public function testResumeAnExpiredSession(): void {
|
||||
$this->assertException("invalid", "User", "ExceptionSession");
|
||||
Arsse::$db->sessionResume("27c6de8da13311e78667001e673b2560");
|
||||
}
|
||||
|
||||
public function testResumeAStaleSession() {
|
||||
public function testResumeAStaleSession(): void {
|
||||
$this->assertException("invalid", "User", "ExceptionSession");
|
||||
Arsse::$db->sessionResume("ab3b3eb8a13311e78667001e673b2560");
|
||||
}
|
||||
|
||||
public function testCreateASession() {
|
||||
public function testCreateASession(): void {
|
||||
$user = "jane.doe@example.com";
|
||||
$id = Arsse::$db->sessionCreate($user);
|
||||
$now = time();
|
||||
|
@ -98,13 +98,13 @@ trait SeriesSession {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCreateASessionWithoutAuthority() {
|
||||
public function testCreateASessionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->sessionCreate("jane.doe@example.com");
|
||||
}
|
||||
|
||||
public function testDestroyASession() {
|
||||
public function testDestroyASession(): void {
|
||||
$user = "jane.doe@example.com";
|
||||
$id = "80fa94c1a11f11e78667001e673b2560";
|
||||
$this->assertTrue(Arsse::$db->sessionDestroy($user, $id));
|
||||
|
@ -115,7 +115,7 @@ trait SeriesSession {
|
|||
$this->assertFalse(Arsse::$db->sessionDestroy($user, $id));
|
||||
}
|
||||
|
||||
public function testDestroyAllSessions() {
|
||||
public function testDestroyAllSessions(): void {
|
||||
$user = "jane.doe@example.com";
|
||||
$this->assertTrue(Arsse::$db->sessionDestroy($user));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]);
|
||||
|
@ -125,13 +125,13 @@ trait SeriesSession {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testDestroyASessionForTheWrongUser() {
|
||||
public function testDestroyASessionForTheWrongUser(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$id = "80fa94c1a11f11e78667001e673b2560";
|
||||
$this->assertFalse(Arsse::$db->sessionDestroy($user, $id));
|
||||
}
|
||||
|
||||
public function testDestroyASessionWithoutAuthority() {
|
||||
public function testDestroyASessionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->sessionDestroy("jane.doe@example.com", "80fa94c1a11f11e78667001e673b2560");
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\TestCase\Database;
|
||||
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Test\Database;
|
||||
use JKingWeb\Arsse\Feed\Exception as FeedException;
|
||||
|
||||
trait SeriesSubscription {
|
||||
public function setUpSeriesSubscription() {
|
||||
public function setUpSeriesSubscription(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
|
@ -143,11 +144,11 @@ trait SeriesSubscription {
|
|||
$this->user = "john.doe@example.com";
|
||||
}
|
||||
|
||||
protected function tearDownSeriesSubscription() {
|
||||
protected function tearDownSeriesSubscription(): void {
|
||||
unset($this->data, $this->user);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToAnExistingFeed() {
|
||||
public function testAddASubscriptionToAnExistingFeed(): void {
|
||||
$url = "http://example.com/feed1";
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
|
@ -162,7 +163,7 @@ trait SeriesSubscription {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToANewFeed() {
|
||||
public function testAddASubscriptionToANewFeed(): void {
|
||||
$url = "http://example.org/feed1";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
|
@ -179,7 +180,7 @@ trait SeriesSubscription {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToANewFeedViaDiscovery() {
|
||||
public function testAddASubscriptionToANewFeedViaDiscovery(): void {
|
||||
$url = "http://localhost:8000/Feed/Discovery/Valid";
|
||||
$discovered = "http://localhost:8000/Feed/Discovery/Feed";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
|
@ -197,10 +198,10 @@ trait SeriesSubscription {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToAnInvalidFeed() {
|
||||
public function testAddASubscriptionToAnInvalidFeed(): void {
|
||||
$url = "http://example.org/feed1";
|
||||
$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, $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
$this->assertException("invalidUrl", "Feed");
|
||||
try {
|
||||
Arsse::$db->subscriptionAdd($this->user, $url, "", "", false);
|
||||
|
@ -215,19 +216,19 @@ trait SeriesSubscription {
|
|||
}
|
||||
}
|
||||
|
||||
public function testAddADuplicateSubscription() {
|
||||
public function testAddADuplicateSubscription(): void {
|
||||
$url = "http://example.com/feed2";
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionAdd($this->user, $url);
|
||||
}
|
||||
|
||||
public function testAddADuplicateSubscriptionWithEquivalentUrl() {
|
||||
public function testAddADuplicateSubscriptionWithEquivalentUrl(): void {
|
||||
$url = "http://EXAMPLE.COM/feed2";
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionAdd($this->user, $url);
|
||||
}
|
||||
|
||||
public function testAddADuplicateSubscriptionViaRedirection() {
|
||||
public function testAddADuplicateSubscriptionViaRedirection(): void {
|
||||
$url = "http://localhost:8000/Feed/Parsing/Valid";
|
||||
Arsse::$db->subscriptionAdd($this->user, $url);
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
|
@ -235,14 +236,14 @@ trait SeriesSubscription {
|
|||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url));
|
||||
}
|
||||
|
||||
public function testAddASubscriptionWithoutAuthority() {
|
||||
public function testAddASubscriptionWithoutAuthority(): void {
|
||||
$url = "http://example.com/feed1";
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionAdd($this->user, $url);
|
||||
}
|
||||
|
||||
public function testRemoveASubscription() {
|
||||
public function testRemoveASubscription(): void {
|
||||
$this->assertTrue(Arsse::$db->subscriptionRemove($this->user, 1));
|
||||
\Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionRemove");
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
|
@ -253,29 +254,29 @@ trait SeriesSubscription {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingSubscription() {
|
||||
public function testRemoveAMissingSubscription(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionRemove($this->user, 2112);
|
||||
}
|
||||
|
||||
public function testRemoveAnInvalidSubscription() {
|
||||
public function testRemoveAnInvalidSubscription(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionRemove($this->user, -1);
|
||||
}
|
||||
|
||||
public function testRemoveASubscriptionForTheWrongOwner() {
|
||||
public function testRemoveASubscriptionForTheWrongOwner(): void {
|
||||
$this->user = "jane.doe@example.com";
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionRemove($this->user, 1);
|
||||
}
|
||||
|
||||
public function testRemoveASubscriptionWithoutAuthority() {
|
||||
public function testRemoveASubscriptionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionRemove($this->user, 1);
|
||||
}
|
||||
|
||||
public function testListSubscriptions() {
|
||||
public function testListSubscriptions(): void {
|
||||
$exp = [
|
||||
[
|
||||
'url' => "http://example.com/feed2",
|
||||
|
@ -303,7 +304,7 @@ trait SeriesSubscription {
|
|||
$this->assertArraySubset($exp[1], Arsse::$db->subscriptionPropertiesGet($this->user, 3));
|
||||
}
|
||||
|
||||
public function testListSubscriptionsInAFolder() {
|
||||
public function testListSubscriptionsInAFolder(): void {
|
||||
$exp = [
|
||||
[
|
||||
'url' => "http://example.com/feed2",
|
||||
|
@ -318,7 +319,7 @@ trait SeriesSubscription {
|
|||
$this->assertResult($exp, Arsse::$db->subscriptionList($this->user, null, false));
|
||||
}
|
||||
|
||||
public function testListSubscriptionsWithoutRecursion() {
|
||||
public function testListSubscriptionsWithoutRecursion(): void {
|
||||
$exp = [
|
||||
[
|
||||
'url' => "http://example.com/feed3",
|
||||
|
@ -333,50 +334,50 @@ trait SeriesSubscription {
|
|||
$this->assertResult($exp, Arsse::$db->subscriptionList($this->user, 2));
|
||||
}
|
||||
|
||||
public function testListSubscriptionsInAMissingFolder() {
|
||||
public function testListSubscriptionsInAMissingFolder(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionList($this->user, 4);
|
||||
}
|
||||
|
||||
public function testListSubscriptionsWithoutAuthority() {
|
||||
public function testListSubscriptionsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionList($this->user);
|
||||
}
|
||||
|
||||
public function testCountSubscriptions() {
|
||||
public function testCountSubscriptions(): void {
|
||||
$this->assertSame(2, Arsse::$db->subscriptionCount($this->user));
|
||||
$this->assertSame(1, Arsse::$db->subscriptionCount($this->user, 2));
|
||||
}
|
||||
|
||||
public function testCountSubscriptionsInAMissingFolder() {
|
||||
public function testCountSubscriptionsInAMissingFolder(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionCount($this->user, 4);
|
||||
}
|
||||
|
||||
public function testCountSubscriptionsWithoutAuthority() {
|
||||
public function testCountSubscriptionsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionCount($this->user);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAMissingSubscription() {
|
||||
public function testGetThePropertiesOfAMissingSubscription(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesGet($this->user, 2112);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAnInvalidSubscription() {
|
||||
public function testGetThePropertiesOfAnInvalidSubscription(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesGet($this->user, -1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfASubscriptionWithoutAuthority() {
|
||||
public function testGetThePropertiesOfASubscriptionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionPropertiesGet($this->user, 1);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfASubscription() {
|
||||
public function testSetThePropertiesOfASubscription(): void {
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, [
|
||||
'title' => "Ook Ook",
|
||||
'folder' => 3,
|
||||
|
@ -400,56 +401,56 @@ trait SeriesSubscription {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMoveASubscriptionToAMissingFolder() {
|
||||
public function testMoveASubscriptionToAMissingFolder(): void {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => 4]);
|
||||
}
|
||||
|
||||
public function testMoveASubscriptionToTheRootFolder() {
|
||||
public function testMoveASubscriptionToTheRootFolder(): void {
|
||||
$this->assertTrue(Arsse::$db->subscriptionPropertiesSet($this->user, 3, ['folder' => null]));
|
||||
}
|
||||
|
||||
public function testRenameASubscriptionToABlankTitle() {
|
||||
public function testRenameASubscriptionToABlankTitle(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => ""]);
|
||||
}
|
||||
|
||||
public function testRenameASubscriptionToAWhitespaceTitle() {
|
||||
public function testRenameASubscriptionToAWhitespaceTitle(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => " "]);
|
||||
}
|
||||
|
||||
public function testRenameASubscriptionToFalse() {
|
||||
public function testRenameASubscriptionToFalse(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => false]);
|
||||
}
|
||||
|
||||
public function testRenameASubscriptionToZero() {
|
||||
public function testRenameASubscriptionToZero(): void {
|
||||
$this->assertTrue(Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => 0]));
|
||||
}
|
||||
|
||||
public function testRenameASubscriptionToAnArray() {
|
||||
public function testRenameASubscriptionToAnArray(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => []]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAMissingSubscription() {
|
||||
public function testSetThePropertiesOfAMissingSubscription(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 2112, ['folder' => null]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAnInvalidSubscription() {
|
||||
public function testSetThePropertiesOfAnInvalidSubscription(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, -1, ['folder' => null]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfASubscriptionWithoutAuthority() {
|
||||
public function testSetThePropertiesOfASubscriptionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => null]);
|
||||
}
|
||||
|
||||
public function testRetrieveTheFaviconOfASubscription() {
|
||||
public function testRetrieveTheFaviconOfASubscription(): void {
|
||||
$exp = "http://example.com/favicon.ico";
|
||||
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(1));
|
||||
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(2));
|
||||
|
@ -465,7 +466,7 @@ trait SeriesSubscription {
|
|||
$this->assertSame('', Arsse::$db->subscriptionFavicon(-2112));
|
||||
}
|
||||
|
||||
public function testRetrieveTheFaviconOfASubscriptionWithUser() {
|
||||
public function testRetrieveTheFaviconOfASubscriptionWithUser(): void {
|
||||
$exp = "http://example.com/favicon.ico";
|
||||
$user = "john.doe@example.com";
|
||||
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(1, $user));
|
||||
|
@ -479,7 +480,7 @@ trait SeriesSubscription {
|
|||
$this->assertSame('', Arsse::$db->subscriptionFavicon(4, $user));
|
||||
}
|
||||
|
||||
public function testRetrieveTheFaviconOfASubscriptionWithUserWithoutAuthority() {
|
||||
public function testRetrieveTheFaviconOfASubscriptionWithUserWithoutAuthority(): void {
|
||||
$exp = "http://example.com/favicon.ico";
|
||||
$user = "john.doe@example.com";
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
|
@ -487,36 +488,36 @@ trait SeriesSubscription {
|
|||
Arsse::$db->subscriptionFavicon(-2112, $user);
|
||||
}
|
||||
|
||||
public function testListTheTagsOfASubscription() {
|
||||
public function testListTheTagsOfASubscription(): void {
|
||||
$this->assertEquals([1,2], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1));
|
||||
$this->assertEquals([2], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 3));
|
||||
$this->assertEquals(["Fascinating","Interesting"], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1, true));
|
||||
$this->assertEquals(["Fascinating"], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 3, true));
|
||||
}
|
||||
|
||||
public function testListTheTagsOfAMissingSubscription() {
|
||||
public function testListTheTagsOfAMissingSubscription(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->subscriptionTagsGet($this->user, 101);
|
||||
}
|
||||
|
||||
public function testListTheTagsOfASubscriptionWithoutAuthority() {
|
||||
public function testListTheTagsOfASubscriptionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testGetRefreshTimeOfASubscription() {
|
||||
public function testGetRefreshTimeOfASubscription(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed($user));
|
||||
$this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed($user, 1));
|
||||
}
|
||||
|
||||
public function testGetRefreshTimeOfAMissingSubscription() {
|
||||
public function testGetRefreshTimeOfAMissingSubscription(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
$this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com", 2));
|
||||
}
|
||||
|
||||
public function testGetRefreshTimeOfASubscriptionWithoutAuthority() {
|
||||
public function testGetRefreshTimeOfASubscriptionWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com"));
|
||||
|
|
|
@ -10,7 +10,7 @@ use JKingWeb\Arsse\Arsse;
|
|||
use JKingWeb\Arsse\Database;
|
||||
|
||||
trait SeriesTag {
|
||||
protected function setUpSeriesTag() {
|
||||
protected function setUpSeriesTag(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
|
@ -104,11 +104,11 @@ trait SeriesTag {
|
|||
$this->user = "john.doe@example.com";
|
||||
}
|
||||
|
||||
protected function tearDownSeriesTag() {
|
||||
protected function tearDownSeriesTag(): void {
|
||||
unset($this->data, $this->checkTags, $this->checkMembers, $this->user);
|
||||
}
|
||||
|
||||
public function testAddATag() {
|
||||
public function testAddATag(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$tagID = $this->nextID("arsse_tags");
|
||||
$this->assertSame($tagID, Arsse::$db->tagAdd($user, ['name' => "Entertaining"]));
|
||||
|
@ -118,33 +118,33 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddADuplicateTag() {
|
||||
public function testAddADuplicateTag(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Interesting"]);
|
||||
}
|
||||
|
||||
public function testAddATagWithAMissingName() {
|
||||
public function testAddATagWithAMissingName(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagAdd("john.doe@example.com", []);
|
||||
}
|
||||
|
||||
public function testAddATagWithABlankName() {
|
||||
public function testAddATagWithABlankName(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagAdd("john.doe@example.com", ['name' => ""]);
|
||||
}
|
||||
|
||||
public function testAddATagWithAWhitespaceName() {
|
||||
public function testAddATagWithAWhitespaceName(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagAdd("john.doe@example.com", ['name' => " "]);
|
||||
}
|
||||
|
||||
public function testAddATagWithoutAuthority() {
|
||||
public function testAddATagWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Boring"]);
|
||||
}
|
||||
|
||||
public function testListTags() {
|
||||
public function testListTags(): void {
|
||||
$exp = [
|
||||
['id' => 2, 'name' => "Fascinating"],
|
||||
['id' => 1, 'name' => "Interesting"],
|
||||
|
@ -160,13 +160,13 @@ trait SeriesTag {
|
|||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagList");
|
||||
}
|
||||
|
||||
public function testListTagsWithoutAuthority() {
|
||||
public function testListTagsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagList("john.doe@example.com");
|
||||
}
|
||||
|
||||
public function testRemoveATag() {
|
||||
public function testRemoveATag(): void {
|
||||
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", 1));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
|
@ -174,7 +174,7 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveATagByName() {
|
||||
public function testRemoveATagByName(): void {
|
||||
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", "Interesting", true));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
|
@ -182,33 +182,33 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingTag() {
|
||||
public function testRemoveAMissingTag(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagRemove("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testRemoveAnInvalidTag() {
|
||||
public function testRemoveAnInvalidTag(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagRemove("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testRemoveAnInvalidTagByName() {
|
||||
public function testRemoveAnInvalidTagByName(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagRemove("john.doe@example.com", [], true);
|
||||
}
|
||||
|
||||
public function testRemoveATagOfTheWrongOwner() {
|
||||
public function testRemoveATagOfTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagRemove("john.doe@example.com", 3); // tag ID 3 belongs to Jane
|
||||
}
|
||||
|
||||
public function testRemoveATagWithoutAuthority() {
|
||||
public function testRemoveATagWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagRemove("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfATag() {
|
||||
public function testGetThePropertiesOfATag(): void {
|
||||
$exp = [
|
||||
'id' => 2,
|
||||
'name' => "Fascinating",
|
||||
|
@ -218,37 +218,37 @@ trait SeriesTag {
|
|||
\Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "tagPropertiesGet");
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAMissingTag() {
|
||||
public function testGetThePropertiesOfAMissingTag(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesGet("john.doe@example.com", 2112);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAnInvalidTag() {
|
||||
public function testGetThePropertiesOfAnInvalidTag(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesGet("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfAnInvalidTagByName() {
|
||||
public function testGetThePropertiesOfAnInvalidTagByName(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesGet("john.doe@example.com", [], true);
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfATagOfTheWrongOwner() {
|
||||
public function testGetThePropertiesOfATagOfTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesGet("john.doe@example.com", 3); // tag ID 3 belongs to Jane
|
||||
}
|
||||
|
||||
public function testGetThePropertiesOfATagWithoutAuthority() {
|
||||
public function testGetThePropertiesOfATagWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagPropertiesGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testMakeNoChangesToATag() {
|
||||
public function testMakeNoChangesToATag(): void {
|
||||
$this->assertFalse(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, []));
|
||||
}
|
||||
|
||||
public function testRenameATag() {
|
||||
public function testRenameATag(): void {
|
||||
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
|
@ -256,7 +256,7 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameATagByName() {
|
||||
public function testRenameATagByName(): void {
|
||||
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
|
@ -264,53 +264,53 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameATagToTheEmptyString() {
|
||||
public function testRenameATagToTheEmptyString(): void {
|
||||
$this->assertException("missing", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => ""]));
|
||||
}
|
||||
|
||||
public function testRenameATagToWhitespaceOnly() {
|
||||
public function testRenameATagToWhitespaceOnly(): void {
|
||||
$this->assertException("whitespace", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => " "]));
|
||||
}
|
||||
|
||||
public function testRenameATagToAnInvalidValue() {
|
||||
public function testRenameATagToAnInvalidValue(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => []]));
|
||||
}
|
||||
|
||||
public function testCauseATagCollision() {
|
||||
public function testCauseATagCollision(): void {
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAMissingTag() {
|
||||
public function testSetThePropertiesOfAMissingTag(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAnInvalidTag() {
|
||||
public function testSetThePropertiesOfAnInvalidTag(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfAnInvalidTagByName() {
|
||||
public function testSetThePropertiesOfAnInvalidTagByName(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true);
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfATagForTheWrongOwner() {
|
||||
public function testSetThePropertiesOfATagForTheWrongOwner(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // tag ID 3 belongs to Jane
|
||||
}
|
||||
|
||||
public function testSetThePropertiesOfATagWithoutAuthority() {
|
||||
public function testSetThePropertiesOfATagWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]);
|
||||
}
|
||||
|
||||
public function testListTaggedSubscriptions() {
|
||||
public function testListTaggedSubscriptions(): void {
|
||||
$exp = [1,5];
|
||||
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1));
|
||||
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Interesting", true));
|
||||
|
@ -322,23 +322,23 @@ trait SeriesTag {
|
|||
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Lonely", true));
|
||||
}
|
||||
|
||||
public function testListTaggedSubscriptionsForAMissingTag() {
|
||||
public function testListTaggedSubscriptionsForAMissingTag(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 3);
|
||||
}
|
||||
|
||||
public function testListTaggedSubscriptionsForAnInvalidTag() {
|
||||
public function testListTaggedSubscriptionsForAnInvalidTag(): void {
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", -1);
|
||||
}
|
||||
|
||||
public function testListTaggedSubscriptionsWithoutAuthority() {
|
||||
public function testListTaggedSubscriptionsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1);
|
||||
}
|
||||
|
||||
public function testApplyATagToSubscriptions() {
|
||||
public function testApplyATagToSubscriptions(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][1][2] = 1;
|
||||
|
@ -346,14 +346,14 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearATagFromSubscriptions() {
|
||||
public function testClearATagFromSubscriptions(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [1,3], Database::ASSOC_REMOVE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyATagToSubscriptionsByName() {
|
||||
public function testApplyATagToSubscriptionsByName(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [3,4], Database::ASSOC_ADD, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][1][2] = 1;
|
||||
|
@ -361,26 +361,26 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearATagFromSubscriptionsByName() {
|
||||
public function testClearATagFromSubscriptionsByName(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [1,3], Database::ASSOC_REMOVE, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyATagToNoSubscriptionsByName() {
|
||||
public function testApplyATagToNoSubscriptionsByName(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_ADD, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearATagFromNoSubscriptionsByName() {
|
||||
public function testClearATagFromNoSubscriptionsByName(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_REMOVE, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testReplaceSubscriptionsOfATag() {
|
||||
public function testReplaceSubscriptionsOfATag(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4], Database::ASSOC_REPLACE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
|
@ -390,7 +390,7 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testPurgeSubscriptionsOfATag() {
|
||||
public function testPurgeSubscriptionsOfATag(): void {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [], Database::ASSOC_REPLACE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
|
@ -398,13 +398,13 @@ trait SeriesTag {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyATagToSubscriptionsWithoutAuthority() {
|
||||
public function testApplyATagToSubscriptionsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]);
|
||||
}
|
||||
|
||||
public function testSummarizeTags() {
|
||||
public function testSummarizeTags(): void {
|
||||
$exp = [
|
||||
['id' => 1, 'name' => "Interesting", 'subscription' => 1],
|
||||
['id' => 1, 'name' => "Interesting", 'subscription' => 5],
|
||||
|
@ -415,7 +415,7 @@ trait SeriesTag {
|
|||
$this->assertResult($exp, Arsse::$db->tagSummarize("john.doe@example.com"));
|
||||
}
|
||||
|
||||
public function testSummarizeTagsWithoutAuthority() {
|
||||
public function testSummarizeTagsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tagSummarize("john.doe@example.com");
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SeriesToken {
|
||||
protected function setUpSeriesToken() {
|
||||
protected function setUpSeriesToken(): void {
|
||||
// set up the test data
|
||||
$past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute"));
|
||||
$future = gmdate("Y-m-d H:i:s", strtotime("now + 1 minute"));
|
||||
|
@ -43,11 +43,11 @@ trait SeriesToken {
|
|||
];
|
||||
}
|
||||
|
||||
protected function tearDownSeriesToken() {
|
||||
protected function tearDownSeriesToken(): void {
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
public function testLookUpAValidToken() {
|
||||
public function testLookUpAValidToken(): void {
|
||||
$exp1 = [
|
||||
'id' => "80fa94c1a11f11e78667001e673b2560",
|
||||
'class' => "fever.login",
|
||||
|
@ -71,22 +71,22 @@ trait SeriesToken {
|
|||
$this->assertArraySubset($exp1, Arsse::$db->tokenLookup("fever.login", "80fa94c1a11f11e78667001e673b2560"));
|
||||
}
|
||||
|
||||
public function testLookUpAMissingToken() {
|
||||
public function testLookUpAMissingToken(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tokenLookup("class", "thisTokenDoesNotExist");
|
||||
}
|
||||
|
||||
public function testLookUpAnExpiredToken() {
|
||||
public function testLookUpAnExpiredToken(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tokenLookup("fever.login", "27c6de8da13311e78667001e673b2560");
|
||||
}
|
||||
|
||||
public function testLookUpATokenOfTheWrongClass() {
|
||||
public function testLookUpATokenOfTheWrongClass(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->tokenLookup("some.class", "80fa94c1a11f11e78667001e673b2560");
|
||||
}
|
||||
|
||||
public function testCreateAToken() {
|
||||
public function testCreateAToken(): void {
|
||||
$user = "jane.doe@example.com";
|
||||
$state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "class", "expires", "user"]]);
|
||||
$id = Arsse::$db->tokenCreate($user, "fever.login");
|
||||
|
@ -100,18 +100,18 @@ trait SeriesToken {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCreateATokenForAMissingUser() {
|
||||
public function testCreateATokenForAMissingUser(): void {
|
||||
$this->assertException("doesNotExist", "User");
|
||||
Arsse::$db->tokenCreate("fever.login", "jane.doe@example.biz");
|
||||
}
|
||||
|
||||
public function testCreateATokenWithoutAuthority() {
|
||||
public function testCreateATokenWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tokenCreate("fever.login", "jane.doe@example.com");
|
||||
}
|
||||
|
||||
public function testRevokeAToken() {
|
||||
public function testRevokeAToken(): void {
|
||||
$user = "jane.doe@example.com";
|
||||
$id = "80fa94c1a11f11e78667001e673b2560";
|
||||
$this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login", $id));
|
||||
|
@ -122,7 +122,7 @@ trait SeriesToken {
|
|||
$this->assertFalse(Arsse::$db->tokenRevoke($user, "fever.login", $id));
|
||||
}
|
||||
|
||||
public function testRevokeAllTokens() {
|
||||
public function testRevokeAllTokens(): void {
|
||||
$user = "jane.doe@example.com";
|
||||
$state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "expires", "user"]]);
|
||||
$this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login"));
|
||||
|
@ -136,7 +136,7 @@ trait SeriesToken {
|
|||
$this->assertFalse(Arsse::$db->tokenRevoke($user, "unknown.class"));
|
||||
}
|
||||
|
||||
public function testRevokeATokenWithoutAuthority() {
|
||||
public function testRevokeATokenWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->tokenRevoke("jane.doe@example.com", "fever.login");
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SeriesUser {
|
||||
protected function setUpSeriesUser() {
|
||||
protected function setUpSeriesUser(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
|
@ -25,11 +25,11 @@ trait SeriesUser {
|
|||
];
|
||||
}
|
||||
|
||||
protected function tearDownSeriesUser() {
|
||||
protected function tearDownSeriesUser(): void {
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
public function testCheckThatAUserExists() {
|
||||
public function testCheckThatAUserExists(): void {
|
||||
$this->assertTrue(Arsse::$db->userExists("jane.doe@example.com"));
|
||||
$this->assertFalse(Arsse::$db->userExists("jane.doe@example.org"));
|
||||
\Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "userExists");
|
||||
|
@ -37,31 +37,31 @@ trait SeriesUser {
|
|||
$this->compareExpectations(static::$drv, $this->data);
|
||||
}
|
||||
|
||||
public function testCheckThatAUserExistsWithoutAuthority() {
|
||||
public function testCheckThatAUserExistsWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->userExists("jane.doe@example.com");
|
||||
}
|
||||
|
||||
public function testGetAPassword() {
|
||||
public function testGetAPassword(): void {
|
||||
$hash = Arsse::$db->userPasswordGet("admin@example.net");
|
||||
$this->assertSame('$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', $hash);
|
||||
\Phake::verify(Arsse::$user)->authorize("admin@example.net", "userPasswordGet");
|
||||
$this->assertTrue(password_verify("secret", $hash));
|
||||
}
|
||||
|
||||
public function testGetThePasswordOfAMissingUser() {
|
||||
public function testGetThePasswordOfAMissingUser(): void {
|
||||
$this->assertException("doesNotExist", "User");
|
||||
Arsse::$db->userPasswordGet("john.doe@example.org");
|
||||
}
|
||||
|
||||
public function testGetAPasswordWithoutAuthority() {
|
||||
public function testGetAPasswordWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->userPasswordGet("admin@example.net");
|
||||
}
|
||||
|
||||
public function testAddANewUser() {
|
||||
public function testAddANewUser(): void {
|
||||
$this->assertTrue(Arsse::$db->userAdd("john.doe@example.org", ""));
|
||||
\Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userAdd");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
|
||||
|
@ -69,18 +69,18 @@ trait SeriesUser {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddAnExistingUser() {
|
||||
public function testAddAnExistingUser(): void {
|
||||
$this->assertException("alreadyExists", "User");
|
||||
Arsse::$db->userAdd("john.doe@example.com", "");
|
||||
}
|
||||
|
||||
public function testAddANewUserWithoutAuthority() {
|
||||
public function testAddANewUserWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->userAdd("john.doe@example.org", "");
|
||||
}
|
||||
|
||||
public function testRemoveAUser() {
|
||||
public function testRemoveAUser(): void {
|
||||
$this->assertTrue(Arsse::$db->userRemove("admin@example.net"));
|
||||
\Phake::verify(Arsse::$user)->authorize("admin@example.net", "userRemove");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
|
||||
|
@ -88,24 +88,24 @@ trait SeriesUser {
|
|||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingUser() {
|
||||
public function testRemoveAMissingUser(): void {
|
||||
$this->assertException("doesNotExist", "User");
|
||||
Arsse::$db->userRemove("john.doe@example.org");
|
||||
}
|
||||
|
||||
public function testRemoveAUserWithoutAuthority() {
|
||||
public function testRemoveAUserWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->userRemove("admin@example.net");
|
||||
}
|
||||
|
||||
public function testListAllUsers() {
|
||||
public function testListAllUsers(): void {
|
||||
$users = ["admin@example.net", "jane.doe@example.com", "john.doe@example.com"];
|
||||
$this->assertSame($users, Arsse::$db->userList());
|
||||
\Phake::verify(Arsse::$user)->authorize("", "userList");
|
||||
}
|
||||
|
||||
public function testListAllUsersWithoutAuthority() {
|
||||
public function testListAllUsersWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->userList();
|
||||
|
@ -114,7 +114,7 @@ trait SeriesUser {
|
|||
/**
|
||||
* @depends testGetAPassword
|
||||
*/
|
||||
public function testSetAPassword() {
|
||||
public function testSetAPassword(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$pass = "secret";
|
||||
$this->assertEquals("", Arsse::$db->userPasswordGet($user));
|
||||
|
@ -125,19 +125,19 @@ trait SeriesUser {
|
|||
$this->assertTrue(password_verify($pass, $hash), "Failed verifying password of $user '$pass' against hash '$hash'.");
|
||||
}
|
||||
|
||||
public function testUnsetAPassword() {
|
||||
public function testUnsetAPassword(): void {
|
||||
$user = "john.doe@example.com";
|
||||
$this->assertEquals("", Arsse::$db->userPasswordGet($user));
|
||||
$this->assertTrue(Arsse::$db->userPasswordSet($user, null));
|
||||
$this->assertNull(Arsse::$db->userPasswordGet($user));
|
||||
}
|
||||
|
||||
public function testSetThePasswordOfAMissingUser() {
|
||||
public function testSetThePasswordOfAMissingUser(): void {
|
||||
$this->assertException("doesNotExist", "User");
|
||||
Arsse::$db->userPasswordSet("john.doe@example.org", "secret");
|
||||
}
|
||||
|
||||
public function testSetAPasswordWithoutAuthority() {
|
||||
public function testSetAPasswordWithoutAuthority(): void {
|
||||
\Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->userPasswordSet("john.doe@example.com", "secret");
|
||||
|
|
|
@ -28,7 +28,7 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideInClauses */
|
||||
public function testGenerateInClause(string $clause, array $values, array $inV, string $inT) {
|
||||
public function testGenerateInClause(string $clause, array $values, array $inV, string $inT): void {
|
||||
$types = array_fill(0, sizeof($values), $inT);
|
||||
$exp = [$clause, $types, $values];
|
||||
$this->assertSame($exp, $this->db->generateIn($inV, $inT));
|
||||
|
@ -62,7 +62,7 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideSearchClauses */
|
||||
public function testGenerateSearchClause(string $clause, array $values, array $inV, array $inC, bool $inAny) {
|
||||
public function testGenerateSearchClause(string $clause, array $values, array $inV, array $inC, bool $inAny): void {
|
||||
// this is not an exhaustive test; integration tests already cover the ins and outs of the functionality
|
||||
$types = array_fill(0, sizeof($values), "str");
|
||||
$exp = [$clause, $types, $values];
|
||||
|
|
|
@ -76,112 +76,112 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
# TESTS
|
||||
|
||||
public function testFetchDriverName() {
|
||||
public function testFetchDriverName(): void {
|
||||
$class = get_class($this->drv);
|
||||
$this->assertTrue(strlen($class::driverName()) > 0);
|
||||
}
|
||||
|
||||
public function testFetchSchemaId() {
|
||||
public function testFetchSchemaId(): void {
|
||||
$class = get_class($this->drv);
|
||||
$this->assertTrue(strlen($class::schemaID()) > 0);
|
||||
}
|
||||
|
||||
public function testCheckCharacterSetAcceptability() {
|
||||
public function testCheckCharacterSetAcceptability(): void {
|
||||
$this->assertTrue($this->drv->charsetAcceptable());
|
||||
}
|
||||
|
||||
public function testTranslateAToken() {
|
||||
public function testTranslateAToken(): void {
|
||||
$this->assertRegExp("/^[a-z][a-z0-9]*$/i", $this->drv->sqlToken("greatest"));
|
||||
$this->assertRegExp("/^\"?[a-z][a-z0-9_\-]*\"?$/i", $this->drv->sqlToken("nocase"));
|
||||
$this->assertRegExp("/^[a-z][a-z0-9]*$/i", $this->drv->sqlToken("like"));
|
||||
$this->assertSame("distinct", $this->drv->sqlToken("distinct"));
|
||||
}
|
||||
|
||||
public function testExecAValidStatement() {
|
||||
public function testExecAValidStatement(): void {
|
||||
$this->assertTrue($this->drv->exec($this->create));
|
||||
}
|
||||
|
||||
public function testExecAnInvalidStatement() {
|
||||
public function testExecAnInvalidStatement(): void {
|
||||
$this->assertException("engineErrorGeneral", "Db");
|
||||
$this->drv->exec("And the meek shall inherit the earth...");
|
||||
}
|
||||
|
||||
public function testExecMultipleStatements() {
|
||||
public function testExecMultipleStatements(): void {
|
||||
$this->assertTrue($this->drv->exec("$this->create; INSERT INTO arsse_test(id) values(2112)"));
|
||||
$this->assertEquals(2112, $this->query("SELECT id from arsse_test"));
|
||||
}
|
||||
|
||||
public function testExecTimeout() {
|
||||
public function testExecTimeout(): void {
|
||||
$this->exec($this->create);
|
||||
$this->exec($this->lock);
|
||||
$this->assertException("general", "Db", "ExceptionTimeout");
|
||||
$this->drv->exec("INSERT INTO arsse_meta(\"key\", value) values('lock', '1')");
|
||||
}
|
||||
|
||||
public function testExecConstraintViolation() {
|
||||
public function testExecConstraintViolation(): void {
|
||||
$this->drv->exec("CREATE TABLE arsse_test(id varchar(255) not null)");
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
$this->drv->exec(static::$insertDefaultValues);
|
||||
}
|
||||
|
||||
public function testExecTypeViolation() {
|
||||
public function testExecTypeViolation(): void {
|
||||
$this->drv->exec($this->create);
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
$this->drv->exec("INSERT INTO arsse_test(id) values('ook')");
|
||||
}
|
||||
|
||||
public function testMakeAValidQuery() {
|
||||
public function testMakeAValidQuery(): void {
|
||||
$this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1"));
|
||||
}
|
||||
|
||||
public function testMakeAnInvalidQuery() {
|
||||
public function testMakeAnInvalidQuery(): void {
|
||||
$this->assertException("engineErrorGeneral", "Db");
|
||||
$this->drv->query("Apollo was astonished; Dionysus thought me mad");
|
||||
}
|
||||
|
||||
public function testQueryConstraintViolation() {
|
||||
public function testQueryConstraintViolation(): void {
|
||||
$this->drv->exec("CREATE TABLE arsse_test(id integer not null)");
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
$this->drv->query(static::$insertDefaultValues);
|
||||
}
|
||||
|
||||
public function testQueryTypeViolation() {
|
||||
public function testQueryTypeViolation(): void {
|
||||
$this->drv->exec($this->create);
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
$this->drv->query("INSERT INTO arsse_test(id) values('ook')");
|
||||
}
|
||||
|
||||
public function testPrepareAValidQuery() {
|
||||
public function testPrepareAValidQuery(): void {
|
||||
$s = $this->drv->prepare("SELECT ?, ?", "int", "int");
|
||||
$this->assertInstanceOf(Statement::class, $s);
|
||||
}
|
||||
|
||||
public function testPrepareAnInvalidQuery() {
|
||||
public function testPrepareAnInvalidQuery(): void {
|
||||
$this->assertException("engineErrorGeneral", "Db");
|
||||
$s = $this->drv->prepare("This is an invalid query", "int", "int")->run();
|
||||
}
|
||||
|
||||
public function testCreateASavepoint() {
|
||||
public function testCreateASavepoint(): void {
|
||||
$this->assertEquals(1, $this->drv->savepointCreate());
|
||||
$this->assertEquals(2, $this->drv->savepointCreate());
|
||||
$this->assertEquals(3, $this->drv->savepointCreate());
|
||||
}
|
||||
|
||||
public function testReleaseASavepoint() {
|
||||
public function testReleaseASavepoint(): void {
|
||||
$this->assertEquals(1, $this->drv->savepointCreate());
|
||||
$this->assertEquals(true, $this->drv->savepointRelease());
|
||||
$this->assertException("savepointInvalid", "Db");
|
||||
$this->drv->savepointRelease();
|
||||
}
|
||||
|
||||
public function testUndoASavepoint() {
|
||||
public function testUndoASavepoint(): void {
|
||||
$this->assertEquals(1, $this->drv->savepointCreate());
|
||||
$this->assertEquals(true, $this->drv->savepointUndo());
|
||||
$this->assertException("savepointInvalid", "Db");
|
||||
$this->drv->savepointUndo();
|
||||
}
|
||||
|
||||
public function testManipulateSavepoints() {
|
||||
public function testManipulateSavepoints(): void {
|
||||
$this->assertEquals(1, $this->drv->savepointCreate());
|
||||
$this->assertEquals(2, $this->drv->savepointCreate());
|
||||
$this->assertEquals(3, $this->drv->savepointCreate());
|
||||
|
@ -198,7 +198,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->drv->savepointRelease(2);
|
||||
}
|
||||
|
||||
public function testManipulateSavepointsSomeMore() {
|
||||
public function testManipulateSavepointsSomeMore(): void {
|
||||
$this->assertEquals(1, $this->drv->savepointCreate());
|
||||
$this->assertEquals(2, $this->drv->savepointCreate());
|
||||
$this->assertEquals(3, $this->drv->savepointCreate());
|
||||
|
@ -209,7 +209,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->drv->savepointUndo(2);
|
||||
}
|
||||
|
||||
public function testBeginATransaction() {
|
||||
public function testBeginATransaction(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr = $this->drv->begin();
|
||||
|
@ -221,7 +221,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(0, $this->query($select));
|
||||
}
|
||||
|
||||
public function testCommitATransaction() {
|
||||
public function testCommitATransaction(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr = $this->drv->begin();
|
||||
|
@ -233,7 +233,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(1, $this->query($select));
|
||||
}
|
||||
|
||||
public function testRollbackATransaction() {
|
||||
public function testRollbackATransaction(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr = $this->drv->begin();
|
||||
|
@ -245,7 +245,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(0, $this->query($select));
|
||||
}
|
||||
|
||||
public function testBeginChainedTransactions() {
|
||||
public function testBeginChainedTransactions(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr1 = $this->drv->begin();
|
||||
|
@ -258,7 +258,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(0, $this->query($select));
|
||||
}
|
||||
|
||||
public function testCommitChainedTransactions() {
|
||||
public function testCommitChainedTransactions(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr1 = $this->drv->begin();
|
||||
|
@ -275,7 +275,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(2, $this->query($select));
|
||||
}
|
||||
|
||||
public function testCommitChainedTransactionsOutOfOrder() {
|
||||
public function testCommitChainedTransactionsOutOfOrder(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr1 = $this->drv->begin();
|
||||
|
@ -291,7 +291,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$tr2->commit();
|
||||
}
|
||||
|
||||
public function testRollbackChainedTransactions() {
|
||||
public function testRollbackChainedTransactions(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr1 = $this->drv->begin();
|
||||
|
@ -310,7 +310,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(0, $this->query($select));
|
||||
}
|
||||
|
||||
public function testRollbackChainedTransactionsOutOfOrder() {
|
||||
public function testRollbackChainedTransactionsOutOfOrder(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr1 = $this->drv->begin();
|
||||
|
@ -329,7 +329,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(0, $this->query($select));
|
||||
}
|
||||
|
||||
public function testPartiallyRollbackChainedTransactions() {
|
||||
public function testPartiallyRollbackChainedTransactions(): void {
|
||||
$select = "SELECT count(*) FROM arsse_test";
|
||||
$this->drv->exec($this->create);
|
||||
$tr1 = $this->drv->begin();
|
||||
|
@ -348,7 +348,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(1, $this->query($select));
|
||||
}
|
||||
|
||||
public function testFetchSchemaVersion() {
|
||||
public function testFetchSchemaVersion(): void {
|
||||
$this->assertSame(0, $this->drv->schemaVersion());
|
||||
$this->drv->exec(str_replace("#", "1", $this->setVersion));
|
||||
$this->assertSame(1, $this->drv->schemaVersion());
|
||||
|
@ -361,7 +361,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($exp, $this->drv->schemaVersion());
|
||||
}
|
||||
|
||||
public function testLockTheDatabase() {
|
||||
public function testLockTheDatabase(): void {
|
||||
// PostgreSQL doesn't actually lock the whole database, only the metadata table
|
||||
// normally the application will first query this table to ensure the schema version is correct,
|
||||
// so the effect is usually the same
|
||||
|
@ -370,7 +370,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->exec($this->lock);
|
||||
}
|
||||
|
||||
public function testUnlockTheDatabase() {
|
||||
public function testUnlockTheDatabase(): void {
|
||||
$this->drv->savepointCreate(true);
|
||||
$this->drv->savepointRelease();
|
||||
$this->drv->savepointCreate(true);
|
||||
|
@ -378,11 +378,11 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertTrue($this->exec(str_replace("#", "3", $this->setVersion)));
|
||||
}
|
||||
|
||||
public function testProduceAStringLiteral() {
|
||||
public function testProduceAStringLiteral(): void {
|
||||
$this->assertSame("'It''s a string!'", $this->drv->literalString("It's a string!"));
|
||||
}
|
||||
|
||||
public function testPerformMaintenance() {
|
||||
public function testPerformMaintenance(): void {
|
||||
// this performs maintenance in the absence of tables; see BaseUpdate.php for another test with tables
|
||||
$this->assertTrue($this->drv->maintenance());
|
||||
}
|
||||
|
|
|
@ -46,18 +46,18 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testConstructResult() {
|
||||
public function testConstructResult(): void {
|
||||
$this->assertInstanceOf(Result::class, new $this->resultClass(...$this->makeResult("SELECT 1")));
|
||||
}
|
||||
|
||||
public function testGetChangeCountAndLastInsertId() {
|
||||
public function testGetChangeCountAndLastInsertId(): void {
|
||||
$this->makeResult(static::$createMeta);
|
||||
$r = new $this->resultClass(...$this->makeResult("INSERT INTO arsse_meta(\"key\",value) values('test', 1)"));
|
||||
$this->assertSame(1, $r->changes());
|
||||
$this->assertSame(0, $r->lastId());
|
||||
}
|
||||
|
||||
public function testGetChangeCountAndLastInsertIdBis() {
|
||||
public function testGetChangeCountAndLastInsertIdBis(): void {
|
||||
$this->makeResult(static::$createTest);
|
||||
$r = new $this->resultClass(...$this->makeResult(static::$insertDefault));
|
||||
$this->assertSame(1, $r->changes());
|
||||
|
@ -67,7 +67,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(2, $r->lastId());
|
||||
}
|
||||
|
||||
public function testIterateOverResults() {
|
||||
public function testIterateOverResults(): void {
|
||||
$exp = [0 => 1, 1 => 2, 2 => 3];
|
||||
$exp = static::$stringOutput ? $this->stringify($exp) : $exp;
|
||||
foreach (new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) {
|
||||
|
@ -76,7 +76,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($exp, $rows);
|
||||
}
|
||||
|
||||
public function testIterateOverResultsTwice() {
|
||||
public function testIterateOverResultsTwice(): void {
|
||||
$exp = [0 => 1, 1 => 2, 2 => 3];
|
||||
$exp = static::$stringOutput ? $this->stringify($exp) : $exp;
|
||||
$result = new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col"));
|
||||
|
@ -90,7 +90,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testGetSingleValues() {
|
||||
public function testGetSingleValues(): void {
|
||||
$exp = [1867, 1970, 2112];
|
||||
$exp = static::$stringOutput ? $this->stringify($exp) : $exp;
|
||||
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year union all select 1970 as year union all select 2112 as year"));
|
||||
|
@ -100,7 +100,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(null, $test->getValue());
|
||||
}
|
||||
|
||||
public function testGetFirstValuesOnly() {
|
||||
public function testGetFirstValuesOnly(): void {
|
||||
$exp = [1867, 1970, 2112];
|
||||
$exp = static::$stringOutput ? $this->stringify($exp) : $exp;
|
||||
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year, 19 as century union all select 1970 as year, 20 as century union all select 2112 as year, 22 as century"));
|
||||
|
@ -110,7 +110,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(null, $test->getValue());
|
||||
}
|
||||
|
||||
public function testGetRows() {
|
||||
public function testGetRows(): void {
|
||||
$exp = [
|
||||
['album' => '2112', 'track' => '2112'],
|
||||
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
||||
|
@ -121,7 +121,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(null, $test->getRow());
|
||||
}
|
||||
|
||||
public function testGetAllRows() {
|
||||
public function testGetAllRows(): void {
|
||||
$exp = [
|
||||
['album' => '2112', 'track' => '2112'],
|
||||
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
||||
|
|
|
@ -46,12 +46,12 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testConstructStatement() {
|
||||
public function testConstructStatement(): void {
|
||||
$this->assertInstanceOf(Statement::class, new $this->statementClass(...$this->makeStatement("SELECT ? as value")));
|
||||
}
|
||||
|
||||
/** @dataProvider provideBindings */
|
||||
public function testBindATypedValue($value, string $type, string $exp) {
|
||||
public function testBindATypedValue($value, string $type, string $exp): void {
|
||||
if ($exp === "null") {
|
||||
$query = "SELECT (? is null) as pass";
|
||||
} else {
|
||||
|
@ -65,7 +65,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideBinaryBindings */
|
||||
public function testHandleBinaryData($value, string $type, string $exp) {
|
||||
public function testHandleBinaryData($value, string $type, string $exp): void {
|
||||
if (in_array(static::$implementation, ["PostgreSQL", "PDO PostgreSQL"])) {
|
||||
$this->markTestIncomplete("Correct handling of binary data with PostgreSQL is not currently implemented");
|
||||
}
|
||||
|
@ -81,13 +81,13 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertTrue((bool) $act);
|
||||
}
|
||||
|
||||
public function testBindMissingValue() {
|
||||
public function testBindMissingValue(): void {
|
||||
$s = new $this->statementClass(...$this->makeStatement("SELECT ? as value", ["int"]));
|
||||
$val = $s->runArray()->getRow()['value'];
|
||||
$this->assertSame(null, $val);
|
||||
}
|
||||
|
||||
public function testBindMultipleValues() {
|
||||
public function testBindMultipleValues(): void {
|
||||
$exp = [
|
||||
'one' => "A",
|
||||
'two' => "B",
|
||||
|
@ -97,7 +97,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($exp, $val);
|
||||
}
|
||||
|
||||
public function testBindRecursively() {
|
||||
public function testBindRecursively(): void {
|
||||
$exp = [
|
||||
'one' => "A",
|
||||
'two' => "B",
|
||||
|
@ -109,20 +109,20 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($exp, $val);
|
||||
}
|
||||
|
||||
public function testBindWithoutType() {
|
||||
public function testBindWithoutType(): void {
|
||||
$this->assertException("paramTypeMissing", "Db");
|
||||
$s = new $this->statementClass(...$this->makeStatement("SELECT ? as value", []));
|
||||
$s->runArray([1]);
|
||||
}
|
||||
|
||||
public function testViolateConstraint() {
|
||||
public function testViolateConstraint(): void {
|
||||
(new $this->statementClass(...$this->makeStatement("CREATE TABLE if not exists arsse_meta(\"key\" varchar(255) primary key not null, value text)")))->run();
|
||||
$s = new $this->statementClass(...$this->makeStatement("INSERT INTO arsse_meta(\"key\") values(?)", ["str"]));
|
||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||
$s->runArray([null]);
|
||||
}
|
||||
|
||||
public function testMismatchTypes() {
|
||||
public function testMismatchTypes(): void {
|
||||
(new $this->statementClass(...$this->makeStatement("CREATE TABLE if not exists arsse_feeds(id integer primary key not null, url text not null)")))->run();
|
||||
$s = new $this->statementClass(...$this->makeStatement("INSERT INTO arsse_feeds(id,url) values(?,?)", ["str", "str"]));
|
||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||
|
|
|
@ -58,43 +58,43 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testLoadMissingFile() {
|
||||
public function testLoadMissingFile(): void {
|
||||
$this->assertException("updateFileMissing", "Db");
|
||||
$this->drv->schemaUpdate(1, $this->base);
|
||||
}
|
||||
|
||||
public function testLoadUnreadableFile() {
|
||||
public function testLoadUnreadableFile(): void {
|
||||
touch($this->path."0.sql");
|
||||
chmod($this->path."0.sql", 0000);
|
||||
$this->assertException("updateFileUnreadable", "Db");
|
||||
$this->drv->schemaUpdate(1, $this->base);
|
||||
}
|
||||
|
||||
public function testLoadCorruptFile() {
|
||||
public function testLoadCorruptFile(): void {
|
||||
file_put_contents($this->path."0.sql", "This is a corrupt file");
|
||||
$this->assertException("updateFileError", "Db");
|
||||
$this->drv->schemaUpdate(1, $this->base);
|
||||
}
|
||||
|
||||
public function testLoadIncompleteFile() {
|
||||
public function testLoadIncompleteFile(): void {
|
||||
file_put_contents($this->path."0.sql", "create table arsse_meta(\"key\" varchar(255) primary key not null, value text);");
|
||||
$this->assertException("updateFileIncomplete", "Db");
|
||||
$this->drv->schemaUpdate(1, $this->base);
|
||||
}
|
||||
|
||||
public function testLoadEmptyFile() {
|
||||
public function testLoadEmptyFile(): void {
|
||||
file_put_contents($this->path."0.sql", "");
|
||||
$this->assertException("updateFileIncomplete", "Db");
|
||||
$this->drv->schemaUpdate(1, $this->base);
|
||||
}
|
||||
|
||||
public function testLoadCorrectFile() {
|
||||
public function testLoadCorrectFile(): void {
|
||||
file_put_contents($this->path."0.sql", static::$minimal1);
|
||||
$this->drv->schemaUpdate(1, $this->base);
|
||||
$this->assertEquals(1, $this->drv->schemaVersion());
|
||||
}
|
||||
|
||||
public function testPerformPartialUpdate() {
|
||||
public function testPerformPartialUpdate(): void {
|
||||
file_put_contents($this->path."0.sql", static::$minimal1);
|
||||
file_put_contents($this->path."1.sql", "UPDATE arsse_meta set value = '1' where \"key\" = 'schema_version'");
|
||||
$this->assertException("updateFileIncomplete", "Db");
|
||||
|
@ -106,31 +106,31 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testPerformSequentialUpdate() {
|
||||
public function testPerformSequentialUpdate(): void {
|
||||
file_put_contents($this->path."0.sql", static::$minimal1);
|
||||
file_put_contents($this->path."1.sql", static::$minimal2);
|
||||
$this->drv->schemaUpdate(2, $this->base);
|
||||
$this->assertEquals(2, $this->drv->schemaVersion());
|
||||
}
|
||||
|
||||
public function testPerformActualUpdate() {
|
||||
public function testPerformActualUpdate(): void {
|
||||
$this->drv->schemaUpdate(Database::SCHEMA_VERSION);
|
||||
$this->assertEquals(Database::SCHEMA_VERSION, $this->drv->schemaVersion());
|
||||
}
|
||||
|
||||
public function testDeclineManualUpdate() {
|
||||
public function testDeclineManualUpdate(): void {
|
||||
// turn auto-updating off
|
||||
Arsse::$conf->dbAutoUpdate = false;
|
||||
$this->assertException("updateManual", "Db");
|
||||
$this->drv->schemaUpdate(Database::SCHEMA_VERSION);
|
||||
}
|
||||
|
||||
public function testDeclineDowngrade() {
|
||||
public function testDeclineDowngrade(): void {
|
||||
$this->assertException("updateTooNew", "Db");
|
||||
$this->drv->schemaUpdate(-1, $this->base);
|
||||
}
|
||||
|
||||
public function testPerformMaintenance() {
|
||||
public function testPerformMaintenance(): void {
|
||||
$this->drv->schemaUpdate(Database::SCHEMA_VERSION);
|
||||
$this->assertTrue($this->drv->maintenance());
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testFailToConnect() {
|
||||
public function testFailToConnect(): void {
|
||||
// for the sake of simplicity we don't distinguish between failure modes, but the MySQL-supplied error messages do
|
||||
self::setConf([
|
||||
'dbMySQLHost' => "example.invalid",
|
||||
|
|
|
@ -34,7 +34,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement {
|
|||
}
|
||||
}
|
||||
|
||||
public function testBindLongString() {
|
||||
public function testBindLongString(): void {
|
||||
// this test requires some set-up to be effective
|
||||
static::$interface->query("CREATE TABLE arsse_test(`value` longtext not null) character set utf8mb4");
|
||||
// we'll use an unrealistic packet size of 1 byte to trigger special handling for strings which are too long for the maximum packet size
|
||||
|
|
|
@ -19,7 +19,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testFailToConnect() {
|
||||
public function testFailToConnect(): void {
|
||||
// for the sake of simplicity we don't distinguish between failure modes, but the MySQL-supplied error messages do
|
||||
self::setConf([
|
||||
'dbMySQLHost' => "example.invalid",
|
||||
|
|
|
@ -20,7 +20,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideConnectionStrings */
|
||||
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp) {
|
||||
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp): void {
|
||||
self::setConf();
|
||||
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
|
||||
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
|
||||
|
@ -62,7 +62,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testFailToConnect() {
|
||||
public function testFailToConnect(): void {
|
||||
// we cannnot distinguish between different connection failure modes
|
||||
self::setConf([
|
||||
'dbPostgreSQLHost' => "example.invalid",
|
||||
|
|
|
@ -20,7 +20,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideConnectionStrings */
|
||||
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp) {
|
||||
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp): void {
|
||||
self::setConf();
|
||||
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
|
||||
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
|
||||
|
@ -62,7 +62,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testFailToConnect() {
|
||||
public function testFailToConnect(): void {
|
||||
// PDO dies not distinguish between different connection failure modes
|
||||
self::setConf([
|
||||
'dbPostgreSQLHost' => "example.invalid",
|
||||
|
|
|
@ -112,79 +112,79 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testFailToCreateDatabase() {
|
||||
public function testFailToCreateDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToCreateJournal() {
|
||||
public function testFailToCreateJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToCreateSharedMmeory() {
|
||||
public function testFailToCreateSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToReadDatabase() {
|
||||
public function testFailToReadDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db";
|
||||
$this->assertException("fileUnreadable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToReadJournal() {
|
||||
public function testFailToReadJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db";
|
||||
$this->assertException("fileUnreadable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToReadSharedMmeory() {
|
||||
public function testFailToReadSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db";
|
||||
$this->assertException("fileUnreadable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToWriteToDatabase() {
|
||||
public function testFailToWriteToDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db";
|
||||
$this->assertException("fileUnwritable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToWriteToJournal() {
|
||||
public function testFailToWriteToJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db";
|
||||
$this->assertException("fileUnwritable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToWriteToSharedMmeory() {
|
||||
public function testFailToWriteToSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db";
|
||||
$this->assertException("fileUnwritable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToAccessDatabase() {
|
||||
public function testFailToAccessDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db";
|
||||
$this->assertException("fileUnusable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToAccessJournal() {
|
||||
public function testFailToAccessJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db";
|
||||
$this->assertException("fileUnusable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToAccessSharedMmeory() {
|
||||
public function testFailToAccessSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db";
|
||||
$this->assertException("fileUnusable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testAssumeDatabaseCorruption() {
|
||||
public function testAssumeDatabaseCorruption(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db";
|
||||
$this->assertException("fileCorrupt", "Db");
|
||||
new Driver;
|
||||
|
|
|
@ -114,79 +114,79 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testFailToCreateDatabase() {
|
||||
public function testFailToCreateDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToCreateJournal() {
|
||||
public function testFailToCreateJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToCreateSharedMmeory() {
|
||||
public function testFailToCreateSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToReadDatabase() {
|
||||
public function testFailToReadDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db";
|
||||
$this->assertException("fileUnreadable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToReadJournal() {
|
||||
public function testFailToReadJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db";
|
||||
$this->assertException("fileUnreadable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToReadSharedMmeory() {
|
||||
public function testFailToReadSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db";
|
||||
$this->assertException("fileUnreadable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToWriteToDatabase() {
|
||||
public function testFailToWriteToDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db";
|
||||
$this->assertException("fileUnwritable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToWriteToJournal() {
|
||||
public function testFailToWriteToJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db";
|
||||
$this->assertException("fileUnwritable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToWriteToSharedMmeory() {
|
||||
public function testFailToWriteToSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db";
|
||||
$this->assertException("fileUnwritable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToAccessDatabase() {
|
||||
public function testFailToAccessDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db";
|
||||
$this->assertException("fileUnusable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToAccessJournal() {
|
||||
public function testFailToAccessJournal(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db";
|
||||
$this->assertException("fileUnusable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testFailToAccessSharedMmeory() {
|
||||
public function testFailToAccessSharedMmeory(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db";
|
||||
$this->assertException("fileUnusable", "Db");
|
||||
new Driver;
|
||||
}
|
||||
|
||||
public function testAssumeDatabaseCorruption() {
|
||||
public function testAssumeDatabaseCorruption(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db";
|
||||
$this->assertException("fileCorrupt", "Db");
|
||||
new Driver;
|
||||
|
|
|
@ -7,7 +7,7 @@ use JKingWeb\Arsse\Test\Result;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Db\ResultAggregate<extended> */
|
||||
class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function testGetChangeCountAndLastInsertId() {
|
||||
public function testGetChangeCountAndLastInsertId(): void {
|
||||
$in = [
|
||||
new Result([], 3, 4),
|
||||
new Result([], 27, 10),
|
||||
|
@ -18,7 +18,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals(2112, $r->lastId());
|
||||
}
|
||||
|
||||
public function testIterateOverResults() {
|
||||
public function testIterateOverResults(): void {
|
||||
$in = [
|
||||
new Result([['col' => 1]]),
|
||||
new Result([['col' => 2]]),
|
||||
|
@ -31,7 +31,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals([0 => 1, 1 => 2, 2 => 3], $rows);
|
||||
}
|
||||
|
||||
public function testIterateOverResultsTwice() {
|
||||
public function testIterateOverResultsTwice(): void {
|
||||
$in = [
|
||||
new Result([['col' => 1]]),
|
||||
new Result([['col' => 2]]),
|
||||
|
@ -49,7 +49,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testGetSingleValues() {
|
||||
public function testGetSingleValues(): void {
|
||||
$test = new ResultAggregate(...[
|
||||
new Result([['year' => 1867]]),
|
||||
new Result([['year' => 1970]]),
|
||||
|
@ -61,7 +61,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(null, $test->getValue());
|
||||
}
|
||||
|
||||
public function testGetFirstValuesOnly() {
|
||||
public function testGetFirstValuesOnly(): void {
|
||||
$test = new ResultAggregate(...[
|
||||
new Result([['year' => 1867, 'century' => 19]]),
|
||||
new Result([['year' => 1970, 'century' => 20]]),
|
||||
|
@ -73,7 +73,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(null, $test->getValue());
|
||||
}
|
||||
|
||||
public function testGetRows() {
|
||||
public function testGetRows(): void {
|
||||
$test = new ResultAggregate(...[
|
||||
new Result([['album' => '2112', 'track' => '2112']]),
|
||||
new Result([['album' => 'Clockwork Angels', 'track' => 'The Wreckers']]),
|
||||
|
@ -87,7 +87,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(null, $test->getRow());
|
||||
}
|
||||
|
||||
public function testGetAllRows() {
|
||||
public function testGetAllRows(): void {
|
||||
$test = new ResultAggregate(...[
|
||||
new Result([['album' => '2112', 'track' => '2112']]),
|
||||
new Result([['album' => 'Clockwork Angels', 'track' => 'The Wreckers']]),
|
||||
|
|
|
@ -6,13 +6,13 @@ use JKingWeb\Arsse\Db\ResultEmpty;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Db\ResultEmpty<extended> */
|
||||
class TestResultEmpty extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function testGetChangeCountAndLastInsertId() {
|
||||
public function testGetChangeCountAndLastInsertId(): void {
|
||||
$r = new ResultEmpty;
|
||||
$this->assertEquals(0, $r->changes());
|
||||
$this->assertEquals(0, $r->lastId());
|
||||
}
|
||||
|
||||
public function testIterateOverResults() {
|
||||
public function testIterateOverResults(): void {
|
||||
$rows = [];
|
||||
foreach (new ResultEmpty as $index => $row) {
|
||||
$rows[$index] = $row['col'];
|
||||
|
@ -20,17 +20,17 @@ class TestResultEmpty extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals([], $rows);
|
||||
}
|
||||
|
||||
public function testGetSingleValues() {
|
||||
public function testGetSingleValues(): void {
|
||||
$test = new ResultEmpty;
|
||||
$this->assertSame(null, $test->getValue());
|
||||
}
|
||||
|
||||
public function testGetRows() {
|
||||
public function testGetRows(): void {
|
||||
$test = new ResultEmpty;
|
||||
$this->assertSame(null, $test->getRow());
|
||||
}
|
||||
|
||||
public function testGetAllRows() {
|
||||
public function testGetAllRows(): void {
|
||||
$test = new ResultEmpty;
|
||||
$rows = [];
|
||||
$this->assertEquals($rows, $test->getAll());
|
||||
|
|
|
@ -23,7 +23,7 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->drv = $drv;
|
||||
}
|
||||
|
||||
public function testManipulateTransactions() {
|
||||
public function testManipulateTransactions(): void {
|
||||
$tr1 = new Transaction($this->drv);
|
||||
$tr2 = new Transaction($this->drv);
|
||||
\Phake::verify($this->drv, \Phake::times(2))->savepointCreate;
|
||||
|
@ -35,7 +35,7 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
}
|
||||
|
||||
public function testCloseTransactions() {
|
||||
public function testCloseTransactions(): void {
|
||||
$tr1 = new Transaction($this->drv);
|
||||
$tr2 = new Transaction($this->drv);
|
||||
$this->assertTrue($tr1->isPending());
|
||||
|
@ -50,7 +50,7 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
}
|
||||
|
||||
public function testIgnoreRollbackErrors() {
|
||||
public function testIgnoreRollbackErrors(): void {
|
||||
\Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale"));
|
||||
$tr1 = new Transaction($this->drv);
|
||||
$tr2 = new Transaction($this->drv);
|
||||
|
|
|
@ -28,7 +28,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData(true);
|
||||
}
|
||||
|
||||
public function testBaseClass() {
|
||||
public function testBaseClass(): void {
|
||||
$this->assertException("unknown");
|
||||
throw new Exception("unknown");
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testBaseClass
|
||||
*/
|
||||
public function testBaseClassWithoutMessage() {
|
||||
public function testBaseClassWithoutMessage(): void {
|
||||
$this->assertException("unknown");
|
||||
throw new Exception();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testBaseClass
|
||||
*/
|
||||
public function testDerivedClass() {
|
||||
public function testDerivedClass(): void {
|
||||
$this->assertException("fileMissing", "Lang");
|
||||
throw new LangException("fileMissing");
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testDerivedClass
|
||||
*/
|
||||
public function testDerivedClassWithMessageParameters() {
|
||||
public function testDerivedClassWithMessageParameters(): void {
|
||||
$this->assertException("fileMissing", "Lang");
|
||||
throw new LangException("fileMissing", "en");
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testBaseClass
|
||||
*/
|
||||
public function testBaseClassWithUnknownCode() {
|
||||
public function testBaseClassWithUnknownCode(): void {
|
||||
$this->assertException("uncoded");
|
||||
throw new Exception("testThisExceptionMessageDoesNotExist");
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testBaseClassWithUnknownCode
|
||||
*/
|
||||
public function testDerivedClassWithMissingMessage() {
|
||||
public function testDerivedClassWithMissingMessage(): void {
|
||||
$this->assertException("uncoded");
|
||||
throw new LangException("testThisExceptionMessageDoesNotExist");
|
||||
}
|
||||
|
||||
/** @covers \JKingWeb\Arsse\ExceptionFatal */
|
||||
public function testFatalException() {
|
||||
public function testFatalException(): void {
|
||||
$this->expectException('JKingWeb\Arsse\ExceptionFatal');
|
||||
throw new \JKingWeb\Arsse\ExceptionFatal("");
|
||||
}
|
||||
|
|
177
tests/cases/Feed/TestException.php
Normal file
177
tests/cases/Feed/TestException.php
Normal file
|
@ -0,0 +1,177 @@
|
|||
<?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\Feed;
|
||||
|
||||
use GuzzleHttp\Exception\BadResponseException;
|
||||
use GuzzleHttp\Exception\TooManyRedirectsException;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use JKingWeb\Arsse\Feed\Exception as FeedException;
|
||||
use PicoFeed\PicoFeedException;
|
||||
|
||||
/**
|
||||
* @covers \JKingWeb\Arsse\Feed\Exception
|
||||
* @group slow */
|
||||
class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
/** @dataProvider provideCurlErrors */
|
||||
public function testHandleCurlErrors(int $code, string $message): void {
|
||||
$e = $this->mockGuzzleException(TransferException::class, "cURL error $code: Some message", 0);
|
||||
$this->assertException($message, "Feed");
|
||||
throw new FeedException("https://example.com/", $e);
|
||||
}
|
||||
|
||||
public function provideCurlErrors() {
|
||||
return [
|
||||
'CURLE_UNSUPPORTED_PROTOCOL' => [1, "invalidUrl"],
|
||||
'CURLE_FAILED_INIT' => [2, "internalError"],
|
||||
'CURLE_URL_MALFORMAT' => [3, "invalidUrl"],
|
||||
'CURLE_URL_MALFORMAT_USER' => [4, "internalError"],
|
||||
'CURLE_COULDNT_RESOLVE_PROXY' => [5, "transmissionError"],
|
||||
'CURLE_COULDNT_RESOLVE_HOST' => [6, "connectionFailed"],
|
||||
'CURLE_COULDNT_CONNECT' => [7, "connectionFailed"],
|
||||
'CURLE_WEIRD_SERVER_REPLY' => [8, "transmissionError"],
|
||||
'CURLE_FTP_ACCESS_DENIED' => [9, "forbidden"],
|
||||
'CURLE_FTP_USER_PASSWORD_INCORRECT' => [10, "unauthorized"],
|
||||
'CURLE_FTP_WEIRD_PASS_REPLY' => [11, "transmissionError"],
|
||||
'CURLE_FTP_WEIRD_USER_REPLY' => [12, "transmissionError"],
|
||||
'CURLE_FTP_WEIRD_PASV_REPLY' => [13, "transmissionError"],
|
||||
'CURLE_FTP_WEIRD_227_FORMAT' => [14, "transmissionError"],
|
||||
'CURLE_FTP_CANT_GET_HOST' => [15, "connectionFailed"],
|
||||
'CURLE_FTP_CANT_RECONNECT' => [16, "connectionFailed"],
|
||||
'CURLE_FTP_COULDNT_SET_BINARY' => [17, "transmissionError"],
|
||||
'CURLE_PARTIAL_FILE' => [18, "transmissionError"],
|
||||
'CURLE_FTP_COULDNT_RETR_FILE' => [19, "transmissionError"],
|
||||
'CURLE_FTP_WRITE_ERROR' => [20, "transmissionError"],
|
||||
'CURLE_FTP_QUOTE_ERROR' => [21, "transmissionError"],
|
||||
'CURLE_HTTP_NOT_FOUND' => [22, "invalidUrl"],
|
||||
'CURLE_WRITE_ERROR' => [23, "transmissionError"],
|
||||
'CURLE_MALFORMAT_USER' => [24, "transmissionError"],
|
||||
'CURLE_FTP_COULDNT_STOR_FILE' => [25, "transmissionError"],
|
||||
'CURLE_READ_ERROR' => [26, "transmissionError"],
|
||||
'CURLE_OUT_OF_MEMORY' => [27, "internalError"],
|
||||
'CURLE_OPERATION_TIMEDOUT' => [28, "timeout"],
|
||||
'CURLE_FTP_COULDNT_SET_ASCII' => [29, "transmissionError"],
|
||||
'CURLE_FTP_PORT_FAILED' => [30, "transmissionError"],
|
||||
'CURLE_FTP_COULDNT_USE_REST' => [31, "transmissionError"],
|
||||
'CURLE_FTP_COULDNT_GET_SIZE' => [32, "transmissionError"],
|
||||
'CURLE_HTTP_RANGE_ERROR' => [33, "transmissionError"],
|
||||
'CURLE_HTTP_POST_ERROR' => [34, "internalError"],
|
||||
'CURLE_SSL_CONNECT_ERROR' => [35, "invalidCertificate"],
|
||||
'CURLE_BAD_DOWNLOAD_RESUME' => [36, "transmissionError"],
|
||||
'CURLE_FILE_COULDNT_READ_FILE' => [37, "transmissionError"],
|
||||
'CURLE_LDAP_CANNOT_BIND' => [38, "transmissionError"],
|
||||
'CURLE_LDAP_SEARCH_FAILED' => [39, "transmissionError"],
|
||||
'CURLE_LIBRARY_NOT_FOUND' => [40, "internalError"],
|
||||
'CURLE_FUNCTION_NOT_FOUND' => [41, "internalError"],
|
||||
'CURLE_ABORTED_BY_CALLBACK' => [42, "internalError"],
|
||||
'CURLE_BAD_FUNCTION_ARGUMENT' => [43, "internalError"],
|
||||
'CURLE_BAD_CALLING_ORDER' => [44, "internalError"],
|
||||
'CURLE_HTTP_PORT_FAILED' => [45, "transmissionError"],
|
||||
'CURLE_BAD_PASSWORD_ENTERED' => [46, "unauthorized"],
|
||||
'CURLE_TOO_MANY_REDIRECTS' => [47, "maxRedirect"],
|
||||
'CURLE_UNKNOWN_TELNET_OPTION' => [48, "internalError"],
|
||||
'CURLE_TELNET_OPTION_SYNTAX' => [49, "internalError"],
|
||||
'Unknown error 50' => [50, "internalError"],
|
||||
'Unknown error 51' => [51, "internalError"],
|
||||
'CURLE_GOT_NOTHING' => [52, "transmissionError"],
|
||||
'CURLE_SSL_ENGINE_NOTFOUND' => [53, "invalidCertificate"],
|
||||
'CURLE_SSL_ENGINE_SETFAILED' => [54, "invalidCertificate"],
|
||||
'CURLE_SEND_ERROR' => [55, "transmissionError"],
|
||||
'CURLE_RECV_ERROR' => [56, "transmissionError"],
|
||||
'CURLE_SHARE_IN_USE' => [57, "internalError"],
|
||||
'CURLE_SSL_CERTPROBLEM' => [58, "invalidCertificate"],
|
||||
'CURLE_SSL_CIPHER' => [59, "invalidCertificate"],
|
||||
'CURLE_SSL_CACERT' => [60, "invalidCertificate"],
|
||||
'CURLE_BAD_CONTENT_ENCODING' => [61, "transmissionError"],
|
||||
'CURLE_LDAP_INVALID_URL' => [62, "invalidUrl"],
|
||||
'CURLE_FILESIZE_EXCEEDED' => [63, "transmissionError"],
|
||||
'CURLE_USE_SSL_FAILED' => [64, "invalidCertificate"],
|
||||
'CURLE_SEND_FAIL_REWIND' => [65, "transmissionError"],
|
||||
'CURLE_SSL_ENGINE_INITFAILED' => [66, "invalidCertificate"],
|
||||
'CURLE_LOGIN_DENIED' => [67, "forbidden"],
|
||||
'CURLE_TFTP_NOTFOUND' => [68, "invalidUrl"],
|
||||
'CURLE_TFTP_PERM' => [69, "forbidden"],
|
||||
'CURLE_REMOTE_DISK_FULL' => [70, "transmissionError"],
|
||||
'CURLE_TFTP_ILLEGAL' => [71, "internalError"],
|
||||
'CURLE_TFTP_UNKNOWNID' => [72, "internalError"],
|
||||
'CURLE_REMOTE_FILE_EXISTS' => [73, "transmissionError"],
|
||||
'CURLE_TFTP_NOSUCHUSER' => [74, "transmissionError"],
|
||||
'CURLE_CONV_FAILED' => [75, "internalError"],
|
||||
'CURLE_CONV_REQD' => [76, "internalError"],
|
||||
'CURLE_SSL_CACERT_BADFILE' => [77, "invalidCertificate"],
|
||||
'CURLE_REMOTE_FILE_NOT_FOUND' => [78, "invalidUrl"],
|
||||
'CURLE_SSH' => [79, "internalError"],
|
||||
'CURLE_SSL_PINNEDPUBKEYNOTMATCH' => [90, "invalidCertificate"],
|
||||
'CURLE_SSL_INVALIDCERTSTATUS' => [91, "invalidCertificate"],
|
||||
'CURLE_HTTP2_STREAM' => [92, "transmissionError"],
|
||||
'CURLE_RECURSIVE_API_CALL' => [93, "internalError"],
|
||||
'CURLE_AUTH_ERROR' => [94, "unauthorized"],
|
||||
'CURLE_HTTP3' => [95, "transmissionError"],
|
||||
'CURLE_QUIC_CONNECT_ERROR' => [96, "connectionFailed"],
|
||||
'Hypothetical error 2112' => [2112, "internalError"],
|
||||
];
|
||||
}
|
||||
|
||||
/** @dataProvider provideHTTPErrors */
|
||||
public function testHandleHttpErrors(int $code, string $message): void {
|
||||
$e = $this->mockGuzzleException(BadResponseException::class, "Irrelevant message", $code);
|
||||
$this->assertException($message, "Feed");
|
||||
throw new FeedException("https://example.com/", $e);
|
||||
}
|
||||
|
||||
public function provideHTTPErrors() {
|
||||
$specials = [
|
||||
401 => "unauthorized",
|
||||
403 => "forbidden",
|
||||
404 => "invalidUrl",
|
||||
408 => "timeout",
|
||||
410 => "invalidUrl",
|
||||
414 => "invalidUrl",
|
||||
451 => "invalidUrl"
|
||||
];
|
||||
$out = array_fill(400, (600 - 400), "transmissionError");
|
||||
foreach ($specials as $k => $t) {
|
||||
$out[$k] = $t;
|
||||
}
|
||||
foreach ($out as $k => $t) {
|
||||
$out[$k] = [$k, $t];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/** @dataProvider providePicoFeedException */
|
||||
public function testHandlePicofeedException(PicoFeedException $e, string $message) {
|
||||
$this->assertException($message, "Feed");
|
||||
throw new FeedException("https://example.com/", $e);
|
||||
}
|
||||
|
||||
public function providePicoFeedException() {
|
||||
return [
|
||||
'Failed feed discovery' => [new \PicoFeed\Reader\SubscriptionNotFoundException(), "subscriptionNotFound"],
|
||||
'Unsupported format' => [new \PicoFeed\Reader\UnsupportedFeedFormatException(), "unsupportedFeedFormat"],
|
||||
'Malformed XML' => [new \PicoFeed\Parser\MalformedXmlException(), "malformedXml"],
|
||||
'XML entity expansion' => [new \PicoFeed\Parser\XmlEntityException(), "xmlEntity"],
|
||||
];
|
||||
}
|
||||
|
||||
public function testHandleExcessRedirections() {
|
||||
$e = $this->mockGuzzleException(TooManyRedirectsException::class, "Irrelevant message", 404);
|
||||
$this->assertException("maxRedirect", "Feed");
|
||||
throw new FeedException("https://example.com/", $e);
|
||||
}
|
||||
|
||||
public function testHandleGenericStreamErrors() {
|
||||
$e = $this->mockGuzzleException(TransferException::class, "Error creating resource: Irrelevant message", 403);
|
||||
$this->assertException("transmissionError", "Feed");
|
||||
throw new FeedException("https://example.com/", $e);
|
||||
}
|
||||
|
||||
public function testHandleUnexpectedError() {
|
||||
$e = new \Exception;
|
||||
$this->assertException("internalError", "Feed");
|
||||
throw new FeedException("https://example.com/", $e);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ use JKingWeb\Arsse\Test\Result;
|
|||
|
||||
/**
|
||||
* @covers \JKingWeb\Arsse\Feed
|
||||
* @covers \JKingWeb\Arsse\Feed\Exception
|
||||
* @group slow */
|
||||
class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
protected static $host = "http://localhost:8000/";
|
||||
|
@ -98,7 +97,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$db = \Phake::mock(Database::class);
|
||||
}
|
||||
|
||||
public function testParseAFeed() {
|
||||
public function testParseAFeed(): void {
|
||||
// test that various properties are set on the feed and on items
|
||||
$f = new Feed(null, $this->base."Parsing/Valid");
|
||||
$this->assertTrue(isset($f->lastModified));
|
||||
|
@ -141,37 +140,37 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($categories, $f->data->items[5]->categories);
|
||||
}
|
||||
|
||||
public function testDiscoverAFeedSuccessfully() {
|
||||
public function testDiscoverAFeedSuccessfully(): void {
|
||||
$this->assertSame($this->base."Discovery/Feed", Feed::discover($this->base."Discovery/Valid"));
|
||||
$this->assertSame($this->base."Discovery/Feed", Feed::discover($this->base."Discovery/Feed"));
|
||||
}
|
||||
|
||||
public function testDiscoverAFeedUnsuccessfully() {
|
||||
public function testDiscoverAFeedUnsuccessfully(): void {
|
||||
$this->assertException("subscriptionNotFound", "Feed");
|
||||
Feed::discover($this->base."Discovery/Invalid");
|
||||
}
|
||||
|
||||
public function testParseEntityExpansionAttack() {
|
||||
public function testParseEntityExpansionAttack(): void {
|
||||
$this->assertException("xmlEntity", "Feed");
|
||||
new Feed(null, $this->base."Parsing/XEEAttack");
|
||||
}
|
||||
|
||||
public function testParseExternalEntityAttack() {
|
||||
public function testParseExternalEntityAttack(): void {
|
||||
$this->assertException("xmlEntity", "Feed");
|
||||
new Feed(null, $this->base."Parsing/XXEAttack");
|
||||
}
|
||||
|
||||
public function testParseAnUnsupportedFeed() {
|
||||
public function testParseAnUnsupportedFeed(): void {
|
||||
$this->assertException("unsupportedFeedFormat", "Feed");
|
||||
new Feed(null, $this->base."Parsing/Unsupported");
|
||||
}
|
||||
|
||||
public function testParseAMalformedFeed() {
|
||||
public function testParseAMalformedFeed(): void {
|
||||
$this->assertException("malformedXml", "Feed");
|
||||
new Feed(null, $this->base."Parsing/Malformed");
|
||||
}
|
||||
|
||||
public function testDeduplicateFeedItems() {
|
||||
public function testDeduplicateFeedItems(): void {
|
||||
// duplicates with dates lead to the newest match being kept
|
||||
$t = strtotime("2002-05-19T15:21:36Z");
|
||||
$f = new Feed(null, $this->base."Deduplication/Permalink-Dates");
|
||||
|
@ -198,25 +197,27 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame("http://example.com/1", $f->newItems[0]->url);
|
||||
}
|
||||
|
||||
public function testHandleCacheHeadersOn304() {
|
||||
// upon 304, the client should re-use the caching header values it supplied the server
|
||||
$t = time();
|
||||
/** @dataProvider provide304ResponseURLs */
|
||||
public function testHandleCacheHeadersOn304(string $url): void {
|
||||
// upon 304, the client should re-use the caching header values it supplied to the server
|
||||
$t = Date::transform("2010-01-01T00:00:00Z", "unix");
|
||||
$e = "78567a";
|
||||
$f = new Feed(null, $this->base."Caching/304Random", Date::transform($t, "http"), $e);
|
||||
$this->assertTime($t, $f->lastModified);
|
||||
$this->assertSame($e, $f->resource->getETag());
|
||||
$f = new Feed(null, $this->base."Caching/304ETagOnly", Date::transform($t, "http"), $e);
|
||||
$this->assertTime($t, $f->lastModified);
|
||||
$this->assertSame($e, $f->resource->getETag());
|
||||
$f = new Feed(null, $this->base."Caching/304LastModOnly", Date::transform($t, "http"), $e);
|
||||
$this->assertTime($t, $f->lastModified);
|
||||
$this->assertSame($e, $f->resource->getETag());
|
||||
$f = new Feed(null, $this->base."Caching/304None", Date::transform($t, "http"), $e);
|
||||
$f = new Feed(null, $this->base.$url."?t=$t&e=$e", Date::transform($t, "http"), $e);
|
||||
$this->assertTime($t, $f->lastModified);
|
||||
$this->assertSame($e, $f->resource->getETag());
|
||||
}
|
||||
|
||||
public function testHandleCacheHeadersOn200() {
|
||||
public function provide304ResponseURLs() {
|
||||
return [
|
||||
'Control' => ["Caching/304Conditional"],
|
||||
'Random last-mod and ETag' => ["Caching/304Random"],
|
||||
'ETag only' => ["Caching/304ETagOnly"],
|
||||
'Last-mod only' => ["Caching/304LastModOnly"],
|
||||
'Neither last-mod nor ETag' => ["Caching/304None"],
|
||||
];
|
||||
}
|
||||
|
||||
public function testHandleCacheHeadersOn200(): void {
|
||||
// these tests should trust the server-returned time, even in cases of obviously incorrect results
|
||||
$t = time() - 2000;
|
||||
$f = new Feed(null, $this->base."Caching/200Past");
|
||||
|
@ -244,7 +245,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertTime($t, $f->lastModified);
|
||||
}
|
||||
|
||||
public function testComputeNextFetchOnError() {
|
||||
public function testComputeNextFetchOnError(): void {
|
||||
for ($a = 0; $a < 100; $a++) {
|
||||
if ($a < 3) {
|
||||
$this->assertTime("now + 5 minutes", Feed::nextFetchOnError($a));
|
||||
|
@ -257,7 +258,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provide304Timestamps */
|
||||
public function testComputeNextFetchFrom304(string $t, string $exp) {
|
||||
public function testComputeNextFetchFrom304(string $t, string $exp): void {
|
||||
$t = $t ? strtotime($t) : "";
|
||||
$f = new Feed(null, $this->base."NextFetch/NotModified?t=$t", Date::transform($t, "http"));
|
||||
$exp = strtotime($exp);
|
||||
|
@ -279,13 +280,13 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testComputeNextFetchFrom304WithoutDate() {
|
||||
public function testComputeNextFetchFrom304WithoutDate(): void {
|
||||
$f = new Feed(null, $this->base."NextFetch/NotModifiedEtag");
|
||||
$exp = strtotime("now + 3 hours");
|
||||
$this->assertTime($exp, $f->nextFetch);
|
||||
}
|
||||
|
||||
public function testComputeNextFetchFrom200() {
|
||||
public function testComputeNextFetchFrom200(): void {
|
||||
// if less than half an hour, check in 15 minutes
|
||||
$f = new Feed(null, $this->base."NextFetch/30m");
|
||||
$exp = strtotime("now + 15 minutes");
|
||||
|
@ -312,7 +313,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertTime($exp, $f->nextFetch);
|
||||
}
|
||||
|
||||
public function testMatchLatestArticles() {
|
||||
public function testMatchLatestArticles(): void {
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
|
||||
$f = new Feed(1, $this->base."Matching/1");
|
||||
$this->assertCount(0, $f->newItems);
|
||||
|
@ -328,7 +329,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertCount(2, $f->changedItems);
|
||||
}
|
||||
|
||||
public function testMatchHistoricalArticles() {
|
||||
public function testMatchHistoricalArticles(): void {
|
||||
\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));
|
||||
$f = new Feed(1, $this->base."Matching/5");
|
||||
|
@ -336,7 +337,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertCount(0, $f->changedItems);
|
||||
}
|
||||
|
||||
public function testScrapeFullContent() {
|
||||
public function testScrapeFullContent(): void {
|
||||
// first make sure that the absence of scraping works as expected
|
||||
$f = new Feed(null, $this->base."Scraping/Feed");
|
||||
$exp = "<p>Partial content</p>";
|
||||
|
|
|
@ -27,48 +27,49 @@ class TestFetching extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::setConf();
|
||||
}
|
||||
|
||||
public function testHandle400() {
|
||||
$this->assertException("unsupportedFeedFormat", "Feed");
|
||||
public function testHandle400(): void {
|
||||
$this->assertException("transmissionError", "Feed");
|
||||
new Feed(null, $this->base."Fetching/Error?code=400");
|
||||
}
|
||||
|
||||
public function testHandle401() {
|
||||
public function testHandle401(): void {
|
||||
$this->assertException("unauthorized", "Feed");
|
||||
new Feed(null, $this->base."Fetching/Error?code=401");
|
||||
}
|
||||
|
||||
public function testHandle403() {
|
||||
public function testHandle403(): void {
|
||||
$this->assertException("forbidden", "Feed");
|
||||
new Feed(null, $this->base."Fetching/Error?code=403");
|
||||
}
|
||||
|
||||
public function testHandle404() {
|
||||
public function testHandle404(): void {
|
||||
$this->assertException("invalidUrl", "Feed");
|
||||
new Feed(null, $this->base."Fetching/Error?code=404");
|
||||
}
|
||||
|
||||
public function testHandle500() {
|
||||
$this->assertException("unsupportedFeedFormat", "Feed");
|
||||
public function testHandle500(): void {
|
||||
$this->assertException("transmissionError", "Feed");
|
||||
new Feed(null, $this->base."Fetching/Error?code=500");
|
||||
}
|
||||
|
||||
public function testHandleARedirectLoop() {
|
||||
public function testHandleARedirectLoop(): void {
|
||||
$this->assertException("maxRedirect", "Feed");
|
||||
new Feed(null, $this->base."Fetching/EndlessLoop?i=0");
|
||||
}
|
||||
|
||||
public function testHandleAnOverlyLargeFeed() {
|
||||
public function testHandleAnOverlyLargeFeed(): void {
|
||||
$this->markTestIncomplete("The nicolus/picofeed library does not implement miniflux/picofeed's max-size setting");
|
||||
Arsse::$conf->fetchSizeLimit = 512;
|
||||
$this->assertException("maxSize", "Feed");
|
||||
new Feed(null, $this->base."Fetching/TooLarge");
|
||||
}
|
||||
|
||||
public function testHandleACertificateError() {
|
||||
public function testHandleACertificateError(): void {
|
||||
$this->assertException("invalidCertificate", "Feed");
|
||||
new Feed(null, "https://localhost:8000/");
|
||||
}
|
||||
|
||||
public function testHandleATimeout() {
|
||||
public function testHandleATimeout(): void {
|
||||
Arsse::$conf->fetchTimeout = 1;
|
||||
$this->assertException("timeout", "Feed");
|
||||
new Feed(null, $this->base."Fetching/Timeout");
|
||||
|
|
|
@ -45,7 +45,7 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideFileExports */
|
||||
public function testExportToAFile(string $file, string $user, bool $flat, $exp) {
|
||||
public function testExportToAFile(string $file, string $user, bool $flat, $exp): void {
|
||||
$path = $this->path.$file;
|
||||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
|
@ -84,7 +84,7 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideFileImports */
|
||||
public function testImportFromAFile(string $file, string $user, bool $flat, bool $replace, $exp) {
|
||||
public function testImportFromAFile(string $file, string $user, bool $flat, bool $replace, $exp): void {
|
||||
$path = $this->path.$file;
|
||||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
|
|
|
@ -146,13 +146,13 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testImportForAMissingUser() {
|
||||
public function testImportForAMissingUser(): void {
|
||||
\Phake::when(Arsse::$user)->exists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User");
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testImportWithInvalidFolder() {
|
||||
public function testImportWithInvalidFolder(): void {
|
||||
$in = [[
|
||||
], [1 =>
|
||||
['id' => 1, 'name' => "", 'parent' => 0],
|
||||
|
@ -162,7 +162,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testImportWithDuplicateFolder() {
|
||||
public function testImportWithDuplicateFolder(): void {
|
||||
$in = [[
|
||||
], [1 =>
|
||||
['id' => 1, 'name' => "New", 'parent' => 0],
|
||||
|
@ -173,7 +173,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testMakeNoEffectiveChanges() {
|
||||
public function testMakeNoEffectiveChanges(): void {
|
||||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/nasa-jpl", 'title' => "NASA JPL", 'folder' => 3, 'tags' => ["tech"]],
|
||||
['url' => "http://localhost:8000/Import/ars", 'title' => "Ars Technica", 'folder' => 2, 'tags' => ["frequent", "tech"]],
|
||||
|
@ -197,7 +197,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->compareExpectations($this->drv, $exp);
|
||||
}
|
||||
|
||||
public function testModifyASubscription() {
|
||||
public function testModifyASubscription(): void {
|
||||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/nasa-jpl", 'title' => "NASA JPL", 'folder' => 3, 'tags' => ["tech"]],
|
||||
['url' => "http://localhost:8000/Import/ars", 'title' => "Ars Technica", 'folder' => 2, 'tags' => ["frequent", "tech"]],
|
||||
|
@ -222,7 +222,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->compareExpectations($this->drv, $exp);
|
||||
}
|
||||
|
||||
public function testImportAFeed() {
|
||||
public function testImportAFeed(): void {
|
||||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => ["frequent", "cryptic"]], //one existing tag and one new one
|
||||
], []];
|
||||
|
@ -237,7 +237,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->compareExpectations($this->drv, $exp);
|
||||
}
|
||||
|
||||
public function testImportAFeedWithAnInvalidTag() {
|
||||
public function testImportAFeedWithAnInvalidTag(): void {
|
||||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => [""]],
|
||||
], []];
|
||||
|
@ -246,7 +246,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testReplaceData() {
|
||||
public function testReplaceData(): void {
|
||||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 1, 'tags' => ["frequent", "cryptic"]],
|
||||
], [1 =>
|
||||
|
|
|
@ -86,28 +86,28 @@ OPML_EXPORT_SERIALIZATION;
|
|||
\Phake::when(Arsse::$user)->exists->thenReturn(true);
|
||||
}
|
||||
|
||||
public function testExportToOpml() {
|
||||
public function testExportToOpml(): void {
|
||||
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders));
|
||||
\Phake::when(Arsse::$db)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
|
||||
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
|
||||
$this->assertXmlStringEqualsXmlString($this->serialization, (new OPML)->export("john.doe@example.com"));
|
||||
}
|
||||
|
||||
public function testExportToFlatOpml() {
|
||||
public function testExportToFlatOpml(): void {
|
||||
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders));
|
||||
\Phake::when(Arsse::$db)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
|
||||
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
|
||||
$this->assertXmlStringEqualsXmlString($this->serializationFlat, (new OPML)->export("john.doe@example.com", true));
|
||||
}
|
||||
|
||||
public function testExportToOpmlAMissingUser() {
|
||||
public function testExportToOpmlAMissingUser(): void {
|
||||
\Phake::when(Arsse::$user)->exists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User");
|
||||
(new OPML)->export("john.doe@example.com");
|
||||
}
|
||||
|
||||
/** @dataProvider provideParserData */
|
||||
public function testParseOpmlForImport(string $file, bool $flat, $exp) {
|
||||
public function testParseOpmlForImport(string $file, bool $flat, $exp): void {
|
||||
$data = file_get_contents(\JKingWeb\Arsse\DOCROOT."Import/OPML/$file");
|
||||
// set up a partial mock to make the ImportExport::parse() method visible
|
||||
$parser = \Phake::makeVisible(\Phake::partialMock(OPML::class));
|
||||
|
|
|
@ -16,14 +16,14 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public $path;
|
||||
public $l;
|
||||
|
||||
public function testListLanguages() {
|
||||
public function testListLanguages(): void {
|
||||
$this->assertCount(sizeof($this->files), $this->l->list("en"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testListLanguages
|
||||
*/
|
||||
public function testSetLanguage() {
|
||||
public function testSetLanguage(): void {
|
||||
$this->assertEquals("en", $this->l->set("en"));
|
||||
$this->assertEquals("en_ca", $this->l->set("en_ca"));
|
||||
$this->assertEquals("de", $this->l->set("de_ch"));
|
||||
|
@ -36,7 +36,7 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testSetLanguage
|
||||
*/
|
||||
public function testLoadInternalStrings() {
|
||||
public function testLoadInternalStrings(): void {
|
||||
$this->assertEquals("", $this->l->set("", true));
|
||||
$this->assertCount(sizeof(TestClass::REQUIRED), $this->l->dump());
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testLoadInternalStrings
|
||||
*/
|
||||
public function testLoadDefaultLanguage() {
|
||||
public function testLoadDefaultLanguage(): void {
|
||||
$this->assertEquals(TestClass::DEFAULT, $this->l->set(TestClass::DEFAULT, true));
|
||||
$str = $this->l->dump();
|
||||
$this->assertArrayHasKey('Exception.JKingWeb/Arsse/Exception.uncoded', $str);
|
||||
|
@ -54,7 +54,7 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testLoadDefaultLanguage
|
||||
*/
|
||||
public function testLoadSupplementaryLanguage() {
|
||||
public function testLoadSupplementaryLanguage(): void {
|
||||
$this->l->set(TestClass::DEFAULT, true);
|
||||
$this->assertEquals("ja", $this->l->set("ja", true));
|
||||
$str = $this->l->dump();
|
||||
|
|
|
@ -16,11 +16,11 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public $path;
|
||||
public $l;
|
||||
|
||||
public function setUpSeries() {
|
||||
public function setUpSeries(): void {
|
||||
$this->l->set(TestClass::DEFAULT, true);
|
||||
}
|
||||
|
||||
public function testLazyLoad() {
|
||||
public function testLazyLoad(): void {
|
||||
$this->l->set("ja");
|
||||
$this->assertArrayNotHasKey('Test.absentText', $this->l->dump());
|
||||
}
|
||||
|
@ -28,14 +28,14 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testLazyLoad
|
||||
*/
|
||||
public function testGetWantedAndLoadedLocale() {
|
||||
public function testGetWantedAndLoadedLocale(): void {
|
||||
$this->l->set("en", true);
|
||||
$this->l->set("ja");
|
||||
$this->assertEquals("ja", $this->l->get());
|
||||
$this->assertEquals("en", $this->l->get(true));
|
||||
}
|
||||
|
||||
public function testLoadCascadeOfFiles() {
|
||||
public function testLoadCascadeOfFiles(): void {
|
||||
$this->l->set("ja", true);
|
||||
$this->assertEquals("de", $this->l->set("de", true));
|
||||
$str = $this->l->dump();
|
||||
|
@ -46,11 +46,11 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testLoadCascadeOfFiles
|
||||
*/
|
||||
public function testLoadSubtag() {
|
||||
public function testLoadSubtag(): void {
|
||||
$this->assertEquals("en_ca", $this->l->set("en_ca", true));
|
||||
}
|
||||
|
||||
public function testFetchAMessage() {
|
||||
public function testFetchAMessage(): void {
|
||||
$this->l->set("de");
|
||||
$this->assertEquals('und der Stein der Weisen', $this->l->msg('Test.presentText'));
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testFetchAMessage
|
||||
*/
|
||||
public function testFetchAMessageWithMissingParameters() {
|
||||
public function testFetchAMessageWithMissingParameters(): void {
|
||||
$this->l->set("en_ca", true);
|
||||
$this->assertEquals('{0} and {1}', $this->l->msg('Test.presentText'));
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testFetchAMessage
|
||||
*/
|
||||
public function testFetchAMessageWithSingleNumericParameter() {
|
||||
public function testFetchAMessageWithSingleNumericParameter(): void {
|
||||
$this->l->set("en_ca", true);
|
||||
$this->assertEquals('Default language file "en" missing', $this->l->msg('Exception.JKingWeb/Arsse/Lang/Exception.defaultFileMissing', TestClass::DEFAULT));
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testFetchAMessage
|
||||
*/
|
||||
public function testFetchAMessageWithMultipleNumericParameters() {
|
||||
public function testFetchAMessageWithMultipleNumericParameters(): void {
|
||||
$this->l->set("en_ca", true);
|
||||
$this->assertEquals('Happy Rotter and the Philosopher\'s Stone', $this->l->msg('Test.presentText', ['Happy Rotter', 'the Philosopher\'s Stone']));
|
||||
}
|
||||
|
@ -82,14 +82,14 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testFetchAMessage
|
||||
*/
|
||||
public function testFetchAMessageWithNamedParameters() {
|
||||
public function testFetchAMessageWithNamedParameters(): void {
|
||||
$this->assertEquals('Message string "Test.absentText" missing from all loaded language files (en)', $this->l->msg('Exception.JKingWeb/Arsse/Lang/Exception.stringMissing', ['msgID' => 'Test.absentText', 'fileList' => 'en']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFetchAMessage
|
||||
*/
|
||||
public function testReloadDefaultStrings() {
|
||||
public function testReloadDefaultStrings(): void {
|
||||
$this->l->set("de", true);
|
||||
$this->l->set("en", true);
|
||||
$this->assertEquals('and the Philosopher\'s Stone', $this->l->msg('Test.presentText'));
|
||||
|
@ -98,7 +98,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/**
|
||||
* @depends testFetchAMessage
|
||||
*/
|
||||
public function testReloadGeneralTagAfterSubtag() {
|
||||
public function testReloadGeneralTagAfterSubtag(): void {
|
||||
$this->l->set("en", true);
|
||||
$this->l->set("en_us", true);
|
||||
$this->assertEquals('and the Sorcerer\'s Stone', $this->l->msg('Test.presentText'));
|
||||
|
|
|
@ -16,65 +16,65 @@ class TestErrors extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public $path;
|
||||
public $l;
|
||||
|
||||
public function setUpSeries() {
|
||||
public function setUpSeries(): void {
|
||||
$this->l->set("", true);
|
||||
}
|
||||
|
||||
public function testLoadEmptyFile() {
|
||||
public function testLoadEmptyFile(): void {
|
||||
$this->assertException("fileCorrupt", "Lang");
|
||||
$this->l->set("fr_ca", true);
|
||||
}
|
||||
|
||||
public function testLoadFileWhichDoesNotReturnAnArray() {
|
||||
public function testLoadFileWhichDoesNotReturnAnArray(): void {
|
||||
$this->assertException("fileCorrupt", "Lang");
|
||||
$this->l->set("it", true);
|
||||
}
|
||||
|
||||
public function testLoadFileWhichIsNotPhp() {
|
||||
public function testLoadFileWhichIsNotPhp(): void {
|
||||
$this->assertException("fileCorrupt", "Lang");
|
||||
$this->l->set("ko", true);
|
||||
}
|
||||
|
||||
public function testLoadFileWhichIsCorrupt() {
|
||||
public function testLoadFileWhichIsCorrupt(): void {
|
||||
$this->assertException("fileCorrupt", "Lang");
|
||||
$this->l->set("zh", true);
|
||||
}
|
||||
|
||||
public function testLoadFileWithooutReadPermission() {
|
||||
public function testLoadFileWithooutReadPermission(): void {
|
||||
$this->assertException("fileUnreadable", "Lang");
|
||||
$this->l->set("ru", true);
|
||||
}
|
||||
|
||||
public function testLoadSubtagOfMissingLanguage() {
|
||||
public function testLoadSubtagOfMissingLanguage(): void {
|
||||
$this->assertException("fileMissing", "Lang");
|
||||
$this->l->set("pt_br", true);
|
||||
}
|
||||
|
||||
public function testFetchInvalidMessage() {
|
||||
public function testFetchInvalidMessage(): void {
|
||||
$this->assertException("stringInvalid", "Lang");
|
||||
$this->l->set("vi", true);
|
||||
$txt = $this->l->msg('Test.presentText');
|
||||
}
|
||||
|
||||
public function testFetchMissingMessage() {
|
||||
public function testFetchMissingMessage(): void {
|
||||
$this->assertException("stringMissing", "Lang");
|
||||
$txt = $this->l->msg('Test.absentText');
|
||||
}
|
||||
|
||||
public function testLoadMissingDefaultLanguage() {
|
||||
public function testLoadMissingDefaultLanguage(): void {
|
||||
unlink($this->path.TestClass::DEFAULT.".php");
|
||||
$this->assertException("defaultFileMissing", "Lang");
|
||||
$this->l->set("fr", true);
|
||||
}
|
||||
|
||||
public function testLoadMissingLanguageWhenFetching() {
|
||||
public function testLoadMissingLanguageWhenFetching(): void {
|
||||
$this->l->set("en_ca");
|
||||
unlink($this->path.TestClass::DEFAULT.".php");
|
||||
$this->assertException("fileMissing", "Lang");
|
||||
$this->l->msg('Test.presentText');
|
||||
}
|
||||
|
||||
public function testLoadMissingDefaultLanguageWhenFetching() {
|
||||
public function testLoadMissingDefaultLanguageWhenFetching(): void {
|
||||
unlink($this->path.TestClass::DEFAULT.".php");
|
||||
$this->l = new TestClass($this->path);
|
||||
$this->assertException("stringMissing", "Lang");
|
||||
|
|
|
@ -11,7 +11,7 @@ use JKingWeb\Arsse\Misc\ValueInfo;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Context\Context<extended> */
|
||||
class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function testVerifyInitialState() {
|
||||
public function testVerifyInitialState(): void {
|
||||
$c = new Context;
|
||||
foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
|
||||
if ($m->isStatic() || strpos($m->name, "__") === 0) {
|
||||
|
@ -23,7 +23,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testSetContextOptions() {
|
||||
public function testSetContextOptions(): void {
|
||||
$v = [
|
||||
'reverse' => true,
|
||||
'limit' => 10,
|
||||
|
@ -85,7 +85,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testCleanIdArrayValues() {
|
||||
public function testCleanIdArrayValues(): void {
|
||||
$methods = ["articles", "editions", "tags", "labels", "subscriptions"];
|
||||
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0];
|
||||
$out = [1, 2, 4];
|
||||
|
@ -95,7 +95,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testCleanFolderIdArrayValues() {
|
||||
public function testCleanFolderIdArrayValues(): void {
|
||||
$methods = ["folders", "foldersShallow"];
|
||||
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0];
|
||||
$out = [1, 2, 4, 0];
|
||||
|
@ -105,7 +105,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testCleanStringArrayValues() {
|
||||
public function testCleanStringArrayValues(): void {
|
||||
$methods = ["searchTerms", "annotationTerms", "titleTerms", "authorTerms", "tagNames", "labelNames"];
|
||||
$now = new \DateTime;
|
||||
$in = [1, 3.0, "ook", 0, true, false, null, $now, ""];
|
||||
|
@ -116,7 +116,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testCloneAContext() {
|
||||
public function testCloneAContext(): void {
|
||||
$c1 = new Context;
|
||||
$c2 = clone $c1;
|
||||
$this->assertEquals($c1, $c2);
|
||||
|
|
|
@ -14,7 +14,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testNormalizeADate() {
|
||||
public function testNormalizeADate(): void {
|
||||
$exp = new \DateTimeImmutable("2018-01-01T00:00:00Z");
|
||||
$this->assertEquals($exp, Date::normalize(1514764800));
|
||||
$this->assertEquals($exp, Date::normalize("2018-01-01T00:00:00"));
|
||||
|
@ -26,7 +26,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertNull(Date::normalize("2018-01-01T00:00:00Z", "http"));
|
||||
}
|
||||
|
||||
public function testFormatADate() {
|
||||
public function testFormatADate(): void {
|
||||
$test = new \DateTimeImmutable("2018-01-01T00:00:00Z");
|
||||
$this->assertNull(Date::transform(null, "http"));
|
||||
$this->assertNull(Date::transform("ook", "http"));
|
||||
|
@ -40,7 +40,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(1514764800.265579, Date::transform("2018-01-01T00:00:00.265579Z", "float", "iso8601m"));
|
||||
}
|
||||
|
||||
public function testMoveDateForward() {
|
||||
public function testMoveDateForward(): void {
|
||||
$test = new \DateTimeImmutable("2018-01-01T00:00:00Z");
|
||||
$this->assertNull(Date::add("P1D", null));
|
||||
$this->assertNull(Date::add("P1D", "ook"));
|
||||
|
@ -49,7 +49,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertNull(Date::add("ook", $test));
|
||||
}
|
||||
|
||||
public function testMoveDateBack() {
|
||||
public function testMoveDateBack(): void {
|
||||
$test = new \DateTimeImmutable("2018-01-01T00:00:00Z");
|
||||
$this->assertNull(Date::sub("P1D", null));
|
||||
$this->assertNull(Date::sub("P1D", "ook"));
|
||||
|
|
|
@ -12,14 +12,14 @@ use Psr\Http\Message\ResponseInterface;
|
|||
/** @covers \JKingWeb\Arsse\Misc\HTTP */
|
||||
class TestHTTP extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
/** @dataProvider provideMediaTypes */
|
||||
public function testMatchMediaType(string $header, array $types, bool $exp) {
|
||||
$msg = (new \Zend\Diactoros\Request)->withHeader("Content-Type", $header);
|
||||
public function testMatchMediaType(string $header, array $types, bool $exp): void {
|
||||
$msg = (new \Laminas\Diactoros\Request)->withHeader("Content-Type", $header);
|
||||
$this->assertSame($exp, HTTP::matchType($msg, ...$types));
|
||||
$msg = (new \Zend\Diactoros\Response)->withHeader("Content-Type", $header);
|
||||
$msg = (new \Laminas\Diactoros\Response)->withHeader("Content-Type", $header);
|
||||
$this->assertSame($exp, HTTP::matchType($msg, ...$types));
|
||||
}
|
||||
|
||||
public function provideMediaTypes() {
|
||||
public function provideMediaTypes(): array {
|
||||
return [
|
||||
["application/json", ["application/json"], true],
|
||||
["APPLICATION/JSON", ["application/json"], true],
|
||||
|
|
|
@ -11,14 +11,14 @@ use JKingWeb\Arsse\Misc\ValueInfo;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Misc\Query */
|
||||
class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function testBasicQuery() {
|
||||
public function testBasicQuery(): void {
|
||||
$q = new Query("select * from table where a = ?", "int", 3);
|
||||
$this->assertSame("select * from table where a = ?", $q->getQuery());
|
||||
$this->assertSame(["int"], $q->getTypes());
|
||||
$this->assertSame([3], $q->getValues());
|
||||
}
|
||||
|
||||
public function testWhereQuery() {
|
||||
public function testWhereQuery(): void {
|
||||
// simple where clause
|
||||
$q = (new Query("select * from table"))->setWhere("a = ?", "int", 3);
|
||||
$this->assertSame("select * from table WHERE a = ?", $q->getQuery());
|
||||
|
@ -46,21 +46,21 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame([2, 4, 1, 3], $q->getValues());
|
||||
}
|
||||
|
||||
public function testGroupedQuery() {
|
||||
public function testGroupedQuery(): void {
|
||||
$q = (new Query("select col1, col2, count(*) as count from table"))->setGroup("col1", "col2");
|
||||
$this->assertSame("select col1, col2, count(*) as count from table GROUP BY col1, col2", $q->getQuery());
|
||||
$this->assertSame([], $q->getTypes());
|
||||
$this->assertSame([], $q->getValues());
|
||||
}
|
||||
|
||||
public function testOrderedQuery() {
|
||||
public function testOrderedQuery(): void {
|
||||
$q = (new Query("select col1, col2, col3 from table"))->setOrder("col1 desc", "col2")->setOrder("col3 asc");
|
||||
$this->assertSame("select col1, col2, col3 from table ORDER BY col1 desc, col2, col3 asc", $q->getQuery());
|
||||
$this->assertSame([], $q->getTypes());
|
||||
$this->assertSame([], $q->getValues());
|
||||
}
|
||||
|
||||
public function testLimitedQuery() {
|
||||
public function testLimitedQuery(): void {
|
||||
// no offset
|
||||
$q = (new Query("select * from table"))->setLimit(5);
|
||||
$this->assertSame("select * from table LIMIT 5", $q->getQuery());
|
||||
|
@ -78,7 +78,7 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame([], $q->getValues());
|
||||
}
|
||||
|
||||
public function testQueryWithCommonTableExpression() {
|
||||
public function testQueryWithCommonTableExpression(): void {
|
||||
$q = (new Query("select * from table where a in (select * from cte where a = ?)", "int", 1))->setCTE("cte", "select * from other_table where a = ? and b = ?", ["str", "str"], [2, 3]);
|
||||
$this->assertSame("WITH RECURSIVE cte as (select * from other_table where a = ? and b = ?) select * from table where a in (select * from cte where a = ?)", $q->getQuery());
|
||||
$this->assertSame(["str", "str", "int"], $q->getTypes());
|
||||
|
@ -90,7 +90,7 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame([2, 3, 4, 5, 1], $q->getValues());
|
||||
}
|
||||
|
||||
public function testQueryWithPushedCommonTableExpression() {
|
||||
public function testQueryWithPushedCommonTableExpression(): void {
|
||||
$q = (new Query("select * from table1"))->setWhere("a between ? and ?", ["datetime", "datetime"], [1, 2])
|
||||
->setCTE("cte1", "select * from table2 where a = ? and b = ?", ["str", "str"], [3, 4])
|
||||
->pushCTE("cte2")
|
||||
|
@ -100,7 +100,7 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame([3, 4, 1, 2, 5], $q->getValues());
|
||||
}
|
||||
|
||||
public function testComplexQuery() {
|
||||
public function testComplexQuery(): void {
|
||||
$q = (new query("select *, ? as const from table", "datetime", 1))
|
||||
->setWhereNot("b = ?", "bool", 2)
|
||||
->setGroup("col1", "col2")
|
||||
|
|
|
@ -15,7 +15,7 @@ class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideNormalizations */
|
||||
public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null) {
|
||||
public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null): void {
|
||||
$this->assertSame($exp, URL::normalize($url, $user, $pass));
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideQueries */
|
||||
public function testAppendQueryParameters(string $url, string $query, string $exp) {
|
||||
public function testAppendQueryParameters(string $url, string $query, string $exp): void {
|
||||
$this->assertSame($exp, URL::queryAppend($url, $query));
|
||||
}
|
||||
|
||||
|
@ -93,11 +93,11 @@ class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideAbsolutes */
|
||||
public function testDetermineAbsoluteness(bool $exp, string $url) {
|
||||
public function testDetermineAbsoluteness(bool $exp, string $url): void {
|
||||
$this->assertSame($exp, URL::absolute($url));
|
||||
}
|
||||
|
||||
public function provideAbsolutes() {
|
||||
public function provideAbsolutes(): array {
|
||||
return [
|
||||
[true, "http://example.com/"],
|
||||
[true, "HTTP://example.com/"],
|
||||
|
|
|
@ -16,7 +16,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testGetIntegerInfo() {
|
||||
public function testGetIntegerInfo(): void {
|
||||
$tests = [
|
||||
[null, I::NULL],
|
||||
["", I::NULL],
|
||||
|
@ -91,7 +91,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame($exp, I::int($value), "Test returned ".decbin(I::int($value))." for value: ".var_export($value, true));
|
||||
}
|
||||
}
|
||||
public function testGetStringInfo() {
|
||||
public function testGetStringInfo(): void {
|
||||
$tests = [
|
||||
[null, I::NULL],
|
||||
["", I::VALID | I::EMPTY],
|
||||
|
@ -162,7 +162,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testValidateDatabaseIdentifier() {
|
||||
public function testValidateDatabaseIdentifier(): void {
|
||||
$tests = [
|
||||
[null, false, true],
|
||||
["", false, true],
|
||||
|
@ -234,7 +234,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testValidateBoolean() {
|
||||
public function testValidateBoolean(): void {
|
||||
$tests = [
|
||||
[null, null],
|
||||
["", false],
|
||||
|
@ -310,7 +310,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideSimpleNormalizationValues */
|
||||
public function testNormalizeSimpleValues($input, string $typeName, $exp, bool $pass, bool $strict, bool $drop) {
|
||||
public function testNormalizeSimpleValues($input, string $typeName, $exp, bool $pass, bool $strict, bool $drop): void {
|
||||
$assert = function($exp, $act, string $msg) {
|
||||
if (is_null($exp)) {
|
||||
$this->assertNull($act, $msg);
|
||||
|
@ -366,7 +366,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideDateNormalizationValues */
|
||||
public function testNormalizeDateValues($input, $format, $exp, bool $strict, bool $drop) {
|
||||
public function testNormalizeDateValues($input, $format, $exp, bool $strict, bool $drop): void {
|
||||
if ($strict && $drop) {
|
||||
$modeName = "strict drop";
|
||||
$modeConst = I::M_STRICT | I::M_DROP;
|
||||
|
@ -397,7 +397,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testNormalizeComplexValues() {
|
||||
public function testNormalizeComplexValues(): void {
|
||||
// Array-mode tests
|
||||
$tests = [
|
||||
[I::T_INT | I::M_DROP, [1, 2, 2.2, 3], [1,2,null,3] ],
|
||||
|
@ -640,7 +640,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
return $out;
|
||||
}
|
||||
|
||||
public function testFlattenArray() {
|
||||
public function testFlattenArray(): void {
|
||||
$arr = [1, [2, 3, [4, 5]], 6, [[7, 8], 9, 10]];
|
||||
$exp = range(1, 10);
|
||||
$this->assertSame($exp, I::flatten($arr));
|
||||
|
|
|
@ -15,10 +15,10 @@ use JKingWeb\Arsse\Db\ExceptionInput;
|
|||
use JKingWeb\Arsse\Db\Transaction;
|
||||
use JKingWeb\Arsse\REST\Fever\API;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
use Zend\Diactoros\Response\XmlResponse;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\Response\XmlResponse;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\Fever\API<extended> */
|
||||
class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -173,7 +173,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideTokenAuthenticationRequests */
|
||||
public function testAuthenticateAUserToken(bool $httpRequired, bool $tokenEnforced, string $httpUser = null, array $dataPost, array $dataGet, ResponseInterface $exp) {
|
||||
public function testAuthenticateAUserToken(bool $httpRequired, bool $tokenEnforced, string $httpUser = null, array $dataPost, array $dataGet, ResponseInterface $exp): void {
|
||||
self::setConf([
|
||||
'userHTTPAuthRequired' => $httpRequired,
|
||||
'userSessionEnforced' => $tokenEnforced,
|
||||
|
@ -244,7 +244,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testListGroups() {
|
||||
public function testListGroups(): void {
|
||||
\Phake::when(Arsse::$db)->tagList(Arsse::$user->id)->thenReturn(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscriptions' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscriptions' => 2],
|
||||
|
@ -271,7 +271,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
public function testListFeeds() {
|
||||
public function testListFeeds(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result([
|
||||
['id' => 1, 'feed' => 5, 'title' => "Ankh-Morpork News", 'url' => "http://example.com/feed", 'source' => "http://example.com/", 'edited' => "2019-01-01 21:12:00", 'favicon' => "http://example.com/favicon.ico"],
|
||||
['id' => 2, 'feed' => 9, 'title' => "Ook, Ook Eek Ook!", 'url' => "http://example.net/feed", 'source' => "http://example.net/", 'edited' => "1988-06-24 12:21:00", 'favicon' => ""],
|
||||
|
@ -299,7 +299,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideItemListContexts */
|
||||
public function testListItems(string $url, Context $c, bool $desc) {
|
||||
public function testListItems(string $url, Context $c, bool $desc): void {
|
||||
$fields = ["id", "subscription", "title", "author", "content", "url", "starred", "unread", "published_date"];
|
||||
$order = [$desc ? "id desc" : "id"];
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->articles['db']));
|
||||
|
@ -329,7 +329,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testListItemIds() {
|
||||
public function testListItemIds(): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved));
|
||||
|
@ -344,7 +344,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->h->dispatch($this->req("api&unread_item_ids")));
|
||||
}
|
||||
|
||||
public function testListHotLinks() {
|
||||
public function testListHotLinks(): void {
|
||||
// hot links are not actually implemented, so an empty array should be all we get
|
||||
$exp = new JsonResponse([
|
||||
'links' => []
|
||||
|
@ -353,7 +353,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideMarkingContexts */
|
||||
public function testSetMarks(string $post, Context $c, array $data, array $out) {
|
||||
public function testSetMarks(string $post, Context $c, array $data, array $out): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved));
|
||||
|
@ -371,7 +371,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideMarkingContexts */
|
||||
public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out) {
|
||||
public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved));
|
||||
|
@ -427,7 +427,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideInvalidRequests */
|
||||
public function testSendInvalidRequests(ServerRequest $req, ResponseInterface $exp) {
|
||||
public function testSendInvalidRequests(ServerRequest $req, ResponseInterface $exp): void {
|
||||
$this->assertMessage($exp, $this->h->dispatch($req));
|
||||
}
|
||||
|
||||
|
@ -439,7 +439,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testMakeABaseQuery() {
|
||||
public function testMakeABaseQuery(): void {
|
||||
$this->h = \Phake::partialMock(API::class);
|
||||
\Phake::when($this->h)->logIn->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionRefreshed(Arsse::$user->id)->thenReturn(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
|
||||
|
@ -467,7 +467,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
public function testUndoReadMarks() {
|
||||
public function testUndoReadMarks(): void {
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$out = ['unread_item_ids' => "4,5,6"];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
|
||||
|
@ -483,7 +483,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db)->articleMark; // only called one time, above
|
||||
}
|
||||
|
||||
public function testOutputToXml() {
|
||||
public function testOutputToXml(): void {
|
||||
\Phake::when($this->h)->processRequest->thenReturn([
|
||||
'items' => $this->articles['rest'],
|
||||
'total_items' => 1024,
|
||||
|
@ -493,13 +493,13 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
public function testListFeedIcons() {
|
||||
public function testListFeedIcons(): void {
|
||||
$act = $this->h->dispatch($this->req("api&favicons"));
|
||||
$exp = new JsonResponse(['favicons' => [['id' => 0, 'data' => API::GENERIC_ICON_TYPE.",".API::GENERIC_ICON_DATA]]]);
|
||||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
public function testAnswerOptionsRequest() {
|
||||
public function testAnswerOptionsRequest(): void {
|
||||
$act = $this->h->dispatch($this->req("api", "", "OPTIONS"));
|
||||
$exp = new EmptyResponse(204, [
|
||||
'Allow' => "POST",
|
||||
|
|
|
@ -36,7 +36,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider providePasswordCreations */
|
||||
public function testRegisterAUserPassword(string $user, string $password = null, $exp) {
|
||||
public function testRegisterAUserPassword(string $user, string $password = null, $exp): void {
|
||||
\Phake::when(Arsse::$user)->generatePassword->thenReturn("RANDOM_PASSWORD");
|
||||
\Phake::when(Arsse::$db)->tokenCreate->thenReturnCallback(function($user, $class, $id = null) {
|
||||
return $id ?? "RANDOM_TOKEN";
|
||||
|
@ -66,7 +66,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testUnregisterAUser() {
|
||||
public function testUnregisterAUser(): void {
|
||||
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(3);
|
||||
$this->assertTrue($this->u->unregister("jane.doe@example.com"));
|
||||
\Phake::verify(Arsse::$db)->tokenRevoke("jane.doe@example.com", "fever.login");
|
||||
|
@ -76,7 +76,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserAuthenticationRequests */
|
||||
public function testAuthenticateAUserName(string $user, string $password, bool $exp) {
|
||||
public function testAuthenticateAUserName(string $user, string $password, bool $exp): void {
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("constraintViolation"));
|
||||
\Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("jane.doe@example.com:secret"))->thenReturn(['user' => "jane.doe@example.com"]);
|
||||
\Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("john.doe@example.com:superman"))->thenReturn(['user' => "john.doe@example.com"]);
|
||||
|
|
|
@ -16,8 +16,8 @@ use JKingWeb\Arsse\Db\ExceptionInput;
|
|||
use JKingWeb\Arsse\Db\Transaction;
|
||||
use JKingWeb\Arsse\REST\NextcloudNews\V1_2;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse as Response;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\NextcloudNews\V1_2<extended> */
|
||||
class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -333,18 +333,18 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
return $value;
|
||||
}
|
||||
|
||||
public function testSendAuthenticationChallenge() {
|
||||
public function testSendAuthenticationChallenge(): void {
|
||||
$exp = new EmptyResponse(401);
|
||||
$this->assertMessage($exp, $this->req("GET", "/", "", [], false));
|
||||
}
|
||||
|
||||
/** @dataProvider provideInvalidPaths */
|
||||
public function testRespondToInvalidPaths($path, $method, $code, $allow = null) {
|
||||
public function testRespondToInvalidPaths($path, $method, $code, $allow = null): void {
|
||||
$exp = new EmptyResponse($code, $allow ? ['Allow' => $allow] : []);
|
||||
$this->assertMessage($exp, $this->req($method, $path));
|
||||
}
|
||||
|
||||
public function provideInvalidPaths() {
|
||||
public function provideInvalidPaths(): array {
|
||||
return [
|
||||
["/", "GET", 404],
|
||||
["/", "POST", 404],
|
||||
|
@ -371,7 +371,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testRespondToInvalidInputTypes() {
|
||||
public function testRespondToInvalidInputTypes(): void {
|
||||
$exp = new EmptyResponse(415, ['Accept' => "application/json"]);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/folders/1", '<data/>', ['Content-Type' => "application/xml"]));
|
||||
$exp = new EmptyResponse(400);
|
||||
|
@ -380,7 +380,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideOptionsRequests */
|
||||
public function testRespondToOptionsRequests(string $url, string $allow, string $accept) {
|
||||
public function testRespondToOptionsRequests(string $url, string $allow, string $accept): void {
|
||||
$exp = new EmptyResponse(204, [
|
||||
'Allow' => $allow,
|
||||
'Accept' => $accept,
|
||||
|
@ -388,7 +388,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("OPTIONS", $url));
|
||||
}
|
||||
|
||||
public function provideOptionsRequests() {
|
||||
public function provideOptionsRequests(): array {
|
||||
return [
|
||||
["/feeds", "HEAD,GET,POST", "application/json"],
|
||||
["/feeds/2112", "DELETE", "application/json"],
|
||||
|
@ -396,7 +396,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testListFolders() {
|
||||
public function testListFolders(): void {
|
||||
$list = [
|
||||
['id' => 1, 'name' => "Software", 'parent' => null],
|
||||
['id' => 12, 'name' => "Hardware", 'parent' => null],
|
||||
|
@ -411,9 +411,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideFolderCreations */
|
||||
public function testAddAFolder(array $input, bool $body, $output, ResponseInterface $exp) {
|
||||
public function testAddAFolder(array $input, bool $body, $output, ResponseInterface $exp): void {
|
||||
if ($output instanceof ExceptionInput) {
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenThrow($output);
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenThrow($output);
|
||||
} else {
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenReturn($output);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet->thenReturn($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null]));
|
||||
|
@ -428,7 +428,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function provideFolderCreations() {
|
||||
public function provideFolderCreations(): array {
|
||||
return [
|
||||
[['name' => "Software"], true, 1, new Response(['folders' => [['id'=> 1, 'name' => "Software"]]])],
|
||||
[['name' => "Software"], false, 1, new Response(['folders' => [['id'=> 1, 'name' => "Software"]]])],
|
||||
|
@ -441,7 +441,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testRemoveAFolder() {
|
||||
public function testRemoveAFolder(): void {
|
||||
\Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$exp = new EmptyResponse(204);
|
||||
$this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
|
||||
|
@ -452,7 +452,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideFolderRenamings */
|
||||
public function testRenameAFolder(array $input, int $id, $output, ResponseInterface $exp) {
|
||||
public function testRenameAFolder(array $input, int $id, $output, ResponseInterface $exp): void {
|
||||
if ($output instanceof ExceptionInput) {
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->thenThrow($output);
|
||||
} else {
|
||||
|
@ -463,7 +463,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, $id, $input);
|
||||
}
|
||||
|
||||
public function provideFolderRenamings() {
|
||||
public function provideFolderRenamings(): array {
|
||||
return [
|
||||
[['name' => "Software"], 1, true, new EmptyResponse(204)],
|
||||
[['name' => "Software"], 2, new ExceptionInput("constraintViolation"), new EmptyResponse(409)],
|
||||
|
@ -474,7 +474,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testRetrieveServerVersion() {
|
||||
public function testRetrieveServerVersion(): void {
|
||||
$exp = new Response([
|
||||
'version' => V1_2::VERSION,
|
||||
'arsse_version' => Arsse::VERSION,
|
||||
|
@ -482,7 +482,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("GET", "/version"));
|
||||
}
|
||||
|
||||
public function testListSubscriptions() {
|
||||
public function testListSubscriptions(): void {
|
||||
$exp1 = [
|
||||
'feeds' => [],
|
||||
'starredCount' => 0,
|
||||
|
@ -502,7 +502,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideNewSubscriptions */
|
||||
public function testAddASubscription(array $input, $id, int $latestEdition, array $output, $moveOutcome, ResponseInterface $exp) {
|
||||
public function testAddASubscription(array $input, $id, int $latestEdition, array $output, $moveOutcome, ResponseInterface $exp): void {
|
||||
if ($id instanceof \Exception) {
|
||||
\Phake::when(Arsse::$db)->subscriptionAdd->thenThrow($id);
|
||||
} else {
|
||||
|
@ -528,12 +528,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
if ($input['folderId'] ?? 0) {
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, $id, ['folder' => (int) $input['folderId']]);
|
||||
} else {
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet;
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function provideNewSubscriptions() {
|
||||
public function provideNewSubscriptions(): array {
|
||||
$feedException = new \JKingWeb\Arsse\Feed\Exception("", new \PicoFeed\Reader\SubscriptionNotFoundException);
|
||||
return [
|
||||
[['url' => "http://example.com/news.atom", 'folderId' => 3], 2112, 0, $this->feeds['db'][0], new ExceptionInput("idMissing"), new Response(['feeds' => [$this->feeds['rest'][0]]])],
|
||||
|
@ -545,7 +545,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testRemoveASubscription() {
|
||||
public function testRemoveASubscription(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$exp = new EmptyResponse(204);
|
||||
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
|
||||
|
@ -555,7 +555,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db, \Phake::times(2))->subscriptionRemove(Arsse::$user->id, 1);
|
||||
}
|
||||
|
||||
public function testMoveASubscription() {
|
||||
public function testMoveASubscription(): void {
|
||||
$in = [
|
||||
['folderId' => 0],
|
||||
['folderId' => 42],
|
||||
|
@ -583,7 +583,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[5])));
|
||||
}
|
||||
|
||||
public function testRenameASubscription() {
|
||||
public function testRenameASubscription(): void {
|
||||
$in = [
|
||||
['feedTitle' => null],
|
||||
['feedTitle' => "Ook"],
|
||||
|
@ -613,7 +613,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[6])));
|
||||
}
|
||||
|
||||
public function testListStaleFeeds() {
|
||||
public function testListStaleFeeds(): void {
|
||||
$out = [
|
||||
[
|
||||
'id' => 42,
|
||||
|
@ -629,7 +629,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("GET", "/feeds/all"));
|
||||
}
|
||||
|
||||
public function testUpdateAFeed() {
|
||||
public function testUpdateAFeed(): void {
|
||||
$in = [
|
||||
['feedId' => 42], // valid
|
||||
['feedId' => 2112], // feed does not exist
|
||||
|
@ -650,7 +650,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[4])));
|
||||
}
|
||||
|
||||
public function testListArticles() {
|
||||
public function testListArticles(): void {
|
||||
$t = new \DateTime;
|
||||
$in = [
|
||||
['type' => 0, 'id' => 42], // type=0 => subscription/feed
|
||||
|
@ -704,7 +704,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5), $this->anything(), ["edition desc"]);
|
||||
}
|
||||
|
||||
public function testMarkAFolderRead() {
|
||||
public function testMarkAFolderRead(): void {
|
||||
$read = ['read' => true];
|
||||
$in = json_encode(['newestItemId' => 2112]);
|
||||
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(1)->latestEdition(2112))->thenReturn(42);
|
||||
|
@ -719,7 +719,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/folders/42/read", $in));
|
||||
}
|
||||
|
||||
public function testMarkASubscriptionRead() {
|
||||
public function testMarkASubscriptionRead(): void {
|
||||
$read = ['read' => true];
|
||||
$in = json_encode(['newestItemId' => 2112]);
|
||||
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(1)->latestEdition(2112))->thenReturn(42);
|
||||
|
@ -734,7 +734,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/feeds/42/read", $in));
|
||||
}
|
||||
|
||||
public function testMarkAllItemsRead() {
|
||||
public function testMarkAllItemsRead(): void {
|
||||
$read = ['read' => true];
|
||||
$in = json_encode(['newestItemId' => 2112]);
|
||||
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->latestEdition(2112))->thenReturn(42);
|
||||
|
@ -746,7 +746,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=ook"));
|
||||
}
|
||||
|
||||
public function testChangeMarksOfASingleArticle() {
|
||||
public function testChangeMarksOfASingleArticle(): void {
|
||||
$read = ['read' => true];
|
||||
$unread = ['read' => false];
|
||||
$star = ['starred' => true];
|
||||
|
@ -772,7 +772,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db, \Phake::times(8))->articleMark(Arsse::$user->id, $this->anything(), $this->anything());
|
||||
}
|
||||
|
||||
public function testChangeMarksOfMultipleArticles() {
|
||||
public function testChangeMarksOfMultipleArticles(): void {
|
||||
$read = ['read' => true];
|
||||
$unread = ['read' => false];
|
||||
$star = ['starred' => true];
|
||||
|
@ -827,7 +827,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[1]));
|
||||
}
|
||||
|
||||
public function testQueryTheServerStatus() {
|
||||
public function testQueryTheServerStatus(): void {
|
||||
$interval = Arsse::$conf->serviceFrequency;
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
$invalid = $valid->sub($interval)->sub($interval);
|
||||
|
@ -847,21 +847,21 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("GET", "/status"));
|
||||
}
|
||||
|
||||
public function testCleanUpBeforeUpdate() {
|
||||
public function testCleanUpBeforeUpdate(): void {
|
||||
\Phake::when(Arsse::$db)->feedCleanup()->thenReturn(true);
|
||||
$exp = new EmptyResponse(204);
|
||||
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
|
||||
\Phake::verify(Arsse::$db)->feedCleanup();
|
||||
}
|
||||
|
||||
public function testCleanUpAfterUpdate() {
|
||||
public function testCleanUpAfterUpdate(): void {
|
||||
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(true);
|
||||
$exp = new EmptyResponse(204);
|
||||
$this->assertMessage($exp, $this->req("GET", "/cleanup/after-update"));
|
||||
\Phake::verify(Arsse::$db)->articleCleanup();
|
||||
}
|
||||
|
||||
public function testQueryTheUserStatus() {
|
||||
public function testQueryTheUserStatus(): void {
|
||||
$act = $this->req("GET", "/user");
|
||||
$exp = new Response([
|
||||
'userId' => Arsse::$user->id,
|
||||
|
@ -872,7 +872,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
public function testPreferJsonOverQueryParameters() {
|
||||
public function testPreferJsonOverQueryParameters(): void {
|
||||
$in = ['name' => "Software"];
|
||||
$url = "/folders?name=Hardware";
|
||||
$out1 = ['id' => 1, 'name' => "Software"];
|
||||
|
@ -885,7 +885,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in)));
|
||||
}
|
||||
|
||||
public function testMeldJsonAndQueryParameters() {
|
||||
public function testMeldJsonAndQueryParameters(): void {
|
||||
$in = ['oldestFirst' => true];
|
||||
$url = "/items?type=2";
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result([]));
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace JKingWeb\Arsse\TestCase\REST\NextcloudNews;
|
|||
|
||||
use JKingWeb\Arsse\REST\NextcloudNews\Versions;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\Response\JsonResponse as Response;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\NextcloudNews\Versions */
|
||||
class TestVersions extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -25,24 +25,24 @@ class TestVersions extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
return (new Versions)->dispatch($req);
|
||||
}
|
||||
|
||||
public function testFetchVersionList() {
|
||||
public function testFetchVersionList(): void {
|
||||
$exp = new Response(['apiLevels' => ['v1-2']]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/"));
|
||||
$this->assertMessage($exp, $this->req("GET", "/"));
|
||||
$this->assertMessage($exp, $this->req("GET", "/"));
|
||||
}
|
||||
|
||||
public function testRespondToOptionsRequest() {
|
||||
public function testRespondToOptionsRequest(): void {
|
||||
$exp = new EmptyResponse(204, ['Allow' => "HEAD,GET"]);
|
||||
$this->assertMessage($exp, $this->req("OPTIONS", "/"));
|
||||
}
|
||||
|
||||
public function testUseIncorrectMethod() {
|
||||
public function testUseIncorrectMethod(): void {
|
||||
$exp = new EmptyResponse(405, ['Allow' => "HEAD,GET"]);
|
||||
$this->assertMessage($exp, $this->req("POST", "/"));
|
||||
}
|
||||
|
||||
public function testUseIncorrectPath() {
|
||||
public function testUseIncorrectPath(): void {
|
||||
$exp = new EmptyResponse(404);
|
||||
$this->assertMessage($exp, $this->req("GET", "/ook"));
|
||||
$this->assertMessage($exp, $this->req("OPTIONS", "/ook"));
|
||||
|
|
|
@ -15,17 +15,17 @@ use JKingWeb\Arsse\REST\NextcloudNews\V1_2 as NCN;
|
|||
use JKingWeb\Arsse\REST\TinyTinyRSS\API as TTRSS;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Request;
|
||||
use Zend\Diactoros\Response;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\Response\TextResponse;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Request;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\TextResponse;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST */
|
||||
class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
||||
/** @dataProvider provideApiMatchData */
|
||||
public function testMatchAUrlToAnApi($apiList, string $input, array $exp) {
|
||||
public function testMatchAUrlToAnApi($apiList, string $input, array $exp): void {
|
||||
$r = new REST($apiList);
|
||||
try {
|
||||
$out = $r->apiMatch($input);
|
||||
|
@ -61,7 +61,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideAuthenticableRequests */
|
||||
public function testAuthenticateRequests(array $serverParams, array $expAttr) {
|
||||
public function testAuthenticateRequests(array $serverParams, array $expAttr): void {
|
||||
$r = new REST();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
|
@ -93,7 +93,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testSendAuthenticationChallenges() {
|
||||
public function testSendAuthenticationChallenges(): void {
|
||||
self::setConf();
|
||||
$r = new REST();
|
||||
$in = new EmptyResponse(401);
|
||||
|
@ -106,7 +106,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUnnormalizedOrigins */
|
||||
public function testNormalizeOrigins(string $origin, string $exp, array $ports = null) {
|
||||
public function testNormalizeOrigins(string $origin, string $exp, array $ports = null): void {
|
||||
$r = new REST();
|
||||
$act = $r->corsNormalizeOrigin($origin, $ports);
|
||||
$this->assertSame($exp, $act);
|
||||
|
@ -149,7 +149,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @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): void {
|
||||
self::setConf();
|
||||
$r = \Phake::partialMock(REST::class);
|
||||
\Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function($origin) {
|
||||
|
@ -187,7 +187,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideCorsHeaders */
|
||||
public function testAddCorsHeaders(string $reqMethod, array $reqHeaders, array $resHeaders, array $expHeaders) {
|
||||
public function testAddCorsHeaders(string $reqMethod, array $reqHeaders, array $resHeaders, array $expHeaders): void {
|
||||
$r = new REST();
|
||||
$req = new Request("", $reqMethod, "php://memory", $reqHeaders);
|
||||
$res = new EmptyResponse(204, $resHeaders);
|
||||
|
@ -251,7 +251,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUnnormalizedResponses */
|
||||
public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null) {
|
||||
public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null): void {
|
||||
$r = \Phake::partialMock(REST::class);
|
||||
\Phake::when($r)->corsNegotiate->thenReturn(true);
|
||||
\Phake::when($r)->challenge->thenReturnCallback(function($res) {
|
||||
|
@ -286,7 +286,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testCreateHandlers() {
|
||||
public function testCreateHandlers(): void {
|
||||
$r = new REST();
|
||||
foreach (REST::API_LIST as $api) {
|
||||
$class = $api['class'];
|
||||
|
@ -295,7 +295,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @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 =""): void {
|
||||
$r = \Phake::partialMock(REST::class);
|
||||
\Phake::when($r)->normalizeResponse->thenReturnCallback(function($res) {
|
||||
return $res;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\TestCase\REST\TinyTinyRSS;
|
||||
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\User;
|
||||
use JKingWeb\Arsse\Database;
|
||||
|
@ -16,9 +17,9 @@ use JKingWeb\Arsse\Db\ExceptionInput;
|
|||
use JKingWeb\Arsse\Db\Transaction;
|
||||
use JKingWeb\Arsse\REST\TinyTinyRSS\API;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\Response\JsonResponse as Response;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\JsonResponse as Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\API<extended>
|
||||
* @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Exception */
|
||||
|
@ -133,7 +134,7 @@ LONG_STRING;
|
|||
return $this->h->dispatch($req);
|
||||
}
|
||||
|
||||
protected function reqAuth($data, $user) {
|
||||
protected function reqAuth($data, $user): ResponseInterface {
|
||||
return $this->req($data, "POST", "", null, $user);
|
||||
}
|
||||
|
||||
|
@ -178,7 +179,7 @@ LONG_STRING;
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testHandleInvalidPaths() {
|
||||
public function testHandleInvalidPaths(): void {
|
||||
$exp = $this->respErr("MALFORMED_INPUT", [], null);
|
||||
$this->assertMessage($exp, $this->req(null, "POST", "", ""));
|
||||
$this->assertMessage($exp, $this->req(null, "POST", "/", ""));
|
||||
|
@ -187,7 +188,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req(null, "POST", "/bad/path", ""));
|
||||
}
|
||||
|
||||
public function testHandleOptionsRequest() {
|
||||
public function testHandleOptionsRequest(): void {
|
||||
$exp = new EmptyResponse(204, [
|
||||
'Allow' => "POST",
|
||||
'Accept' => "application/json, text/json",
|
||||
|
@ -195,14 +196,14 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req(null, "OPTIONS", "", ""));
|
||||
}
|
||||
|
||||
public function testHandleInvalidData() {
|
||||
public function testHandleInvalidData(): void {
|
||||
$exp = $this->respErr("MALFORMED_INPUT", [], null);
|
||||
$this->assertMessage($exp, $this->req(null, "POST", "", "This is not valid JSON data"));
|
||||
$this->assertMessage($exp, $this->req(null, "POST", "", "")); // lack of data is also an error
|
||||
}
|
||||
|
||||
/** @dataProvider provideLoginRequests */
|
||||
public function testLogIn(array $conf, $httpUser, array $data, $sessions) {
|
||||
public function testLogIn(array $conf, $httpUser, array $data, $sessions): void {
|
||||
Arsse::$user->id = null;
|
||||
self::setConf($conf);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(false);
|
||||
|
@ -236,7 +237,7 @@ LONG_STRING;
|
|||
}
|
||||
|
||||
/** @dataProvider provideResumeRequests */
|
||||
public function testValidateASession(array $conf, $httpUser, string $data, $result) {
|
||||
public function testValidateASession(array $conf, $httpUser, string $data, $result): void {
|
||||
Arsse::$user->id = null;
|
||||
self::setConf($conf);
|
||||
\Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
|
||||
|
@ -273,7 +274,7 @@ LONG_STRING;
|
|||
return $this->generateLoginRequests("isLoggedIn");
|
||||
}
|
||||
|
||||
public function generateLoginRequests(string $type) {
|
||||
public function generateLoginRequests(string $type): array {
|
||||
$john = "john.doe@example.com";
|
||||
$johnGood = [
|
||||
'user' => $john,
|
||||
|
@ -520,7 +521,7 @@ LONG_STRING;
|
|||
}
|
||||
}
|
||||
|
||||
public function testHandleGenericError() {
|
||||
public function testHandleGenericError(): void {
|
||||
\Phake::when(Arsse::$user)->auth(Arsse::$user->id, $this->anything())->thenThrow(new \JKingWeb\Arsse\Db\ExceptionTimeout("general"));
|
||||
$data = [
|
||||
'op' => "login",
|
||||
|
@ -531,7 +532,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($data));
|
||||
}
|
||||
|
||||
public function testLogOut() {
|
||||
public function testLogOut(): void {
|
||||
\Phake::when(Arsse::$db)->sessionDestroy->thenReturn(true);
|
||||
$data = [
|
||||
'op' => "logout",
|
||||
|
@ -542,7 +543,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db)->sessionDestroy(Arsse::$user->id, "PriestsOfSyrinx");
|
||||
}
|
||||
|
||||
public function testHandleUnknownMethods() {
|
||||
public function testHandleUnknownMethods(): void {
|
||||
$exp = $this->respErr("UNKNOWN_METHOD", ['method' => "thisMethodDoesNotExist"]);
|
||||
$data = [
|
||||
'op' => "thisMethodDoesNotExist",
|
||||
|
@ -551,7 +552,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($data));
|
||||
}
|
||||
|
||||
public function testHandleMixedCaseMethods() {
|
||||
public function testHandleMixedCaseMethods(): void {
|
||||
$data = [
|
||||
'op' => "isLoggedIn",
|
||||
'sid' => "PriestsOfSyrinx",
|
||||
|
@ -566,7 +567,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($data));
|
||||
}
|
||||
|
||||
public function testRetrieveServerVersion() {
|
||||
public function testRetrieveServerVersion(): void {
|
||||
$data = [
|
||||
'op' => "getVersion",
|
||||
'sid' => "PriestsOfSyrinx",
|
||||
|
@ -578,7 +579,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($data));
|
||||
}
|
||||
|
||||
public function testRetrieveProtocolLevel() {
|
||||
public function testRetrieveProtocolLevel(): void {
|
||||
$data = [
|
||||
'op' => "getApiLevel",
|
||||
'sid' => "PriestsOfSyrinx",
|
||||
|
@ -587,7 +588,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($data));
|
||||
}
|
||||
|
||||
public function testAddACategory() {
|
||||
public function testAddACategory(): void {
|
||||
$in = [
|
||||
['op' => "addCategory", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"],
|
||||
['op' => "addCategory", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware", 'parent_id' => 1],
|
||||
|
@ -638,7 +639,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($in[5]));
|
||||
}
|
||||
|
||||
public function testRemoveACategory() {
|
||||
public function testRemoveACategory(): void {
|
||||
$in = [
|
||||
['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42],
|
||||
['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112],
|
||||
|
@ -661,7 +662,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(3))->folderRemove(Arsse::$user->id, $this->anything());
|
||||
}
|
||||
|
||||
public function testMoveACategory() {
|
||||
public function testMoveACategory(): void {
|
||||
$in = [
|
||||
['op' => "moveCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42, 'parent_id' => 1],
|
||||
['op' => "moveCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112, 'parent_id' => 2],
|
||||
|
@ -713,7 +714,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(5))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
|
||||
}
|
||||
|
||||
public function testRenameACategory() {
|
||||
public function testRenameACategory(): void {
|
||||
$in = [
|
||||
['op' => "renameCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42, 'caption' => "Ook"],
|
||||
['op' => "renameCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112, 'caption' => "Eek"],
|
||||
|
@ -753,7 +754,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(3))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
|
||||
}
|
||||
|
||||
public function testAddASubscription() {
|
||||
public function testAddASubscription(): void {
|
||||
$in = [
|
||||
['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx", 'feed_url' => "http://example.com/0"],
|
||||
['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx", 'feed_url' => "http://example.com/1", 'category_id' => 42],
|
||||
|
@ -785,12 +786,12 @@ LONG_STRING;
|
|||
];
|
||||
$out = [
|
||||
['code' => 1, 'feed_id' => 2],
|
||||
['code' => 5, 'message' => (new \JKingWeb\Arsse\Feed\Exception("http://example.com/1", new \PicoFeed\Client\UnauthorizedException()))->getMessage()],
|
||||
['code' => 5, 'message' => (new \JKingWeb\Arsse\Feed\Exception("http://example.com/1", $this->mockGuzzleException(ClientException::class, "", 401)))->getMessage()],
|
||||
['code' => 1, 'feed_id' => 0],
|
||||
['code' => 0, 'feed_id' => 3],
|
||||
['code' => 0, 'feed_id' => 1],
|
||||
['code' => 3, 'message' => (new \JKingWeb\Arsse\Feed\Exception("http://localhost:8000/Feed/Discovery/Invalid", new \PicoFeed\Reader\SubscriptionNotFoundException()))->getMessage()],
|
||||
['code' => 2, 'message' => (new \JKingWeb\Arsse\Feed\Exception("http://example.com/6", new \PicoFeed\Client\InvalidUrlException()))->getMessage()],
|
||||
['code' => 2, 'message' => (new \JKingWeb\Arsse\Feed\Exception("http://example.com/6", $this->mockGuzzleException(ClientException::class, "", 404)))->getMessage()],
|
||||
['code' => 6, 'message' => (new \JKingWeb\Arsse\Feed\Exception("http://example.com/7", new \PicoFeed\Parser\MalformedXmlException()))->getMessage()],
|
||||
['code' => 1, 'feed_id' => 4],
|
||||
['code' => 0, 'feed_id' => 4],
|
||||
|
@ -802,12 +803,12 @@ LONG_STRING;
|
|||
['id' => 4, 'url' => "http://example.com/9"],
|
||||
];
|
||||
\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", $this->mockGuzzleException(ClientException::class, "", 401)));
|
||||
\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[4])->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", $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
\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[9])->thenThrow(new ExceptionInput("constraintViolation"));
|
||||
|
@ -828,7 +829,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet(Arsse::$user->id, 4, ['folder' => 1]);
|
||||
}
|
||||
|
||||
public function testRemoveASubscription() {
|
||||
public function testRemoveASubscription(): void {
|
||||
$in = [
|
||||
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42],
|
||||
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112],
|
||||
|
@ -850,7 +851,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(5))->subscriptionRemove(Arsse::$user->id, $this->anything());
|
||||
}
|
||||
|
||||
public function testMoveASubscription() {
|
||||
public function testMoveASubscription(): void {
|
||||
$in = [
|
||||
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => 1],
|
||||
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'category_id' => 2],
|
||||
|
@ -892,7 +893,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(4))->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
|
||||
}
|
||||
|
||||
public function testRenameASubscription() {
|
||||
public function testRenameASubscription(): void {
|
||||
$in = [
|
||||
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => "Ook"],
|
||||
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'caption' => "Eek"],
|
||||
|
@ -934,7 +935,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[2]);
|
||||
}
|
||||
|
||||
public function testRetrieveTheGlobalUnreadCount() {
|
||||
public function testRetrieveTheGlobalUnreadCount(): void {
|
||||
$in = ['op' => "getUnread", 'sid' => "PriestsOfSyrinx"];
|
||||
\Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v([
|
||||
['id' => 1, 'unread' => 2112],
|
||||
|
@ -945,7 +946,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
||||
public function testRetrieveTheServerConfiguration() {
|
||||
public function testRetrieveTheServerConfiguration(): void {
|
||||
$in = ['op' => "getConfig", 'sid' => "PriestsOfSyrinx"];
|
||||
$interval = Arsse::$conf->serviceFrequency;
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
|
@ -960,7 +961,7 @@ LONG_STRING;
|
|||
$this->assertMessage($this->respGood($exp[1]), $this->req($in));
|
||||
}
|
||||
|
||||
public function testUpdateAFeed() {
|
||||
public function testUpdateAFeed(): void {
|
||||
$in = [
|
||||
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 1],
|
||||
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2],
|
||||
|
@ -980,7 +981,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($in[3]));
|
||||
}
|
||||
|
||||
public function testAddALabel() {
|
||||
public function testAddALabel(): void {
|
||||
$in = [
|
||||
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"],
|
||||
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware",],
|
||||
|
@ -1025,7 +1026,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($in[4]));
|
||||
}
|
||||
|
||||
public function testRemoveALabel() {
|
||||
public function testRemoveALabel(): void {
|
||||
$in = [
|
||||
['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -1042],
|
||||
['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -2112],
|
||||
|
@ -1053,7 +1054,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db)->labelRemove(Arsse::$user->id, 1088);
|
||||
}
|
||||
|
||||
public function testRenameALabel() {
|
||||
public function testRenameALabel(): void {
|
||||
$in = [
|
||||
['op' => "renameLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -1042, 'caption' => "Ook"],
|
||||
['op' => "renameLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -2112, 'caption' => "Eek"],
|
||||
|
@ -1099,7 +1100,7 @@ LONG_STRING;
|
|||
\Phake::verify(Arsse::$db, \Phake::times(6))->labelPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
|
||||
}
|
||||
|
||||
public function testRetrieveCategoryLists() {
|
||||
public function testRetrieveCategoryLists(): void {
|
||||
$in = [
|
||||
['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'include_empty' => true],
|
||||
['op' => "getCategories", 'sid' => "PriestsOfSyrinx"],
|
||||
|
@ -1171,7 +1172,7 @@ LONG_STRING;
|
|||
}
|
||||
}
|
||||
|
||||
public function testRetrieveCounterList() {
|
||||
public function testRetrieveCounterList(): void {
|
||||
$in = ['op' => "getCounters", 'sid' => "PriestsOfSyrinx"];
|
||||
\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)));
|
||||
|
@ -1206,7 +1207,7 @@ LONG_STRING;
|
|||
$this->assertMessage($this->respGood($exp), $this->req($in));
|
||||
}
|
||||
|
||||
public function testRetrieveTheLabelList() {
|
||||
public function testRetrieveTheLabelList(): void {
|
||||
$in = [
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx"],
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 1],
|
||||
|
@ -1251,7 +1252,7 @@ LONG_STRING;
|
|||
}
|
||||
}
|
||||
|
||||
public function testAssignArticlesToALabel() {
|
||||
public function testAssignArticlesToALabel(): void {
|
||||
$list = [
|
||||
range(1, 100),
|
||||
range(1, 50),
|
||||
|
@ -1289,7 +1290,7 @@ LONG_STRING;
|
|||
$this->assertMessage($exp, $this->req($in[6]));
|
||||
}
|
||||
|
||||
public function testRetrieveFeedTree() {
|
||||
public function testRetrieveFeedTree(): void {
|
||||
$in = [
|
||||
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx", 'include_empty' => true],
|
||||
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx"],
|
||||
|
@ -1306,7 +1307,7 @@ LONG_STRING;
|
|||
$this->assertMessage($this->respGood($exp), $this->req($in[1]));
|
||||
}
|
||||
|
||||
public function testMarkFeedsAsRead() {
|
||||
public function testMarkFeedsAsRead(): void {
|
||||
$in1 = [
|
||||
// no-ops
|
||||
['op' => "catchupFeed", 'sid' => "PriestsOfSyrinx"],
|
||||
|
@ -1357,7 +1358,7 @@ LONG_STRING;
|
|||
\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(): void {
|
||||
$in1 = [
|
||||
['op' => "getFeeds", 'sid' => "PriestsOfSyrinx"],
|
||||
['op' => "getFeeds", 'sid' => "PriestsOfSyrinx", 'cat_id' => -1],
|
||||
|
@ -1519,7 +1520,7 @@ LONG_STRING;
|
|||
return $out;
|
||||
}
|
||||
|
||||
public function testChangeArticles() {
|
||||
public function testChangeArticles(): void {
|
||||
$in = [
|
||||
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx"],
|
||||
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1"],
|
||||
|
@ -1604,7 +1605,7 @@ LONG_STRING;
|
|||
}
|
||||
}
|
||||
|
||||
public function testListArticles() {
|
||||
public function testListArticles(): void {
|
||||
$in = [
|
||||
// error conditions
|
||||
['op' => "getArticle", 'sid' => "PriestsOfSyrinx"],
|
||||
|
@ -1693,7 +1694,7 @@ LONG_STRING;
|
|||
$this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5]));
|
||||
}
|
||||
|
||||
public function testRetrieveCompactHeadlines() {
|
||||
public function testRetrieveCompactHeadlines(): void {
|
||||
$in1 = [
|
||||
// erroneous input
|
||||
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx"],
|
||||
|
@ -1779,7 +1780,7 @@ LONG_STRING;
|
|||
}
|
||||
}
|
||||
|
||||
public function testRetrieveFullHeadlines() {
|
||||
public function testRetrieveFullHeadlines(): void {
|
||||
$in1 = [
|
||||
// empty results
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 0],
|
||||
|
@ -1895,7 +1896,7 @@ LONG_STRING;
|
|||
}
|
||||
}
|
||||
|
||||
public function testRetrieveFullHeadlinesCheckingExtraFields() {
|
||||
public function testRetrieveFullHeadlinesCheckingExtraFields(): void {
|
||||
$in = [
|
||||
// empty results
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4],
|
||||
|
|
|
@ -11,8 +11,8 @@ use JKingWeb\Arsse\User;
|
|||
use JKingWeb\Arsse\Database;
|
||||
use JKingWeb\Arsse\REST\TinyTinyRSS\Icon;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\Response\EmptyResponse as Response;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\EmptyResponse as Response;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\REST\TinyTinyRSS\Icon<extended> */
|
||||
class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -40,15 +40,15 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
return $this->h->dispatch($req);
|
||||
}
|
||||
|
||||
protected function reqAuth(string $target, string $method = "GET") {
|
||||
protected function reqAuth(string $target, string $method = "GET"): ResponseInterface {
|
||||
return $this->req($target, $method, $this->user);
|
||||
}
|
||||
|
||||
protected function reqAuthFailed(string $target, string $method = "GET") {
|
||||
protected function reqAuthFailed(string $target, string $method = "GET"): ResponseInterface {
|
||||
return $this->req($target, $method, "");
|
||||
}
|
||||
|
||||
public function testRetrieveFavion() {
|
||||
public function testRetrieveFavion(): void {
|
||||
\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(2112, $this->anything())->thenReturn("http://example.net/logo.png");
|
||||
|
@ -71,7 +71,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("2112.ico", "PUT"));
|
||||
}
|
||||
|
||||
public function testRetrieveFavionWithHttpAuthentication() {
|
||||
public function testRetrieveFavionWithHttpAuthentication(): void {
|
||||
$url = "http://example.org/icon.gif\r\nLocation: http://bad.example.com/";
|
||||
\Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn("");
|
||||
\Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->user)->thenReturn($url);
|
||||
|
|
|
@ -118,7 +118,7 @@ class TestSearch extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideSearchStrings */
|
||||
public function testApplySearchToContext(string $search, $exp) {
|
||||
public function testApplySearchToContext(string $search, $exp): void {
|
||||
$act = Search::parse($search);
|
||||
$this->assertEquals($exp, $act);
|
||||
}
|
||||
|
|
|
@ -19,16 +19,16 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$db = \Phake::mock(Database::class);
|
||||
}
|
||||
|
||||
public function testConstruct() {
|
||||
public function testConstruct(): void {
|
||||
$this->assertTrue(Driver::requirementsMet());
|
||||
$this->assertInstanceOf(DriverInterface::class, new Driver);
|
||||
}
|
||||
|
||||
public function testFetchDriverName() {
|
||||
public function testFetchDriverName(): void {
|
||||
$this->assertTrue(strlen(Driver::driverName()) > 0);
|
||||
}
|
||||
|
||||
public function testEnqueueFeeds() {
|
||||
public function testEnqueueFeeds(): void {
|
||||
$d = new Driver;
|
||||
$this->assertSame(3, $d->queue(1, 2, 3));
|
||||
$this->assertSame(5, $d->queue(4, 5));
|
||||
|
@ -36,7 +36,7 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(1, $d->queue(5));
|
||||
}
|
||||
|
||||
public function testRefreshFeeds() {
|
||||
public function testRefreshFeeds(): void {
|
||||
$d = new Driver;
|
||||
$d->queue(1, 4, 3);
|
||||
$this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec());
|
||||
|
|
|
@ -22,14 +22,14 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->srv = new Service();
|
||||
}
|
||||
|
||||
public function testCheckIn() {
|
||||
public function testCheckIn(): void {
|
||||
$now = time();
|
||||
$this->srv->checkIn();
|
||||
\Phake::verify(Arsse::$db)->metaSet("service_last_checkin", \Phake::capture($then), "datetime");
|
||||
$this->assertTime($now, $then);
|
||||
}
|
||||
|
||||
public function testReportHavingCheckedIn() {
|
||||
public function testReportHavingCheckedIn(): void {
|
||||
// the mock's metaGet() returns null by default
|
||||
$this->assertFalse(Service::hasCheckedIn());
|
||||
$interval = Arsse::$conf->serviceFrequency;
|
||||
|
@ -40,27 +40,27 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertFalse(Service::hasCheckedIn());
|
||||
}
|
||||
|
||||
public function testPerformPreCleanup() {
|
||||
public function testPerformPreCleanup(): void {
|
||||
$this->assertTrue(Service::cleanupPre());
|
||||
\Phake::verify(Arsse::$db)->feedCleanup();
|
||||
\Phake::verify(Arsse::$db)->sessionCleanup();
|
||||
}
|
||||
|
||||
public function testPerformShortPostCleanup() {
|
||||
public function testPerformShortPostCleanup(): void {
|
||||
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(0);
|
||||
$this->assertTrue(Service::cleanupPost());
|
||||
\Phake::verify(Arsse::$db)->articleCleanup();
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->driverMaintenance();
|
||||
}
|
||||
|
||||
public function testPerformFullPostCleanup() {
|
||||
public function testPerformFullPostCleanup(): void {
|
||||
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(1);
|
||||
$this->assertTrue(Service::cleanupPost());
|
||||
\Phake::verify(Arsse::$db)->articleCleanup();
|
||||
\Phake::verify(Arsse::$db)->driverMaintenance();
|
||||
}
|
||||
|
||||
public function testRefreshFeeds() {
|
||||
public function testRefreshFeeds(): void {
|
||||
// set up mock database actions
|
||||
\Phake::when(Arsse::$db)->metaSet->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->feedCleanup->thenReturn(true);
|
||||
|
|
|
@ -18,16 +18,16 @@ class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::setConf();
|
||||
}
|
||||
|
||||
public function testConstruct() {
|
||||
public function testConstruct(): void {
|
||||
$this->assertTrue(Driver::requirementsMet());
|
||||
$this->assertInstanceOf(DriverInterface::class, new Driver);
|
||||
}
|
||||
|
||||
public function testFetchDriverName() {
|
||||
public function testFetchDriverName(): void {
|
||||
$this->assertTrue(strlen(Driver::driverName()) > 0);
|
||||
}
|
||||
|
||||
public function testEnqueueFeeds() {
|
||||
public function testEnqueueFeeds(): void {
|
||||
$d = new Driver;
|
||||
$this->assertSame(3, $d->queue(1, 2, 3));
|
||||
$this->assertSame(5, $d->queue(4, 5));
|
||||
|
@ -35,7 +35,7 @@ class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(1, $d->queue(5));
|
||||
}
|
||||
|
||||
public function testRefreshFeeds() {
|
||||
public function testRefreshFeeds(): void {
|
||||
$d = \Phake::partialMock(Driver::class);
|
||||
\Phake::when($d)->execCmd->thenReturnCallback(function(string $cmd) {
|
||||
// FIXME: Does this work in Windows?
|
||||
|
|
|
@ -22,7 +22,7 @@ class TestArsse extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public function testLoadExistingData() {
|
||||
public function testLoadExistingData(): void {
|
||||
$lang = Arsse::$lang = \Phake::mock(Lang::class);
|
||||
$db = Arsse::$db = \Phake::mock(Database::class);
|
||||
$user = Arsse::$user = \Phake::mock(User::class);
|
||||
|
@ -36,7 +36,7 @@ class TestArsse extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify($lang)->set("test");
|
||||
}
|
||||
|
||||
public function testLoadNewData() {
|
||||
public function testLoadNewData(): void {
|
||||
if (!\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet() && !\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
|
||||
$this->markTestSkipped("A functional SQLite interface is required for this test");
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
|
||||
}
|
||||
|
||||
public function testConstruct() {
|
||||
public function testConstruct(): void {
|
||||
$this->assertInstanceOf(DriverInterface::class, new Driver);
|
||||
}
|
||||
|
||||
public function testFetchDriverName() {
|
||||
public function testFetchDriverName(): void {
|
||||
$this->assertTrue(strlen(Driver::driverName()) > 0);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
* @dataProvider provideAuthentication
|
||||
* @group slow
|
||||
*/
|
||||
public function testAuthenticateAUser(bool $authorized, string $user, $password, bool $exp) {
|
||||
public function testAuthenticateAUser(bool $authorized, string $user, $password, bool $exp): void {
|
||||
if ($authorized) {
|
||||
\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"
|
||||
|
@ -74,12 +74,12 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
}
|
||||
|
||||
public function testAuthorizeAnAction() {
|
||||
public function testAuthorizeAnAction(): void {
|
||||
\Phake::verifyNoFurtherInteraction(Arsse::$db);
|
||||
$this->assertTrue((new Driver)->authorize("someone", "something"));
|
||||
}
|
||||
|
||||
public function testListUsers() {
|
||||
public function testListUsers(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$jane = "jane.doe@example.com";
|
||||
\Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]);
|
||||
|
@ -89,7 +89,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db, \Phake::times(2))->userList;
|
||||
}
|
||||
|
||||
public function testCheckThatAUserExists() {
|
||||
public function testCheckThatAUserExists(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$jane = "jane.doe@example.com";
|
||||
\Phake::when(Arsse::$db)->userExists($john)->thenReturn(true);
|
||||
|
@ -101,7 +101,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db)->userExists($jane);
|
||||
}
|
||||
|
||||
public function testAddAUser() {
|
||||
public function testAddAUser(): void {
|
||||
$john = "john.doe@example.com";
|
||||
\Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) {
|
||||
return $pass;
|
||||
|
@ -114,7 +114,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::verify(Arsse::$db)->userAdd;
|
||||
}
|
||||
|
||||
public function testRemoveAUser() {
|
||||
public function testRemoveAUser(): void {
|
||||
$john = "john.doe@example.com";
|
||||
\Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
|
||||
$driver = new Driver;
|
||||
|
@ -128,21 +128,21 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public function testSetAPassword() {
|
||||
public function testSetAPassword(): void {
|
||||
$john = "john.doe@example.com";
|
||||
\Phake::verifyNoFurtherInteraction(Arsse::$db);
|
||||
$this->assertSame("superman", (new Driver)->userPasswordSet($john, "superman"));
|
||||
$this->assertSame(null, (new Driver)->userPasswordSet($john, null));
|
||||
}
|
||||
|
||||
public function testUnsetAPassword() {
|
||||
public function testUnsetAPassword(): void {
|
||||
$drv = \Phake::partialMock(Driver::class);
|
||||
\Phake::when($drv)->userExists->thenReturn(true);
|
||||
\Phake::verifyNoFurtherInteraction(Arsse::$db);
|
||||
$this->assertTrue($drv->userPasswordUnset("john.doe@example.com"));
|
||||
}
|
||||
|
||||
public function testUnsetAPasswordForAMssingUser() {
|
||||
public function testUnsetAPasswordForAMssingUser(): void {
|
||||
$drv = \Phake::partialMock(Driver::class);
|
||||
\Phake::when($drv)->userExists->thenReturn(false);
|
||||
\Phake::verifyNoFurtherInteraction(Arsse::$db);
|
||||
|
|
|
@ -24,12 +24,12 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->drv = \Phake::mock(Driver::class);
|
||||
}
|
||||
|
||||
public function testConstruct() {
|
||||
public function testConstruct(): void {
|
||||
$this->assertInstanceOf(User::class, new User($this->drv));
|
||||
$this->assertInstanceOf(User::class, new User);
|
||||
}
|
||||
|
||||
public function testConversionToString() {
|
||||
public function testConversionToString(): void {
|
||||
$u = new User;
|
||||
$u->id = "john.doe@example.com";
|
||||
$this->assertSame("john.doe@example.com", (string) $u);
|
||||
|
@ -38,7 +38,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideAuthentication */
|
||||
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp) {
|
||||
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp): void {
|
||||
Arsse::$conf->userPreAuth = $preAuth;
|
||||
\Phake::when($this->drv)->auth->thenReturn(false);
|
||||
\Phake::when($this->drv)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
||||
|
@ -69,7 +69,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideUserList */
|
||||
public function testListUsers(bool $authorized, $exp) {
|
||||
public function testListUsers(bool $authorized, $exp): void {
|
||||
$u = new User($this->drv);
|
||||
\Phake::when($this->drv)->authorize->thenReturn($authorized);
|
||||
\Phake::when($this->drv)->userList->thenReturn(["john.doe@example.com", "jane.doe@example.com"]);
|
||||
|
@ -89,7 +89,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideExistence */
|
||||
public function testCheckThatAUserExists(bool $authorized, string $user, $exp) {
|
||||
public function testCheckThatAUserExists(bool $authorized, string $user, $exp): void {
|
||||
$u = new User($this->drv);
|
||||
\Phake::when($this->drv)->authorize->thenReturn($authorized);
|
||||
\Phake::when($this->drv)->userExists("john.doe@example.com")->thenReturn(true);
|
||||
|
@ -112,7 +112,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideAdditions */
|
||||
public function testAddAUser(bool $authorized, string $user, $password, $exp) {
|
||||
public function testAddAUser(bool $authorized, string $user, $password, $exp): void {
|
||||
$u = new User($this->drv);
|
||||
\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"));
|
||||
|
@ -130,7 +130,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideAdditions */
|
||||
public function testAddAUserWithARandomPassword(bool $authorized, string $user, $password, $exp) {
|
||||
public function testAddAUserWithARandomPassword(bool $authorized, string $user, $password, $exp): void {
|
||||
$u = \Phake::partialMock(User::class, $this->drv);
|
||||
\Phake::when($this->drv)->authorize->thenReturn($authorized);
|
||||
\Phake::when($this->drv)->userAdd($this->anything(), $this->isNull())->thenReturn(null);
|
||||
|
@ -172,7 +172,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideRemovals */
|
||||
public function testRemoveAUser(bool $authorized, string $user, bool $exists, $exp) {
|
||||
public function testRemoveAUser(bool $authorized, string $user, bool $exists, $exp): void {
|
||||
$u = new User($this->drv);
|
||||
\Phake::when($this->drv)->authorize->thenReturn($authorized);
|
||||
\Phake::when($this->drv)->userRemove("john.doe@example.com")->thenReturn(true);
|
||||
|
@ -210,7 +210,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider providePasswordChanges */
|
||||
public function testChangeAPassword(bool $authorized, string $user, $password, bool $exists, $exp) {
|
||||
public function testChangeAPassword(bool $authorized, string $user, $password, bool $exists, $exp): void {
|
||||
$u = new User($this->drv);
|
||||
\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) {
|
||||
|
@ -237,7 +237,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider providePasswordChanges */
|
||||
public function testChangeAPasswordToARandomPassword(bool $authorized, string $user, $password, bool $exists, $exp) {
|
||||
public function testChangeAPasswordToARandomPassword(bool $authorized, string $user, $password, bool $exists, $exp): void {
|
||||
$u = \Phake::partialMock(User::class, $this->drv);
|
||||
\Phake::when($this->drv)->authorize->thenReturn($authorized);
|
||||
\Phake::when($this->drv)->userPasswordSet($this->anything(), $this->isNull(), $this->anything())->thenReturn(null);
|
||||
|
@ -289,7 +289,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider providePasswordClearings */
|
||||
public function testClearAPassword(bool $authorized, bool $exists, string $user, $exp) {
|
||||
public function testClearAPassword(bool $authorized, bool $exists, string $user, $exp): void {
|
||||
\Phake::when($this->drv)->authorize->thenReturn($authorized);
|
||||
\Phake::when($this->drv)->userPasswordUnset->thenReturn(true);
|
||||
\Phake::when($this->drv)->userPasswordUnset("jane.doe@example.net", null)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
|
||||
|
|
22
tests/docroot/Feed/Caching/304Conditional.php
Normal file
22
tests/docroot/Feed/Caching/304Conditional.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
// this test returns 400 rather than 304 if the values of If-Modified-Since
|
||||
// and If-None-Match doesn't match $G_GET['t'] and $_GET['e'] respectively, or
|
||||
// if the $_GET members are missing
|
||||
if (
|
||||
!($_GET['t'] ?? "") ||
|
||||
!($_GET['e'] ?? "") ||
|
||||
($_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? "") !== gmdate("D, d M Y H:i:s \G\M\T", (int) $_GET['t']) ||
|
||||
($_SERVER['HTTP_IF_NONE_MATCH'] ?? "") !== $_GET['e']
|
||||
) {
|
||||
return [
|
||||
'code' => 400,
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'code' => 304,
|
||||
'lastMod' => random_int(0, 2^31),
|
||||
'fields' => [
|
||||
"ETag: ".bin2hex(random_bytes(8)),
|
||||
],
|
||||
];
|
||||
}
|
|
@ -2,6 +2,6 @@
|
|||
'code' => 304,
|
||||
'cache' => false,
|
||||
'fields' => [
|
||||
"ETag: ".$_SERVER['HTTP_IF_NONE_MATCH'],
|
||||
"ETag: ".($_SERVER['HTTP_IF_NONE_MATCH'] ?? "No ETag supplied"),
|
||||
],
|
||||
];
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
'code' => 304,
|
||||
'cache' => false,
|
||||
'fields' => [
|
||||
'Last-Modified: '.$_SERVER['HTTP_IF_MODIFIED_SINCE'],
|
||||
'Last-Modified: '.($_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? "No timestamp supplied"),
|
||||
],
|
||||
];
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\Test;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use JKingWeb\Arsse\Exception;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Conf;
|
||||
|
@ -18,9 +20,9 @@ use Psr\Http\Message\MessageInterface;
|
|||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
use Zend\Diactoros\Response\XmlResponse;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\Response\XmlResponse;
|
||||
|
||||
/** @coversNothing */
|
||||
abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
||||
|
@ -34,7 +36,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
self::clearData();
|
||||
}
|
||||
|
||||
public static function clearData(bool $loadLang = true) {
|
||||
public static function clearData(bool $loadLang = true): void {
|
||||
date_default_timezone_set("America/Toronto");
|
||||
$r = new \ReflectionClass(\JKingWeb\Arsse\Arsse::class);
|
||||
$props = array_keys($r->getStaticProperties());
|
||||
|
@ -46,7 +48,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public static function setConf(array $conf = [], bool $force = true) {
|
||||
public static function setConf(array $conf = [], bool $force = true): void {
|
||||
$defaults = [
|
||||
'dbSQLite3File' => ":memory:",
|
||||
'dbSQLite3Timeout' => 0,
|
||||
|
@ -127,7 +129,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
return $req;
|
||||
}
|
||||
|
||||
public function assertException($msg = "", string $prefix = "", string $type = "Exception") {
|
||||
public function assertException($msg = "", string $prefix = "", string $type = "Exception"): void {
|
||||
if (func_num_args()) {
|
||||
if ($msg instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
$this->expectException(get_class($msg));
|
||||
|
@ -149,7 +151,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
protected function assertMessage(MessageInterface $exp, MessageInterface $act, string $text = '') {
|
||||
protected function assertMessage(MessageInterface $exp, MessageInterface $act, string $text = ''): void {
|
||||
if ($exp instanceof ResponseInterface) {
|
||||
$this->assertInstanceOf(ResponseInterface::class, $act, $text);
|
||||
$this->assertEquals($exp->getStatusCode(), $act->getStatusCode(), $text);
|
||||
|
@ -173,7 +175,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($exp->getHeaders(), $act->getHeaders(), $text);
|
||||
}
|
||||
|
||||
public function assertTime($exp, $test, string $msg = '') {
|
||||
public function assertTime($exp, $test, string $msg = ''): void {
|
||||
$test = $this->approximateTime($exp, $test);
|
||||
$exp = Date::transform($exp, "iso8601");
|
||||
$test = Date::transform($test, "iso8601");
|
||||
|
@ -299,7 +301,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
return $out;
|
||||
}
|
||||
|
||||
public function assertResult(array $expected, Result $data) {
|
||||
public function assertResult(array $expected, Result $data): void {
|
||||
$data = $data->getAll();
|
||||
$this->assertCount(sizeof($expected), $data, "Number of result rows (".sizeof($data).") differs from number of expected rows (".sizeof($expected).")");
|
||||
if (sizeof($expected)) {
|
||||
|
@ -325,4 +327,16 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
$this->assertArraySubset($expected, [], false, "Expectations not in result set.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Guzzle's exception classes require some fairly complicated construction; this abstracts it all away so that only message and code need be supplied */
|
||||
protected function mockGuzzleException(string $class, ?string $message = null, ?int $code = null, ?\Throwable $e = null): GuzzleException {
|
||||
if (is_a($class, RequestException::class, true)) {
|
||||
$req = \Phake::mock(RequestInterface::class);
|
||||
$res = \Phake::mock(ResponseInterface::class);
|
||||
\Phake::when($res)->getStatusCode->thenReturn($code ?? 0);
|
||||
return new $class($message ?? "", $req, $res, $e);
|
||||
} else {
|
||||
return new $class($message ?? "", $code ?? 0, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ trait MySQL {
|
|||
return $tables;
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []) {
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->query("UNLOCK TABLES; ROLLBACK");
|
||||
|
@ -63,7 +63,7 @@ trait MySQL {
|
|||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []) {
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->query("UNLOCK TABLES; ROLLBACK");
|
||||
|
|
|
@ -47,11 +47,11 @@ trait MySQLPDO {
|
|||
return MySQL::dbTableList($db);
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []) {
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
MySQL::dbTruncate($db, $afterStatements);
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []) {
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
MySQL::dbRaze($db, $afterStatements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ trait PostgreSQL {
|
|||
}
|
||||
}
|
||||
|
||||
public static function dbExec($db, $q) {
|
||||
public static function dbExec($db, $q): void {
|
||||
if ($db instanceof Driver) {
|
||||
$db->exec($q);
|
||||
} elseif ($db instanceof \PDO) {
|
||||
|
@ -52,7 +52,7 @@ trait PostgreSQL {
|
|||
}
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []) {
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
@self::dbExec($db, "ROLLBACK");
|
||||
|
@ -72,7 +72,7 @@ trait PostgreSQL {
|
|||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []) {
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
@self::dbExec($db, "ROLLBACK");
|
||||
|
|
|
@ -33,11 +33,11 @@ trait PostgreSQLPDO {
|
|||
return PostgreSQL::dbTableList($db);
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []) {
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
PostgreSQL::dbTruncate($db, $afterStatements);
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []) {
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
PostgreSQL::dbRaze($db, $afterStatements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ trait SQLite3 {
|
|||
return $tables;
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []) {
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->exec("ROLLBACK");
|
||||
|
@ -69,7 +69,7 @@ trait SQLite3 {
|
|||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []) {
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->exec("ROLLBACK");
|
||||
|
|
|
@ -30,11 +30,11 @@ trait SQLite3PDO {
|
|||
return SQLite3::dbTableList($db);
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []) {
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
SQLite3::dbTruncate($db, $afterStatements);
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []) {
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
SQLite3::dbRaze($db, $afterStatements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<file>cases/User/TestUser.php</file>
|
||||
</testsuite>
|
||||
<testsuite name="Feed parser">
|
||||
<file>cases/Feed/TestException.php</file>
|
||||
<file>cases/Feed/TestFetching.php</file>
|
||||
<file>cases/Feed/TestFeed.php</file>
|
||||
</testsuite>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue