Compare commits
16 Commits
2176e7312b
...
8c1050f40a
Author | SHA1 | Date | |
---|---|---|---|
8c1050f40a
|
|||
2bea372973
|
|||
69e6850c16
|
|||
8006695093
|
|||
db31822a3f
|
|||
0fb368b96d
|
|||
66e704de47
|
|||
a03f072a69
|
|||
d83ed2d0eb
|
|||
2c58e0554b
|
|||
1f2f63c9af
|
|||
c9dce8f782
|
|||
0c0d059dd3
|
|||
5d80f82040
|
|||
5c2c1a47cc
|
|||
ae12cfdf0f
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/.phpunit.cache/
|
18
exceptions/MDFailedToCreateDirectory.php
Normal file
18
exceptions/MDFailedToCreateDirectory.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?PHP
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* Reports a failure to create a new directory.
|
||||
*/
|
||||
final class MDFailedToCreateDirectory extends Exception {
|
||||
/**
|
||||
* Error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorMessage() {
|
||||
//error message
|
||||
return 'Failed to create directory';
|
||||
|
||||
}
|
||||
}
|
14
phpunit.xml
Normal file
14
phpunit.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.4/phpunit.xsd" backupGlobals="false" beStrictAboutChangesToGlobalState="true" beStrictAboutOutputDuringTests="true" bootstrap="tests/bootstrap.php" cacheResult="false" colors="true" enforceTimeLimit="true" executionOrder="depends,defects" failOnRisky="true" failOnWarning="true" processIsolation="true" stopOnError="true" stopOnFailure="true" stopOnIncomplete="true" stopOnSkipped="true" stopOnRisky="true" testdox="true" timeoutForSmallTests="1" timeoutForMediumTests="10" timeoutForLargeTests="60" cacheDirectory=".phpunit.cache" backupStaticProperties="false" requireCoverageMetadata="false" beStrictAboutCoverageMetadata="false">
|
||||
<testsuites>
|
||||
<testsuite name="tests">
|
||||
<directory>tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<coverage/>
|
||||
<source>
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</source>
|
||||
</phpunit>
|
@ -71,7 +71,7 @@ final class MD_STD {
|
||||
return;
|
||||
}
|
||||
if (\mkdir($pathname, $mode, $recursive) === false) {
|
||||
throw new Exception("Failed to create directory: $pathname");
|
||||
throw new MDFailedToCreateDirectory("Failed to create directory: $pathname");
|
||||
}
|
||||
|
||||
}
|
||||
@ -303,6 +303,27 @@ final class MD_STD {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around self::strtotime() that will return MDParseException (an expected
|
||||
* exception) rather than MDInvalidInputDate (an unexpected exception).
|
||||
*
|
||||
* @param string $datetime String to convert.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function strtotime_for_public_apis(string $datetime):int {
|
||||
|
||||
try {
|
||||
$output = self::strtotime($datetime);
|
||||
}
|
||||
catch (MDInvalidInputDate $e) {
|
||||
throw new MDParseException($e->getMessage());
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a curl request with the given presets.
|
||||
*
|
||||
|
@ -14,7 +14,7 @@ final class MD_STD_IN {
|
||||
*
|
||||
* @param mixed $input Input string.
|
||||
*
|
||||
* @return integer
|
||||
* @return positive-int
|
||||
*/
|
||||
public static function sanitize_id(mixed $input):int {
|
||||
|
||||
@ -39,11 +39,11 @@ final class MD_STD_IN {
|
||||
*
|
||||
* @param mixed $input Input string.
|
||||
*
|
||||
* @return integer
|
||||
* @return 0|positive-int
|
||||
*/
|
||||
public static function sanitize_id_or_zero(mixed $input):int {
|
||||
|
||||
if ($input === "") {
|
||||
if ($input === "" || $input === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -92,14 +92,18 @@ final class MD_STD_IN {
|
||||
*
|
||||
* @param mixed $input Input string.
|
||||
*
|
||||
* @return string
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public static function sanitize_rgb_color(mixed $input):string {
|
||||
|
||||
$output = \filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
|
||||
if (empty($output = \filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH))) {
|
||||
throw new MDInvalidColorCode("Invalid color code provided: " . $output);
|
||||
}
|
||||
|
||||
if ($output === false
|
||||
|| (preg_match('/^[a-zA-Z0-9]{3}$/', $output) === false && preg_match('/^[a-zA-Z0-9]{6}$/', $output) === false)
|
||||
$output = \strtoupper($output);
|
||||
|
||||
if (!in_array(strlen($output), [3, 6], true)
|
||||
|| (MD_STD::preg_replace_str('/[A-F0-9]/', '', $output) !== '')
|
||||
) {
|
||||
throw new MDInvalidColorCode("Invalid color code provided: " . $output);
|
||||
}
|
||||
@ -113,7 +117,7 @@ final class MD_STD_IN {
|
||||
*
|
||||
* @param array<mixed> $inputs Input array.
|
||||
*
|
||||
* @return list<integer>
|
||||
* @return list<positive-int>
|
||||
*/
|
||||
public static function sanitize_id_array(array $inputs):array {
|
||||
|
||||
@ -197,13 +201,51 @@ final class MD_STD_IN {
|
||||
return "";
|
||||
}
|
||||
|
||||
$output = \filter_var($input, FILTER_SANITIZE_URL);
|
||||
if (($output = \filter_var($output, FILTER_VALIDATE_URL)) === false) {
|
||||
throw new MDInvalidUrl("Invalid input URL");
|
||||
try {
|
||||
if (($output = \filter_var($input, FILTER_VALIDATE_URL)) === false) {
|
||||
throw new MDInvalidUrl("Invalid input URL");
|
||||
}
|
||||
}
|
||||
catch (MDInvalidUrl $e) {
|
||||
if (($parsed = parse_url($input)) === false || empty($parsed['scheme']) || empty($parsed['host']) || empty($parsed['path'])) {
|
||||
throw new MDInvalidUrl("Invalid input URL");
|
||||
}
|
||||
$rewritten = $parsed['scheme'] . '://';
|
||||
if (!empty($parsed['user']) && !empty($parsed['pass'])) {
|
||||
$rewritten .= $parsed['user'] . ':' . $parsed['pass'] . '@';
|
||||
}
|
||||
$rewritten .= $parsed['host'];
|
||||
if (!empty($parsed['port'])) $rewritten .= ':' . $parsed['port'];
|
||||
$rewritten .= str_replace('%2F' , '/', urlencode($parsed['path']));
|
||||
if (!empty($parsed['query'])) {
|
||||
$rewritten .= '?' . str_replace('%3D', '=', urlencode($parsed['query']));
|
||||
}
|
||||
if (($output = \filter_var($rewritten, FILTER_VALIDATE_URL)) === false) {
|
||||
throw new MDInvalidUrl("Invalid input URL" . \urlencode($input));
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($output)) return '';
|
||||
// As per the RFC, URLs should not exceed 2048. Enough real-world ones
|
||||
// do. But they certainly should not exceed 10000 characters.
|
||||
if (\strlen($output) > 10000) {
|
||||
throw new MDInvalidUrl("The entered URL seems to be valid otherwise, but is overly long.");
|
||||
}
|
||||
|
||||
// Check for valid schemes
|
||||
if (MD_STD::startsWithAny($input, ['https://', 'http://', 'ftp://']) === false) {
|
||||
try {
|
||||
if (MD_STD::startsWithAny($output, ['https://', 'http://', 'ftp://']) === false) {
|
||||
throw new MDInvalidUrl("Invalid input URL" . PHP_EOL . $output . PHP_EOL . strtolower($output));
|
||||
}
|
||||
}
|
||||
catch (MDInvalidUrl $e) {
|
||||
if (MD_STD::startsWithAny(strtolower($output), ['https://', 'http://', 'ftp://']) === true) {
|
||||
$output = strtolower(substr($output, 0, 8)) . substr($output, 8);
|
||||
}
|
||||
else throw $e;
|
||||
}
|
||||
|
||||
if (\str_contains($output, '.') === false) {
|
||||
throw new MDInvalidUrl("Invalid input URL");
|
||||
}
|
||||
|
||||
@ -224,9 +266,8 @@ final class MD_STD_IN {
|
||||
return "";
|
||||
}
|
||||
|
||||
$output = \filter_var($input, FILTER_SANITIZE_EMAIL);
|
||||
if (($output = \filter_var($output, FILTER_VALIDATE_EMAIL)) === false) {
|
||||
throw new MDInvalidEmail("Invalid input email address");
|
||||
if (($output = \filter_var($input, FILTER_VALIDATE_EMAIL)) === false) {
|
||||
throw new MDInvalidEmail("Invalid input email address" . ' '. $input);
|
||||
}
|
||||
|
||||
return $output;
|
||||
@ -302,7 +343,7 @@ final class MD_STD_IN {
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function validate_longitude(string|int $input):float {
|
||||
public static function validate_longitude(string|int|float $input):float {
|
||||
|
||||
if (is_string($input)) $output = self::sanitize_float($input);
|
||||
else $output = $input;
|
||||
@ -322,7 +363,7 @@ final class MD_STD_IN {
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function validate_latitude(string|int $input):float {
|
||||
public static function validate_latitude(string|int|float $input):float {
|
||||
|
||||
if (is_string($input)) $output = self::sanitize_float($input);
|
||||
else $output = $input;
|
||||
@ -373,6 +414,27 @@ final class MD_STD_IN {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a ZIP code.
|
||||
*
|
||||
* @param string $input Input string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function validate_zip_code(string $input):string {
|
||||
|
||||
if (($input = trim($input)) === "") {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (\mb_strlen($input) > 7) {
|
||||
throw new MDgenericInvalidInputsException("ZIP code is too long");
|
||||
}
|
||||
|
||||
return $input;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an UTF8 version of a string.
|
||||
*
|
||||
|
149
src/testing/MD_STD_TEST_PROVIDERS.php
Normal file
149
src/testing/MD_STD_TEST_PROVIDERS.php
Normal file
@ -0,0 +1,149 @@
|
||||
<?PHP
|
||||
/**
|
||||
* Test for ensuring that search RSS feeds are generated correctly.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the manifest.
|
||||
*/
|
||||
final class MD_STD_TEST_PROVIDERS {
|
||||
|
||||
/**
|
||||
* Data provider for returning invalid URLs.
|
||||
*
|
||||
* @return array<array{0: string}>
|
||||
*/
|
||||
public static function invalid_url_provider():array {
|
||||
|
||||
$output = [
|
||||
'Space in protocol name' => ["h ttps://www.museum-digital.org"],
|
||||
'Unwanted protocol' => ["telegram://www.museum-digital.org"],
|
||||
'String without protocol' => ["www.museum-digital.org"],
|
||||
'Localhost' => ["http://localhost"],
|
||||
|
||||
// As per the RFC, URLs should not exceed 2048. Enough real-world ones
|
||||
// do. But they certainly should not exceed 10000 characters.
|
||||
'Overly long URL (> 10000 chars)' => ["https://www.museum-digital.org/" . str_repeat('a', 10000)],
|
||||
];
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for working URLs.
|
||||
*
|
||||
* @return array<array{0: string, 1: string}>
|
||||
*/
|
||||
public static function valid_url_provider():array {
|
||||
|
||||
return [
|
||||
'Regular URL without path or query' => ['https://www.museum-digital.org', 'https://www.museum-digital.org'],
|
||||
'URL with uppercase character in scheme' => ['Https://www.museum-digital.org', 'https://www.museum-digital.org'],
|
||||
'URL with cyrillic characters, HTML-encoded ' => [
|
||||
'https://sr.wikipedia.org/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4',
|
||||
'https://sr.wikipedia.org/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4',
|
||||
],
|
||||
'URL with cyrillic characters, not HTML-encoded ' => [
|
||||
'https://sr.wikipedia.org/wiki/Београд',
|
||||
'https://sr.wikipedia.org/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4',
|
||||
],
|
||||
'URL with: scheme, user, pass, host, path, query' => [
|
||||
'https://username:password@sr.wikipedia.org:9000/wiki/Београд?test=hi',
|
||||
'https://username:password@sr.wikipedia.org:9000/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4?test=hi',
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for working mail addresses.
|
||||
*
|
||||
* @return array<array{0: string, 1: string}>
|
||||
*/
|
||||
public static function invalid_email_provider():array {
|
||||
|
||||
// Invalid addresses as per https://codefool.tumblr.com/post/15288874550/list-of-valid-and-invalid-email-addresses
|
||||
$invalid = [
|
||||
'plainaddress',
|
||||
'#@%^%#$@#$@#.com',
|
||||
'@example.com',
|
||||
'Joe Smith <email@example.com>',
|
||||
'email.example.com',
|
||||
'email@example@example.com',
|
||||
'.email@example.com',
|
||||
'email.@example.com',
|
||||
'email..email@example.com',
|
||||
'あいうえお@example.com',
|
||||
'email@example.com (Joe Smith)',
|
||||
'email@example',
|
||||
'email@-example.com',
|
||||
'email@111.222.333.44444',
|
||||
'email@example..com',
|
||||
'Abc..123@example.com',
|
||||
'“(),:;<>[\]@example.com',
|
||||
'just"not"right@example.com',
|
||||
'this\ is"really"not\allowed@example.com',
|
||||
];
|
||||
|
||||
$output = [];
|
||||
foreach ($invalid as $addr) {
|
||||
$output[$addr] = [
|
||||
$addr,
|
||||
];
|
||||
}
|
||||
|
||||
$output['Mail address is too long'] = [str_repeat("a", 10000) . '@example.com'];
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for working mail addresses.
|
||||
*
|
||||
* @return array<array{0: string, 1: string}>
|
||||
*/
|
||||
public static function valid_email_provider():array {
|
||||
|
||||
// Valid addresses as per https://codefool.tumblr.com/post/15288874550/list-of-valid-and-invalid-email-addresses
|
||||
// Excluding:
|
||||
//
|
||||
// 'email@123.123.123.123',
|
||||
// 'email@[123.123.123.123]',
|
||||
// '“email”@example.com',
|
||||
//
|
||||
// as per PHP's FILTER_VALIDATE_EMAIL
|
||||
$valid = [
|
||||
'email@example.com',
|
||||
'firstname.lastname@example.com',
|
||||
'email@subdomain.example.com',
|
||||
'firstname+lastname@example.com',
|
||||
'1234567890@example.com',
|
||||
'email@example-one.com',
|
||||
'_______@example.com',
|
||||
'email@example.name',
|
||||
'email@example.museum',
|
||||
'email@example.co.jp',
|
||||
'firstname-lastname@example.com',
|
||||
];
|
||||
|
||||
$output = [];
|
||||
foreach ($valid as $addr) {
|
||||
$output[$addr] = [
|
||||
$addr,
|
||||
$addr,
|
||||
];
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
}
|
628
tests/MD_STD_IN_Test.php
Normal file
628
tests/MD_STD_IN_Test.php
Normal file
@ -0,0 +1,628 @@
|
||||
<?PHP
|
||||
/**
|
||||
* Tests for MD_STD_IN.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Tests for MD_STD_IN.
|
||||
*/
|
||||
final class MD_STD_IN_Test extends TestCase {
|
||||
/**
|
||||
* Data provider for valid IDs.
|
||||
*
|
||||
* @return array<array{0: mixed, 1: int}>
|
||||
*/
|
||||
public static function valid_id_provider():array {
|
||||
|
||||
$values = [
|
||||
[1, 1],
|
||||
["1", 1],
|
||||
["1111111", 1111111],
|
||||
];
|
||||
|
||||
$output = [];
|
||||
foreach ($values as $value) {
|
||||
$output[gettype($value[0]) . ': ' . var_export($value[0], true)] = $value;
|
||||
}
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_id().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_id
|
||||
* @dataProvider \MD_STD_IN_Test::valid_id_provider
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
* @param integer $expected Expected output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_id_works(mixed $to_validate, int $expected):void {
|
||||
self::assertEquals($expected, MD_STD_IN::sanitize_id($to_validate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for valid IDs.
|
||||
*
|
||||
* @return array<array{0: mixed}>
|
||||
*/
|
||||
public static function invalid_id_provider():array {
|
||||
|
||||
$output = self::invalid_id_provider_without_zero();
|
||||
$output['Number 0'] = [0];
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_id().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_id
|
||||
* @dataProvider \MD_STD_IN_Test::invalid_id_provider
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_id_fails(mixed $to_validate):void {
|
||||
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id($to_validate);
|
||||
|
||||
}
|
||||
/**
|
||||
* Data provider for valid IDs.
|
||||
*
|
||||
* @return array<array{0: mixed, 1: int}>
|
||||
*/
|
||||
public static function valid_id_or_zero_provider():array {
|
||||
|
||||
$output = self::valid_id_provider();
|
||||
$output['Integer 0'] = [0, 0];
|
||||
$output['String 0'] = [0, 0];
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_id_or_zero().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_id_or_zero
|
||||
* @dataProvider \MD_STD_IN_Test::valid_id_or_zero_provider
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
* @param integer $expected Expected output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_id_or_zero_works(mixed $to_validate, int $expected):void {
|
||||
|
||||
self::assertEquals($expected, MD_STD_IN::sanitize_id_or_zero($to_validate));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for valid IDs.
|
||||
*
|
||||
* @return array<array{0: mixed}>
|
||||
*/
|
||||
public static function invalid_id_provider_without_zero():array {
|
||||
|
||||
return [
|
||||
'Number too high' => [1000000000000000000000000000000000000],
|
||||
'Number with character in the middle' => ["1a2"],
|
||||
'Number with suffixed string' => ["12a"],
|
||||
'String character' => ["a"],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_id_or_zero().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_id_or_zero
|
||||
* @dataProvider \MD_STD_IN_Test::invalid_id_provider_without_zero
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_id_or_zero_fails(mixed $to_validate):void {
|
||||
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_or_zero($to_validate);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for text with its expected cleaned values.
|
||||
*
|
||||
* @return array<array{0: mixed, 1: string}>
|
||||
*/
|
||||
public static function text_with_expected_return_value_provider():array {
|
||||
|
||||
return [
|
||||
'Empty string' => ['', ''],
|
||||
'Integer 0' => [0, '0'],
|
||||
'String 0' => ['0', '0'],
|
||||
'Regular string' => ['a', 'a'],
|
||||
'String with double whitespace in between' => ['a a', 'a a'],
|
||||
'String to be trimmed (spaces)' => ['a ', 'a'],
|
||||
'String to be trimmed (newline)' => ['a ' . PHP_EOL, 'a'],
|
||||
'Empty array' => [[], ''],
|
||||
'Array with content' => [['test' => 'test'], ''],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_text().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_text
|
||||
* @dataProvider \MD_STD_IN_Test::text_with_expected_return_value_provider
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
* @param string $expected Expected output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_text(mixed $to_validate, string $expected):void {
|
||||
|
||||
self::assertEquals($expected, MD_STD_IN::sanitize_text($to_validate));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for working RGB colors.
|
||||
*
|
||||
* @return array<array{0: mixed, 1: string}>
|
||||
*/
|
||||
public static function valid_rgb_colors_provider():array {
|
||||
|
||||
return [
|
||||
'Three character version' => ['AAA', 'AAA'],
|
||||
'Three character version (int)' => ['111', '111'],
|
||||
'Three character version (mixed)' => ['1a1', '1A1'],
|
||||
'Six character version' => ['AAAAAA', 'AAAAAA'],
|
||||
'Six character version (int)' => ['111111', '111111'],
|
||||
'Six character version (mixed)' => ['1a1AAA', '1A1AAA'],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for strings that are not rgb colors.
|
||||
*
|
||||
* @return array<array{0: mixed}>
|
||||
*/
|
||||
public static function invalid_rgb_colors_provider():array {
|
||||
|
||||
$output = [
|
||||
'Array' => [[]],
|
||||
'Three characters, but invalid ones' => ['ZZZ'],
|
||||
'Six characters, but invalid ones' => ['111ZZZ'],
|
||||
'Three characters, but with spaces' => ['ZZZ '],
|
||||
];
|
||||
|
||||
for ($i = 0; $i++; $i < 10) {
|
||||
if ($i === 3 || $i === 6) continue;
|
||||
$output['Valid characters repeated ' . $i . ' times'] = [$i];
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_rgb_color().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_rgb_color
|
||||
* @dataProvider \MD_STD_IN_Test::valid_rgb_colors_provider
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
* @param string $expected Expected output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_rgb_color_works(mixed $to_validate, string $expected):void {
|
||||
|
||||
self::assertEquals($expected, MD_STD_IN::sanitize_rgb_color($to_validate));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_rgb_color()'s failure modes.
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_rgb_color
|
||||
* @dataProvider \MD_STD_IN_Test::invalid_rgb_colors_provider
|
||||
*
|
||||
* @param mixed $to_validate Input to validate.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_rgb_color_fails(mixed $to_validate):void {
|
||||
|
||||
self::expectException(MDInvalidColorCode::class);
|
||||
MD_STD_IN::sanitize_rgb_color($to_validate);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_id_array().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_id_array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_id_array():void {
|
||||
|
||||
self::assertEquals([1], MD_STD_IN::sanitize_id_array([1]));
|
||||
self::assertEquals([1, 2], MD_STD_IN::sanitize_id_array(["1", 2]));
|
||||
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_array([0]);
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_array([0, 1]);
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_array([100000000000000000000000000000]);
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_array(["1a2"]);
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_array(["12a"]);
|
||||
self::expectException(MDpageParameterNotNumericException::class);
|
||||
MD_STD_IN::sanitize_id_array(["a"]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing get_http_input_text().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::get_http_input_text
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_http_input_text():void {
|
||||
|
||||
$_GET['test'] = "a";
|
||||
self::assertEquals("a", MD_STD_IN::get_http_input_text("test"));
|
||||
unset($_GET['test']);
|
||||
|
||||
$_POST['test'] = "a";
|
||||
self::assertEquals("a", MD_STD_IN::get_http_input_text("test"));
|
||||
unset($_POST['test']);
|
||||
|
||||
$_POST['test'] = [];
|
||||
self::assertEquals("", MD_STD_IN::get_http_input_text("test"));
|
||||
unset($_POST['test']);
|
||||
|
||||
self::assertEquals("", MD_STD_IN::get_http_input_text("test"));
|
||||
|
||||
self::expectException(MDpageParameterNotFromListException::class);
|
||||
MD_STD_IN::get_http_input_text("a", "", ['a']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing get_http_post_text().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::get_http_post_text
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_http_post_text():void {
|
||||
|
||||
$_POST['test'] = "a";
|
||||
self::assertEquals("a", MD_STD_IN::get_http_post_text("test"));
|
||||
unset($_POST['test']);
|
||||
|
||||
$_POST['test'] = [];
|
||||
self::assertEquals("", MD_STD_IN::get_http_post_text("test"));
|
||||
unset($_POST['test']);
|
||||
|
||||
self::assertEquals("", MD_STD_IN::get_http_post_text("test"));
|
||||
|
||||
self::expectException(MDpageParameterNotFromListException::class);
|
||||
MD_STD_IN::get_http_post_text("a", "", ['a']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_url().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_url
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_url_with_empty_string():void {
|
||||
|
||||
// Ensure empty inputs return empty output
|
||||
self::assertEquals("", MD_STD_IN::sanitize_url(""));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_url().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_url
|
||||
* @dataProvider \MD_STD_TEST_PROVIDERS::valid_url_provider
|
||||
*
|
||||
* @param string $to_validate Input to validate.
|
||||
* @param string $expected Expected output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_url_works(string $to_validate, string $expected):void {
|
||||
|
||||
self::assertEquals($expected, MD_STD_IN::sanitize_url($to_validate));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_url().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_url
|
||||
* @dataProvider \MD_STD_TEST_PROVIDERS::invalid_url_provider
|
||||
*
|
||||
* @param string $to_validate Input to validate.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_url_fails(string $to_validate):void {
|
||||
|
||||
self::expectException(MDInvalidUrl::class);
|
||||
MD_STD_IN::sanitize_url($to_validate);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_email().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_email
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_email_empty():void {
|
||||
|
||||
self::assertEquals("", MD_STD_IN::sanitize_email(""));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_email().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_email
|
||||
* @dataProvider \MD_STD_TEST_PROVIDERS::valid_email_provider
|
||||
*
|
||||
* @param string $to_validate Input to validate.
|
||||
* @param string $expected Expected output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_email_works(string $to_validate, string $expected):void {
|
||||
self::assertEquals($expected, MD_STD_IN::sanitize_email($to_validate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_email() fails when it should.
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_email
|
||||
* @dataProvider \MD_STD_TEST_PROVIDERS::invalid_email_provider
|
||||
*
|
||||
* @param string $to_validate Input to validate.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_email_fails(string $to_validate):void {
|
||||
|
||||
self::expectException(MDInvalidEmail::class);
|
||||
MD_STD_IN::sanitize_email($to_validate);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing validate_password().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::validate_password
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_validate_password():void {
|
||||
|
||||
self::assertEquals(['password_too_short', 'password_has_no_number_no_special_char'], MD_STD_IN::validate_password("a"));
|
||||
self::assertEquals(['password_has_no_number_no_special_char'], MD_STD_IN::validate_password("aaaaaaaaaaaaaaaaaaaa"));
|
||||
self::assertEquals(['password_too_short'], MD_STD_IN::validate_password("!a323!"));
|
||||
self::assertEquals([], MD_STD_IN::validate_password("!a324324324123!"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing validate_phone_number().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::validate_phone_number
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_validate_phone_number():void {
|
||||
|
||||
self::assertEquals("", MD_STD_IN::validate_phone_number(""));
|
||||
self::assertEquals("+1932-1321123", MD_STD_IN::validate_phone_number("+1932-1321123"));
|
||||
self::assertEquals("+49 (030) 21321123", MD_STD_IN::validate_phone_number("+49 (030) 21321123"));
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_phone_number("test@example.org");
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_phone_number("+123456789 z");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing sanitize_float().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::sanitize_float
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_float():void {
|
||||
|
||||
self::assertEquals(0, MD_STD_IN::sanitize_float("0"));
|
||||
self::assertEquals(12, MD_STD_IN::sanitize_float("12"));
|
||||
self::assertEquals(12.12, MD_STD_IN::sanitize_float("12.12"));
|
||||
self::assertEquals(12.12, MD_STD_IN::sanitize_float("12,12"));
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::sanitize_float("test");
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::sanitize_float("");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing validate_longitude().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::validate_longitude
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_validate_longitude():void {
|
||||
|
||||
self::assertEquals(0, MD_STD_IN::validate_longitude("0"));
|
||||
self::assertEquals(12, MD_STD_IN::validate_longitude("12"));
|
||||
self::assertEquals(12, MD_STD_IN::validate_longitude(12));
|
||||
self::assertEquals(12.12, MD_STD_IN::validate_longitude("12.12"));
|
||||
self::assertEquals(12.12, MD_STD_IN::validate_longitude("12,12"));
|
||||
self::assertEquals(12.12, MD_STD_IN::validate_longitude(12.12));
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_longitude("test");
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_longitude("");
|
||||
self::expectException(MDCoordinateOutOfRange::class);
|
||||
MD_STD_IN::validate_longitude("1900");
|
||||
self::expectException(MDCoordinateOutOfRange::class);
|
||||
MD_STD_IN::validate_longitude(1900);
|
||||
self::expectException(MDCoordinateOutOfRange::class);
|
||||
MD_STD_IN::validate_longitude(-1900);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing validate_latitude().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::validate_latitude
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_validate_latitude():void {
|
||||
|
||||
self::assertEquals(0, MD_STD_IN::validate_latitude("0"));
|
||||
self::assertEquals(12, MD_STD_IN::validate_latitude("12"));
|
||||
self::assertEquals(12, MD_STD_IN::validate_latitude(12));
|
||||
self::assertEquals(12.12, MD_STD_IN::validate_latitude("12.12"));
|
||||
self::assertEquals(12.12, MD_STD_IN::validate_latitude("12,12"));
|
||||
self::assertEquals(12.12, MD_STD_IN::validate_latitude(12.12));
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_latitude("test");
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_latitude("");
|
||||
self::expectException(MDCoordinateOutOfRange::class);
|
||||
MD_STD_IN::validate_latitude("1900");
|
||||
self::expectException(MDCoordinateOutOfRange::class);
|
||||
MD_STD_IN::validate_latitude(1900);
|
||||
self::expectException(MDCoordinateOutOfRange::class);
|
||||
MD_STD_IN::validate_latitude(-1900);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing validate_isbn().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::validate_isbn
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_validate_isbn():void {
|
||||
|
||||
self::assertEquals("", MD_STD_IN::validate_isbn(""));
|
||||
self::assertEquals("0943396042", MD_STD_IN::validate_isbn("0943396042"));
|
||||
self::assertEquals("0943396042", MD_STD_IN::validate_isbn("0-943396-04-2"));
|
||||
self::assertEquals("094339604X", MD_STD_IN::validate_isbn("0-943396-04-X"));
|
||||
|
||||
self::assertEquals("1230943396042", MD_STD_IN::validate_isbn("1230943396042"));
|
||||
self::assertEquals("1230943396042", MD_STD_IN::validate_isbn("1230-943396-04-2"));
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_isbn("X094339604");
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_isbn("094339604a");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing validate_zip_code().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::validate_zip_code
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_validate_zip_code():void {
|
||||
|
||||
self::assertEquals("", MD_STD_IN::validate_zip_code(""));
|
||||
self::assertEquals("1234", MD_STD_IN::validate_zip_code(" 1234"));
|
||||
|
||||
self::expectException(MDgenericInvalidInputsException::class);
|
||||
MD_STD_IN::validate_zip_code("X094339604");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for testing ensureStringIsUtf8().
|
||||
*
|
||||
* @small
|
||||
* @covers \MD_STD_IN::ensureStringIsUtf8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_ensureStringIsUtf8():void {
|
||||
|
||||
self::assertEquals("ä", MD_STD_IN::ensureStringIsUtf8("ä"));
|
||||
self::assertEquals("ä", MD_STD_IN::ensureStringIsUtf8(iconv("UTF-8", 'ISO-8859-1//TRANSLIT', "ä")));
|
||||
self::assertEquals("a", MD_STD_IN::ensureStringIsUtf8(iconv("UTF-8", 'ISO-2022-JP//TRANSLIT', "ä")));
|
||||
|
||||
}
|
||||
}
|
@ -17,9 +17,7 @@ final class MD_STD_SECTest extends TestCase {
|
||||
/**
|
||||
* Function for testing if the page can be opened using invalid values for objektnum.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
* @group MissingInputs
|
||||
* @group SafeForProduction
|
||||
* @small
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
25
tests/bootstrap.php
Normal file
25
tests/bootstrap.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?PHP
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* Autoloader for musdb.
|
||||
*
|
||||
* @param string $className Name of the class to load.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
\spl_autoload_register(function(string $className):void {
|
||||
|
||||
// Try using class map as defined through /scripts/buildClassMap.php
|
||||
|
||||
foreach (array_merge([__DIR__ . '/../tests', __DIR__ . '/../src', __DIR__ . '/../src/testing', __DIR__ . '/../../MDErrorReporter', __DIR__ . '/../../MDErrorReporter/exceptions', __DIR__ . '/../../MDErrorReporter/exceptions/generic', __DIR__ . '/../../MDErrorReporter/exceptions/updates', __DIR__ . '/../../MDErrorReporter/exceptions/page']) as $classDir) {
|
||||
|
||||
if (\file_exists("$classDir/$className.php")) {
|
||||
include "$classDir/$className.php";
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
Reference in New Issue
Block a user