Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remake auth testing #32

Open
butschster opened this issue Jan 17, 2023 · 2 comments
Open

Remake auth testing #32

butschster opened this issue Jan 17, 2023 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@butschster
Copy link
Member

No description provided.

@butschster butschster added the enhancement New feature or request label Jan 17, 2023
@butschster butschster self-assigned this Jan 17, 2023
@leon0399
Copy link

leon0399 commented Sep 6, 2024

Hi, @butschster! Am I right in assuming that https://spiral.dev/docs/testing-http/current/en#sessionauthentication is not really working? At least with AuthMiddleware:

// RoutesBootloader

protected function middlewareGroups(): array
{
    return [
        'api.jwt' => [
            AuthMiddleware::class,
            new ExceptionFirewall(new UnauthorizedException()),
        ],
    ];
}

protected function configureRouteGroups(GroupRegistry $groups): void
{
    $groups->getGroup('api.v1')
        ->addMiddleware('middleware:api.jwt')
        ->setNamePrefix('api.v1.')
        ->setPrefix('/api/v1');
}
// Test

 $response = $this->http()
    ->withActor($userActor)
    ->get('/api/v1/cards')
    ->assertOk();

With a call trace, I can see that AuthMiddleware is being resolved long before the scoped request from FakeHttp.

Even this, manually booting the app with a custom Container with pre-made bindings does not work since Bootloaders override bindings.

$container = new Container();

$container->removeBinding(ActorProviderInterface::class);
$container->removeBinding(TokenStorageInterface::class);
$container->removeBinding(TransportRegistry::class);

$container->bindSingleton(ActorProviderInterface::class, new FakeActorProvider($userActor));
$container->bindSingleton(TokenStorageInterface::class, new FakeTokenStorage());

$transport = new TransportRegistry();
$transport->setTransport('testing', new HeaderTransport('X-Test-Token'));
$container->bindSingleton(TransportRegistry::class, $transport);

$this->initApp([], $container);

...

$response = $this->http()
    ->withActor($userActor)
    ->get('/api/v1/cards')
    ->assertOk();

The only way I was able to make it work is the following:

$container = new Container();

$container->removeBinding(ActorProviderInterface::class);
$container->removeBinding(TokenStorageInterface::class);
$container->removeBinding(TransportRegistry::class);

$fakeActorProvider = new FakeActorProvider($userActor);
$container->bindSingleton(ActorProviderInterface::class, $fakeActorProvider);
$fakeTokenStorage = new FakeTokenStorage();
$container->bindSingleton(TokenStorageInterface::class, $fakeTokenStorage);

$transport = new TransportRegistry();
$transport->setTransport('testing', new HeaderTransport('X-Test-Token'));
$container->bindSingleton(TransportRegistry::class, $transport);

+ $container->bindSingleton(AuthMiddleware::class, new AuthMiddleware(
+     $container->get(ScopeInterface::class),
+     $fakeActorProvider,
+     $fakeTokenStorage,
+     $transport,
+ ));

$this->initApp([], $container);

$response = $this->http()
    ->withActor($userActor)
    ->get('/api/v1/cards')
    ->assertOk();

Which is not convenient at all

@leon0399
Copy link

leon0399 commented Sep 6, 2024

Ok, in the end, I remade it even better:

$response = $this->http()
    ->withAuthorizationToken($this->actorToken($userActor))
    ->getJson('/api/v1/cards')
    ->assertOk();

...
    
protected function actorToken(ActorInterface $actor): string
{
    /** @var JWTTokenStorage $storage */
    $storage = $this->getContainer()
        ->get(TokenStorageProviderInterface::class)
        ->getStorage('jwt');

    return $storage->create($actor)->getID();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants