Triggering Absinthe subscriptions through schema configuration does not seem to work in tests. Why?

Hello,

While following along the Craft GraphQL APIs in Elixir with Absinthe book and taking a stab at the exercises for chapter 8 (locking down the api) I came across a (for me being totally new to subscriptions in absinthe right now) strange problem that I don’t seem to find a solution for (or maybe I am struck with temporal blindness).

For reference, I created an example repository with the code that does implement the PlateSlate phoenix project as described in the book (only diverging a bit with regards to file placement and module naming).

To summarize the workings of the project: In the system there are customers and employees. Customers can place an order on some menu items. Employees can update the order and both can subscribe to updates on the orders (but customers may only receive updates for their own orders).

Within the graphiql interface this all seems to work well, but when it comes to the test cases for updating the order (update to ready and complete) it seems that the trigger configured within the updateOrder subscription is not executed and therefore no subscriptions data is being pushed.

What does not seem to work

There are two test cases for subscriptions on order updates, one for marking the
order as ready and one for marking it as complete.

The relevant source for the ready update test lives here
plate_slate/test/plate_slate_web/graphql/subscription_update_order_test.exs:85

The source for the complete update test lives in the same file
plate_slate/test/plate_slate_web/graphql/subscription_update_order_test.exs:128

In both cases, a customer and employee is created. Then two orders are created
and the customer is subscribed to the updateOrder field for both of them.
(The way it is set up here, the subscription should succeed but delivery should
be restricted)

After that, for the ready order test, Absinthe.run is used to call the
readyOrder mutation with the employee as current user. This succeeds. As can
be seen at plate_slate/lib/plate_slate_web/graphql/resolvers/ordering.ex:22,
we publish the subscription manually using Absinthe.Subscription.publish.

For the complete order test, Absinthe.run is also being used (this time to
call the completeOrder mutation). The main difference is here that instead
of manually publishing within the resolver, the updateOrder field is
configured to trigger upon :complete_order within the schema
(lib/plate_slate_web/graphql/schema/ordering_types.ex:93).
This time it doesn’t seem to work though, the mailbox stays empty.

The project can be cloned and should be pretty ready to go I think… In order to see the failing test.

cd plate_slate
mix deps.get
mix test

And the tests work again when I manually trigger the subscription using Absinthe.Subscription.publish … (uncomment the lines over here)

What would be expected

That running the mutation through absinthe run within the tests would
also cause the trigger configuration within the schema to be cause
subscription data to be delivered.

Any Ideas what the issue could be?

@benwilson512 suggested a fix for the problem. It boils down to the fact, that when the Absinthe.run function is called within the test like this:

    Absinthe.run(
      @complete_order_mutation,
      PlateSlateWeb.GraphQL.Schema,
      [
        context: %{current_user: employee},
        variables: %{"id" => order.id}
      ]
    )

Absinthe cannot figure out which pubsub to use for the subscriptions (which for example the Absinthe plug is taking care of for you). So extending the context like this context: %{current_user: employee, pubsub: PlateSlateWeb.Endpoint}, lets Absinthe know which pubsub it should use to publish the subscription data.

Thank you @benwilson512 :+1:

3 Likes