Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Florine W. Dekker | d7c2658ba6 | |
Florine W. Dekker | 2daa74b319 | |
Florine W. Dekker | 6a1be5ac2f | |
Florine W. Dekker | 7b86673590 | |
Florine W. Dekker | e024bc4cf8 |
|
@ -1,7 +1,7 @@
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = grunt => {
|
module.exports = grunt => {
|
||||||
const testTarget = grunt.option("test-target") || ".";
|
const testFilter = grunt.option("test-filter") || "'' .";
|
||||||
|
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
pkg: grunt.file.readJSON("package.json"),
|
pkg: grunt.file.readJSON("package.json"),
|
||||||
|
@ -71,7 +71,7 @@ module.exports = grunt => {
|
||||||
exec: "composer.phar install --no-dev"
|
exec: "composer.phar install --no-dev"
|
||||||
},
|
},
|
||||||
phpunit: {
|
phpunit: {
|
||||||
exec: `cd dist/ && chmod +x .vendor/bin/phpunit && .vendor/bin/phpunit --testdox ${testTarget}`
|
exec: `cd dist/ && chmod +x .vendor/bin/phpunit && .vendor/bin/phpunit --filter ${testFilter}`
|
||||||
},
|
},
|
||||||
stan: {
|
stan: {
|
||||||
exec: "vendor/bin/phpstan analyse -l 8 src/main src/test"
|
exec: "vendor/bin/phpstan analyse -l 8 src/main src/test"
|
||||||
|
|
30
README.md
30
README.md
|
@ -9,9 +9,10 @@ This tool regularly checks if people are still alive according to Wikipedia, and
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
### Requirements
|
### Requirements
|
||||||
* PHP 8.1+ (i.e. `apt install php php-cgi`)
|
* PHP 8.1+ (i.e. `apt install php php-cgi`) (compiled with Argon2 support)
|
||||||
* [PHP cURL](https://www.php.net/manual/en/book.curl.php) (i.e. `apt install php-curl`)
|
* [PHP cURL](https://www.php.net/manual/en/book.curl.php) (i.e. `apt install php-curl`)
|
||||||
* [PHP DOM](https://www.php.net/manual/en/book.dom.php) (i.e. `apt install php-dom`)
|
* [PHP DOM](https://www.php.net/manual/en/book.dom.php) (i.e. `apt install php-dom`)
|
||||||
|
* [PHP mbstring](https://www.php.net/manual/en/book.mbstring.php) (i.e. `apt install php-mbstring`)
|
||||||
* [PHP SQLite 3](https://www.php.net/manual/en/book.sqlite3.php) (i.e. `apt install php-sqlite3`)
|
* [PHP SQLite 3](https://www.php.net/manual/en/book.sqlite3.php) (i.e. `apt install php-sqlite3`)
|
||||||
* [composer](https://getcomposer.org/) (make sure `composer.phar` is on your path)
|
* [composer](https://getcomposer.org/) (make sure `composer.phar` is on your path)
|
||||||
* [npm](https://www.npmjs.com/)
|
* [npm](https://www.npmjs.com/)
|
||||||
|
@ -45,7 +46,10 @@ composer.phar update
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Static analysis
|
### Static analysis and tests
|
||||||
|
Note that PHPUnit suppresses output from `print`.
|
||||||
|
Instead, you can use `fwrite(STDERR, print_r("my message", TRUE));`.
|
||||||
|
|
||||||
* Run static analysis
|
* Run static analysis
|
||||||
```shell
|
```shell
|
||||||
npm run analyze
|
npm run analyze
|
||||||
|
@ -54,10 +58,24 @@ npm install
|
||||||
```shell
|
```shell
|
||||||
npm run test
|
npm run test
|
||||||
```
|
```
|
||||||
* Run all tests in package
|
* Run only select tests
|
||||||
```shell
|
```shell
|
||||||
npm run test -- --test-target=com/fwdekker/deathnotifier/wikipedia/
|
npm run test -- --test-filter="test-name file-name"
|
||||||
```
|
```
|
||||||
|
Note that a `test-name` of `''` and a `file-name` of `.` matches all tests.
|
||||||
|
|
||||||
|
* Run all tests in package
|
||||||
|
```shell
|
||||||
|
npm run test -- --test-filter="'' com/fwdekker/deathnotifier/wikipedia/"
|
||||||
|
```
|
||||||
|
* Run all tests in class
|
||||||
|
```shell
|
||||||
|
npm run test -- --test-filter="'' com/fwdekker/deathnotifier/wikipedia/WikipediaTest.php"
|
||||||
|
```
|
||||||
|
* Run only specific test
|
||||||
|
```shell
|
||||||
|
npm run test -- --test-filter="test_query_detects_dead_person ."
|
||||||
|
```
|
||||||
* Run static analysis and tests
|
* Run static analysis and tests
|
||||||
```shell
|
```shell
|
||||||
npm run check
|
npm run check
|
||||||
|
@ -77,12 +95,12 @@ Inside the installation directory, create `config.ini.php` and use it to overrid
|
||||||
Make sure only the user that runs PHP can read/write `config.ini.php`.
|
Make sure only the user that runs PHP can read/write `config.ini.php`.
|
||||||
|
|
||||||
### Cron jobs
|
### Cron jobs
|
||||||
You should run the `process-email-queue` and `update-all-trackings` actions regularly;
|
You should run the `process-email-queue` and `update-trackings` actions regularly;
|
||||||
recommended is every minute and every five minutes, respectively.
|
recommended is every minute and every five minutes, respectively.
|
||||||
For example, you can add the following lines to your crontab (e.g. using `sudo -u www crontab -e`):
|
For example, you can add the following lines to your crontab (e.g. using `sudo -u www crontab -e`):
|
||||||
```
|
```
|
||||||
* * * * * cd /var/www/death-notifier && php /var/www/death-notifier/api.php action=process-email-queue password=secret_password
|
* * * * * cd /var/www/death-notifier && php /var/www/death-notifier/api.php action=process-email-queue password=secret_password
|
||||||
*/5 * * * * cd /var/www/death-notifier && php /var/www/death-notifier/api.php action=update-all-trackings password=secret_password
|
*/5 * * * * cd /var/www/death-notifier && php /var/www/death-notifier/api.php action=update-trackings password=secret_password
|
||||||
```
|
```
|
||||||
Replace `secret_password` with the password you configured in `config.ini.php`.
|
Replace `secret_password` with the password you configured in `config.ini.php`.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "fwdekker/death-notifier",
|
"name": "fwdekker/death-notifier",
|
||||||
"description": "Get notified when a famous person dies.",
|
"description": "Get notified when a famous person dies.",
|
||||||
"version": "1.1.0", "_comment_version": "Also update version in `package.json`!",
|
"version": "1.3.0", "_comment_version": "Also update version in `package.json`!",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://git.fwdekker.com/tools/death-notifier",
|
"homepage": "https://git.fwdekker.com/tools/death-notifier",
|
||||||
|
@ -19,12 +19,12 @@
|
||||||
"composer/semver": "^3.3",
|
"composer/semver": "^3.3",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"monolog/monolog": "^3.3",
|
"monolog/monolog": "^3.4",
|
||||||
"phpmailer/phpmailer": "^6.8"
|
"phpmailer/phpmailer": "^6.8"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.9",
|
"phpstan/phpstan": "^1.10.32",
|
||||||
"phpunit/phpunit": "^9.5"
|
"phpunit/phpunit": "^10.3.2"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
Binary file not shown.
Binary file not shown.
12
package.json
12
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "death-notifier",
|
"name": "death-notifier",
|
||||||
"version": "1.1.0", "_comment_version": "Also update version in `composer.json`!",
|
"version": "1.3.0", "_comment_version": "Also update version in `composer.json`!",
|
||||||
"description": "Get notified when a famous person dies.",
|
"description": "Get notified when a famous person dies.",
|
||||||
"author": "Florine W. Dekker",
|
"author": "Florine W. Dekker",
|
||||||
"browser": "dist/bundle.js",
|
"browser": "dist/bundle.js",
|
||||||
|
@ -27,10 +27,10 @@
|
||||||
"grunt-focus": "^1.0.0",
|
"grunt-focus": "^1.0.0",
|
||||||
"grunt-run": "^0.8.1",
|
"grunt-run": "^0.8.1",
|
||||||
"grunt-text-replace": "^0.4.0",
|
"grunt-text-replace": "^0.4.0",
|
||||||
"grunt-webpack": "^5.0.0",
|
"grunt-webpack": "^6.0.0",
|
||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.4.4",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.2.2",
|
||||||
"webpack": "^5.76.2",
|
"webpack": "^5.88.2",
|
||||||
"webpack-cli": "^5.0.1"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,37 @@
|
||||||
;<?php exit(); ?>
|
;<?php exit(); ?>
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
# bcrypt hash of password to use the CLI of `api.php`. If set to its default value, or if empty, the CLI is disabled.
|
# PHC-formatted hash of password for the CLI of `api.php`. You can create one using PHP's `password_hash`. Escaping
|
||||||
cli_password = REPLACE THIS WITH A SECRET VALUE
|
# dollar symbols is optional. If set to its default value, or if empty, the CLI is disabled.
|
||||||
|
cli_password = "REPLACE THIS WITH A SECRET VALUE"
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
# File to store SQLite database in.
|
# File to store SQLite database in.
|
||||||
filename = .death-notifier.db
|
filename = ".death-notifier.db"
|
||||||
|
|
||||||
[logger]
|
[logger]
|
||||||
# File to store general logs in.
|
# File to store general logs in.
|
||||||
filename = .death-notifier.log
|
filename = ".death-notifier.log"
|
||||||
# Log level for general log events. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels
|
# Log level for general log events. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels
|
||||||
level = 250
|
level = 250
|
||||||
|
|
||||||
[logger_db]
|
[logger_db]
|
||||||
# File to store database logs in.
|
# File to store database logs in.
|
||||||
filename = .death-notifier.db.log
|
filename = ".death-notifier.db.log"
|
||||||
# Log level for database log events. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels
|
# Log level for database log events. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels
|
||||||
level = 250
|
level = 250
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
# Host name of SMTP server to send mail through.
|
# Host name of SMTP server to send mail through.
|
||||||
host = TODO
|
host = "TODO"
|
||||||
# Port of SMTP server to send mail through.
|
# Port of SMTP server to send mail through.
|
||||||
port = TODO
|
port = TODO
|
||||||
# Username to authenticate with at SMTP server.
|
# Username to authenticate with at SMTP server.
|
||||||
username = TODO
|
username = "TODO"
|
||||||
# Password to authenticate with at SMTP server.
|
# Password to authenticate with at SMTP server.
|
||||||
password = TODO
|
password = "TODO"
|
||||||
# Name to show to recipient.
|
# Name to show to recipient.
|
||||||
from_name = TODO
|
from_name = "TODO"
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
# `true` if and only if insecure file permissions for config files should be tolerated.
|
# `true` if and only if insecure file permissions for config files should be tolerated.
|
||||||
|
@ -38,8 +39,13 @@ allow_config_insecure_permissions = false
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
# The path to the directory containing the site's main page.
|
# The path to the directory containing the site's main page.
|
||||||
base_path = https://example.com/death-notifier/
|
base_path = "https://example.com/death-notifier/"
|
||||||
# The path at which users can report bugs, or an empty string if there is no such path.
|
# The path at which users can report bugs, or an empty string if there is no such path.
|
||||||
issue_path =
|
issue_path = ""
|
||||||
# The message to display at the top of all pages. A blank string hides the message.
|
# The message to display at the top of all pages. A blank string hides the message.
|
||||||
global_message =
|
global_message = ""
|
||||||
|
|
||||||
|
[wikipedia]
|
||||||
|
# Contact information to include in requests to Wikipedia's API. Typically a URL and an email address separated by a
|
||||||
|
# semicolon. See also https://www.mediawiki.org/wiki/API:Etiquette.
|
||||||
|
user_agent_contact = "https://example.com/death-notifier; name@example.com"
|
||||||
|
|
|
@ -409,7 +409,7 @@
|
||||||
|
|
||||||
<input id="delete-account-actual-email" type="hidden" name="email" />
|
<input id="delete-account-actual-email" type="hidden" name="email" />
|
||||||
|
|
||||||
<label for="delete-account-email">Confirm email</label>
|
<label for="delete-account-email">Confirm email address</label>
|
||||||
<input id="delete-account-email" name="email" autocomplete="off" />
|
<input id="delete-account-email" name="email" autocomplete="off" />
|
||||||
<small id="delete-account-email-hint" data-hint-for="delete-account-email"></small>
|
<small id="delete-account-email-hint" data-hint-for="delete-account-email"></small>
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ class ProcessEmailQueueAction extends Action
|
||||||
$mailer->SMTPKeepAlive = true;
|
$mailer->SMTPKeepAlive = true;
|
||||||
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
||||||
$mailer->Host = $config["host"];
|
$mailer->Host = $config["host"];
|
||||||
$mailer->Port = $config["port"];
|
$mailer->Port = intval($config["port"]);
|
||||||
$mailer->Username = $config["username"];
|
$mailer->Username = $config["username"];
|
||||||
$mailer->Password = $config["password"];
|
$mailer->Password = $config["password"];
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -183,7 +183,7 @@ class NotifyStatusChangedEmail extends Email
|
||||||
|
|
||||||
public function get_subject(): string
|
public function get_subject(): string
|
||||||
{
|
{
|
||||||
return "$this->name may be $this->new_status";
|
return "Death Notifier: $this->name may be $this->new_status";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_body(): string
|
public function get_body(): string
|
||||||
|
@ -195,6 +195,10 @@ class NotifyStatusChangedEmail extends Email
|
||||||
"For more information, read their Wikipedia article at " .
|
"For more information, read their Wikipedia article at " .
|
||||||
"https://en.wikipedia.org/wiki/" . rawurlencode($this->name) .
|
"https://en.wikipedia.org/wiki/" . rawurlencode($this->name) .
|
||||||
"\n\n" .
|
"\n\n" .
|
||||||
|
"Note that Wikipedia is not a reliable source of information and is subject to vandalism and errors. " .
|
||||||
|
"Please check if reliable news sources have reported on $this->name before spreading this message to " .
|
||||||
|
"others." .
|
||||||
|
"\n\n" .
|
||||||
"You are receiving this message because of the preferences in your Death Notifier account. " .
|
"You are receiving this message because of the preferences in your Death Notifier account. " .
|
||||||
"To unsubscribe from these messages, go to the Death Notifier website, log in, and change your email " .
|
"To unsubscribe from these messages, go to the Death Notifier website, log in, and change your email " .
|
||||||
"preferences." .
|
"preferences." .
|
||||||
|
@ -237,7 +241,7 @@ class NotifyArticleDeletedEmail extends Email
|
||||||
|
|
||||||
public function get_subject(): string
|
public function get_subject(): string
|
||||||
{
|
{
|
||||||
return "$this->name article has been deleted";
|
return "Death Notifier: $this->name article has been deleted";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_body(): string
|
public function get_body(): string
|
||||||
|
@ -292,7 +296,7 @@ class NotifyArticleUndeletedEmail extends Email
|
||||||
|
|
||||||
public function get_subject(): string
|
public function get_subject(): string
|
||||||
{
|
{
|
||||||
return "$this->name article has been re-created";
|
return "Death Notifier: $this->name article has been re-created";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_body(): string
|
public function get_body(): string
|
||||||
|
|
|
@ -104,7 +104,7 @@ class UserList
|
||||||
VALUES (:email, :password)
|
VALUES (:email, :password)
|
||||||
RETURNING email_verification_token;");
|
RETURNING email_verification_token;");
|
||||||
$stmt->bindValue(":email", $email);
|
$stmt->bindValue(":email", $email);
|
||||||
$stmt->bindValue(":password", password_hash($password, PASSWORD_BCRYPT));
|
$stmt->bindValue(":password", password_hash($password, PASSWORD_ARGON2ID));
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
return $stmt->fetchAll(PDO::FETCH_ASSOC)[0]["email_verification_token"];
|
return $stmt->fetchAll(PDO::FETCH_ASSOC)[0]["email_verification_token"];
|
||||||
}
|
}
|
||||||
|
@ -265,11 +265,12 @@ class UserList
|
||||||
public function set_password(string $uuid, string $password): void
|
public function set_password(string $uuid, string $password): void
|
||||||
{
|
{
|
||||||
$stmt = $this->database->conn->prepare("UPDATE users
|
$stmt = $this->database->conn->prepare("UPDATE users
|
||||||
SET password=:password, password_last_change=unixepoch(),
|
SET password=:password,
|
||||||
|
password_last_change=unixepoch(),
|
||||||
password_reset_token=null
|
password_reset_token=null
|
||||||
WHERE uuid=:uuid;");
|
WHERE uuid=:uuid;");
|
||||||
$stmt->bindValue(":uuid", $uuid);
|
$stmt->bindValue(":uuid", $uuid);
|
||||||
$stmt->bindValue(":password", password_hash($password, PASSWORD_BCRYPT));
|
$stmt->bindValue(":password", password_hash($password, PASSWORD_ARGON2ID));
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace com\fwdekker\deathnotifier\wikipedia;
|
namespace com\fwdekker\deathnotifier\wikipedia;
|
||||||
|
|
||||||
use com\fwdekker\deathnotifier\LoggerUtil;
|
use com\fwdekker\deathnotifier\Config;
|
||||||
use com\fwdekker\deathnotifier\Util;
|
use com\fwdekker\deathnotifier\Util;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
|
|
||||||
|
@ -19,9 +19,7 @@ class Wikipedia
|
||||||
/**
|
/**
|
||||||
* The user agent used to represent the death notifier to Wikipedia.
|
* The user agent used to represent the death notifier to Wikipedia.
|
||||||
*/
|
*/
|
||||||
private const USER_AGENT =
|
private const USER_AGENT_FORMAT = "death-notifier/%%VERSION_NUMBER%% (%1\$s) %2\$s";
|
||||||
"death-notifier/%%VERSION_NUMBER%% " .
|
|
||||||
"(https://git.fwdekker.com/tools/death-notifier; florine@fwdekker.com)";
|
|
||||||
/**
|
/**
|
||||||
* Number of articles to query per query.
|
* Number of articles to query per query.
|
||||||
*/
|
*/
|
||||||
|
@ -48,10 +46,13 @@ class Wikipedia
|
||||||
*/
|
*/
|
||||||
private function api_fetch(array $params): mixed
|
private function api_fetch(array $params): mixed
|
||||||
{
|
{
|
||||||
|
$curl_version = curl_version()["version"] ?? "unknown";
|
||||||
|
$user_agent = sprintf(self::USER_AGENT_FORMAT, Config::get("wikipedia")["user_agent_contact"], $curl_version);
|
||||||
|
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
curl_setopt($ch, CURLOPT_URL, self::API_URL . http_build_query($params));
|
curl_setopt($ch, CURLOPT_URL, self::API_URL . http_build_query($params));
|
||||||
curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT);
|
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
|
||||||
|
|
||||||
$output = curl_exec($ch);
|
$output = curl_exec($ch);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
@ -262,7 +263,7 @@ class Wikipedia
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
$category_titles = array_column($article["categories"], "title");
|
$category_titles = array_column($article["categories"], "title");
|
||||||
$dead_regex = "/^Category:([0-9]{1,4}s? (BC |AD )?deaths|Year of death (missing|unknown))$/";
|
$dead_regex = "/^Category:([0-9]{1,4}s? (BC |AD )?(deaths|suicides)|Year of death (missing|unknown))$/";
|
||||||
|
|
||||||
if (!empty(array_filter($category_titles, fn($it) => preg_match($dead_regex, $it))))
|
if (!empty(array_filter($category_titles, fn($it) => preg_match($dead_regex, $it))))
|
||||||
return PersonStatus::Dead;
|
return PersonStatus::Dead;
|
||||||
|
|
|
@ -44,9 +44,9 @@ class EqualsCliPasswordRuleTest extends TestCase
|
||||||
* Returns the test cases.
|
* Returns the test cases.
|
||||||
*
|
*
|
||||||
* @return array<string, array{string|null, string|null, class-string<Throwable>|null, string|null}> the test cases
|
* @return array<string, array{string|null, string|null, class-string<Throwable>|null, string|null}> the test cases
|
||||||
* @see RuleTest::test_check()
|
* @see RuleTestTemplate::test_check()
|
||||||
*/
|
*/
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$hash = "\$2y\$04\$fwXTw7Rjzw0EpU094u4agOBaBNqtCHGc4TMoxfbPrxuqO5tpYyRka"; # Hash of "password"
|
$hash = "\$2y\$04\$fwXTw7Rjzw0EpU094u4agOBaBNqtCHGc4TMoxfbPrxuqO5tpYyRka"; # Hash of "password"
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ use InvalidArgumentException;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see EqualsRule}.
|
* Unit tests for {@see EqualsRule}.
|
||||||
*/
|
*/
|
||||||
class EqualsRuleTest extends RuleTest
|
class EqualsRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
$value = InvalidValueException::class;
|
$value = InvalidValueException::class;
|
||||||
|
|
|
@ -8,9 +8,9 @@ use InvalidArgumentException;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see HasStringLengthRule}.
|
* Unit tests for {@see HasStringLengthRule}.
|
||||||
*/
|
*/
|
||||||
class HasStringLengthRuleTest extends RuleTest
|
class HasStringLengthRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
$value = InvalidValueException::class;
|
$value = InvalidValueException::class;
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace com\fwdekker\deathnotifier\validation;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see IsBooleanRule}.
|
* Unit tests for {@see IsBooleanRule}.
|
||||||
*/
|
*/
|
||||||
class IsBooleanRuleTest extends RuleTest
|
class IsBooleanRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace com\fwdekker\deathnotifier\validation;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see IsEmailRule}.
|
* Unit tests for {@see IsEmailRule}.
|
||||||
*/
|
*/
|
||||||
class IsEmailRuleTest extends RuleTest
|
class IsEmailRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
$value = InvalidValueException::class;
|
$value = InvalidValueException::class;
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace com\fwdekker\deathnotifier\validation;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see IsNotBlankRule}.
|
* Unit tests for {@see IsNotBlankRule}.
|
||||||
*/
|
*/
|
||||||
class IsNotBlankRuleTest extends RuleTest
|
class IsNotBlankRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
$value = InvalidValueException::class;
|
$value = InvalidValueException::class;
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace com\fwdekker\deathnotifier\validation;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see IsStringRule}.
|
* Unit tests for {@see IsStringRule}.
|
||||||
*/
|
*/
|
||||||
class IsStringRuleTest extends RuleTest
|
class IsStringRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace com\fwdekker\deathnotifier\validation;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see IsValidCsrfTokenRule}.
|
* Unit tests for {@see IsValidCsrfTokenRule}.
|
||||||
*/
|
*/
|
||||||
class IsValidCsrfTokenRuleTest extends RuleTest
|
class IsValidCsrfTokenRuleTest extends RuleTestTemplate
|
||||||
{
|
{
|
||||||
public function check_provider(): array
|
public static function check_provider(): array
|
||||||
{
|
{
|
||||||
$type = InvalidTypeException::class;
|
$type = InvalidTypeException::class;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use Throwable;
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@see Rule} implementations.
|
* Unit tests for {@see Rule} implementations.
|
||||||
*/
|
*/
|
||||||
abstract class RuleTest extends TestCase
|
abstract class RuleTestTemplate extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Tests the output of {@see Rule::check()}.
|
* Tests the output of {@see Rule::check()}.
|
||||||
|
@ -40,7 +40,7 @@ abstract class RuleTest extends TestCase
|
||||||
* Returns the test cases.
|
* Returns the test cases.
|
||||||
*
|
*
|
||||||
* @return array<string, array{Rule, mixed|null, class-string<Throwable>|null, string|null}> the test cases
|
* @return array<string, array{Rule, mixed|null, class-string<Throwable>|null, string|null}> the test cases
|
||||||
* @see RuleTest::test_check()
|
* @see RuleTestTemplate::test_check()
|
||||||
*/
|
*/
|
||||||
abstract public function check_provider(): array;
|
abstract public static function check_provider(): array;
|
||||||
}
|
}
|
|
@ -135,6 +135,13 @@ class WikipediaTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_query_detects_dead_person(): void
|
public function test_query_detects_dead_person(): void
|
||||||
|
{
|
||||||
|
$output = $this->wikipedia->query_people_info(["Sophie (musician)"], resolve_moves: false);
|
||||||
|
|
||||||
|
self::assertEquals(PersonStatus::Dead, $output->results["Sophie (musician)"]["status"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_query_detects_suicide_person(): void
|
||||||
{
|
{
|
||||||
$output = $this->wikipedia->query_people_info(["Adolf Hitler"], resolve_moves: false);
|
$output = $this->wikipedia->query_people_info(["Adolf Hitler"], resolve_moves: false);
|
||||||
|
|
||||||
|
@ -150,8 +157,8 @@ class WikipediaTest extends TestCase
|
||||||
|
|
||||||
public function test_query_detects_possibly_living_person(): void
|
public function test_query_detects_possibly_living_person(): void
|
||||||
{
|
{
|
||||||
$output = $this->wikipedia->query_people_info(["Judge Edward Aaron"], resolve_moves: false);
|
$output = $this->wikipedia->query_people_info(["Angela Anderes"], resolve_moves: false);
|
||||||
|
|
||||||
self::assertEquals(PersonStatus::PossiblyAlive, $output->results["Judge Edward Aaron"]["status"]);
|
self::assertEquals(PersonStatus::PossiblyAlive, $output->results["Angela Anderes"]["status"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue