innhold/tests/Unit/PetitionFormTestPure.php

163 lines
6 KiB
PHP
Raw Normal View History

<?php
// PetitionFormTest.php (which loads first alphabetically) already required
// petition-form.php and defined Context / Hook / Hooks stubs.
// This file only adds tests — no re-requires or re-declarations needed.
/**
* Build a minimal Context mock that supports get('translations') and get('currentLang').
*/
function mockContext(array $translations = [], string $lang = 'no'): object
{
return new class($translations, $lang) extends Context {
public function __construct(
private array $translations,
private string $lang
) {}
public function get(string $key, mixed $default = null): mixed
{
return match ($key) {
'translations' => $this->translations,
'currentLang' => $this->lang,
default => $default,
};
}
};
}
// --- petitionT ---
it('returns the key when no translation is found', function () {
$ctx = mockContext([]);
expect(petitionT($ctx, 'petition', 'missing_key'))->toBe('missing_key');
});
it('returns the translated string when found', function () {
$ctx = mockContext(['petition.greeting' => 'Hei!']);
expect(petitionT($ctx, 'petition', 'greeting'))->toBe('Hei!');
});
it('applies placeholder replacements', function () {
$ctx = mockContext(['petition.email_greeting' => 'Hei {name}!']);
expect(petitionT($ctx, 'petition', 'email_greeting', ['name' => 'Kari']))->toBe('Hei Kari!');
});
it('applies multiple replacements in a single string', function () {
$ctx = mockContext(['petition.thanks' => 'Takk {name} for {title}']);
$result = petitionT($ctx, 'petition', 'thanks', ['name' => 'Ola', 'title' => 'kampanjen']);
expect($result)->toBe('Takk Ola for kampanjen');
});
it('uses the section as part of the translation key', function () {
$ctx = mockContext(['regions.oslo' => 'Oslo', 'petition.oslo' => 'Wrong']);
expect(petitionT($ctx, 'regions', 'oslo'))->toBe('Oslo');
});
// --- petitionGetIdFromPath ---
it('returns the basename of a path as the petition ID', function () {
expect(petitionGetIdFromPath('/content/underskriftskampanje/my-petition'))->toBe('my-petition');
});
it('strips a leading numeric prefix from the folder name', function () {
expect(petitionGetIdFromPath('/content/01-my-petition'))->toBe('my-petition');
expect(petitionGetIdFromPath('/content/001-my-petition'))->toBe('my-petition');
});
it('leaves non-prefixed names intact', function () {
expect(petitionGetIdFromPath('/content/medisinsk-cannabis'))->toBe('medisinsk-cannabis');
});
it('returns null when the basename is empty', function () {
expect(petitionGetIdFromPath('/'))->toBeNull();
});
// --- petitionFormatDate ---
it('formats a date in Norwegian by default', function () {
date_default_timezone_set('UTC');
$ctx = mockContext([], 'no');
// 2024-03-15 10:05:00 UTC
$ts = mktime(10, 5, 0, 3, 15, 2024);
expect(petitionFormatDate($ts, $ctx))->toBe('15. mars 2024, 10:05');
});
it('formats a date in English when lang is en', function () {
date_default_timezone_set('UTC');
$ctx = mockContext([], 'en');
$ts = mktime(10, 5, 0, 3, 15, 2024);
expect(petitionFormatDate($ts, $ctx))->toBe('March 15, 2024, 10:05');
});
it('uses Norwegian month names for an unknown language', function () {
date_default_timezone_set('UTC');
$ctx = mockContext([], 'fr');
$ts = mktime(0, 0, 0, 1, 1, 2024);
$result = petitionFormatDate($ts, $ctx);
expect($result)->toContain('januar');
});
it('uses the correct Norwegian month names', function () {
date_default_timezone_set('UTC');
$ctx = mockContext([], 'no');
$months = ['januar','februar','mars','april','mai','juni',
'juli','august','september','oktober','november','desember'];
foreach ($months as $i => $name) {
$ts = mktime(0, 0, 0, $i + 1, 1, 2024);
expect(petitionFormatDate($ts, $ctx))->toContain($name);
}
});
// --- petitionFormatSignature ---
it('shows only first name and region for semi display', function () {
$ctx = mockContext([
'petition.from_region' => 'fra',
'regions.oslo' => 'Oslo',
]);
$sig = ['firstname' => 'Kari', 'surname' => 'Hansen', 'region' => 'oslo', 'display' => 'semi'];
$result = petitionFormatSignature($sig, $ctx);
expect($result)->toBe('Kari fra Oslo');
expect($result)->not->toContain('Hansen');
});
it('shows full name and region for full display', function () {
$ctx = mockContext([
'petition.from_region' => 'fra',
'regions.oslo' => 'Oslo',
]);
$sig = ['firstname' => 'Kari', 'surname' => 'Hansen', 'region' => 'oslo', 'display' => 'full'];
expect(petitionFormatSignature($sig, $ctx))->toBe('Kari Hansen fra Oslo');
});
it('shows anonymous label for anonymous display', function () {
$ctx = mockContext([
'petition.from_region' => 'fra',
'petition.anonymous_name' => 'Anonym',
'regions.oslo' => 'Oslo',
]);
$sig = ['firstname' => 'Kari', 'surname' => 'Hansen', 'region' => 'oslo', 'display' => 'anonymous'];
$result = petitionFormatSignature($sig, $ctx);
expect($result)->toContain('Anonym');
expect($result)->not->toContain('Kari');
expect($result)->not->toContain('Hansen');
});
it('HTML-escapes names in full display mode', function () {
$ctx = mockContext([
'petition.from_region' => 'fra',
'regions.oslo' => 'Oslo',
]);
$sig = ['firstname' => '<b>Kari</b>', 'surname' => '<script>', 'region' => 'oslo', 'display' => 'full'];
$result = petitionFormatSignature($sig, $ctx);
expect($result)->toContain('&lt;b&gt;');
expect($result)->not->toContain('<b>');
});
it('falls back to the region key when no translation exists', function () {
$ctx = mockContext(['petition.from_region' => 'fra']);
$sig = ['firstname' => 'Ola', 'surname' => 'Nilsen', 'region' => 'trondelag', 'display' => 'semi'];
expect(petitionFormatSignature($sig, $ctx))->toContain('trondelag');
});