api-platform / docs

API Platform documentation
https://api-platform.com/docs/
164 stars 1.06k forks source link

ServiceNotFoundException when testing JWT authentication (security.user_password_hasher) #1827

Open bikusta opened 10 months ago

bikusta commented 10 months ago

Hi everyone,

I followed the API Platform documentation to test JWT authentication: https://api-platform.com/docs/core/jwt/#testing

When running the test a ServiceNotFoundException is thrown:

1) App\Tests\Api\AuthenticationTest::testLogin Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: The "security.user_password_hasher" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.

I am new to API Platform and Symfony, so I don't understand the magic of the frameworks, yet. What do I have to do to resolve that exception?

Versions:

API Platform: 3.1.14 Symfony: 6.3

My full test case in AuthenticationTest.php:

<?php

namespace App\Tests\Api;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use App\Entity\User;
use Zenstruck\Foundry\Test\ResetDatabase;

class AuthenticationTest extends ApiTestCase
{
    use ResetDatabase;

    public function testLogin(): void
    {
        $client = self::createClient();
        $container = self::getContainer();
        $hasher = $container->get('security.user_password_hasher');

        $user = new User();
        $user->setMobile('+4907044753847');
        $user->setPassword($hasher->hashPassword($user, 'm|Na0wMU|'));

        $manager = $container->get('doctrine')->getManager();
        $manager->persist($user);
        $manager->flush();

        // Token anfordern
        $response = $client->request('POST', '/auth', [
            'headers' => ['Content-Type' => 'application/json'],
            'json' => [
                'mobile' => '+4907044753847',
                'password' => 'm|Na0wMU|'
            ]
        ]);

        $json = $response->toArray();
        $this->assertResponseIsSuccessful();
        $this->assertArrayHasKey('token', $json);

        // Zugriff ohne Authorisierung testen
        $client->request('GET', '/greetings');
        $this->assertResponseStatusCodeSame(401);

        // Zugriff mit Authorisierung testen
        $client->request('GET', '/greetings', ['auth_bearer' => $json['token']]);
        $this->assertResponseIsSuccessful();
    }
}

Remark: I managed to replace "Hautelook\AliceBundle\PhpUnit\ReloadDatabaseTrait" by "Zenstruck\Foundry\Test\ResetDatabase", which was my first problem. But I am struggling with the "ServiceNotFoundException" for several hours now.