Skip to content

Commit

Permalink
Always register webhooks with offline sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
paulomarg committed Feb 8, 2024
1 parent 8fc434a commit ce87d58
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 34 deletions.
8 changes: 6 additions & 2 deletions app/controllers/shopify_app/callback_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,12 @@ def user_access_scopes_strategy
end

def perform_post_authenticate_jobs(session)
install_webhooks(session)
install_scripttags(session)
# Ensure we use the offline session to install webhooks and scripttags
offline_session = session.online? ? shop_session : session

install_webhooks(offline_session)
install_scripttags(offline_session)

perform_after_authenticate_job(session)
end

Expand Down
90 changes: 58 additions & 32 deletions test/controllers/callback_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,21 @@ def perform; end
end

module ShopifyApp
SHOP_DOMAIN = "shop.myshopify.io"

class CallbackControllerTest < ActionController::TestCase
setup do
@routes = ShopifyApp::Engine.routes
ShopifyApp::SessionRepository.shop_storage = ShopifyApp::InMemoryShopSessionStore
ShopifyApp::SessionRepository.user_storage = nil
ShopifyAppConfigurer.setup_context
I18n.locale = :en
@stubbed_session = ShopifyAPI::Auth::Session.new(shop: "shop", access_token: "token")
@stubbed_session = ShopifyAPI::Auth::Session.new(shop: SHOP_DOMAIN, access_token: "token")
@stubbed_cookie = ShopifyAPI::Auth::Oauth::SessionCookie.new(value: "", expires: Time.now)
@host = "little-shoppe-of-horrors.#{ShopifyApp.configuration.myshopify_domain}"
host = Base64.strict_encode64(@host + "/admin")
@callback_params = {
shop: "shop",
shop: SHOP_DOMAIN,
code: "code",
state: "state",
timestamp: "timestamp",
Expand All @@ -50,14 +52,14 @@ class CallbackControllerTest < ActionController::TestCase
test "#callback flashes error in Spanish" do
I18n.expects(:t).with("could_not_log_in")
get :callback,
params: { shop: "shop", code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
params: { shop: SHOP_DOMAIN, code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
end

test "#callback rescued errors of ShopifyAPI::Error will not emit a deprecation notice" do
ShopifyAPI::Auth::Oauth.expects(:validate_auth_callback).raises(ShopifyAPI::Errors::MissingRequiredArgumentError)
assert_not_deprecated do
get :callback,
params: { shop: "shop", code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
params: { shop: SHOP_DOMAIN, code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
end
assert_equal flash[:error], "Could not log in to Shopify store"
end
Expand All @@ -69,7 +71,7 @@ class CallbackControllerTest < ActionController::TestCase

ShopifyApp::Logger.expects(:deprecated).never
get :callback,
params: { shop: "shop", code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
params: { shop: SHOP_DOMAIN, code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
end

test "#callback rescued non-shopify errors will be deprecated" do
Expand All @@ -86,7 +88,7 @@ class CallbackControllerTest < ActionController::TestCase
assert_within_deprecation_schedule(version)
ShopifyApp::Logger.expects(:deprecated).with(message, version)
get :callback,
params: { shop: "shop", code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
params: { shop: SHOP_DOMAIN, code: "code", state: "state", timestamp: "timestamp", host: "host", hmac: "hmac" }
end

test "#callback calls ShopifyAPI::Auth::Oauth.validate_auth_callback" do
Expand Down Expand Up @@ -118,29 +120,14 @@ class CallbackControllerTest < ActionController::TestCase
end

test "#callback sets the shopify_user_id in the Rails session when session is online" do
associated_user = ShopifyAPI::Auth::AssociatedUser.new(
id: 42,
first_name: "LeeeEEeeeeee3roy",
last_name: "Jenkins",
email: "dat_email@tho.com",
email_verified: true,
locale: "en",
collaborator: true,
account_owner: true,
)
mock_session = ShopifyAPI::Auth::Session.new(
shop: "shop",
access_token: "token",
is_online: true,
associated_user: associated_user,
)
mock_session = online_session
mock_oauth(session: mock_session)
get :callback, params: @callback_params
assert_equal session[:shopify_user_id], associated_user.id
assert_equal session[:shopify_user_id], mock_session.associated_user.id
end

test "#callback DOES NOT set the shopify_user_id in the Rails session when session is offline" do
mock_session = ShopifyAPI::Auth::Session.new(shop: "shop", access_token: "token", is_online: false)
mock_session = ShopifyAPI::Auth::Session.new(shop: SHOP_DOMAIN, access_token: "token", is_online: false)
mock_oauth(session: mock_session)
get :callback, params: @callback_params
assert_nil session[:shopify_user_id]
Expand All @@ -166,7 +153,7 @@ class CallbackControllerTest < ActionController::TestCase
config.webhooks = [{ topic: "carts/update", address: "example-app.com/webhooks" }]
end

ShopifyApp::WebhooksManager.expects(:queue).with("shop", "token")
ShopifyApp::WebhooksManager.expects(:queue).with(SHOP_DOMAIN, "token")

mock_oauth
get :callback, params: @callback_params
Expand All @@ -189,7 +176,7 @@ class CallbackControllerTest < ActionController::TestCase
config.after_authenticate_job = { job: Shopify::AfterAuthenticateJob, inline: true }
end

Shopify::AfterAuthenticateJob.expects(:perform_now).with(shop_domain: "shop")
Shopify::AfterAuthenticateJob.expects(:perform_now).with(shop_domain: SHOP_DOMAIN)

mock_oauth
get :callback, params: @callback_params
Expand All @@ -200,7 +187,7 @@ class CallbackControllerTest < ActionController::TestCase
config.after_authenticate_job = { job: Shopify::AfterAuthenticateJob, inline: false }
end

Shopify::AfterAuthenticateJob.expects(:perform_later).with(shop_domain: "shop")
Shopify::AfterAuthenticateJob.expects(:perform_later).with(shop_domain: SHOP_DOMAIN)

mock_oauth
get :callback, params: @callback_params
Expand All @@ -222,7 +209,7 @@ class CallbackControllerTest < ActionController::TestCase
config.after_authenticate_job = { job: Shopify::AfterAuthenticateJob }
end

Shopify::AfterAuthenticateJob.expects(:perform_later).with(shop_domain: "shop")
Shopify::AfterAuthenticateJob.expects(:perform_later).with(shop_domain: SHOP_DOMAIN)

mock_oauth
get :callback, params: @callback_params
Expand All @@ -233,7 +220,7 @@ class CallbackControllerTest < ActionController::TestCase
config.after_authenticate_job = { job: "Shopify::AfterAuthenticateJob", inline: false }
end

Shopify::AfterAuthenticateJob.expects(:perform_later).with(shop_domain: "shop")
Shopify::AfterAuthenticateJob.expects(:perform_later).with(shop_domain: SHOP_DOMAIN)

mock_oauth
get :callback, params: @callback_params
Expand Down Expand Up @@ -296,20 +283,40 @@ class CallbackControllerTest < ActionController::TestCase
config.webhooks = [{ topic: "carts/update", address: "example-app.com/webhooks" }]
end

ShopifyApp::WebhooksManager.expects(:queue).with("shop", "token")
ShopifyApp::WebhooksManager.expects(:queue).with(SHOP_DOMAIN, "token")

get :callback, params: @callback_params
assert_response 302
end

test "#callback performs install_webhook job with an offline session after an online session OAuth" do
shop_storage = ShopifyApp::InMemoryShopSessionStore

ShopifyApp.configure do |config|
config.webhooks = [{ topic: "carts/update", address: "example-app.com/webhooks" }]
config.shop_session_repository = shop_storage
config.user_session_repository = ShopifyApp::InMemoryUserSessionStore
end
mock_oauth(session: online_session)
shop_storage.store(@stubbed_session)

ShopifyApp::WebhooksManager.expects(:queue).with(SHOP_DOMAIN, "token")

get :callback, params: @callback_params
assert_response 302
rescue => e
shop_storage.clear
raise e
end

test "#callback performs install_scripttags job after authentication" do
mock_oauth

ShopifyApp.configure do |config|
config.scripttags = [{ event: "onload", src: "https://example.com/fancy.js" }]
end

ShopifyApp::ScripttagsManager.expects(:queue).with("shop", "token", ShopifyApp.configuration.scripttags)
ShopifyApp::ScripttagsManager.expects(:queue).with(SHOP_DOMAIN, "token", ShopifyApp.configuration.scripttags)

get :callback, params: @callback_params
assert_response 302
Expand All @@ -322,7 +329,7 @@ class CallbackControllerTest < ActionController::TestCase
config.after_authenticate_job = { job: Shopify::AfterAuthenticateJob, inline: true }
end

Shopify::AfterAuthenticateJob.expects(:perform_now).with(shop_domain: "shop")
Shopify::AfterAuthenticateJob.expects(:perform_now).with(shop_domain: SHOP_DOMAIN)

get :callback, params: @callback_params
assert_response 302
Expand All @@ -348,5 +355,24 @@ def mock_oauth(cookie: @stubbed_cookie, session: @stubbed_session)
session: session,
})
end

def online_session
associated_user = ShopifyAPI::Auth::AssociatedUser.new(
id: 42,
first_name: "LeeeEEeeeeee3roy",
last_name: "Jenkins",
email: "dat_email@tho.com",
email_verified: true,
locale: "en",
collaborator: true,
account_owner: true,
)
ShopifyAPI::Auth::Session.new(
shop: SHOP_DOMAIN,
access_token: "online-token",
is_online: true,
associated_user: associated_user,
)
end
end
end

0 comments on commit ce87d58

Please sign in to comment.