directAdminBinary()); }); test('directadmin vacation api builds scoped payload for one mailbox', function (): void { $api = new DirectAdminVacationApi('/usr/local/directadmin/directadmin'); $payload = $api->buildSavePayload('info@example.com', [ 'subject_prefix' => 'Urlop', 'reply_every_message' => false, 'repeat_minutes' => 1440, 'body' => 'Body', 'start_value' => '2026-06-10|morning', 'end_value' => '2026-06-24|evening', ]); assert_same('info', $payload['user']); assert_same('example.com', $payload['domain']); assert_same('Body', $payload['text']); assert_same('Urlop', $payload['subject']); assert_same('1d', $payload['reply_once_time']); assert_false(isset($payload['email'])); assert_false(isset($payload['subject_prefix'])); assert_false(isset($payload['reply_frequency'])); assert_same('morning', $payload['starttime']); assert_same('evening', $payload['endtime']); }); test('directadmin vacation api reports http error response bodies', function (): void { $runner = static function (array $args, string $stdin): string { if ($args[0] === '/bin/echo') { return 'https://directadmin.invalid/CMD_LOGIN_KEY'; } assert_same('curl', $args[0]); return "error=1&text=Unable to set vacation&details=Invalid repeat value\n500"; }; $api = new DirectAdminVacationApi('/bin/echo', null, $runner); try { $api->saveVacation('alice', 'info@example.com', [ 'subject_prefix' => 'Urlop', 'reply_every_message' => false, 'repeat_minutes' => 1440, 'body' => 'Body', 'start_value' => '2026-06-10|morning', 'end_value' => '2026-06-24|evening', ], false); } catch (RuntimeException $e) { assert_contains('DirectAdmin API HTTP 500', $e->getMessage()); assert_contains('Invalid repeat value', $e->getMessage()); return; } throw new RuntimeException('Expected HTTP error to fail'); }); test('directadmin vacation api reports legacy api error payloads', function (): void { $runner = static function (array $args, string $stdin): string { if ($args[0] === '/bin/echo') { return 'https://directadmin.invalid/CMD_LOGIN_KEY'; } return "error=1&text=Unable%20to%20set%20vacation&details=Bad%20mailbox\n200"; }; $api = new DirectAdminVacationApi('/bin/echo', null, $runner); try { $api->saveVacation('alice', 'info@example.com', [ 'subject_prefix' => 'Urlop', 'reply_every_message' => false, 'repeat_minutes' => 1440, 'body' => 'Body', 'start_value' => '2026-06-10|morning', 'end_value' => '2026-06-24|evening', ], false); } catch (RuntimeException $e) { assert_contains('DirectAdmin API error', $e->getMessage()); assert_contains('Bad mailbox', $e->getMessage()); return; } throw new RuntimeException('Expected legacy API error to fail'); }); test('directadmin vacation api detects existing native vacation by mailbox', function (): void { $api = new DirectAdminVacationApi('/usr/local/directadmin/directadmin', static function (string $owner, string $endpoint, array $payload): string { assert_same('alice', $owner); assert_same('CMD_API_EMAIL_VACATION', $endpoint); assert_same(['domain' => 'example.com'], $payload); return 'info=starttime%3Dmorning%26text%3DBody&sales=starttime%3Devening'; }); assert_true($api->vacationExists('alice', 'info@example.com')); assert_false($api->vacationExists('alice', 'new@example.com')); });