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

FEATURE REQUEST: header parameter in query/mutate (apollo-server-testing) #4337

Closed
devdudeio opened this issue Jul 1, 2020 · 7 comments
Closed

Comments

@devdudeio
Copy link

devdudeio commented Jul 1, 2020

To test the complete stack in my integrationtests it would be cool if I could also set a header for a query or mutation. (e.g. authorization header to test scopes)

...
const headers = { authorization: "jwt...", otherFancyHeader: "jo" }
const { query } = createTestClient(server);
const res = await query({ query, variables, headers });
...
@devdudeio devdudeio changed the title header parameter in query/mutate (apollo-server-testing) FEATURE REQUEST: header parameter in query/mutate (apollo-server-testing) Jul 1, 2020
@JoA-MoS
Copy link

JoA-MoS commented Mar 26, 2021

@dude-awesome - any workaround for this that you have discovered?

@glasser
Copy link
Member

glasser commented Mar 29, 2021

apollo-server-testing is just a very thin wrapper around server.executeOperation and I'm considering removing the wrapper in AS3 (#4952).

I recently merged an improvement to executeOperation (#4166) which allows you to specify the same integration-specific argument to executeOperation that the normal HTTP path provides to your context function. Is this what you're looking for — the ability to read request information in your context function? Or something else? (This hasn't been released yet but it'll go out in the next minor release, probably v2.23.0.)

@devdudeio
Copy link
Author

devdudeio commented Mar 31, 2021

@JoA-MoS the only workaround I have is to pass a static context into my test-server to set my authorization header, so I can see what my resolvers are returning when the user does´nt have the required scopes for a specific graphql operation.

like

...
    context: () => ({
        headers: {
            'authorization': 'foo',
            'otherHeader': 'bar'
        }
    })
...

@glasser
Copy link
Member

glasser commented May 25, 2021

apollo-server-testing is now deprecated (#5238) and will be removed in v3. As mentioned above, since v2.23 you have been able to pass a second argument to executeOperation which is passed to your context argument. You can also pass headers like server.executeOperation({ query: QUERY, http: {headers} }).

@glasser glasser closed this as completed May 25, 2021
@maplesteve
Copy link

@glasser

You can also pass headers like server.executeOperation({ query: QUERY, http: {headers} }).

How is headers supposed to look like exactly?
This does not work (apollo-server-lambda v3.3.0)

const result = await server.executeOperation({
  http: {
    headers: {
      // error: ...is not assignable to type 'Headers'
      authorization: 'foo',
      otherHeader: 'bar'
    }
  },
  query: gqlQuery
})

Would be great if you could provide an example on how to use executeOperation with headers.

@glasser
Copy link
Member

glasser commented Sep 21, 2021

I guess this is a bit more subtle in practice.

The headers you pass in http.headers inside the first argument needs to be a Headers object (ie from the browser-style fetch API), so you'd need something like {query, http: {headers: new Headers({authorization: 'foo'})}. This might run into typescript issues where it expects you to provide url and method on the http object as well. This affects the request as stored on the requestContext and visible to plugins, etc. This data structure is the same no matter which web framework integration you use.

However, this doesn't affect the "context argument" passed to your context function. As documented the second argument to executeOperation is the middleware-specific context field. For Lambda, you can access headers either in a Lambda-like way from the event option, or in an Express-like way from the express.req option. So you should format that argument in whatever way your context function expects to read it.

Honestly, I don't think executeOperation is a great way to test any logic that depends on the HTTP structure of your request. It's a nice simple way to test the underlying GraphQL execution directly, perhaps with a special version of your context function that just lets you pass the parsed context through executeOperation, but if you want to test your server in a way that depends on what the HTTP request looks like, I'd suggest just running your ApolloServer normally and running queries against it using @apollo/client/link/http or just your favorite HTTP testing library.

@maplesteve
Copy link

Thanks a lot for your very helpful answer. We'll lay out our testing strategy accordingly.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants