From 67d62eff70728aec5e8aa88a1611a0d9aba41499 Mon Sep 17 00:00:00 2001 From: Jeppe B <2jepp9350@gmail.com> Date: Wed, 10 Jun 2026 18:53:13 +0200 Subject: [PATCH] Sync fake email deliveries across API tests --- services/nginx/app/classes/email.php | 70 ++++++++++++++++++- .../nginx/app/tests/Support/Api/ApiClient.php | 4 ++ .../Unit/Email/FakeEmailDeliveriesTest.php | 49 +++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 services/nginx/app/tests/Unit/Email/FakeEmailDeliveriesTest.php diff --git a/services/nginx/app/classes/email.php b/services/nginx/app/classes/email.php index e85d938f..1f0b1186 100644 --- a/services/nginx/app/classes/email.php +++ b/services/nginx/app/classes/email.php @@ -128,13 +128,13 @@ use Psr\Http\Client\ClientExceptionInterface; private function sendEmailMailerSend(string $to, string $recipient_name, string $subject, string $message, string $html = null, string $references = null, array $attachments = []): void { if (self::isFakeDeliveryEnabled()) { - self::$fake_deliveries[] = [ + self::recordFakeDelivery([ 'to' => $to, 'recipient_name' => $recipient_name, 'subject' => $subject, 'message' => $message, 'html' => $html, - ]; + ]); return; } @@ -225,6 +225,72 @@ use Psr\Http\Client\ClientExceptionInterface; public static function resetFakeDeliveries(): void { self::$fake_deliveries = []; + $path = self::getFakeDeliveriesPath(); + if ($path !== null && is_file($path)) { + unlink($path); + } + } + + public static function syncFakeDeliveries(): void + { + $path = self::getFakeDeliveriesPath(); + if ($path === null || !is_file($path)) { + self::$fake_deliveries = []; + return; + } + + $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if ($lines === false) { + self::$fake_deliveries = []; + return; + } + + $deliveries = []; + foreach ($lines as $line) { + $delivery = json_decode($line, true); + if (is_array($delivery)) { + $deliveries[] = $delivery; + } + } + + self::$fake_deliveries = $deliveries; + } + + private static function recordFakeDelivery(array $delivery): void + { + self::$fake_deliveries[] = $delivery; + + $path = self::getFakeDeliveriesPath(); + if ($path === null) { + return; + } + + $directory = dirname($path); + if (!is_dir($directory)) { + mkdir($directory, 0777, true); + } + + file_put_contents($path, json_encode($delivery, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL, FILE_APPEND | LOCK_EX); + } + + private static function getFakeDeliveriesPath(): ?string + { + if (!self::isFakeDeliveryEnabled()) { + return null; + } + + $configuredPath = trim((string)(getenv('EMAIL_FAKE_DELIVERIES_PATH') ?: '')); + if ($configuredPath !== '') { + return $configuredPath; + } + + if (getenv('RUN_API_TESTS') !== '1') { + return null; + } + + return rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) + . DIRECTORY_SEPARATOR + . 'truckwash-email-fake-deliveries-' . md5((string)getcwd()) . '.jsonl'; } private static function isFakeDeliveryEnabled(): bool diff --git a/services/nginx/app/tests/Support/Api/ApiClient.php b/services/nginx/app/tests/Support/Api/ApiClient.php index b2869985..b9d79974 100644 --- a/services/nginx/app/tests/Support/Api/ApiClient.php +++ b/services/nginx/app/tests/Support/Api/ApiClient.php @@ -96,6 +96,10 @@ final class ApiClient $decoded = json_decode($body, true); + if (getenv('EMAIL_FAKE_MODE') === '1' && class_exists(\classes\email::class)) { + \classes\email::syncFakeDeliveries(); + } + return new ApiResponse($status, $responseHeaders, $decoded, (string)$body); } } diff --git a/services/nginx/app/tests/Unit/Email/FakeEmailDeliveriesTest.php b/services/nginx/app/tests/Unit/Email/FakeEmailDeliveriesTest.php new file mode 100644 index 00000000..088b4be3 --- /dev/null +++ b/services/nginx/app/tests/Unit/Email/FakeEmailDeliveriesTest.php @@ -0,0 +1,49 @@ + 'customer@example.test', + 'recipient_name' => 'Customer', + 'subject' => 'Subject', + 'message' => '', + 'html' => '
Body
', + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL); + + email::syncFakeDeliveries(); + + expect(email::$fake_deliveries) + ->toHaveCount(1) + ->and(email::$fake_deliveries[0]['to'] ?? null) + ->toBe('customer@example.test') + ->and(email::$fake_deliveries[0]['subject'] ?? null) + ->toBe('Subject'); + } finally { + email::resetFakeDeliveries(); + if (is_file($path)) { + unlink($path); + } + if ($previousFakeMode === false) { + putenv('EMAIL_FAKE_MODE'); + } else { + putenv('EMAIL_FAKE_MODE=' . $previousFakeMode); + } + if ($previousFakePath === false) { + putenv('EMAIL_FAKE_DELIVERIES_PATH'); + } else { + putenv('EMAIL_FAKE_DELIVERIES_PATH=' . $previousFakePath); + } + } +});