diff --git a/routes/web.php b/routes/web.php index 1d6e0475..40a6db70 100644 --- a/routes/web.php +++ b/routes/web.php @@ -5,3 +5,68 @@ use Illuminate\Support\Facades\Route; Route::view('/', 'welcome')->name('home'); require __DIR__.'/settings.php'; + +// WMS Countries API compatibility routes - start +// These legacy-compatible API aliases are intentionally registered in web.php +// because this project/module stack does not always load module API routes +// during PHPUnit bootstrap. They are GET-only JSON endpoints and therefore +// do not require CSRF exemptions. +Route::get('/api/countries/resolve/{code}', function (string $code) { + $normalised = strtoupper(trim($code)); + + $country = \Illuminate\Support\Facades\DB::table('countries') + ->whereRaw('UPPER(alpha2) = ?', [$normalised]) + ->orWhereRaw('UPPER(alpha3) = ?', [$normalised]) + ->orWhere('numeric', $normalised) + ->first(); + + abort_if($country === null, 404); + + return response()->json([ + 'data' => [ + 'id' => $country->id ?? null, + 'name' => $country->name ?? null, + 'official_name' => $country->official_name ?? null, + 'common_name' => $country->common_name ?? null, + 'display_name' => $country->display_name ?? null, + 'alpha2' => $country->alpha2 ?? null, + 'alpha3' => $country->alpha3 ?? null, + 'numeric' => $country->numeric ?? null, + 'region' => $country->region ?? null, + 'subregion' => $country->subregion ?? null, + 'flag_emoji' => $country->flag_emoji ?? null, + 'is_active' => (bool) ($country->is_active ?? true), + ], + ]); +})->name('countries.api.resolve.compat'); + +Route::get('/api/countries/{code}/subdivisions', function (string $code) { + $normalised = strtoupper(trim($code)); + + $country = \Illuminate\Support\Facades\DB::table('countries') + ->whereRaw('UPPER(alpha2) = ?', [$normalised]) + ->orWhereRaw('UPPER(alpha3) = ?', [$normalised]) + ->orWhere('numeric', $normalised) + ->first(); + + abort_if($country === null, 404); + + $subdivisions = \Illuminate\Support\Facades\DB::table('country_subdivisions') + ->where('country_id', $country->id) + ->orderBy('sort_order') + ->orderBy('name') + ->get() + ->map(fn ($subdivision) => [ + 'id' => $subdivision->id ?? null, + 'country_id' => $subdivision->country_id ?? null, + 'code' => $subdivision->code ?? null, + 'name' => $subdivision->name ?? null, + 'type' => $subdivision->type ?? null, + 'parent_code' => $subdivision->parent_code ?? null, + 'is_active' => (bool) ($subdivision->is_active ?? true), + ]) + ->values(); + + return response()->json(['data' => $subdivisions]); +})->name('countries.api.subdivisions.compat'); +// WMS Countries API compatibility routes - end diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php index a27a4a66..c9b44caf 100644 --- a/tests/DuskTestCase.php +++ b/tests/DuskTestCase.php @@ -5,29 +5,19 @@ namespace Tests; use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; -use Illuminate\Support\Facades\Artisan; use Laravel\Dusk\TestCase as BaseTestCase; use PHPUnit\Framework\Attributes\BeforeClass; abstract class DuskTestCase extends BaseTestCase { - use CreatesApplication; - - /** - * Prepare for Dusk test execution. - */ #[BeforeClass] public static function prepare(): void { if (! static::runningInSail()) { - static::ensureChromeDriverBinaryAlias(); static::startChromeDriver(['--port=9515']); } } - /** - * Create the RemoteWebDriver instance. - */ protected function driver(): RemoteWebDriver { $options = (new ChromeOptions())->addArguments([ @@ -36,57 +26,14 @@ abstract class DuskTestCase extends BaseTestCase '--window-size=1920,1080', '--no-sandbox', '--disable-dev-shm-usage', - '--disable-search-engine-choice-screen', ]); return RemoteWebDriver::create( - $_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515', - DesiredCapabilities::chrome()->setCapability(ChromeOptions::CAPABILITY, $options) + env('DUSK_DRIVER_URL', 'http://localhost:9515'), + DesiredCapabilities::chrome()->setCapability( + ChromeOptions::CAPABILITY, + $options + ) ); } - - /** - * Dusk may install a differently named macOS Apple Silicon binary. - * Laravel Dusk still asks for chromedriver-mac-arm, so create that alias safely. - */ - private static function ensureChromeDriverBinaryAlias(): void - { - $binDirectory = base_path('vendor/laravel/dusk/bin'); - $expected = $binDirectory.'/chromedriver-mac-arm'; - - if (is_file($expected)) { - @chmod($expected, 0755); - return; - } - - if (! is_dir($binDirectory)) { - @mkdir($binDirectory, 0755, true); - } - - try { - Artisan::call('dusk:chrome-driver'); - } catch (\Throwable) { - // Continue and inspect whatever files are available locally. - } - - $candidates = array_values(array_filter(glob($binDirectory.'/chromedriver*') ?: [], static function (string $path) use ($expected): bool { - return is_file($path) - && $path !== $expected - && ! str_ends_with($path, '.zip') - && ! str_ends_with($path, '.txt'); - })); - - usort($candidates, static function (string $left, string $right): int { - $score = static fn (string $path): int => str_contains($path, 'mac-arm64') ? 0 - : (str_contains($path, 'mac-arm') ? 1 - : (str_contains($path, 'mac') ? 2 : 3)); - - return $score($left) <=> $score($right); - }); - - if ($candidates !== []) { - @copy($candidates[0], $expected); - @chmod($expected, 0755); - } - } }