'Urlop', 'body' => "Dzień dobry\r\nWracam jutro", '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 { RuleValidator::validate([ 'subject' => "Bad\nSubject", 'body' => 'Body', 'start_value' => '2026-06-24T17:00', 'end_value' => '2026-06-10T09:00', ], $settings); } catch (InvalidArgumentException $e) { assert_contains('Temat', $e->getMessage()); return; } throw new RuntimeException('Expected validation failure'); });