disco_app 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Rakefile +37 -0
- data/app/assets/images/disco_app/icon.svg +1 -0
- data/app/assets/javascripts/disco_app/components/filterable_shop_list.js.jsx +65 -0
- data/app/assets/javascripts/disco_app/components/shop_filter_tab.js.jsx +34 -0
- data/app/assets/javascripts/disco_app/components/shop_filter_tabs.js.jsx +21 -0
- data/app/assets/javascripts/disco_app/components/shop_list.js.jsx +140 -0
- data/app/assets/javascripts/disco_app/components/shop_row.js.jsx +27 -0
- data/app/assets/javascripts/disco_app/components/shopify_admin_link.js.jsx +29 -0
- data/app/assets/javascripts/disco_app/components.js +5 -0
- data/app/assets/javascripts/disco_app/disco_app.js +7 -0
- data/app/assets/javascripts/disco_app/frame.js +152 -0
- data/app/assets/javascripts/disco_app/shopify-turbolinks.js +7 -0
- data/app/assets/stylesheets/disco_app/bootstrap/_custom.scss +54 -0
- data/app/assets/stylesheets/disco_app/bootstrap/_variables.scss +872 -0
- data/app/assets/stylesheets/disco_app/disco/_buttons.scss +31 -0
- data/app/assets/stylesheets/disco_app/disco/_cards.scss +51 -0
- data/app/assets/stylesheets/disco_app/disco/_forms.scss +23 -0
- data/app/assets/stylesheets/disco_app/disco/_grid.scss +58 -0
- data/app/assets/stylesheets/disco_app/disco/_sections.scss +61 -0
- data/app/assets/stylesheets/disco_app/disco/_tables.scss +57 -0
- data/app/assets/stylesheets/disco_app/disco/_tabs.scss +61 -0
- data/app/assets/stylesheets/disco_app/disco/_type.scss +39 -0
- data/app/assets/stylesheets/disco_app/disco/mixins/_flexbox.scss +394 -0
- data/app/assets/stylesheets/disco_app/disco_app.scss +16 -0
- data/app/assets/stylesheets/disco_app/frame/_buttons.scss +54 -0
- data/app/assets/stylesheets/disco_app/frame/_forms.scss +26 -0
- data/app/assets/stylesheets/disco_app/frame/_layout.scss +77 -0
- data/app/assets/stylesheets/disco_app/frame/_type.scss +32 -0
- data/app/assets/stylesheets/disco_app/frame.scss +9 -0
- data/app/controllers/disco_app/admin/app_settings_controller.rb +3 -0
- data/app/controllers/disco_app/admin/application_controller.rb +3 -0
- data/app/controllers/disco_app/admin/concerns/app_settings_controller.rb +24 -0
- data/app/controllers/disco_app/admin/concerns/authenticated_controller.rb +20 -0
- data/app/controllers/disco_app/admin/concerns/plans_controller.rb +51 -0
- data/app/controllers/disco_app/admin/concerns/shops_controller.rb +7 -0
- data/app/controllers/disco_app/admin/plans_controller.rb +3 -0
- data/app/controllers/disco_app/admin/resources/shops_controller.rb +3 -0
- data/app/controllers/disco_app/admin/shops_controller.rb +3 -0
- data/app/controllers/disco_app/charges_controller.rb +47 -0
- data/app/controllers/disco_app/concerns/app_proxy_controller.rb +40 -0
- data/app/controllers/disco_app/concerns/authenticated_controller.rb +56 -0
- data/app/controllers/disco_app/concerns/carrier_request_controller.rb +21 -0
- data/app/controllers/disco_app/frame_controller.rb +9 -0
- data/app/controllers/disco_app/install_controller.rb +27 -0
- data/app/controllers/disco_app/subscriptions_controller.rb +40 -0
- data/app/controllers/disco_app/webhooks_controller.rb +46 -0
- data/app/controllers/sessions_controller.rb +22 -0
- data/app/helpers/disco_app/application_helper.rb +28 -0
- data/app/jobs/disco_app/app_installed_job.rb +3 -0
- data/app/jobs/disco_app/app_uninstalled_job.rb +3 -0
- data/app/jobs/disco_app/concerns/app_installed_job.rb +39 -0
- data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +20 -0
- data/app/jobs/disco_app/concerns/shop_update_job.rb +16 -0
- data/app/jobs/disco_app/concerns/subscription_changed_job.rb +7 -0
- data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +52 -0
- data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +61 -0
- data/app/jobs/disco_app/shop_job.rb +27 -0
- data/app/jobs/disco_app/shop_update_job.rb +3 -0
- data/app/jobs/disco_app/subscription_changed_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_carrier_service_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_webhooks_job.rb +3 -0
- data/app/models/disco_app/app_settings.rb +3 -0
- data/app/models/disco_app/application_charge.rb +18 -0
- data/app/models/disco_app/concerns/app_settings.rb +7 -0
- data/app/models/disco_app/concerns/plan.rb +26 -0
- data/app/models/disco_app/concerns/plan_code.rb +15 -0
- data/app/models/disco_app/concerns/shop.rb +76 -0
- data/app/models/disco_app/concerns/subscription.rb +48 -0
- data/app/models/disco_app/concerns/synchronises.rb +39 -0
- data/app/models/disco_app/plan.rb +3 -0
- data/app/models/disco_app/plan_code.rb +3 -0
- data/app/models/disco_app/recurring_application_charge.rb +18 -0
- data/app/models/disco_app/session_storage.rb +18 -0
- data/app/models/disco_app/shop.rb +3 -0
- data/app/models/disco_app/subscription.rb +3 -0
- data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +46 -0
- data/app/resources/disco_app/admin/resources/shop_resource.rb +4 -0
- data/app/services/disco_app/carrier_request_service.rb +15 -0
- data/app/services/disco_app/charges_service.rb +81 -0
- data/app/services/disco_app/proxy_service.rb +17 -0
- data/app/services/disco_app/subscription_service.rb +37 -0
- data/app/services/disco_app/webhook_service.rb +30 -0
- data/app/views/disco_app/admin/app_settings/edit.html.erb +5 -0
- data/app/views/disco_app/admin/plans/_form.html.erb +27 -0
- data/app/views/disco_app/admin/plans/edit.html.erb +7 -0
- data/app/views/disco_app/admin/plans/index.html.erb +32 -0
- data/app/views/disco_app/admin/plans/new.html.erb +7 -0
- data/app/views/disco_app/admin/shops/index.html.erb +12 -0
- data/app/views/disco_app/charges/activate.html.erb +1 -0
- data/app/views/disco_app/charges/create.html.erb +1 -0
- data/app/views/disco_app/charges/new.html.erb +12 -0
- data/app/views/disco_app/frame/frame.html.erb +36 -0
- data/app/views/disco_app/install/installing.html.erb +7 -0
- data/app/views/disco_app/install/uninstalling.html.erb +1 -0
- data/app/views/disco_app/proxy_errors/404.html.erb +1 -0
- data/app/views/disco_app/shared/_card.html.erb +14 -0
- data/app/views/disco_app/shared/_section.html.erb +17 -0
- data/app/views/disco_app/subscriptions/new.html.erb +25 -0
- data/app/views/layouts/admin/_navbar.html.erb +25 -0
- data/app/views/layouts/admin.html.erb +27 -0
- data/app/views/layouts/application.html.erb +18 -0
- data/app/views/layouts/embedded_app.html.erb +41 -0
- data/app/views/layouts/embedded_app_modal.html.erb +17 -0
- data/app/views/sessions/new.html.erb +26 -0
- data/config/routes.rb +44 -0
- data/db/migrate/20150525000000_create_shops_if_not_existent.rb +15 -0
- data/db/migrate/20150525162112_add_status_to_shops.rb +5 -0
- data/db/migrate/20150525171422_add_meta_to_shops.rb +11 -0
- data/db/migrate/20150629210346_add_charge_status_to_shop.rb +5 -0
- data/db/migrate/20150814214025_add_more_meta_to_shops.rb +15 -0
- data/db/migrate/20151017231302_create_disco_app_plans.rb +13 -0
- data/db/migrate/20151017232027_create_disco_app_subscriptions.rb +15 -0
- data/db/migrate/20151017234409_move_shop_to_disco_app_engine.rb +5 -0
- data/db/migrate/20160112233706_create_disco_app_sessions.rb +12 -0
- data/db/migrate/20160113194418_add_shop_id_to_disco_app_sessions.rb +6 -0
- data/db/migrate/20160223111044_create_disco_app_settings.rb +8 -0
- data/db/migrate/20160301223215_update_plans.rb +22 -0
- data/db/migrate/20160301224558_update_subscriptions.rb +13 -0
- data/db/migrate/20160302104816_create_disco_app_recurring_application_charges.rb +14 -0
- data/db/migrate/20160302105259_create_disco_app_application_charges.rb +14 -0
- data/db/migrate/20160302134728_drop_charge_status_from_shops.rb +5 -0
- data/db/migrate/20160302142941_add_shopify_attributes_to_charges.rb +8 -0
- data/db/migrate/20160331093148_create_disco_app_plan_codes.rb +14 -0
- data/db/migrate/20160401044420_add_status_to_plan_codes.rb +5 -0
- data/db/migrate/20160401045551_add_amount_and_plan_code_to_disco_app_subscriptions.rb +7 -0
- data/lib/disco_app/configuration.rb +39 -0
- data/lib/disco_app/engine.rb +26 -0
- data/lib/disco_app/session.rb +14 -0
- data/lib/disco_app/support/file_fixtures.rb +23 -0
- data/lib/disco_app/test_help.rb +11 -0
- data/lib/disco_app/version.rb +3 -0
- data/lib/disco_app.rb +6 -0
- data/lib/generators/disco_app/USAGE +5 -0
- data/lib/generators/disco_app/adminify/adminify_generator.rb +35 -0
- data/lib/generators/disco_app/disco_app_generator.rb +164 -0
- data/lib/generators/disco_app/mailify/mailify_generator.rb +54 -0
- data/lib/generators/disco_app/monitorify/monitorify_generator.rb +28 -0
- data/lib/generators/disco_app/monitorify/templates/config/newrelic.yml +26 -0
- data/lib/generators/disco_app/monitorify/templates/initializers/rollbar.rb +12 -0
- data/lib/generators/disco_app/reactify/reactify_generator.rb +45 -0
- data/lib/generators/disco_app/templates/assets/javascripts/application.js +17 -0
- data/lib/generators/disco_app/templates/assets/stylesheets/application.scss +5 -0
- data/lib/generators/disco_app/templates/config/puma.rb +15 -0
- data/lib/generators/disco_app/templates/controllers/home_controller.rb +7 -0
- data/lib/generators/disco_app/templates/initializers/disco_app.rb +19 -0
- data/lib/generators/disco_app/templates/initializers/session_store.rb +2 -0
- data/lib/generators/disco_app/templates/initializers/shopify_app.rb +7 -0
- data/lib/generators/disco_app/templates/initializers/shopify_session_repository.rb +7 -0
- data/lib/generators/disco_app/templates/root/Procfile +2 -0
- data/lib/generators/disco_app/templates/views/home/index.html.erb +2 -0
- data/lib/tasks/carrier_service.rake +10 -0
- data/lib/tasks/sessions.rake +9 -0
- data/lib/tasks/start.rake +3 -0
- data/lib/tasks/webhooks.rake +10 -0
- data/test/controllers/disco_app/admin/shops_controller_test.rb +54 -0
- data/test/controllers/disco_app/charges_controller_test.rb +91 -0
- data/test/controllers/disco_app/install_controller_test.rb +50 -0
- data/test/controllers/disco_app/subscriptions_controller_test.rb +73 -0
- data/test/controllers/disco_app/webhooks_controller_test.rb +58 -0
- data/test/controllers/home_controller_test.rb +92 -0
- data/test/controllers/proxy_controller_test.rb +42 -0
- data/test/disco_app_test.rb +7 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +17 -0
- data/test/dummy/app/assets/stylesheets/application.scss +5 -0
- data/test/dummy/app/controllers/application_controller.rb +6 -0
- data/test/dummy/app/controllers/disco_app/admin/shops_controller.rb +8 -0
- data/test/dummy/app/controllers/home_controller.rb +7 -0
- data/test/dummy/app/controllers/proxy_controller.rb +8 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/disco_app/app_installed_job.rb +16 -0
- data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +11 -0
- data/test/dummy/app/jobs/products_create_job.rb +7 -0
- data/test/dummy/app/jobs/products_delete_job.rb +7 -0
- data/test/dummy/app/jobs/products_update_job.rb +7 -0
- data/test/dummy/app/models/disco_app/shop.rb +15 -0
- data/test/dummy/app/models/product.rb +6 -0
- data/test/dummy/app/views/home/index.html.erb +2 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +38 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.codeship.yml +23 -0
- data/test/dummy/config/database.yml +20 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +85 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/disco_app.rb +19 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/omniauth.rb +9 -0
- data/test/dummy/config/initializers/session_store.rb +2 -0
- data/test/dummy/config/initializers/shopify_app.rb +7 -0
- data/test/dummy/config/initializers/shopify_session_repository.rb +7 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +10 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/migrate/20160307182229_create_products.rb +11 -0
- data/test/dummy/db/schema.rb +138 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fixtures/api/widget_store/charges/activate_application_charge_request.json +16 -0
- data/test/fixtures/api/widget_store/charges/activate_application_charge_response.json +1 -0
- data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_request.json +20 -0
- data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_response.json +1 -0
- data/test/fixtures/api/widget_store/charges/create_application_charge_request.json +9 -0
- data/test/fixtures/api/widget_store/charges/create_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_request.json +9 -0
- data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_request.json +9 -0
- data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/get_accepted_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/get_accepted_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/get_declined_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/get_declined_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/get_pending_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/get_pending_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/shop.json +46 -0
- data/test/fixtures/api/widget_store/webhooks.json +1 -0
- data/test/fixtures/disco_app/application_charges.yml +11 -0
- data/test/fixtures/disco_app/plan_codes.yml +6 -0
- data/test/fixtures/disco_app/plans.yml +37 -0
- data/test/fixtures/disco_app/recurring_application_charges.yml +11 -0
- data/test/fixtures/disco_app/shops.yml +10 -0
- data/test/fixtures/disco_app/subscriptions.yml +21 -0
- data/test/fixtures/products.yml +4 -0
- data/test/fixtures/webhooks/app_uninstalled.json +46 -0
- data/test/fixtures/webhooks/product_created.json +167 -0
- data/test/fixtures/webhooks/product_deleted.json +3 -0
- data/test/fixtures/webhooks/product_updated.json +167 -0
- data/test/integration/synchronises_test.rb +55 -0
- data/test/jobs/disco_app/app_installed_job_test.rb +42 -0
- data/test/jobs/disco_app/app_uninstalled_job_test.rb +30 -0
- data/test/models/disco_app/plan_test.rb +5 -0
- data/test/models/disco_app/session_test.rb +31 -0
- data/test/models/disco_app/shop_test.rb +27 -0
- data/test/services/disco_app/charges_service_test.rb +104 -0
- data/test/services/disco_app/subscription_service_test.rb +59 -0
- data/test/support/test_file_fixtures.rb +29 -0
- data/test/support/test_shopify_api.rb +16 -0
- data/test/test_helper.rb +52 -0
- metadata +660 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::ChargesControllerTest < ActionController::TestCase
|
|
4
|
+
include ActiveJob::TestHelper
|
|
5
|
+
include DiscoApp::Test::ShopifyAPI
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@shop = disco_app_shops(:widget_store)
|
|
9
|
+
@current_subscription = disco_app_subscriptions(:current_widget_store_subscription)
|
|
10
|
+
@new_charge = disco_app_recurring_application_charges(:new_widget_store_subscription_recurring_charge)
|
|
11
|
+
@routes = DiscoApp::Engine.routes
|
|
12
|
+
log_in_as(@shop)
|
|
13
|
+
@shop.installed!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def teardown
|
|
17
|
+
@shop = nil
|
|
18
|
+
@current_subscription = nil
|
|
19
|
+
WebMock.reset!
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test 'non-logged in user is redirected to the login page' do
|
|
23
|
+
log_out
|
|
24
|
+
get(:new, subscription_id: @current_subscription)
|
|
25
|
+
assert_redirected_to ShopifyApp::Engine.routes.url_helpers.login_path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'logged-in, never installed user is redirected to the install page' do
|
|
29
|
+
@shop.never_installed!
|
|
30
|
+
get(:new, subscription_id: @current_subscription)
|
|
31
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.install_path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test 'user with paid-for current subscription can not access page' do
|
|
35
|
+
get(:new, subscription_id: @current_subscription)
|
|
36
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test 'user with unpaid current subscription can access page' do
|
|
40
|
+
@current_subscription.active_charge.destroy
|
|
41
|
+
get(:new, subscription_id: @current_subscription)
|
|
42
|
+
assert_response :ok
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
test 'user with unpaid current subscription can create new charge and is redirected to confirmation url' do
|
|
46
|
+
stub_api_request(:post, "#{@shop.admin_url}/recurring_application_charges.json", 'widget_store/charges/create_second_recurring_application_charge')
|
|
47
|
+
|
|
48
|
+
@current_subscription.active_charge.destroy
|
|
49
|
+
post(:create, subscription_id: @current_subscription)
|
|
50
|
+
assert_redirected_to 'https://apple.myshopify.com/admin/charges/654381179/confirm_recurring_application_charge?signature=BAhpBHsQASc%3D--b2e90c6e4e94fbae15a464c566a31a1c23e6bffa'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
test 'user trying to activate charge for invalid gets not found and hence 404' do
|
|
54
|
+
assert_raises ActiveRecord::RecordNotFound do
|
|
55
|
+
get(:activate, subscription_id: '123', id: '456', charge_id: '789')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test 'user trying to activate invalid charge for valid subscription gets redirected to new charge page for that subscription' do
|
|
60
|
+
@current_subscription.active_charge.destroy
|
|
61
|
+
get(:activate, subscription_id: @current_subscription, id: '456', charge_id: '789')
|
|
62
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_charge_path(@current_subscription)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
test 'user trying to activate pending charge is redirected back to new charge page' do
|
|
66
|
+
stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_pending_recurring_application_charge')
|
|
67
|
+
|
|
68
|
+
@current_subscription.active_charge.destroy
|
|
69
|
+
get(:activate, subscription_id: @current_subscription, id: @new_charge.id, charge_id: @new_charge.shopify_id)
|
|
70
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_charge_path(@current_subscription)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
test 'user trying to activate declined charge is redirected back to new charge page' do
|
|
74
|
+
stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_declined_recurring_application_charge')
|
|
75
|
+
|
|
76
|
+
@current_subscription.active_charge.destroy
|
|
77
|
+
get(:activate, subscription_id: @current_subscription, id: @new_charge.id, charge_id: @new_charge.shopify_id)
|
|
78
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_charge_path(@current_subscription)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
test 'user trying to activate accepted charge succeeds and is redirected to the root page' do
|
|
82
|
+
stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_accepted_recurring_application_charge')
|
|
83
|
+
stub_api_request(:post, "#{@shop.admin_url}/recurring_application_charges/654381179/activate.json", 'widget_store/charges/activate_recurring_application_charge')
|
|
84
|
+
|
|
85
|
+
@current_subscription.active_charge.destroy
|
|
86
|
+
get(:activate, subscription_id: @current_subscription, id: @new_charge.id, charge_id: @new_charge.shopify_id)
|
|
87
|
+
assert_equal @new_charge, @current_subscription.active_charge
|
|
88
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::InstallControllerTest < ActionController::TestCase
|
|
4
|
+
include ActiveJob::TestHelper
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@shop = disco_app_shops(:widget_store)
|
|
8
|
+
@routes = DiscoApp::Engine.routes
|
|
9
|
+
log_in_as(@shop)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def teardown
|
|
13
|
+
@shop = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'logged-in but uninstalled user triggers installation from install page' do
|
|
17
|
+
get(:install)
|
|
18
|
+
assert_redirected_to :installing
|
|
19
|
+
assert_enqueued_jobs 1
|
|
20
|
+
@shop.reload
|
|
21
|
+
assert @shop.awaiting_install?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'logged-in and installed user is redirected to installing url for install/uninstalling actions' do
|
|
25
|
+
@shop.installed!
|
|
26
|
+
[:install, :uninstalling].each do |action|
|
|
27
|
+
get(:install)
|
|
28
|
+
assert_redirected_to :installing
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test 'logged-in and installed user is redirected to root url for installing' do
|
|
33
|
+
@shop.installed!
|
|
34
|
+
get(:installing)
|
|
35
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'logged-in and uninstalling user sees uninstalling page' do
|
|
39
|
+
@shop.uninstalling!
|
|
40
|
+
get(:uninstalling)
|
|
41
|
+
assert_response :success
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test 'logged-in and uninstalled user starts install process again' do
|
|
45
|
+
@shop.uninstalled!
|
|
46
|
+
get(:uninstalling)
|
|
47
|
+
assert_redirected_to :install
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::SubscriptionsControllerTest < ActionController::TestCase
|
|
4
|
+
include ActiveJob::TestHelper
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@shop = disco_app_shops(:widget_store)
|
|
8
|
+
@current_subscription = disco_app_subscriptions(:current_widget_store_subscription)
|
|
9
|
+
@routes = DiscoApp::Engine.routes
|
|
10
|
+
log_in_as(@shop)
|
|
11
|
+
@shop.installed!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def teardown
|
|
15
|
+
@shop = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test 'non-logged in user is redirected to the login page' do
|
|
19
|
+
log_out
|
|
20
|
+
get(:new)
|
|
21
|
+
assert_redirected_to ShopifyApp::Engine.routes.url_helpers.login_path
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'logged-in, never installed user is redirected to the install page' do
|
|
25
|
+
@shop.never_installed!
|
|
26
|
+
get(:new)
|
|
27
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.install_path
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test 'logged-in, installed user with no current subscription can access page' do
|
|
31
|
+
@current_subscription.destroy
|
|
32
|
+
get(:new)
|
|
33
|
+
assert_response :ok
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
test 'logged-in, installed user with current subscription can access page' do
|
|
37
|
+
get(:new)
|
|
38
|
+
assert_response :ok
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test 'logged-in, installed user with current subscription can create new subscription' do
|
|
42
|
+
post(:create, subscription: { plan: disco_app_plans(:premium) })
|
|
43
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
44
|
+
assert_equal disco_app_plans(:premium), @shop.current_plan
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
test 'logged-in, installed user with no subscription can create new subscription for available plan' do
|
|
48
|
+
@current_subscription.destroy
|
|
49
|
+
post(:create, subscription: { plan: disco_app_plans(:premium) })
|
|
50
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
51
|
+
assert_equal disco_app_plans(:premium), @shop.current_plan
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test 'logged-in, installed user with current subscription can not create new subscription for unavailable plan' do
|
|
55
|
+
post(:create, subscription: { plan: disco_app_plans(:cheapo) })
|
|
56
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_path
|
|
57
|
+
assert_equal @current_subscription, @shop.current_subscription
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
test 'logged-in, installed user with current subscription can not create new subscription with invalid plan code' do
|
|
61
|
+
post(:create, subscription: { plan: disco_app_plans(:premium), plan_code: 'BANANA' })
|
|
62
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_path
|
|
63
|
+
assert_equal @current_subscription, @shop.current_subscription
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test 'logged-in, installed user with current subscription can create new subscription with valid plan code' do
|
|
67
|
+
post(:create, subscription: { plan: disco_app_plans(:premium), plan_code: 'PODCAST' })
|
|
68
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
69
|
+
assert_equal disco_app_plans(:premium), @shop.current_plan
|
|
70
|
+
assert_equal 8999, @shop.current_subscription.amount
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::WebhooksControllerTest < ActionController::TestCase
|
|
4
|
+
include ActiveJob::TestHelper
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@shop = disco_app_shops(:widget_store)
|
|
8
|
+
@routes = DiscoApp::Engine.routes
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def teardown
|
|
12
|
+
@shop = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test 'webhook request without authentication information returns unauthorized' do
|
|
16
|
+
body = webhook_fixture('app_uninstalled')
|
|
17
|
+
post(:process_webhook, body)
|
|
18
|
+
assert_response :unauthorized
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'webhook request with no HMAC returns unauthorized' do
|
|
22
|
+
body = webhook_fixture('app_uninstalled')
|
|
23
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
24
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
25
|
+
post(:process_webhook, body)
|
|
26
|
+
assert_response :unauthorized
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test 'webhook request with invalid HMAC returns unauthorized' do
|
|
30
|
+
body = webhook_fixture('app_uninstalled')
|
|
31
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
32
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
33
|
+
@request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = '0000'
|
|
34
|
+
post(:process_webhook, body)
|
|
35
|
+
assert_response :unauthorized
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'webhook request with valid HMAC returns OK' do
|
|
39
|
+
body = webhook_fixture('app_uninstalled')
|
|
40
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
41
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
42
|
+
@request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = DiscoApp::WebhookService.calculated_hmac(body, ShopifyApp.configuration.secret)
|
|
43
|
+
post(:process_webhook, body)
|
|
44
|
+
assert_response :ok
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
test 'app uninstalled job queued when app/uninstalled webhook arrives' do
|
|
48
|
+
body = webhook_fixture('app_uninstalled')
|
|
49
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
50
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
51
|
+
@request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = DiscoApp::WebhookService.calculated_hmac(body, ShopifyApp.configuration.secret)
|
|
52
|
+
|
|
53
|
+
assert_enqueued_with(job: DiscoApp::AppUninstalledJob) do
|
|
54
|
+
post(:process_webhook, body)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class HomeControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@shop = disco_app_shops(:widget_store)
|
|
7
|
+
@current_subscription = disco_app_subscriptions(:current_widget_store_subscription)
|
|
8
|
+
@current_recurring_charge = disco_app_recurring_application_charges(:current_widget_store_subscription_recurring_charge)
|
|
9
|
+
log_in_as(@shop)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def teardown
|
|
13
|
+
@shop = nil
|
|
14
|
+
@current_subscription = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test 'non-logged in user is redirected to the login page' do
|
|
18
|
+
log_out
|
|
19
|
+
get(:index)
|
|
20
|
+
assert_redirected_to ShopifyApp::Engine.routes.url_helpers.login_path
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test 'logged-in, never installed user is redirected to the install page' do
|
|
24
|
+
get(:index)
|
|
25
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.install_path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'logged-in, awaiting install user is redirected to the installing page' do
|
|
29
|
+
@shop.awaiting_install!
|
|
30
|
+
get(:index)
|
|
31
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.installing_path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test 'logged-in, installing user is redirected to the installing page' do
|
|
35
|
+
@shop.installing!
|
|
36
|
+
get(:index)
|
|
37
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.installing_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test 'logged-in, awaiting uninstall user is redirected to the uninstalling page' do
|
|
41
|
+
@shop.awaiting_uninstall!
|
|
42
|
+
get(:index)
|
|
43
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.uninstalling_path
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'logged-in, uninstalling user is redirected to the uninstalling page' do
|
|
47
|
+
@shop.uninstalling!
|
|
48
|
+
get(:index)
|
|
49
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.uninstalling_path
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test 'logged-in, uninstalled user is redirected to the install page' do
|
|
53
|
+
@shop.uninstalled!
|
|
54
|
+
get(:index)
|
|
55
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.install_path
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'logged-in, installed user with no current subscription is redirected to new subscription page' do
|
|
59
|
+
@shop.installed!
|
|
60
|
+
@current_subscription.destroy
|
|
61
|
+
get(:index)
|
|
62
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_path
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
test 'logged-in, installed user with no cancelled subscription is redirected to new subscription page' do
|
|
66
|
+
@shop.installed!
|
|
67
|
+
@current_subscription.cancelled!
|
|
68
|
+
get(:index)
|
|
69
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_path
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test 'logged-in, installed user with current but unpaid subscription is redirected to new charges page' do
|
|
73
|
+
@shop.installed!
|
|
74
|
+
@current_recurring_charge.destroy
|
|
75
|
+
get(:index)
|
|
76
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_charge_path(@current_subscription)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
test 'logged-in, installed user with current subscription with declined charge is redirected to new charges page' do
|
|
80
|
+
@shop.installed!
|
|
81
|
+
@current_recurring_charge.declined!
|
|
82
|
+
get(:index)
|
|
83
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.new_subscription_charge_path(@current_subscription)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
test 'logged-in, installed user with a current and paid subscription is able to access the page' do
|
|
87
|
+
@shop.installed!
|
|
88
|
+
get(:index)
|
|
89
|
+
assert_response :success
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class ProxyControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@shop = disco_app_shops(:widget_store)
|
|
7
|
+
@secret = ShopifyApp.configuration.secret
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def teardown
|
|
11
|
+
@shop = nil
|
|
12
|
+
@secret = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test 'app proxy request without authentication information returns unauthorized' do
|
|
16
|
+
get(:index)
|
|
17
|
+
assert_response :unauthorized
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test 'app proxy request with incorrect authentication information returns unauthorized' do
|
|
21
|
+
get(:index, proxy_params(shop: @shop.shopify_domain).merge(signature: 'invalid_signature'))
|
|
22
|
+
assert_response :unauthorized
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test 'app proxy request with correct authentication information returns ok and has shop context' do
|
|
26
|
+
get(:index, proxy_params(shop: @shop.shopify_domain))
|
|
27
|
+
assert_response :ok
|
|
28
|
+
assert_equal @shop, assigns(:shop)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'app proxy request with correct authentication information but unknown shop returns 404' do
|
|
32
|
+
get(:index, proxy_params(shop: 'unknown.myshopify.com'))
|
|
33
|
+
assert_response :not_found
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def proxy_params(**params)
|
|
39
|
+
params.merge(signature: DiscoApp::ProxyService.calculated_signature(params, @secret))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
data/test/dummy/Rakefile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// compiled file.
|
|
9
|
+
//
|
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
|
+
// about supported directives.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require turbolinks
|
|
16
|
+
//= require disco_app/disco_app
|
|
17
|
+
//= require_tree .
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class DiscoApp::AppInstalledJob < DiscoApp::ShopJob
|
|
2
|
+
include DiscoApp::Concerns::AppInstalledJob
|
|
3
|
+
|
|
4
|
+
DEVELOPMENT_PLAN_ID = 1
|
|
5
|
+
|
|
6
|
+
# Implement the default_plan method to define an initial plan for shops based
|
|
7
|
+
# on their status.
|
|
8
|
+
def default_plan
|
|
9
|
+
@default_plan ||= begin
|
|
10
|
+
if @shop.plan_name === 'affiliate'
|
|
11
|
+
DiscoApp::Plan.find(DEVELOPMENT_PLAN_ID)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class DiscoApp::AppUninstalledJob < DiscoApp::ShopJob
|
|
2
|
+
include DiscoApp::Concerns::AppUninstalledJob
|
|
3
|
+
|
|
4
|
+
# Extend the perform method to change the country name of the shop to
|
|
5
|
+
# 'Nowhere' on uninstallation.
|
|
6
|
+
def perform(domain, shop_data)
|
|
7
|
+
super(domain, shop_data)
|
|
8
|
+
@shop.update(country_name: 'Nowhere')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'active_utils'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::Shop < ActiveRecord::Base
|
|
4
|
+
include DiscoApp::Concerns::Shop
|
|
5
|
+
|
|
6
|
+
# Extend the Shop model to return the Shop's country as an ActiveUtils country.
|
|
7
|
+
def country
|
|
8
|
+
begin
|
|
9
|
+
ActiveUtils::Country.find(country_name)
|
|
10
|
+
rescue ActiveUtils::InvalidCountryCodeError
|
|
11
|
+
nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
data/test/dummy/bin/rake
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
# path to your application root.
|
|
5
|
+
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
|
|
6
|
+
|
|
7
|
+
Dir.chdir APP_ROOT do
|
|
8
|
+
# This script is a starting point to setup your application.
|
|
9
|
+
# Add necessary setup steps to this file:
|
|
10
|
+
|
|
11
|
+
puts "== Installing dependencies =="
|
|
12
|
+
system "gem install bundler --conservative"
|
|
13
|
+
system "bundle check || bundle install"
|
|
14
|
+
|
|
15
|
+
# puts "\n== Copying sample files =="
|
|
16
|
+
# unless File.exist?("config/database.yml")
|
|
17
|
+
# system "cp config/database.yml.sample config/database.yml"
|
|
18
|
+
# end
|
|
19
|
+
|
|
20
|
+
puts "\n== Preparing database =="
|
|
21
|
+
system "bin/rake db:setup"
|
|
22
|
+
|
|
23
|
+
puts "\n== Removing old logs and tempfiles =="
|
|
24
|
+
system "rm -f log/*"
|
|
25
|
+
system "rm -rf tmp/cache"
|
|
26
|
+
|
|
27
|
+
puts "\n== Restarting application server =="
|
|
28
|
+
system "touch tmp/restart.txt"
|
|
29
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'rails/all'
|
|
4
|
+
|
|
5
|
+
Bundler.require(*Rails.groups)
|
|
6
|
+
require "disco_app"
|
|
7
|
+
|
|
8
|
+
module Dummy
|
|
9
|
+
class Application < Rails::Application
|
|
10
|
+
config.action_dispatch.default_headers['P3P'] = 'CP="Not used"'
|
|
11
|
+
config.action_dispatch.default_headers.delete('X-Frame-Options')
|
|
12
|
+
# Settings in config/environments/* take precedence over those specified here.
|
|
13
|
+
# Application configuration should go into files in config/initializers
|
|
14
|
+
# -- all .rb files in that directory are automatically loaded.
|
|
15
|
+
|
|
16
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
|
17
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
|
18
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
|
19
|
+
|
|
20
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
|
21
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
|
22
|
+
# config.i18n.default_locale = :de
|
|
23
|
+
|
|
24
|
+
# Set the default host for absolute URL routing purposes
|
|
25
|
+
routes.default_url_options[:host] = ENV['DEFAULT_HOST']
|
|
26
|
+
|
|
27
|
+
# Configure custom session storage
|
|
28
|
+
ActionDispatch::Session::ActiveRecordStore.session_class = DiscoApp::Session
|
|
29
|
+
ActiveRecord::SessionStore::Session.table_name = 'disco_app_sessions'
|
|
30
|
+
|
|
31
|
+
# Explicitly prevent real charges being created by default
|
|
32
|
+
config.x.shopify_charges_real = false
|
|
33
|
+
|
|
34
|
+
# Do not swallow errors in after_commit/after_rollback callbacks.
|
|
35
|
+
config.active_record.raise_in_transactional_callbacks = true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|