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
113
tests/Unit/PetitionCliTest.php
Normal file
113
tests/Unit/PetitionCliTest.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
// petition-cli.php has a CLI-only guard; tests always run in CLI so it passes.
|
||||
// It defines BASE_DIR / DATA_DIR / PETITIONS_DIR / SMTP_LOG / IGNORE_LIST pointing
|
||||
// to real custom/data/ paths, but the functions tested here are pure-logic and
|
||||
// do not touch those constants.
|
||||
require_once CUSTOM_DIR . '/petition-cli.php';
|
||||
|
||||
// --- isIgnored ---
|
||||
|
||||
it('returns false when the ignore list is empty', function () {
|
||||
expect(isIgnored([], 'failed', 'my-petition', 'user@example.com'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('returns true when the exact key is present', function () {
|
||||
$ignoreList = [
|
||||
'failed|my-petition|user@example.com' => [
|
||||
'timestamp' => 1700000000,
|
||||
'type' => 'failed',
|
||||
'petition_id' => 'my-petition',
|
||||
'email' => 'user@example.com',
|
||||
'reason' => 'bounced',
|
||||
],
|
||||
];
|
||||
expect(isIgnored($ignoreList, 'failed', 'my-petition', 'user@example.com'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('matches the email case-insensitively', function () {
|
||||
$ignoreList = [
|
||||
'failed|my-petition|user@example.com' => [
|
||||
'timestamp' => 0, 'type' => 'failed', 'petition_id' => 'my-petition',
|
||||
'email' => 'user@example.com', 'reason' => '',
|
||||
],
|
||||
];
|
||||
expect(isIgnored($ignoreList, 'failed', 'my-petition', 'User@EXAMPLE.COM'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('returns false when the type does not match', function () {
|
||||
$ignoreList = [
|
||||
'failed|my-petition|user@example.com' => [
|
||||
'timestamp' => 0, 'type' => 'failed', 'petition_id' => 'my-petition',
|
||||
'email' => 'user@example.com', 'reason' => '',
|
||||
],
|
||||
];
|
||||
expect(isIgnored($ignoreList, 'unconfirmed', 'my-petition', 'user@example.com'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('returns false when the petition_id does not match', function () {
|
||||
$ignoreList = [
|
||||
'failed|my-petition|user@example.com' => [
|
||||
'timestamp' => 0, 'type' => 'failed', 'petition_id' => 'my-petition',
|
||||
'email' => 'user@example.com', 'reason' => '',
|
||||
],
|
||||
];
|
||||
expect(isIgnored($ignoreList, 'failed', 'other-petition', 'user@example.com'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('returns false when the email does not match', function () {
|
||||
$ignoreList = [
|
||||
'failed|my-petition|user@example.com' => [
|
||||
'timestamp' => 0, 'type' => 'failed', 'petition_id' => 'my-petition',
|
||||
'email' => 'user@example.com', 'reason' => '',
|
||||
],
|
||||
];
|
||||
expect(isIgnored($ignoreList, 'failed', 'my-petition', 'other@example.com'))->toBeFalse();
|
||||
});
|
||||
|
||||
// --- formatDate ---
|
||||
|
||||
it('formats a unix timestamp as Y-m-d H:i', function () {
|
||||
$result = formatDate(0);
|
||||
expect($result)->toMatch('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/');
|
||||
});
|
||||
|
||||
it('produces the expected date string for a known timestamp', function () {
|
||||
// 2024-03-15 10:05:00 UTC — pin to UTC so test is locale-independent
|
||||
$original = date_default_timezone_get();
|
||||
date_default_timezone_set('UTC');
|
||||
$ts = mktime(10, 5, 0, 3, 15, 2024);
|
||||
expect(formatDate($ts))->toBe('2024-03-15 10:05');
|
||||
date_default_timezone_set($original);
|
||||
});
|
||||
|
||||
// --- buildConfirmationEmail ---
|
||||
|
||||
it('returns an array with subject and body keys', function () {
|
||||
$sig = ['petition_id' => 'test', 'firstname' => 'Kari', 'token' => 'abc'];
|
||||
$result = buildConfirmationEmail($sig, 'Test Campaign');
|
||||
expect($result)->toHaveKeys(['subject', 'body']);
|
||||
});
|
||||
|
||||
it('includes the recipient first name in the body', function () {
|
||||
$sig = ['petition_id' => 'test', 'firstname' => 'Ingrid', 'token' => 'tok1'];
|
||||
expect(buildConfirmationEmail($sig, 'X')['body'])->toContain('Ingrid');
|
||||
});
|
||||
|
||||
it('includes the petition title in the body', function () {
|
||||
$sig = ['petition_id' => 'test', 'firstname' => 'Ola', 'token' => 'tok2'];
|
||||
expect(buildConfirmationEmail($sig, 'Medisinsk Cannabis')['body'])->toContain('Medisinsk Cannabis');
|
||||
});
|
||||
|
||||
it('includes the confirmation URL with the correct token', function () {
|
||||
$sig = ['petition_id' => 'my-petition', 'firstname' => 'Per', 'token' => 'tok999'];
|
||||
$body = buildConfirmationEmail($sig, 'X')['body'];
|
||||
expect($body)->toContain('?confirm=tok999');
|
||||
expect($body)->toContain('/underskriftskampanje/my-petition/');
|
||||
});
|
||||
|
||||
it('uses the petition_id in the confirmation URL', function () {
|
||||
$sig = ['petition_id' => 'helse-kampanje', 'firstname' => 'Liv', 'token' => 'x'];
|
||||
$body = buildConfirmationEmail($sig, 'X')['body'];
|
||||
expect($body)->toContain('/underskriftskampanje/helse-kampanje/');
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue