A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
Hello, I am new to building Shopify apps and I have started a project using a Rails 6 app with the shopify_app gem (v18.x) and a graphql controller.
I'm trying to write a request spec which uses the setup described in this issue to mock Oauth and provide the login helper to login the shop, in order to test my GraphQL mutations.
The problem I am facing as it stands is in my login method I set the shopify_domain on the session object and expect to have it available as part of the session object in my graphql controller, so I can pass it to the context param and make it available to any Query or Mutation.
This is the helper login method inspired by the github issue:
# spec/support/shopify_helpers.rb
module ShopifyHelpers
def shopify_login(shop)
# https://github.com/Shopify/shopify_app/issues/1266
# standard for Shopify tests, cookie or JWT
ShopifyApp.configuration.embedded_app = false
# standard for OmniAuth tests of all kinds
OmniAuth.config.test_mode = true
# recommended to enable /auth/shopify and bypass devise override
OmniAuth.config.allowed_request_methods = [:get]
# silences omniauth noise telling me that the above line opens us up to vulnerabilities
OmniAuth.config.silence_get_warning = true
# standard implementation for mocking out the shopify omniauth provider structure
OmniAuth.config.add_mock(
:shopify,
provider: 'shopify',
uid: shop.shopify_domain,
credentials: { token: shop.shopify_token }
)
# the next 4 lines are technically setting `request.env['key']` on a request that has not yet been made
Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[:shopify]
Rails.application.env_config['omniauth.params'] = { shop: shop.shopify_domain }
Rails.application.env_config['jwt.shopify_domain'] = shop.shopify_domain
Rails.application.env_config['jwt.shopify_user_id'] = 'test-shopify-user'
get '/auth/shopify'
follow_redirect!
@request.session[:shop_id] = shop.id
@request.session[:shopify_domain] = shop.shopify_domain
request.headers.merge!('Authorization': "Bearer "blah")
end
end
RSpec.configure do |config|
config.include ShopifyHelpers, type: :request
end
In the GraphQL controller, I set the shopify_domain from the session:
class GraphqlController < AuthenticatedController
def execute
...
# Session gets set HERE
context = {
current_shopify_domain: session[:shopify_domain],
}
result = Schema.execute(query, variables: variables, context: context, operation_name: operation_name)
...
end
Then I setup my RSpec suite as follows:
module Mutations
module Model
RSpec.describe CreateModel, type: :request do
let(:shop) { create(:shop) }
let(:model) { build(:model, shop: shop) }
before(:each) do
shopify_login(shop)
session[:shop_id] = shop.id
session[:shopify_domain] = shop.shopify_domain
end
describe '.resolve' do
it 'creates a model' do
expect do
# session[:shopify_domain] exists here
post '/graphql', params: {
query: query(...)
}
end.to change { Model.count }.by(1)
end
...
end
The problem I am seeing is session[:shopify_domain] is nil inside the GraphqlController#execute method, the key seems to get unset for some reason before the post /graphql request happens in the test suite.
Has anyone encountered this issue and would be able to help?
Thank you very much 🙂