Add browser and unit test suite with Pest + Playwright
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.
This commit is contained in:
parent
0b61643ec5
commit
b8e6d2537d
20 changed files with 1331 additions and 33 deletions
105
tests/Unit/NewsletterSignupTest.php
Normal file
105
tests/Unit/NewsletterSignupTest.php
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
<?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");
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue