feat: derive autoresponder schedule from backend
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once PLUGIN_ROOT . '/exec/lib/Settings.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/BackendRuntimeConfig.php';
|
||||
|
||||
test('backend runtime sync invokes backend script when setting changes', function (): void {
|
||||
$settingsPath = TEST_TMP . '/backend-runtime.conf';
|
||||
test_write($settingsPath, "GLOBAL_AUTORESPONDER_BACKEND=exim\n");
|
||||
$settings = Settings::load($settingsPath);
|
||||
|
||||
$script = TEST_TMP . '/backend.sh';
|
||||
test_write($script, "#!/bin/sh\necho \"$1\" >> " . escapeshellarg(TEST_TMP . '/called.log') . "\nmkdir -p " . escapeshellarg(TEST_TMP . '/config') . "\nprintf '{\"active_backend\":\"%s\"}\\n' \"$1\" > " . escapeshellarg(TEST_TMP . '/config/backend-state.json') . "\n");
|
||||
chmod($script, 0700);
|
||||
|
||||
BackendRuntimeConfig::sync($settings, $script, TEST_TMP . '/config/backend-state.json');
|
||||
assert_same("exim\n", file_get_contents(TEST_TMP . '/called.log'));
|
||||
|
||||
BackendRuntimeConfig::sync($settings, $script, TEST_TMP . '/config/backend-state.json');
|
||||
assert_same("exim\n", file_get_contents(TEST_TMP . '/called.log'), 'Script should not run again when backend is already active');
|
||||
});
|
||||
@@ -10,7 +10,7 @@ test('settings validate defaults and external paths', function (): void {
|
||||
'DEFAULT_PLUGIN_LANGUAGE=pl',
|
||||
'DEFAULT_ENABLE=false',
|
||||
'GLOBAL_AUTORESPONDER_TIMEZONE=Europe/Warsaw',
|
||||
'GLOBAL_AUTORESPONDER_SCHEDULE_MODE=exact_hour',
|
||||
'GLOBAL_AUTORESPONDER_BACKEND=exim',
|
||||
'GLOBAL_AUTORESPONDER_REPLY_EVERY_MESSAGE=false',
|
||||
'GLOBAL_AUTORESPONDER_REPEAT_MINUTES=60',
|
||||
'GLOBAL_AUTORESPONDER_DYNAMIC_MAILBOX_SCOPE=true',
|
||||
@@ -23,6 +23,7 @@ test('settings validate defaults and external paths', function (): void {
|
||||
assert_false($settings->defaultEnable());
|
||||
assert_same('Europe/Warsaw', $settings->timezone());
|
||||
assert_same('exact_hour', $settings->scheduleMode());
|
||||
assert_same('exim', $settings->backendMode());
|
||||
assert_same(60, $settings->repeatMinutes());
|
||||
assert_same('/usr/local/hitme_plugins/global-autoresponders/config', Settings::CONFIG_DIR);
|
||||
assert_same('/usr/local/hitme_plugins/global-autoresponders/data', Settings::DATA_DIR);
|
||||
@@ -30,7 +31,7 @@ test('settings validate defaults and external paths', function (): void {
|
||||
|
||||
test('settings reject invalid timezone and schedule mode', function (): void {
|
||||
$path = TEST_TMP . '/bad-settings.conf';
|
||||
test_write($path, "GLOBAL_AUTORESPONDER_TIMEZONE=Not/AZone\nGLOBAL_AUTORESPONDER_SCHEDULE_MODE=bad\n");
|
||||
test_write($path, "GLOBAL_AUTORESPONDER_TIMEZONE=Not/AZone\nGLOBAL_AUTORESPONDER_BACKEND=bad\n");
|
||||
try {
|
||||
Settings::load($path);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
@@ -40,6 +41,19 @@ test('settings reject invalid timezone and schedule mode', function (): void {
|
||||
throw new RuntimeException('Expected invalid settings to fail');
|
||||
});
|
||||
|
||||
test('backend mode derives schedule mode', function (): void {
|
||||
$path = TEST_TMP . '/backend.conf';
|
||||
test_write($path, "GLOBAL_AUTORESPONDER_BACKEND=da\n");
|
||||
$settings = Settings::load($path);
|
||||
assert_same('da', $settings->backendMode());
|
||||
assert_same('directadmin_period', $settings->scheduleMode());
|
||||
|
||||
test_write($path, "GLOBAL_AUTORESPONDER_BACKEND=exim\n");
|
||||
$settings = Settings::load($path);
|
||||
assert_same('exim', $settings->backendMode());
|
||||
assert_same('exact_hour', $settings->scheduleMode());
|
||||
});
|
||||
|
||||
test('directadmin user access follows DEFAULT_ENABLE and per-user overrides', function (): void {
|
||||
$settingsPath = TEST_TMP . '/access.conf';
|
||||
test_write($settingsPath, "DEFAULT_ENABLE=false\n");
|
||||
|
||||
@@ -28,3 +28,51 @@ test('directadmin user hooks are clickable and point to reserved icon path', fun
|
||||
assert_contains('<a href="/CMD_PLUGINS/global-autoresponder/index.html"', $txt);
|
||||
assert_contains('Globalne autorespondery', $txt);
|
||||
});
|
||||
|
||||
test('rule form uses minute time input and no summary box in exim mode', function (): void {
|
||||
require_once PLUGIN_ROOT . '/exec/lib/Settings.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/Lang.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/DirectAdminUser.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/CsrfGuard.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/RuleRepository.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/AuditLog.php';
|
||||
require_once PLUGIN_ROOT . '/exec/lib/AppContext.php';
|
||||
require_once PLUGIN_ROOT . '/exec/handlers/_form_helpers.php';
|
||||
|
||||
$settingsPath = TEST_TMP . '/form.conf';
|
||||
test_write($settingsPath, "DEFAULT_PLUGIN_LANGUAGE=pl\nGLOBAL_AUTORESPONDER_BACKEND=exim\n");
|
||||
$settings = Settings::load($settingsPath);
|
||||
$ctx = new AppContext(
|
||||
new DirectAdminUser('alice', 'enhanced', 'pl', TEST_TMP . '/config'),
|
||||
$settings,
|
||||
new RuleRepository(TEST_TMP . '/data'),
|
||||
new CsrfGuard('secret', 'alice', 'sid'),
|
||||
Lang::load('pl', $settings),
|
||||
new AuditLog(TEST_TMP . '/audit.log')
|
||||
);
|
||||
|
||||
$html = render_rule_form($ctx, 'create', null);
|
||||
assert_contains('type="time"', $html);
|
||||
assert_contains('step="60"', $html);
|
||||
assert_false(strpos($html, 'summary-card') !== false, 'Summary box should not be rendered in create/edit form');
|
||||
assert_contains('Temat', $html);
|
||||
assert_contains('Treść wiadomości', $html);
|
||||
});
|
||||
|
||||
test('rule form uses native period selector in da mode', function (): void {
|
||||
$settingsPath = TEST_TMP . '/form-da.conf';
|
||||
test_write($settingsPath, "DEFAULT_PLUGIN_LANGUAGE=pl\nGLOBAL_AUTORESPONDER_BACKEND=da\n");
|
||||
$settings = Settings::load($settingsPath);
|
||||
$ctx = new AppContext(
|
||||
new DirectAdminUser('alice', 'enhanced', 'pl', TEST_TMP . '/config'),
|
||||
$settings,
|
||||
new RuleRepository(TEST_TMP . '/data'),
|
||||
new CsrfGuard('secret', 'alice', 'sid'),
|
||||
Lang::load('pl', $settings),
|
||||
new AuditLog(TEST_TMP . '/audit.log')
|
||||
);
|
||||
$html = render_rule_form($ctx, 'create', null);
|
||||
assert_contains('name="start_value_period"', $html);
|
||||
assert_contains('Rano', $html);
|
||||
assert_false(strpos($html, 'type="time"') !== false);
|
||||
});
|
||||
|
||||
@@ -6,22 +6,37 @@ require_once PLUGIN_ROOT . '/exec/lib/RuleValidator.php';
|
||||
|
||||
test('rule validator normalizes exact hour schedule', function (): void {
|
||||
$settingsPath = TEST_TMP . '/validator.conf';
|
||||
test_write($settingsPath, "GLOBAL_AUTORESPONDER_TIMEZONE=Europe/Warsaw\nGLOBAL_AUTORESPONDER_SCHEDULE_MODE=exact_hour\n");
|
||||
test_write($settingsPath, "GLOBAL_AUTORESPONDER_TIMEZONE=Europe/Warsaw\nGLOBAL_AUTORESPONDER_BACKEND=exim\n");
|
||||
$settings = Settings::load($settingsPath);
|
||||
$rule = RuleValidator::validate([
|
||||
'subject' => 'Urlop',
|
||||
'body' => "Dzień dobry\r\nWracam jutro",
|
||||
'start_value' => '2026-06-10T09:00',
|
||||
'end_value' => '2026-06-24T17:00',
|
||||
'start_value' => '2026-06-10T09:37',
|
||||
'end_value' => '2026-06-24T17:12',
|
||||
'enabled' => '1',
|
||||
], $settings);
|
||||
|
||||
assert_same('Urlop', $rule['subject']);
|
||||
assert_same("Dzień dobry\nWracam jutro", $rule['body']);
|
||||
assert_same('exact_hour', $rule['schedule_mode']);
|
||||
assert_same('2026-06-10T09:37', $rule['start_value']);
|
||||
assert_true($rule['start_ts'] < $rule['end_ts']);
|
||||
});
|
||||
|
||||
test('rule validator accepts da period schedule when backend is da', function (): void {
|
||||
$settingsPath = TEST_TMP . '/validator-da.conf';
|
||||
test_write($settingsPath, "GLOBAL_AUTORESPONDER_BACKEND=da\n");
|
||||
$settings = Settings::load($settingsPath);
|
||||
$rule = RuleValidator::validate([
|
||||
'subject' => 'Urlop',
|
||||
'body' => 'Body',
|
||||
'start_value' => '2026-06-10|morning',
|
||||
'end_value' => '2026-06-24|evening',
|
||||
'enabled' => '1',
|
||||
], $settings);
|
||||
assert_same('directadmin_period', $rule['schedule_mode']);
|
||||
});
|
||||
|
||||
test('rule validator rejects header injection and reversed dates', function (): void {
|
||||
$settings = Settings::load(TEST_TMP . '/missing.conf');
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user