innhold/tests/Unit/NewsletterSignupTest.php

106 lines
3.6 KiB
PHP
Raw Permalink Normal View History

<?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('&lt;b&gt;Name &amp; &quot;Label&quot;&lt;/b&gt;');
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");
}
});