disco_app 0.8.9

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.
Files changed (257) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +37 -0
  3. data/app/assets/images/disco_app/icon.svg +1 -0
  4. data/app/assets/javascripts/disco_app/components/filterable_shop_list.js.jsx +60 -0
  5. data/app/assets/javascripts/disco_app/components/shop_filter_tab.js.jsx +34 -0
  6. data/app/assets/javascripts/disco_app/components/shop_filter_tabs.js.jsx +21 -0
  7. data/app/assets/javascripts/disco_app/components/shop_list.js.jsx +144 -0
  8. data/app/assets/javascripts/disco_app/components/shop_row.js.jsx +27 -0
  9. data/app/assets/javascripts/disco_app/components/shopify_admin_link.js.jsx +29 -0
  10. data/app/assets/javascripts/disco_app/components.js +5 -0
  11. data/app/assets/javascripts/disco_app/disco_app.js +7 -0
  12. data/app/assets/javascripts/disco_app/frame.js +152 -0
  13. data/app/assets/javascripts/disco_app/shopify-turbolinks.js +7 -0
  14. data/app/assets/stylesheets/disco_app/bootstrap/_custom.scss +54 -0
  15. data/app/assets/stylesheets/disco_app/bootstrap/_variables.scss +872 -0
  16. data/app/assets/stylesheets/disco_app/disco/_buttons.scss +31 -0
  17. data/app/assets/stylesheets/disco_app/disco/_cards.scss +52 -0
  18. data/app/assets/stylesheets/disco_app/disco/_forms.scss +23 -0
  19. data/app/assets/stylesheets/disco_app/disco/_grid.scss +58 -0
  20. data/app/assets/stylesheets/disco_app/disco/_sections.scss +61 -0
  21. data/app/assets/stylesheets/disco_app/disco/_tables.scss +57 -0
  22. data/app/assets/stylesheets/disco_app/disco/_tabs.scss +61 -0
  23. data/app/assets/stylesheets/disco_app/disco/_type.scss +39 -0
  24. data/app/assets/stylesheets/disco_app/disco/mixins/_flexbox.scss +394 -0
  25. data/app/assets/stylesheets/disco_app/disco_app.scss +16 -0
  26. data/app/assets/stylesheets/disco_app/frame/_buttons.scss +54 -0
  27. data/app/assets/stylesheets/disco_app/frame/_forms.scss +26 -0
  28. data/app/assets/stylesheets/disco_app/frame/_layout.scss +77 -0
  29. data/app/assets/stylesheets/disco_app/frame/_type.scss +32 -0
  30. data/app/assets/stylesheets/disco_app/frame.scss +9 -0
  31. data/app/controllers/disco_app/admin/app_settings_controller.rb +3 -0
  32. data/app/controllers/disco_app/admin/application_controller.rb +3 -0
  33. data/app/controllers/disco_app/admin/concerns/app_settings_controller.rb +24 -0
  34. data/app/controllers/disco_app/admin/concerns/authenticated_controller.rb +20 -0
  35. data/app/controllers/disco_app/admin/concerns/plans_controller.rb +51 -0
  36. data/app/controllers/disco_app/admin/concerns/shops_controller.rb +7 -0
  37. data/app/controllers/disco_app/admin/plans_controller.rb +3 -0
  38. data/app/controllers/disco_app/admin/resources/shops_controller.rb +3 -0
  39. data/app/controllers/disco_app/admin/shops_controller.rb +3 -0
  40. data/app/controllers/disco_app/charges_controller.rb +47 -0
  41. data/app/controllers/disco_app/concerns/app_proxy_controller.rb +40 -0
  42. data/app/controllers/disco_app/concerns/authenticated_controller.rb +56 -0
  43. data/app/controllers/disco_app/concerns/carrier_request_controller.rb +21 -0
  44. data/app/controllers/disco_app/frame_controller.rb +9 -0
  45. data/app/controllers/disco_app/install_controller.rb +27 -0
  46. data/app/controllers/disco_app/subscriptions_controller.rb +32 -0
  47. data/app/controllers/disco_app/webhooks_controller.rb +46 -0
  48. data/app/controllers/sessions_controller.rb +28 -0
  49. data/app/helpers/disco_app/application_helper.rb +28 -0
  50. data/app/jobs/disco_app/app_installed_job.rb +3 -0
  51. data/app/jobs/disco_app/app_uninstalled_job.rb +3 -0
  52. data/app/jobs/disco_app/concerns/app_installed_job.rb +39 -0
  53. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +20 -0
  54. data/app/jobs/disco_app/concerns/shop_update_job.rb +16 -0
  55. data/app/jobs/disco_app/concerns/subscription_changed_job.rb +7 -0
  56. data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +52 -0
  57. data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +61 -0
  58. data/app/jobs/disco_app/shop_job.rb +27 -0
  59. data/app/jobs/disco_app/shop_update_job.rb +3 -0
  60. data/app/jobs/disco_app/subscription_changed_job.rb +3 -0
  61. data/app/jobs/disco_app/synchronise_carrier_service_job.rb +3 -0
  62. data/app/jobs/disco_app/synchronise_webhooks_job.rb +3 -0
  63. data/app/models/disco_app/app_settings.rb +3 -0
  64. data/app/models/disco_app/application_charge.rb +18 -0
  65. data/app/models/disco_app/concerns/app_settings.rb +7 -0
  66. data/app/models/disco_app/concerns/plan.rb +26 -0
  67. data/app/models/disco_app/concerns/plan_code.rb +15 -0
  68. data/app/models/disco_app/concerns/shop.rb +80 -0
  69. data/app/models/disco_app/concerns/subscription.rb +48 -0
  70. data/app/models/disco_app/concerns/synchronises.rb +39 -0
  71. data/app/models/disco_app/plan.rb +3 -0
  72. data/app/models/disco_app/plan_code.rb +3 -0
  73. data/app/models/disco_app/recurring_application_charge.rb +18 -0
  74. data/app/models/disco_app/session_storage.rb +18 -0
  75. data/app/models/disco_app/shop.rb +3 -0
  76. data/app/models/disco_app/subscription.rb +3 -0
  77. data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +45 -0
  78. data/app/resources/disco_app/admin/resources/shop_resource.rb +4 -0
  79. data/app/services/disco_app/carrier_request_service.rb +15 -0
  80. data/app/services/disco_app/charges_service.rb +81 -0
  81. data/app/services/disco_app/proxy_service.rb +17 -0
  82. data/app/services/disco_app/subscription_service.rb +46 -0
  83. data/app/services/disco_app/webhook_service.rb +30 -0
  84. data/app/views/disco_app/admin/app_settings/edit.html.erb +5 -0
  85. data/app/views/disco_app/admin/plans/_form.html.erb +75 -0
  86. data/app/views/disco_app/admin/plans/edit.html.erb +7 -0
  87. data/app/views/disco_app/admin/plans/index.html.erb +41 -0
  88. data/app/views/disco_app/admin/plans/new.html.erb +7 -0
  89. data/app/views/disco_app/admin/shops/index.html.erb +12 -0
  90. data/app/views/disco_app/charges/activate.html.erb +1 -0
  91. data/app/views/disco_app/charges/create.html.erb +1 -0
  92. data/app/views/disco_app/charges/new.html.erb +12 -0
  93. data/app/views/disco_app/frame/frame.html.erb +36 -0
  94. data/app/views/disco_app/install/installing.html.erb +7 -0
  95. data/app/views/disco_app/install/uninstalling.html.erb +1 -0
  96. data/app/views/disco_app/proxy_errors/404.html.erb +1 -0
  97. data/app/views/disco_app/shared/_card.html.erb +14 -0
  98. data/app/views/disco_app/shared/_section.html.erb +17 -0
  99. data/app/views/disco_app/subscriptions/new.html.erb +25 -0
  100. data/app/views/layouts/admin/_navbar.html.erb +25 -0
  101. data/app/views/layouts/admin.html.erb +23 -0
  102. data/app/views/layouts/application.html.erb +18 -0
  103. data/app/views/layouts/embedded_app.html.erb +41 -0
  104. data/app/views/layouts/embedded_app_modal.html.erb +17 -0
  105. data/app/views/sessions/new.html.erb +26 -0
  106. data/config/routes.rb +46 -0
  107. data/db/migrate/20150525000000_create_shops_if_not_existent.rb +15 -0
  108. data/db/migrate/20150525162112_add_status_to_shops.rb +5 -0
  109. data/db/migrate/20150525171422_add_meta_to_shops.rb +11 -0
  110. data/db/migrate/20150629210346_add_charge_status_to_shop.rb +5 -0
  111. data/db/migrate/20150814214025_add_more_meta_to_shops.rb +15 -0
  112. data/db/migrate/20151017231302_create_disco_app_plans.rb +13 -0
  113. data/db/migrate/20151017232027_create_disco_app_subscriptions.rb +15 -0
  114. data/db/migrate/20151017234409_move_shop_to_disco_app_engine.rb +5 -0
  115. data/db/migrate/20160112233706_create_disco_app_sessions.rb +12 -0
  116. data/db/migrate/20160113194418_add_shop_id_to_disco_app_sessions.rb +6 -0
  117. data/db/migrate/20160223111044_create_disco_app_settings.rb +8 -0
  118. data/db/migrate/20160301223215_update_plans.rb +22 -0
  119. data/db/migrate/20160301224558_update_subscriptions.rb +13 -0
  120. data/db/migrate/20160302104816_create_disco_app_recurring_application_charges.rb +14 -0
  121. data/db/migrate/20160302105259_create_disco_app_application_charges.rb +14 -0
  122. data/db/migrate/20160302134728_drop_charge_status_from_shops.rb +5 -0
  123. data/db/migrate/20160302142941_add_shopify_attributes_to_charges.rb +8 -0
  124. data/db/migrate/20160331093148_create_disco_app_plan_codes.rb +14 -0
  125. data/db/migrate/20160401044420_add_status_to_plan_codes.rb +5 -0
  126. data/db/migrate/20160401045551_add_amount_and_plan_code_to_disco_app_subscriptions.rb +7 -0
  127. data/db/migrate/20160425205211_add_source_to_disco_app_subscriptions.rb +5 -0
  128. data/db/migrate/20160426033520_add_trial_period_days_to_disco_app_subscriptions.rb +5 -0
  129. data/lib/disco_app/configuration.rb +39 -0
  130. data/lib/disco_app/constants.rb +4 -0
  131. data/lib/disco_app/engine.rb +26 -0
  132. data/lib/disco_app/session.rb +14 -0
  133. data/lib/disco_app/support/file_fixtures.rb +23 -0
  134. data/lib/disco_app/test_help.rb +11 -0
  135. data/lib/disco_app/version.rb +3 -0
  136. data/lib/disco_app.rb +7 -0
  137. data/lib/generators/disco_app/USAGE +5 -0
  138. data/lib/generators/disco_app/adminify/adminify_generator.rb +35 -0
  139. data/lib/generators/disco_app/disco_app_generator.rb +164 -0
  140. data/lib/generators/disco_app/mailify/mailify_generator.rb +54 -0
  141. data/lib/generators/disco_app/monitorify/monitorify_generator.rb +28 -0
  142. data/lib/generators/disco_app/monitorify/templates/config/newrelic.yml +26 -0
  143. data/lib/generators/disco_app/monitorify/templates/initializers/rollbar.rb +12 -0
  144. data/lib/generators/disco_app/reactify/reactify_generator.rb +45 -0
  145. data/lib/generators/disco_app/templates/assets/javascripts/application.js +17 -0
  146. data/lib/generators/disco_app/templates/assets/stylesheets/application.scss +5 -0
  147. data/lib/generators/disco_app/templates/config/puma.rb +15 -0
  148. data/lib/generators/disco_app/templates/controllers/home_controller.rb +7 -0
  149. data/lib/generators/disco_app/templates/initializers/disco_app.rb +19 -0
  150. data/lib/generators/disco_app/templates/initializers/session_store.rb +2 -0
  151. data/lib/generators/disco_app/templates/initializers/shopify_app.rb +7 -0
  152. data/lib/generators/disco_app/templates/initializers/shopify_session_repository.rb +7 -0
  153. data/lib/generators/disco_app/templates/root/Procfile +2 -0
  154. data/lib/generators/disco_app/templates/views/home/index.html.erb +2 -0
  155. data/lib/tasks/carrier_service.rake +10 -0
  156. data/lib/tasks/sessions.rake +9 -0
  157. data/lib/tasks/start.rake +3 -0
  158. data/lib/tasks/webhooks.rake +10 -0
  159. data/test/controllers/disco_app/admin/shops_controller_test.rb +54 -0
  160. data/test/controllers/disco_app/charges_controller_test.rb +92 -0
  161. data/test/controllers/disco_app/install_controller_test.rb +50 -0
  162. data/test/controllers/disco_app/subscriptions_controller_test.rb +68 -0
  163. data/test/controllers/disco_app/webhooks_controller_test.rb +58 -0
  164. data/test/controllers/home_controller_test.rb +92 -0
  165. data/test/controllers/proxy_controller_test.rb +42 -0
  166. data/test/disco_app_test.rb +7 -0
  167. data/test/dummy/Rakefile +6 -0
  168. data/test/dummy/app/assets/javascripts/application.js +17 -0
  169. data/test/dummy/app/assets/stylesheets/application.scss +5 -0
  170. data/test/dummy/app/controllers/application_controller.rb +6 -0
  171. data/test/dummy/app/controllers/disco_app/admin/shops_controller.rb +8 -0
  172. data/test/dummy/app/controllers/home_controller.rb +7 -0
  173. data/test/dummy/app/controllers/proxy_controller.rb +8 -0
  174. data/test/dummy/app/helpers/application_helper.rb +2 -0
  175. data/test/dummy/app/jobs/disco_app/app_installed_job.rb +16 -0
  176. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +11 -0
  177. data/test/dummy/app/jobs/products_create_job.rb +7 -0
  178. data/test/dummy/app/jobs/products_delete_job.rb +7 -0
  179. data/test/dummy/app/jobs/products_update_job.rb +7 -0
  180. data/test/dummy/app/models/disco_app/shop.rb +15 -0
  181. data/test/dummy/app/models/product.rb +6 -0
  182. data/test/dummy/app/views/home/index.html.erb +2 -0
  183. data/test/dummy/bin/bundle +3 -0
  184. data/test/dummy/bin/rails +4 -0
  185. data/test/dummy/bin/rake +4 -0
  186. data/test/dummy/bin/setup +29 -0
  187. data/test/dummy/config/application.rb +38 -0
  188. data/test/dummy/config/boot.rb +5 -0
  189. data/test/dummy/config/database.codeship.yml +23 -0
  190. data/test/dummy/config/database.yml +20 -0
  191. data/test/dummy/config/environment.rb +5 -0
  192. data/test/dummy/config/environments/development.rb +41 -0
  193. data/test/dummy/config/environments/production.rb +85 -0
  194. data/test/dummy/config/environments/test.rb +42 -0
  195. data/test/dummy/config/initializers/assets.rb +11 -0
  196. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  197. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  198. data/test/dummy/config/initializers/disco_app.rb +19 -0
  199. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  200. data/test/dummy/config/initializers/inflections.rb +16 -0
  201. data/test/dummy/config/initializers/mime_types.rb +4 -0
  202. data/test/dummy/config/initializers/omniauth.rb +9 -0
  203. data/test/dummy/config/initializers/session_store.rb +2 -0
  204. data/test/dummy/config/initializers/shopify_app.rb +7 -0
  205. data/test/dummy/config/initializers/shopify_session_repository.rb +7 -0
  206. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  207. data/test/dummy/config/locales/en.yml +23 -0
  208. data/test/dummy/config/routes.rb +10 -0
  209. data/test/dummy/config/secrets.yml +22 -0
  210. data/test/dummy/config.ru +4 -0
  211. data/test/dummy/db/migrate/20160307182229_create_products.rb +11 -0
  212. data/test/dummy/db/schema.rb +140 -0
  213. data/test/dummy/public/404.html +67 -0
  214. data/test/dummy/public/422.html +67 -0
  215. data/test/dummy/public/500.html +66 -0
  216. data/test/dummy/public/favicon.ico +0 -0
  217. data/test/fixtures/api/widget_store/charges/activate_application_charge_request.json +16 -0
  218. data/test/fixtures/api/widget_store/charges/activate_application_charge_response.json +1 -0
  219. data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_request.json +20 -0
  220. data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_response.json +1 -0
  221. data/test/fixtures/api/widget_store/charges/create_application_charge_request.json +9 -0
  222. data/test/fixtures/api/widget_store/charges/create_application_charge_response.json +16 -0
  223. data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_request.json +9 -0
  224. data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_response.json +20 -0
  225. data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_request.json +9 -0
  226. data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_response.json +20 -0
  227. data/test/fixtures/api/widget_store/charges/get_accepted_application_charge_response.json +16 -0
  228. data/test/fixtures/api/widget_store/charges/get_accepted_recurring_application_charge_response.json +20 -0
  229. data/test/fixtures/api/widget_store/charges/get_declined_application_charge_response.json +16 -0
  230. data/test/fixtures/api/widget_store/charges/get_declined_recurring_application_charge_response.json +20 -0
  231. data/test/fixtures/api/widget_store/charges/get_pending_application_charge_response.json +16 -0
  232. data/test/fixtures/api/widget_store/charges/get_pending_recurring_application_charge_response.json +20 -0
  233. data/test/fixtures/api/widget_store/shop.json +46 -0
  234. data/test/fixtures/api/widget_store/webhooks.json +1 -0
  235. data/test/fixtures/disco_app/application_charges.yml +11 -0
  236. data/test/fixtures/disco_app/plan_codes.yml +13 -0
  237. data/test/fixtures/disco_app/plans.yml +37 -0
  238. data/test/fixtures/disco_app/recurring_application_charges.yml +11 -0
  239. data/test/fixtures/disco_app/shops.yml +10 -0
  240. data/test/fixtures/disco_app/subscriptions.yml +21 -0
  241. data/test/fixtures/products.yml +4 -0
  242. data/test/fixtures/webhooks/app_uninstalled.json +46 -0
  243. data/test/fixtures/webhooks/product_created.json +167 -0
  244. data/test/fixtures/webhooks/product_deleted.json +3 -0
  245. data/test/fixtures/webhooks/product_updated.json +167 -0
  246. data/test/integration/synchronises_test.rb +55 -0
  247. data/test/jobs/disco_app/app_installed_job_test.rb +55 -0
  248. data/test/jobs/disco_app/app_uninstalled_job_test.rb +30 -0
  249. data/test/models/disco_app/plan_test.rb +5 -0
  250. data/test/models/disco_app/session_test.rb +31 -0
  251. data/test/models/disco_app/shop_test.rb +27 -0
  252. data/test/services/disco_app/charges_service_test.rb +105 -0
  253. data/test/services/disco_app/subscription_service_test.rb +60 -0
  254. data/test/support/test_file_fixtures.rb +29 -0
  255. data/test/support/test_shopify_api.rb +16 -0
  256. data/test/test_helper.rb +52 -0
  257. metadata +663 -0
@@ -0,0 +1,105 @@
1
+ require 'test_helper'
2
+
3
+ class DiscoApp::ChargesServiceTest < ActiveSupport::TestCase
4
+ include DiscoApp::Test::ShopifyAPI
5
+
6
+ def setup
7
+ @shop = disco_app_shops(:widget_store)
8
+ @subscription = disco_app_subscriptions(:current_widget_store_subscription)
9
+ @new_charge = disco_app_recurring_application_charges(:new_widget_store_subscription_recurring_charge)
10
+
11
+ @dev_shop = disco_app_shops(:widget_store_dev)
12
+ @dev_subscription = disco_app_subscriptions(:current_widget_store_dev_subscription)
13
+ @dev_new_charge = disco_app_application_charges(:new_widget_store_dev_subscription_one_time_charge)
14
+
15
+ Timecop.freeze
16
+ end
17
+
18
+ def teardown
19
+ @shop = nil
20
+ @subscription = nil
21
+ @new_charge = nil
22
+
23
+ @dev_shop = nil
24
+ @dev_subscription = nil
25
+ @dev_new_charge = nil
26
+
27
+ Timecop.return
28
+
29
+ WebMock.reset!
30
+ end
31
+
32
+ test 'creating a new charge for a recurring subscription is successful' do
33
+ skip('some indeterminancy in this test')
34
+ stub_api_request(:post, "#{@shop.admin_url}/recurring_application_charges.json", 'widget_store/charges/create_recurring_application_charge')
35
+
36
+ new_charge = DiscoApp::ChargesService.create(@shop, @subscription)
37
+ assert_equal 654381179, new_charge.shopify_id
38
+ assert_equal 'https://apple.myshopify.com/admin/charges/654381179/confirm_recurring_application_charge?signature=BAhpBHsQASc%3D--b2e90c6e4e94fbae15a464c566a31a1c23e6bffa', new_charge.confirmation_url
39
+ end
40
+
41
+ test 'activating a pending recurring charge is not successful' do
42
+ stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_pending_recurring_application_charge')
43
+ assert_not DiscoApp::ChargesService.activate(@shop, @new_charge)
44
+ assert @new_charge.pending?
45
+ end
46
+
47
+ test 'activating a declined recurring charge is not successful' do
48
+ stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_declined_recurring_application_charge')
49
+ assert_not DiscoApp::ChargesService.activate(@shop, @new_charge)
50
+ assert @new_charge.declined?
51
+ end
52
+
53
+ test 'activating an accepted recurring charge is successful and cancels any existing recurring charges' do
54
+ stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_accepted_recurring_application_charge')
55
+ stub_api_request(:post, "#{@shop.admin_url}/recurring_application_charges/654381179/activate.json", 'widget_store/charges/activate_recurring_application_charge')
56
+
57
+ old_charge = @subscription.active_charge
58
+ assert old_charge.active?
59
+
60
+ assert DiscoApp::ChargesService.activate(@shop, @new_charge)
61
+ assert @new_charge.active?
62
+
63
+ old_charge.reload
64
+ assert old_charge.cancelled?
65
+ end
66
+
67
+ test 'activating an accepted recurring charge cancels other recurring charges' do
68
+ stub_api_request(:get, "#{@shop.admin_url}/recurring_application_charges/654381179.json", 'widget_store/charges/get_accepted_recurring_application_charge')
69
+ stub_api_request(:post, "#{@shop.admin_url}/recurring_application_charges/654381179/activate.json", 'widget_store/charges/activate_recurring_application_charge')
70
+
71
+ assert DiscoApp::ChargesService.activate(@shop, @new_charge)
72
+ assert @new_charge.active?
73
+ end
74
+
75
+ test 'creating a new charge for a one-time subscription is successful' do
76
+ stub_api_request(:post, "#{@dev_shop.admin_url}/application_charges.json", 'widget_store/charges/create_application_charge')
77
+
78
+ new_charge = DiscoApp::ChargesService.create(@dev_shop, @dev_subscription)
79
+ assert_equal 1012637323, new_charge.shopify_id
80
+ assert_equal 'https://apple.myshopify.com/admin/charges/1012637323/confirm_application_charge?signature=BAhpBIueWzw%3D--0ea1abacaf9d6fd538b7e9a7023e9b71ce1c7e98', new_charge.confirmation_url
81
+ end
82
+
83
+ test 'activating a pending one-time charge is not successful' do
84
+ stub_api_request(:get, "#{@dev_shop.admin_url}/application_charges/1012637323.json", 'widget_store/charges/get_pending_application_charge')
85
+
86
+ assert_not DiscoApp::ChargesService.activate(@dev_shop, @dev_new_charge)
87
+ assert @dev_new_charge.pending?
88
+ end
89
+
90
+ test 'activating a declined one-time charge is not successful' do
91
+ stub_api_request(:get, "#{@dev_shop.admin_url}/application_charges/1012637323.json", 'widget_store/charges/get_declined_application_charge')
92
+
93
+ assert_not DiscoApp::ChargesService.activate(@dev_shop, @dev_new_charge)
94
+ assert @dev_new_charge.declined?
95
+ end
96
+
97
+ test 'activating an accepted one-time charge is successful' do
98
+ stub_api_request(:get, "#{@dev_shop.admin_url}/application_charges/1012637323.json", 'widget_store/charges/get_accepted_application_charge')
99
+ stub_api_request(:post, "#{@dev_shop.admin_url}/application_charges/1012637323/activate.json", 'widget_store/charges/activate_application_charge')
100
+
101
+ assert DiscoApp::ChargesService.activate(@dev_shop, @dev_new_charge)
102
+ assert @dev_new_charge.active?
103
+ end
104
+
105
+ end
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ class DiscoApp::SubscriptionServiceTest < ActiveSupport::TestCase
4
+ include ActiveJob::TestHelper
5
+
6
+ def setup
7
+ @shop = disco_app_shops(:widget_store)
8
+ @subscription = disco_app_subscriptions(:current_widget_store_subscription)
9
+ Timecop.freeze
10
+ end
11
+
12
+ def teardown
13
+ @shop = nil
14
+ @subscription = nil
15
+ Timecop.return
16
+ end
17
+
18
+ test 'subscribing to a new plan deactivates current subscription and swaps to new plan' do
19
+ DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium))
20
+ @subscription.reload
21
+ assert @subscription.cancelled?
22
+ assert_equal disco_app_plans(:premium), @shop.current_subscription.plan
23
+ end
24
+
25
+ test 'subscribing to a new plan enqueues subscription changed background job' do
26
+ assert_enqueued_with(job: DiscoApp::SubscriptionChangedJob) do
27
+ DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium))
28
+ end
29
+ end
30
+
31
+ test 'subscribing to a new plan works for a shop without a subscription' do
32
+ @subscription.destroy
33
+ DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium))
34
+ assert_equal disco_app_plans(:premium), @shop.current_subscription.plan
35
+ end
36
+
37
+ test 'new subscription for a plan without a trial period created correctly' do
38
+ new_subscription = DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:comped))
39
+ assert new_subscription.active?
40
+ assert_equal nil, new_subscription.trial_start_at
41
+ assert_equal nil, new_subscription.trial_end_at
42
+ end
43
+
44
+ test 'new subscription for a plan with a trial period created correctly' do
45
+ new_subscription = DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium))
46
+ assert new_subscription.trial?
47
+ assert_equal Time.now, new_subscription.trial_start_at
48
+ assert_equal 28.days.from_now, new_subscription.trial_end_at
49
+ end
50
+
51
+ test 'new subscription for a plan with a plan code created correctly' do
52
+ new_subscription = DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium), 'PODCAST')
53
+ assert new_subscription.trial?
54
+ assert_equal Time.now, new_subscription.trial_start_at
55
+ assert_equal 60.days.from_now, new_subscription.trial_end_at
56
+ assert_equal 60, new_subscription.trial_period_days
57
+ assert_equal 8999, new_subscription.amount
58
+ end
59
+
60
+ end
@@ -0,0 +1,29 @@
1
+ module DiscoApp::Test
2
+ module FileFixtures
3
+
4
+ # Return an XML fixture as an XML string.
5
+ def xml_fixture(path)
6
+ filename = File.join(File.dirname(File.dirname(__FILE__)), 'fixtures', 'xml', "#{path}.xml")
7
+ File.read(filename)
8
+ end
9
+
10
+ # Return a JSON fixture as an indifferent hash.
11
+ def json_fixture(path)
12
+ filename = File.join(File.dirname(File.dirname(__FILE__)), 'fixtures', 'json', "#{path}.json")
13
+ HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(File.read(filename)))
14
+ end
15
+
16
+ # API fixtures are special-case JSON fixtures.
17
+ def api_fixture(path)
18
+ filename = File.join(File.dirname(File.dirname(__FILE__)), 'fixtures', 'api', "#{path}.json")
19
+ HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(File.read(filename)))
20
+ end
21
+
22
+ # Webhook fixtures are special-case JSON fixtures.
23
+ def webhook_fixture(path)
24
+ filename = File.join(File.dirname(File.dirname(__FILE__)), 'fixtures', 'webhooks', "#{path}.json")
25
+ File.read(filename)
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ module DiscoApp::Test
2
+ module ShopifyAPI
3
+
4
+ def stub_api_request(method, endpoint, fixture_name)
5
+ if method == :get
6
+ stub_request(method, endpoint)
7
+ .to_return(status: 200, body: api_fixture("#{fixture_name}_response").to_json)
8
+ elsif method == :post
9
+ stub_request(method, endpoint)
10
+ .with(body: api_fixture("#{fixture_name}_request").to_json)
11
+ .to_return(status: 201, body: api_fixture("#{fixture_name}_response").to_json)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,52 @@
1
+ # Configure Rails Environment
2
+ ENV['RAILS_ENV'] = 'test'
3
+ ENV['DEFAULT_HOST'] = 'https://test.example.com'
4
+ ENV['SHOPIFY_APP_NAME'] = 'Test Application'
5
+ ENV['SHOPIFY_APP_API_KEY'] = 'f61b26d635309536c3c83c0adc3cb972'
6
+ ENV['SHOPIFY_APP_SECRET'] = 'b607d1f8b992dccb017f9315f07af9c4'
7
+ ENV['SHOPIFY_APP_REDIRECT_URI'] = 'https://test.example.com/shopify/auth/callback'
8
+ ENV['SHOPIFY_APP_SCOPE'] = 'read_products'
9
+ ENV['SHOPIFY_CHARGES_REAL'] = 'false'
10
+
11
+ require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
12
+ ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
13
+ ActiveRecord::Migrator.migrations_paths << File.expand_path('../../db/migrate', __FILE__)
14
+ require "rails/test_help"
15
+
16
+ # Require our additional test support helpers.
17
+ require 'support/test_file_fixtures'
18
+ require 'support/test_shopify_api'
19
+
20
+ # Require WebMock
21
+ require 'webmock/minitest'
22
+
23
+ # Filter out Minitest backtrace while allowing backtrace from other libraries
24
+ # to be shown.
25
+ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
26
+
27
+ # Load support files
28
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
29
+
30
+ # Load fixtures from the engine
31
+ if ActiveSupport::TestCase.respond_to?(:fixture_path=)
32
+ ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
33
+ ActiveSupport::TestCase.fixtures :all
34
+ end
35
+
36
+ # Set up the base test class.
37
+ class ActiveSupport::TestCase
38
+
39
+ # Include helper modules common to all tests.
40
+ include DiscoApp::Test::FileFixtures
41
+
42
+ def log_in_as(shop)
43
+ session[:shopify] = shop.id
44
+ session[:shopify_domain] = shop.shopify_domain
45
+ end
46
+
47
+ def log_out
48
+ session[:shopify] = nil
49
+ session[:shopify_domain] = nil
50
+ end
51
+
52
+ end