CsaGuzzleBundle icon indicating copy to clipboard operation
CsaGuzzleBundle copied to clipboard

Mocking JWT/JKU service in tests is tedious

Open marijnhurkens opened this issue 4 years ago • 2 comments

Withing my Symfony project I use an external authentication service which uses the OpenId connect standard. This involves decoding and verifying JWT tokens which a user sends with a request and using external public keys (JKU) to verify the signature.

I am using PHPunit for tests and I want to test the decoding and verification code I wrote for the tokens. The class which does the decoding and verifying uses a Guzzle client which I have setup using this bundle. I have looked at the options for mocking responses, and as far as I can see the only option is to use the Mock middleware and record / replay the responses.

The problem is that I don't have access to the private key of the service I use, so I can't generate a test JWT with test claims myself which would match the response from the JKU public key. So now I have to record the JKU response, go in the recorded file and change the response to match my own generated public JKU. Then I have to be careful to not change back the mock middleware back to record which would overwrite the JKU response.

My ideal solution would be to override the handler settings of the Guzzle client in the test configuration of the CsaGuzzleBundle, but I have no idea if this is possible? This way I could use the MockHandler to have full control over the responses. Is that possible?

marijnhurkens avatar Jun 27 '19 07:06 marijnhurkens

Perhaps you could override the service that does the JWT signature and use that in your test environment. Failing that, than yes, you need to generate mock responses then manually edit them. It's not pretty, but it works.

andreicio avatar Jan 28 '20 12:01 andreicio

Hi, @marijnhurkens. Could you explain a bit more about the way you use Guzzle for that?

I don't think it should be the clients' responsibility to encode/decode the payload. This should be the responsibility of a decorating class, which would get the raw data from the Guzzle client.

I think that approach would be much more flexible, as you could directly mock the guzzle client and check what is passed to the client (encoding). You would also be able to configure the Mock middleware to mock responses, or actually directly mock the client in that case, as it would be a dependency of your decoding service.

Note that this is the approach that was initially taken by guzzle-services, as well as the initial PR which was made to support the Symfony or JMS serializers.

csarrazi avatar Feb 21 '20 10:02 csarrazi