diff --git a/Makefile b/Makefile index 66e7dc4..c9f1a99 100644 --- a/Makefile +++ b/Makefile @@ -96,7 +96,15 @@ demo-smoke: [ -z "$$PORT" ] && PORT=$$(grep "^PORT=" demo/symfony8/.env.example 2>/dev/null | cut -d= -f2 | tr -d '\r'); \ [ -z "$$PORT" ] && PORT=8010; \ echo "Smoke GET http://localhost:$$PORT/en/login"; \ - code=$$(curl -fsS -o /dev/null -w "%{http_code}" "http://localhost:$$PORT/en/login" || true); \ + code=000; \ + i=0; \ + while [ $$i -lt 30 ]; do \ + code=$$(curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:$$PORT/en/login" || true); \ + [ -z "$$code" ] && code=000; \ + if [ "$$code" = "200" ]; then break; fi; \ + i=$$((i+1)); \ + sleep 2; \ + done; \ if [ "$$code" != "200" ]; then echo "demo-smoke failed: HTTP $$code"; exit 1; fi; \ echo "demo-smoke OK (HTTP 200)" diff --git a/demo/symfony8/Dockerfile b/demo/symfony8/Dockerfile index 7cb1f30..493151a 100644 --- a/demo/symfony8/Dockerfile +++ b/demo/symfony8/Dockerfile @@ -7,7 +7,8 @@ RUN install-php-extensions intl pdo_mysql zip COPY --from=composer:2 /usr/bin/composer /usr/bin/composer -RUN git config --global --add safe.directory /app +RUN git config --global --add safe.directory /app && \ + git config --global --add safe.directory /var/auth-kit-bundle WORKDIR /app diff --git a/demo/symfony8/docker/entrypoint.sh b/demo/symfony8/docker/entrypoint.sh index e5c30df..22b0591 100644 --- a/demo/symfony8/docker/entrypoint.sh +++ b/demo/symfony8/docker/entrypoint.sh @@ -1,6 +1,9 @@ #!/bin/sh set -e +git config --global --add safe.directory /app 2>/dev/null || true +git config --global --add safe.directory /var/auth-kit-bundle 2>/dev/null || true + # Wait until Composer has installed the app (make up runs install after start). # Without this, FrankenPHP worker mode exits immediately on a clean checkout (CI). i=0 diff --git a/src/Twig/AuthKitUiExtension.php b/src/Twig/AuthKitUiExtension.php index 99e7efb..b85b804 100644 --- a/src/Twig/AuthKitUiExtension.php +++ b/src/Twig/AuthKitUiExtension.php @@ -55,12 +55,21 @@ public function getGlobals(): array public function getFunctions(): array { - return [ + $functions = [ new TwigFunction('nowo_auth_kit_outbound_mail_ready', $this->isOutboundMailReady(...)), new TwigFunction('nowo_auth_kit_slide_to_confirm_assets', $this->shouldLoadSlideToConfirmAssets(...)), new TwigFunction('nowo_auth_kit_device_intelligence_assets', $this->shouldLoadDeviceIntelligenceAssets(...)), new TwigFunction('nowo_auth_kit_otp_input_assets', $this->shouldLoadOtpInputAssets(...)), ]; + + // Optional bundle Twig functions are referenced in _slide_to_confirm_assets.html.twig; + // register no-op stubs so templates compile when the package is not installed. + if (!class_exists('Nowo\\SlideToConfirmBundle\\Twig\\NowoSlideToConfirmTwigExtension')) { + $functions[] = new TwigFunction('nowo_slide_to_confirm_asset_path', static fn (): string => ''); // @codeCoverageIgnore + $functions[] = new TwigFunction('nowo_slide_to_confirm_asset_package', static fn (): string => ''); // @codeCoverageIgnore + } + + return $functions; } public function isOutboundMailReady(): bool diff --git a/tests/Unit/Twig/AuthKitUiExtensionTest.php b/tests/Unit/Twig/AuthKitUiExtensionTest.php index 1b3c6e4..9cc9f5e 100644 --- a/tests/Unit/Twig/AuthKitUiExtensionTest.php +++ b/tests/Unit/Twig/AuthKitUiExtensionTest.php @@ -62,12 +62,35 @@ public function isReady(): bool self::assertFalse($extension->isOutboundMailReady()); } + public function testRegistersSlideToConfirmStubTwigFunctionsWhenBundleAbsent(): void + { + if (class_exists('Nowo\\SlideToConfirmBundle\\Twig\\NowoSlideToConfirmTwigExtension')) { + self::markTestSkipped('SlideToConfirm bundle is installed in this environment.'); + } + + $extension = new AuthKitUiExtension([], [], new AlwaysOutboundMailReadyChecker()); + $byName = []; + foreach ($extension->getFunctions() as $function) { + $byName[$function->getName()] = $function->getCallable(); + } + + self::assertArrayHasKey('nowo_slide_to_confirm_asset_path', $byName); + self::assertArrayHasKey('nowo_slide_to_confirm_asset_package', $byName); + + /** @var callable(): string $pathCallable */ + $pathCallable = $byName['nowo_slide_to_confirm_asset_path']; + /** @var callable(): string $packageCallable */ + $packageCallable = $byName['nowo_slide_to_confirm_asset_package']; + self::assertSame('', $pathCallable()); + self::assertSame('', $packageCallable()); + } + public function testRegistersOutboundMailReadyTwigFunction(): void { $extension = new AuthKitUiExtension([], [], new AlwaysOutboundMailReadyChecker()); $functions = $extension->getFunctions(); - self::assertCount(4, $functions); + self::assertCount(class_exists('Nowo\\SlideToConfirmBundle\\Twig\\NowoSlideToConfirmTwigExtension') ? 4 : 6, $functions); self::assertSame('nowo_auth_kit_outbound_mail_ready', $functions[0]->getName()); self::assertSame('nowo_auth_kit_slide_to_confirm_assets', $functions[1]->getName()); self::assertSame('nowo_auth_kit_device_intelligence_assets', $functions[2]->getName());