Add comprehensive test coverage for core site features (content, navigation, language, FAQ, news, petition, newsletter) using Pest browser tests and unit tests for custom plugins. Includes test infrastructure (Containerfile.test, compose.test.yaml), test documentation, and test files covering petition form logic, CSV handling, translation, date formatting, rate limiting, and map data building.
105 lines
3.6 KiB
PHP
105 lines
3.6 KiB
PHP
<?php
|
|
|
|
// newsletter-signup.php calls session_start() at load time — pre-initialise
|
|
// $_SESSION so the guard fires correctly without emitting headers.
|
|
$_SESSION = [];
|
|
$_SERVER['REMOTE_ADDR'] ??= '127.0.0.1';
|
|
$_SERVER['HTTP_HOST'] ??= 'localhost';
|
|
|
|
require_once CUSTOM_DIR . '/plugins/page/newsletter-signup.php';
|
|
|
|
// --- newsletterT ---
|
|
|
|
it('returns the fallback value when no global context is present', function () {
|
|
unset($GLOBALS['ctx']);
|
|
expect(newsletterT('name_label'))->toBe('Navn');
|
|
expect(newsletterT('submit_button'))->toBe('Meld deg på');
|
|
expect(newsletterT('success_message'))->toBe('Sjekk innboksen din!');
|
|
});
|
|
|
|
it('returns the key itself for an unknown key when no context is present', function () {
|
|
unset($GLOBALS['ctx']);
|
|
expect(newsletterT('nonexistent_key'))->toBe('nonexistent_key');
|
|
});
|
|
|
|
it('returns a translation from context when available', function () {
|
|
$GLOBALS['ctx'] = new class {
|
|
public function get(string $key, mixed $default = null): mixed
|
|
{
|
|
return $key === 'translations'
|
|
? ['newsletter.name_label' => 'Name']
|
|
: $default;
|
|
}
|
|
};
|
|
expect(newsletterT('name_label'))->toBe('Name');
|
|
unset($GLOBALS['ctx']);
|
|
});
|
|
|
|
it('falls back to the key when context has no matching translation', function () {
|
|
$GLOBALS['ctx'] = new class {
|
|
public function get(string $key, mixed $default = null): mixed
|
|
{
|
|
return $key === 'translations' ? [] : $default;
|
|
}
|
|
};
|
|
expect(newsletterT('name_label'))->toBe('name_label');
|
|
unset($GLOBALS['ctx']);
|
|
});
|
|
|
|
// --- newsletterCheckRateLimit ---
|
|
|
|
it('returns true when no previous submission is recorded in the session', function () {
|
|
unset($_SESSION['newsletter_last_submit']);
|
|
expect(newsletterCheckRateLimit())->toBeTrue();
|
|
});
|
|
|
|
it('returns false immediately after a submission', function () {
|
|
$_SESSION['newsletter_last_submit'] = time();
|
|
expect(newsletterCheckRateLimit())->toBeFalse();
|
|
});
|
|
|
|
it('returns false when 29 seconds have elapsed', function () {
|
|
$_SESSION['newsletter_last_submit'] = time() - 29;
|
|
expect(newsletterCheckRateLimit())->toBeFalse();
|
|
});
|
|
|
|
it('returns true when exactly 30 seconds have elapsed', function () {
|
|
$_SESSION['newsletter_last_submit'] = time() - 30;
|
|
expect(newsletterCheckRateLimit())->toBeTrue();
|
|
});
|
|
|
|
it('returns true when more than 30 seconds have elapsed', function () {
|
|
$_SESSION['newsletter_last_submit'] = time() - 60;
|
|
expect(newsletterCheckRateLimit())->toBeTrue();
|
|
});
|
|
|
|
// --- newsletterGetTranslations ---
|
|
|
|
it('returns all expected translation keys', function () {
|
|
unset($GLOBALS['ctx']);
|
|
expect(newsletterGetTranslations())->toHaveKeys([
|
|
'nameLabel', 'namePlaceholder', 'emailLabel', 'emailPlaceholder',
|
|
'notice', 'submitButton', 'successMessage', 'successConfirm', 'errorMessage',
|
|
]);
|
|
});
|
|
|
|
it('HTML-escapes special characters in translation values', function () {
|
|
$GLOBALS['ctx'] = new class {
|
|
public function get(string $key, mixed $default = null): mixed
|
|
{
|
|
return $key === 'translations'
|
|
? ['newsletter.name_label' => '<b>Name & "Label"</b>']
|
|
: $default;
|
|
}
|
|
};
|
|
$translations = newsletterGetTranslations();
|
|
expect($translations['nameLabel'])->toBe('<b>Name & "Label"</b>');
|
|
unset($GLOBALS['ctx']);
|
|
});
|
|
|
|
it('returns string values for all keys', function () {
|
|
unset($GLOBALS['ctx']);
|
|
foreach (newsletterGetTranslations() as $key => $value) {
|
|
expect($value)->toBeString("Key '{$key}' should be a string");
|
|
}
|
|
});
|