disco_app 0.12.7.pre.puma.pre.3 → 0.18.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (354) hide show
  1. checksums.yaml +5 -5
  2. data/Rakefile +1 -5
  3. data/app/assets/components/disco_app/forms/model-form.es6.jsx +2 -7
  4. data/app/assets/images/disco_app/.keep +0 -0
  5. data/app/assets/images/disco_app/logo.png +0 -0
  6. data/app/assets/javascripts/disco_app/components/custom/shop_row.js.jsx +2 -1
  7. data/app/assets/javascripts/disco_app/components/ui-kit/forms/base_form.es6.jsx +16 -44
  8. data/app/assets/javascripts/disco_app/components/ui-kit/forms/input-checkbox.es6.jsx +10 -5
  9. data/app/clients/disco_app/api_client.rb +25 -19
  10. data/app/clients/disco_app/graphql_client.rb +85 -0
  11. data/app/controllers/disco_app/admin/app_settings_controller.rb +2 -0
  12. data/app/controllers/disco_app/admin/application_controller.rb +3 -1
  13. data/app/controllers/disco_app/admin/concerns/app_settings_controller.rb +2 -1
  14. data/app/controllers/disco_app/admin/concerns/authenticated_controller.rb +5 -3
  15. data/app/controllers/disco_app/admin/concerns/plans_controller.rb +3 -2
  16. data/app/controllers/disco_app/admin/concerns/shops_controller.rb +1 -0
  17. data/app/controllers/disco_app/admin/concerns/sources_controller.rb +52 -0
  18. data/app/controllers/disco_app/admin/concerns/subscriptions_controller.rb +3 -2
  19. data/app/controllers/disco_app/admin/plans_controller.rb +2 -0
  20. data/app/controllers/disco_app/admin/resources/shops_controller.rb +2 -0
  21. data/app/controllers/disco_app/admin/shops_controller.rb +2 -0
  22. data/app/controllers/disco_app/admin/sources_controller.rb +5 -0
  23. data/app/controllers/disco_app/admin/subscriptions_controller.rb +2 -0
  24. data/app/controllers/disco_app/charges_controller.rb +12 -8
  25. data/app/controllers/disco_app/concerns/app_proxy_controller.rb +6 -6
  26. data/app/controllers/disco_app/concerns/authenticated_controller.rb +31 -23
  27. data/app/controllers/disco_app/concerns/carrier_request_controller.rb +22 -11
  28. data/app/controllers/disco_app/concerns/user_authenticated_controller.rb +18 -0
  29. data/app/controllers/disco_app/concerns/webhooks_controller.rb +49 -0
  30. data/app/controllers/disco_app/flow/actions_controller.rb +9 -0
  31. data/app/controllers/disco_app/flow/concerns/actions_controller.rb +23 -0
  32. data/app/controllers/disco_app/flow/concerns/trigger_usage_controller.rb +29 -0
  33. data/app/controllers/disco_app/flow/concerns/verifies_flow_payload.rb +39 -0
  34. data/app/controllers/disco_app/flow/trigger_usage_controller.rb +9 -0
  35. data/app/controllers/disco_app/frame_controller.rb +0 -1
  36. data/app/controllers/disco_app/install_controller.rb +3 -6
  37. data/app/controllers/disco_app/subscriptions_controller.rb +12 -4
  38. data/app/controllers/disco_app/user_sessions_controller.rb +58 -0
  39. data/app/controllers/disco_app/webhooks_controller.rb +2 -43
  40. data/app/controllers/sessions_controller.rb +5 -6
  41. data/app/helpers/disco_app/application_helper.rb +7 -7
  42. data/app/jobs/application_job.rb +2 -0
  43. data/app/jobs/disco_app/app_installed_job.rb +2 -0
  44. data/app/jobs/disco_app/app_uninstalled_job.rb +2 -0
  45. data/app/jobs/disco_app/concerns/app_installed_job.rb +3 -4
  46. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +2 -1
  47. data/app/jobs/disco_app/concerns/customers_data_request_job.rb +13 -0
  48. data/app/jobs/disco_app/concerns/customers_redact_job.rb +13 -0
  49. data/app/jobs/disco_app/concerns/render_asset_group_job.rb +2 -1
  50. data/app/jobs/disco_app/concerns/shop_redact_job.rb +13 -0
  51. data/app/jobs/disco_app/concerns/shop_update_job.rb +10 -3
  52. data/app/jobs/disco_app/concerns/subscription_changed_job.rb +2 -1
  53. data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +9 -8
  54. data/app/jobs/disco_app/concerns/synchronise_resources_job.rb +3 -6
  55. data/app/jobs/disco_app/concerns/synchronise_users_job.rb +18 -0
  56. data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +48 -18
  57. data/app/jobs/disco_app/customers_data_request_job.rb +5 -0
  58. data/app/jobs/disco_app/customers_redact_job.rb +5 -0
  59. data/app/jobs/disco_app/flow/process_action_job.rb +11 -0
  60. data/app/jobs/disco_app/flow/process_trigger_job.rb +11 -0
  61. data/app/jobs/disco_app/render_asset_group_job.rb +2 -0
  62. data/app/jobs/disco_app/send_subscription_job.rb +1 -1
  63. data/app/jobs/disco_app/shop_job.rb +12 -5
  64. data/app/jobs/disco_app/shop_redact_job.rb +5 -0
  65. data/app/jobs/disco_app/shop_update_job.rb +2 -0
  66. data/app/jobs/disco_app/subscription_changed_job.rb +2 -0
  67. data/app/jobs/disco_app/synchronise_carrier_service_job.rb +2 -0
  68. data/app/jobs/disco_app/synchronise_resources_job.rb +2 -0
  69. data/app/jobs/disco_app/synchronise_users_job.rb +5 -0
  70. data/app/jobs/disco_app/synchronise_webhooks_job.rb +2 -0
  71. data/app/models/application_record.rb +5 -0
  72. data/app/models/disco_app/app_settings.rb +3 -1
  73. data/app/models/disco_app/application_charge.rb +8 -2
  74. data/app/models/disco_app/concerns/app_settings.rb +2 -0
  75. data/app/models/disco_app/concerns/can_be_liquified.rb +34 -18
  76. data/app/models/disco_app/concerns/has_metafields.rb +100 -44
  77. data/app/models/disco_app/concerns/plan.rb +15 -7
  78. data/app/models/disco_app/concerns/plan_code.rb +5 -3
  79. data/app/models/disco_app/concerns/renders_assets.rb +15 -21
  80. data/app/models/disco_app/concerns/shop.rb +39 -16
  81. data/app/models/disco_app/concerns/source.rb +13 -0
  82. data/app/models/disco_app/concerns/subscription.rb +14 -7
  83. data/app/models/disco_app/concerns/synchronises.rb +16 -16
  84. data/app/models/disco_app/concerns/taggable.rb +8 -3
  85. data/app/models/disco_app/concerns/user.rb +21 -0
  86. data/app/models/disco_app/flow/action.rb +9 -0
  87. data/app/models/disco_app/flow/concerns/action.rb +27 -0
  88. data/app/models/disco_app/flow/concerns/trigger.rb +28 -0
  89. data/app/models/disco_app/flow/concerns/trigger_usage.rb +17 -0
  90. data/app/models/disco_app/flow/trigger.rb +9 -0
  91. data/app/models/disco_app/flow/trigger_usage.rb +9 -0
  92. data/app/models/disco_app/plan.rb +3 -1
  93. data/app/models/disco_app/plan_code.rb +3 -1
  94. data/app/models/disco_app/recurring_application_charge.rb +9 -2
  95. data/app/models/disco_app/session_storage.rb +5 -2
  96. data/app/models/disco_app/shop.rb +3 -1
  97. data/app/models/disco_app/source.rb +5 -0
  98. data/app/models/disco_app/subscription.rb +3 -1
  99. data/app/models/disco_app/user.rb +5 -0
  100. data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +16 -19
  101. data/app/resources/disco_app/admin/resources/shop_resource.rb +1 -0
  102. data/app/services/disco_app/carrier_request_service.rb +3 -3
  103. data/app/services/disco_app/charges_service.rb +28 -38
  104. data/app/services/disco_app/flow/create_action.rb +35 -0
  105. data/app/services/disco_app/flow/create_trigger.rb +34 -0
  106. data/app/services/disco_app/flow/process_action.rb +50 -0
  107. data/app/services/disco_app/flow/process_trigger.rb +72 -0
  108. data/app/services/disco_app/flow/update_trigger_usage.rb +42 -0
  109. data/app/services/disco_app/partner_app_service.rb +151 -0
  110. data/app/services/disco_app/proxy_service.rb +2 -2
  111. data/app/services/disco_app/request_validation_service.rb +2 -2
  112. data/app/services/disco_app/subscription_service.rb +62 -28
  113. data/app/services/disco_app/synchronise_resources_service.rb +54 -0
  114. data/app/services/disco_app/webhook_service.rb +9 -11
  115. data/app/views/disco_app/admin/sources/_form.html.erb +34 -0
  116. data/app/views/disco_app/admin/sources/edit.html.erb +7 -0
  117. data/app/views/disco_app/admin/sources/index.html.erb +32 -0
  118. data/app/views/disco_app/admin/sources/new.html.erb +7 -0
  119. data/app/views/disco_app/user_sessions/new.html.erb +12 -0
  120. data/app/views/layouts/admin/_nav_items.erb +7 -0
  121. data/app/views/layouts/admin.html.erb +1 -2
  122. data/app/views/layouts/application.html.erb +1 -2
  123. data/app/views/layouts/embedded_app.html.erb +2 -4
  124. data/app/views/layouts/embedded_app_modal.html.erb +2 -3
  125. data/app/views/shopify_app/sessions/new.html.erb +2 -4
  126. data/config/routes.rb +15 -3
  127. data/db/migrate/20150525000000_create_shops_if_not_existent.rb +81 -81
  128. data/db/migrate/20170315062548_create_disco_app_sources.rb +12 -0
  129. data/db/migrate/20170315062629_add_sources_to_shop_subscriptions.rb +16 -0
  130. data/db/migrate/20170327214540_create_disco_app_users.rb +14 -0
  131. data/db/migrate/20170606160751_fix_disco_app_users_index.rb +8 -0
  132. data/db/migrate/20181229100327_create_flow_actions_and_triggers.rb +32 -0
  133. data/db/migrate/20200405000000_create_flow_trigger_usages.rb +16 -0
  134. data/lib/disco_app/configuration.rb +12 -5
  135. data/lib/disco_app/constants.rb +4 -2
  136. data/lib/disco_app/engine.rb +1 -1
  137. data/lib/disco_app/session.rb +1 -0
  138. data/lib/disco_app/support/file_fixtures.rb +2 -1
  139. data/lib/disco_app/version.rb +3 -1
  140. data/lib/generators/disco_app/install/USAGE +5 -0
  141. data/lib/generators/disco_app/install/install_generator.rb +297 -0
  142. data/lib/generators/disco_app/{templates → install/templates}/assets/javascripts/application.js +0 -0
  143. data/lib/generators/disco_app/{templates → install/templates}/assets/javascripts/components.js +0 -0
  144. data/lib/generators/disco_app/{templates → install/templates}/assets/stylesheets/application.scss +0 -0
  145. data/lib/generators/disco_app/install/templates/config/appsignal.yml +12 -0
  146. data/lib/generators/disco_app/install/templates/config/cable.yml.tt +11 -0
  147. data/lib/generators/disco_app/{templates → install/templates}/config/database.yml.tt +7 -3
  148. data/lib/generators/disco_app/install/templates/config/environments/staging.rb +108 -0
  149. data/lib/generators/disco_app/{templates → install/templates}/config/puma.rb +0 -0
  150. data/lib/generators/disco_app/{templates → install/templates}/controllers/home_controller.rb +1 -0
  151. data/lib/generators/disco_app/{templates → install/templates}/initializers/disco_app.rb +5 -0
  152. data/lib/generators/disco_app/install/templates/initializers/session_store.rb +2 -0
  153. data/lib/generators/disco_app/install/templates/initializers/shopify_app.rb +11 -0
  154. data/lib/generators/disco_app/{templates → install/templates}/initializers/shopify_session_repository.rb +2 -1
  155. data/lib/generators/disco_app/install/templates/initializers/timber.rb +4 -0
  156. data/lib/generators/disco_app/install/templates/root/.editorconfig +9 -0
  157. data/lib/generators/disco_app/install/templates/root/.env +27 -0
  158. data/lib/generators/disco_app/install/templates/root/.env.local +29 -0
  159. data/lib/generators/disco_app/install/templates/root/.github/PULL_REQUEST_TEMPLATE.md +18 -0
  160. data/lib/generators/disco_app/install/templates/root/.gitignore +65 -0
  161. data/lib/generators/disco_app/install/templates/root/.rspec +1 -0
  162. data/lib/generators/disco_app/install/templates/root/.rubocop.yml +758 -0
  163. data/lib/generators/disco_app/install/templates/root/.tool-versions +2 -0
  164. data/lib/generators/disco_app/{templates → install/templates}/root/CHECKS +0 -0
  165. data/lib/generators/disco_app/{templates → install/templates}/root/Procfile +0 -0
  166. data/lib/generators/disco_app/install/templates/root/README.md +26 -0
  167. data/lib/generators/disco_app/install/templates/root/package.json.tt +17 -0
  168. data/lib/generators/disco_app/install/templates/spec/rails_helper.rb +40 -0
  169. data/lib/generators/disco_app/install/templates/spec/spec_helper.rb +24 -0
  170. data/lib/generators/disco_app/install/templates/spec/support/active_job.rb +13 -0
  171. data/lib/generators/disco_app/install/templates/spec/support/coveralls.rb +3 -0
  172. data/lib/generators/disco_app/install/templates/spec/support/database_cleaner.rb +17 -0
  173. data/lib/generators/disco_app/install/templates/spec/support/factory_bot.rb +3 -0
  174. data/lib/generators/disco_app/install/templates/spec/support/helpers/json_helper.rb +13 -0
  175. data/lib/generators/disco_app/install/templates/spec/support/shared_examples/a_synchronise_job.rb +12 -0
  176. data/lib/generators/disco_app/install/templates/spec/support/shoulda.rb +6 -0
  177. data/lib/generators/disco_app/install/templates/spec/support/vcr.rb +14 -0
  178. data/lib/generators/disco_app/install/templates/spec/support/webmock.rb +8 -0
  179. data/lib/generators/disco_app/{templates → install/templates}/views/home/index.html.erb +0 -0
  180. data/lib/generators/disco_app/react/USAGE +5 -0
  181. data/lib/generators/disco_app/react/react_generator.rb +108 -0
  182. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/base_controller.rb +18 -0
  183. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/home_controller.rb +10 -0
  184. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/shops_controller.rb +11 -0
  185. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/users_controller.rb +11 -0
  186. data/lib/generators/disco_app/react/templates/app/controllers/embedded/home_controller.rb +13 -0
  187. data/lib/generators/disco_app/react/templates/app/models/api_response.rb +107 -0
  188. data/lib/generators/disco_app/react/templates/app/serializers/disco_app/shop_serializer.rb +13 -0
  189. data/lib/generators/disco_app/react/templates/app/serializers/disco_app/user_serializer.rb +13 -0
  190. data/lib/generators/disco_app/react/templates/app/serializers/empty_serializer.rb +5 -0
  191. data/lib/generators/disco_app/react/templates/app/serializers/error_serializer.rb +76 -0
  192. data/lib/generators/disco_app/react/templates/app/views/embedded/home/index.html.erb +12 -0
  193. data/lib/generators/disco_app/react/templates/app/views/layouts/embedded.html.erb +10 -0
  194. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/App.jsx +77 -0
  195. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/HomePage.jsx +34 -0
  196. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/EmbeddedPage.jsx +70 -0
  197. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/ErrorBanner.jsx +58 -0
  198. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/PaginationWrapper.jsx +10 -0
  199. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/ScrollToTop.jsx +23 -0
  200. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/withApi.jsx +125 -0
  201. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/index.jsx +39 -0
  202. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/utils.js +19 -0
  203. data/lib/generators/disco_app/react/templates/app/webpack/packs/embedded.js +2 -0
  204. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/banners.scss +7 -0
  205. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/busy.scss +3 -0
  206. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/index.scss +3 -0
  207. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/pagination.scss +5 -0
  208. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded.scss +2 -0
  209. data/lib/generators/disco_app/react/templates/config/initializers/mime_types.rb +13 -0
  210. data/lib/generators/disco_app/react/templates/config/initializers/omniauth.rb +27 -0
  211. data/lib/generators/disco_app/react/templates/config/initializers/version.rb.tt +7 -0
  212. data/lib/generators/disco_app/react/templates/config/webpack/staging.js +5 -0
  213. data/lib/generators/disco_app/react/templates/config/webpack/test.js +5 -0
  214. data/lib/generators/disco_app/react/templates/config/webpacker.yml +96 -0
  215. data/lib/generators/disco_app/react/templates/root/.eslintignore +5 -0
  216. data/lib/generators/disco_app/react/templates/root/.eslintrc +69 -0
  217. data/lib/generators/disco_app/react/templates/root/.prettierrc +3 -0
  218. data/lib/generators/disco_app/react/templates/root/VERSION +1 -0
  219. data/lib/generators/disco_app/react/templates/root/babel.config.js +72 -0
  220. data/lib/generators/disco_app/react/templates/root/package.json.tt +84 -0
  221. data/lib/generators/disco_app/react/templates/root/postcss.config.js +14 -0
  222. data/lib/tasks/api.rake +0 -2
  223. data/lib/tasks/carrier_service.rake +0 -2
  224. data/lib/tasks/database.rake +1 -1
  225. data/lib/tasks/partner_app.rake +26 -0
  226. data/lib/tasks/sessions.rake +0 -2
  227. data/lib/tasks/shops.rake +0 -2
  228. data/lib/tasks/users.rake +8 -0
  229. data/lib/tasks/webhooks.rake +0 -2
  230. data/test/clients/disco_app/api_client_test.rb +3 -3
  231. data/test/controllers/disco_app/admin/shops_controller_test.rb +1 -0
  232. data/test/controllers/disco_app/charges_controller_test.rb +19 -21
  233. data/test/controllers/disco_app/flow/trigger_usage_controller_test.rb +41 -0
  234. data/test/controllers/disco_app/install_controller_test.rb +2 -1
  235. data/test/controllers/disco_app/subscriptions_controller_test.rb +6 -5
  236. data/test/controllers/disco_app/webhooks_controller_test.rb +6 -5
  237. data/test/controllers/home_controller_test.rb +2 -2
  238. data/test/controllers/proxy_controller_test.rb +3 -3
  239. data/test/disco_app_test.rb +3 -1
  240. data/test/dummy/Rakefile +1 -1
  241. data/test/dummy/app/assets/config/manifest.js +2 -0
  242. data/test/dummy/app/controllers/application_controller.rb +2 -0
  243. data/test/dummy/app/controllers/carrier_request_controller.rb +1 -0
  244. data/test/dummy/app/controllers/disco_app/admin/shops_controller.rb +2 -1
  245. data/test/dummy/app/controllers/home_controller.rb +1 -0
  246. data/test/dummy/app/controllers/proxy_controller.rb +2 -1
  247. data/test/dummy/app/javascript/packs/application.js +18 -0
  248. data/test/dummy/app/jobs/application_job.rb +2 -0
  249. data/test/dummy/app/jobs/carts_update_job.rb +1 -1
  250. data/test/dummy/app/jobs/disco_app/app_installed_job.rb +2 -3
  251. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +3 -2
  252. data/test/dummy/app/jobs/products_create_job.rb +1 -1
  253. data/test/dummy/app/jobs/products_delete_job.rb +1 -1
  254. data/test/dummy/app/jobs/products_update_job.rb +1 -1
  255. data/test/dummy/app/models/application_record.rb +5 -0
  256. data/test/dummy/app/models/cart.rb +8 -7
  257. data/test/dummy/app/models/disco_app/shop.rb +8 -6
  258. data/test/dummy/app/models/js_configuration.rb +2 -1
  259. data/test/dummy/app/models/product.rb +4 -3
  260. data/test/dummy/app/models/widget_configuration.rb +2 -1
  261. data/test/dummy/babel.config.js +72 -0
  262. data/test/dummy/bin/bundle +1 -1
  263. data/test/dummy/bin/rails +1 -1
  264. data/test/dummy/bin/setup +8 -8
  265. data/test/dummy/bin/webpack +19 -0
  266. data/test/dummy/bin/webpack-dev-server +19 -0
  267. data/test/dummy/config/application.rb +3 -5
  268. data/test/dummy/config/boot.rb +2 -2
  269. data/test/dummy/config/database.yml +4 -0
  270. data/test/dummy/config/environment.rb +1 -1
  271. data/test/dummy/config/environments/staging.rb +85 -0
  272. data/test/dummy/config/environments/test.rb +2 -2
  273. data/test/dummy/config/initializers/disco_app.rb +8 -1
  274. data/test/dummy/config/initializers/omniauth.rb +3 -4
  275. data/test/dummy/config/initializers/session_store.rb +1 -1
  276. data/test/dummy/config/initializers/shopify_app.rb +1 -0
  277. data/test/dummy/config/initializers/shopify_session_repository.rb +1 -1
  278. data/test/dummy/config/routes.rb +0 -2
  279. data/test/dummy/config/secrets.yml +3 -0
  280. data/test/dummy/config/webpack/development.js +5 -0
  281. data/test/dummy/config/webpack/environment.js +3 -0
  282. data/test/dummy/config/webpack/production.js +5 -0
  283. data/test/dummy/config/webpack/test.js +5 -0
  284. data/test/dummy/config/webpacker.yml +95 -0
  285. data/test/dummy/db/migrate/20160307182229_create_products.rb +3 -1
  286. data/test/dummy/db/migrate/20160530160739_create_asset_models.rb +3 -1
  287. data/test/dummy/db/migrate/20161105054746_create_carts.rb +3 -1
  288. data/test/dummy/db/schema.rb +141 -88
  289. data/test/dummy/package.json +10 -0
  290. data/test/dummy/postcss.config.js +12 -0
  291. data/test/dummy/yarn.lock +7278 -0
  292. data/test/fixtures/api/subscriptions/valid_request.json +2 -2
  293. data/test/fixtures/api/widget_store/charges/{activate_application_charge_request.json → get_active_application_charge_response.json} +1 -1
  294. data/test/fixtures/api/widget_store/charges/{activate_recurring_application_charge_request.json → get_active_recurring_application_charge_response.json} +2 -2
  295. data/test/fixtures/api/widget_store/empty_webhooks.json +3 -0
  296. data/test/fixtures/api/widget_store/existing_webhooks.json +43 -0
  297. data/test/fixtures/api/widget_store/products/get_metafields_empty_response.json +3 -0
  298. data/test/fixtures/api/widget_store/products/get_metafields_with_existing_response.json +11 -0
  299. data/test/fixtures/api/widget_store/products/write_metafields_multiple_namespaces_request.json +4 -0
  300. data/test/fixtures/api/widget_store/products/write_metafields_single_namespace_request.json +2 -0
  301. data/test/fixtures/api/widget_store/products/write_metafields_with_existing_single_namespace_request.json +21 -0
  302. data/test/fixtures/api/widget_store/{charges/activate_application_charge_response.json → products/write_metafields_with_existing_single_namespace_response.json} +0 -0
  303. data/test/fixtures/api/widget_store/shops/get_metafields_with_existing_response.json +11 -0
  304. data/test/fixtures/api/widget_store/shops/write_metafields_with_existing_first_request.json +9 -0
  305. data/test/fixtures/api/widget_store/{charges/activate_recurring_application_charge_response.json → shops/write_metafields_with_existing_first_response.json} +0 -0
  306. data/test/fixtures/api/widget_store/shops/write_metafields_with_existing_second_request.json +9 -0
  307. data/test/fixtures/api/widget_store/shops/write_metafields_with_existing_second_response.json +1 -0
  308. data/test/fixtures/api/widget_store/users.json +42 -0
  309. data/test/fixtures/disco_app/shops.yml +9 -2
  310. data/test/fixtures/disco_app/sources.yml +3 -0
  311. data/test/fixtures/liquid/model.liquid +8 -8
  312. data/test/fixtures/webhooks/flow/trigger_usage.json +7 -0
  313. data/test/integration/synchronises_test.rb +20 -13
  314. data/test/jobs/disco_app/app_installed_job_test.rb +30 -11
  315. data/test/jobs/disco_app/app_uninstalled_job_test.rb +5 -2
  316. data/test/jobs/disco_app/send_subscription_job_test.rb +3 -2
  317. data/test/jobs/disco_app/synchronise_carrier_service_job_test.rb +1 -0
  318. data/test/jobs/disco_app/synchronise_users_job_test.rb +27 -0
  319. data/test/jobs/disco_app/synchronise_webhooks_job_test.rb +78 -9
  320. data/test/models/disco_app/can_be_liquified_test.rb +3 -1
  321. data/test/models/disco_app/has_metafields_test.rb +109 -20
  322. data/test/models/disco_app/renders_assets_test.rb +2 -1
  323. data/test/models/disco_app/session_test.rb +2 -2
  324. data/test/models/disco_app/shop_test.rb +1 -1
  325. data/test/services/disco_app/charges_service_test.rb +10 -14
  326. data/test/services/disco_app/flow/create_action_test.rb +51 -0
  327. data/test/services/disco_app/flow/create_trigger_test.rb +56 -0
  328. data/test/services/disco_app/flow/process_action_test.rb +68 -0
  329. data/test/services/disco_app/flow/process_trigger_test.rb +94 -0
  330. data/test/services/disco_app/flow/update_trigger_usage_test.rb +87 -0
  331. data/test/services/disco_app/subscription_service_test.rb +3 -2
  332. data/test/services/disco_app/synchronise_resources_service_test.rb +57 -0
  333. data/test/support/test_file_fixtures.rb +2 -2
  334. data/test/support/test_shopify_api.rb +1 -1
  335. data/test/test_helper.rb +24 -6
  336. data/test/vcr/flow_trigger_invalid_title.yml +35 -0
  337. data/test/vcr/flow_trigger_valid.yml +38 -0
  338. data/test/vcr/synchronise_products.yml +130 -0
  339. data/test/vcr/synchronise_products_paginated.yml +119 -0
  340. data/test/vcr/synchronise_products_since_id.yml +125 -0
  341. data/test/vcr/synchronise_products_with_params.yml +130 -0
  342. data/test/vcr/webhook_failure.yml +640 -0
  343. metadata +388 -142
  344. data/app/clients/disco_app/disco_api_error.rb +0 -2
  345. data/lib/generators/disco_app/USAGE +0 -5
  346. data/lib/generators/disco_app/disco_app_generator.rb +0 -236
  347. data/lib/generators/disco_app/templates/config/newrelic.yml +0 -26
  348. data/lib/generators/disco_app/templates/initializers/rollbar.rb +0 -23
  349. data/lib/generators/disco_app/templates/initializers/session_store.rb +0 -2
  350. data/lib/generators/disco_app/templates/initializers/shopify_app.rb +0 -6
  351. data/test/dummy/config/database.gitlab-ci.yml +0 -24
  352. data/test/fixtures/api/widget_store/charges/get_accepted_application_charge_response.json +0 -16
  353. data/test/fixtures/api/widget_store/charges/get_accepted_recurring_application_charge_response.json +0 -20
  354. data/test/fixtures/api/widget_store/webhooks.json +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 00ea85f26e287b6a9f785c3e9761064244e39bc6
4
- data.tar.gz: 5564413348495e202135e4b6209c1204da54148e
2
+ SHA256:
3
+ metadata.gz: a75590acf98965732300783166f37bc5b7424d85e39b602831f6d79ac496cf9b
4
+ data.tar.gz: 4ef13a5f01e043a3464698539245bd4982a0bb82c4a20a7c4081176f795f30b6
5
5
  SHA512:
6
- metadata.gz: 56b1b6b57952ac3df28088a1866e1d79c67932bc77ea0120ba1b094645033ec877068f16b12f21fbaa54d1c335b0fa1b0a20c27c5bd59f96cc77f382be5ae006
7
- data.tar.gz: b04189e5088811e22ae96d6d1bacec8c3a6b35f200c9ef3223da11c836520474dc7c548457e0e9fa9dc6fde15a83cb84edfda6db402fab2bfd32bfebaf2cc6e7
6
+ metadata.gz: e1179214f99827a732d322c1361707625578872484baa6430a946f887750d6b5b6d299c7c0558505d743993dc38db713ee1853338cd2ebd8552d391968d761a8
7
+ data.tar.gz: d835598d84013984dfa24c565e8868e21225b166dab8ca9ea09d05b7907568ec71d8eba4ab846cc6af5f03459df82e31786094a3b5fc7f1d438469e0c2ac7138
data/Rakefile CHANGED
@@ -14,14 +14,11 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
-
21
20
  load 'rails/tasks/statistics.rake'
22
21
 
23
-
24
-
25
22
  Bundler::GemHelper.install_tasks
26
23
 
27
24
  require 'rake/testtask'
@@ -33,5 +30,4 @@ Rake::TestTask.new(:test) do |t|
33
30
  t.verbose = false
34
31
  end
35
32
 
36
-
37
33
  task default: :test
@@ -2,7 +2,7 @@ class ModelForm extends BaseForm {
2
2
 
3
3
  render() {
4
4
  const { modelTitle, modelName, modelUrl, modelsUrl, children, authenticityToken } = this.props;
5
- const errors = this.renderErrors();
5
+ const errorsElement = this.getErrorsElement();
6
6
 
7
7
  return(
8
8
  <form action={modelUrl ? modelUrl : modelsUrl} acceptCharset="UTF-8" method="POST" data-shopify-app-submit="ea.save">
@@ -10,12 +10,7 @@ class ModelForm extends BaseForm {
10
10
  <input type="hidden" name="_method" value={modelUrl ? 'patch' : 'post'} />
11
11
  <input type="hidden" name="authenticity_token" value={authenticityToken}/>
12
12
 
13
- {(() => {
14
- if (!errors) return false;
15
- return (
16
- {errors}
17
- );
18
- })()}
13
+ {errorsElement}
19
14
 
20
15
  {children}
21
16
 
File without changes
@@ -29,7 +29,8 @@ var ShopRow = (props) => {
29
29
  return (
30
30
  <tr>
31
31
  <td>
32
- <a href={editShopUrl}>{domainName}</a><br />
32
+ {domainName}
33
+ <br />
33
34
  <a href={'mailto:' + shop.attributes.email}>{shop.attributes.email}</a>
34
35
  </td>
35
36
  <td>{shop.attributes.status}</td>
@@ -5,64 +5,36 @@
5
5
  class BaseForm extends React.Component {
6
6
 
7
7
  /**
8
- * check if the field parameter has errors associated.
9
- * if no parameters are given, it checks if there's at least an error at all
10
- **/
11
- hasErrors(field) {
12
- if ((arguments.length === 0 && this.errorKeys().length > 0) ||
13
- (this.props.errors && this.props.errors.errors.indexOf(field) > -1)) {
14
- return true;
15
- }
16
- return false;
17
- }
18
-
19
- /**
20
- * returns a list of fields that contain errors
21
- **/
22
- errorKeys() {
23
- return this.props.errors.errors;
24
- }
25
-
26
- /**
27
- * returns the type of resource associate with this error
28
- **/
29
- errorType() {
30
- return this.props.errors.type;
31
- }
32
-
33
- /**
34
- * returns the error messages
35
- **/
36
- errorMessages() {
37
- return this.props.errors.messages;
38
- }
39
-
40
- /**
41
- * renders basic form errors
42
- **/
43
- renderErrors() {
44
- if (!this.hasErrors()) {
8
+ * Returns the JSX required to render a list of errors.
9
+ *
10
+ * @returns {*}
11
+ */
12
+ getErrorsElement() {
13
+ const { errors } = this.props;
14
+
15
+ // Don't render anything if no errors present.
16
+ if(!errors || !errors.errors || (errors.errors.length == 0)) {
45
17
  return null;
46
18
  }
47
19
 
48
- var title = "There " + (this.errorMessages().length == 1 ? "is" : "are") + " " + this.errorMessages().length + " error" + (this.errorMessages().length > 1 ? "s" : "") + " for this " + this.errorType() + ":";
49
- var errorMessages = this.errorMessages().map(function(message) {
50
- return <li>{message}</li>;
51
- });
20
+ const errorCount = errors.errors.length;
21
+ const singleError = (errorCount == 1);
52
22
 
53
23
  return (
54
24
  <div className="ui-banner ui-banner--status-error ui-banner--default-vertical-spacing ui-banner--default-horizontal-spacing">
55
25
  <div className="ui-banner__ribbon">
56
26
  <svg className="next-icon next-icon--24" viewBox="0 0 24 24">
57
- <path d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.6 0 12 0zm0 4c1.4 0 2.7.4 3.9 1L12 8.8 8.8 12 5 15.9c-.6-1.1-1-2.5-1-3.9 0-4.4 3.6-8 8-8zm0 16c-1.4 0-2.7-.4-3.9-1l3.9-3.9 3.2-3.2L19 8.1c.6 1.1 1 2.5 1 3.9 0 4.4-3.6 8-8 8z"></path>
27
+ <use xmlns="http://www.w3.org/1999/xlink" xlinkHref="#next-error" />
58
28
  </svg>
59
29
  </div>
60
30
  <div className="ui-banner__content">
61
31
  <h2 className="ui-banner__title">
62
- {title}
32
+ There {singleError ? 'is' : 'are'} {errorCount} error{singleError ? '' : 's'} for this {errors.type}:
63
33
  </h2>
64
34
  <ul>
65
- {errorMessages}
35
+ {errors.messages.map((message, i) => {
36
+ return <li key={i}>{message}</li>;
37
+ })}
66
38
  </ul>
67
39
  </div>
68
40
  </div>
@@ -1,6 +1,6 @@
1
- const InputCheckbox = ({ label, name, value, checked, inline, isLast, onChange, disabled = false }) => {
1
+ const InputCheckbox = ({ label, name, checked, inline, isLast, onChange, disabled = false }) => {
2
2
 
3
- const id = `${name}[${value}]`;
3
+ const id = name;
4
4
 
5
5
  const wrapperClassName = classNames({
6
6
  'next-input-wrapper': true,
@@ -16,14 +16,19 @@ const InputCheckbox = ({ label, name, value, checked, inline, isLast, onChange,
16
16
  });
17
17
 
18
18
  const handleChange = (e) => {
19
- onChange && onChange(e.target.value);
19
+ onChange && onChange(e.target.checked);
20
20
  };
21
21
 
22
22
  return(
23
23
  <div className={wrapperClassName}>
24
24
  <label htmlFor={id} className={labelClassName}>{label}</label>
25
- <input id={id} className="next-checkbox" type="checkbox" value={value} name={name} checked={checked} onChange={handleChange} disabled={disabled} />
26
- <span className="next-checkbox--styled" />
25
+ <input type="hidden" value="0" name={name} />
26
+ <input id={id} className="next-checkbox" type="checkbox" value="1" name={name} checked={checked} onChange={handleChange} disabled={disabled} />
27
+ <span className="next-checkbox--styled">
28
+ <svg className="next-icon next-icon--size-10 next-icon--blue checkmark">
29
+ <use xmlns="http://www.w3.org/1999/xlink" xlinkHref="#next-checkmark" />
30
+ </svg>
31
+ </span>
27
32
  </div>
28
33
  )
29
34
 
@@ -1,27 +1,33 @@
1
1
  require 'rest-client'
2
2
 
3
- class DiscoApp::ApiClient
3
+ module DiscoApp
4
4
 
5
- SUBSCRIPTION_ENDPOINT = 'app_subscriptions.json'
5
+ class DiscoApiError < StandardError; end
6
6
 
7
- def initialize(shop, url)
8
- @shop = shop
9
- @url = url
10
- end
7
+ class ApiClient
8
+
9
+ SUBSCRIPTION_ENDPOINT = 'app_subscriptions.json'.freeze
11
10
 
12
- def create_app_subscription
13
- return unless @url.present?
14
- url = @url + SUBSCRIPTION_ENDPOINT
15
- begin
16
- response = RestClient::Request.execute(
17
- method: :post,
18
- headers: { content_type: :json },
19
- url: url,
20
- payload: { shop: @shop, subscription: @shop.current_subscription }.to_json
21
- )
22
- rescue RestClient::BadRequest, RestClient::ResourceNotFound => e
23
- raise DiscoApiError.new(e.message)
11
+ def initialize(shop, url)
12
+ @shop = shop
13
+ @url = url
24
14
  end
25
- end
26
15
 
16
+ def create_app_subscription
17
+ return if @url.blank?
18
+
19
+ url = @url + SUBSCRIPTION_ENDPOINT
20
+ begin
21
+ RestClient::Request.execute(
22
+ method: :post,
23
+ headers: { content_type: :json },
24
+ url: url,
25
+ payload: { shop: @shop, subscription: @shop.current_subscription }.to_json
26
+ )
27
+ rescue RestClient::BadRequest, RestClient::ResourceNotFound => e
28
+ raise DiscoApiError, e.message
29
+ end
30
+ end
31
+
32
+ end
27
33
  end
@@ -0,0 +1,85 @@
1
+ require 'rest-client'
2
+
3
+ ##
4
+ # This file defines a very simple GraphQL API client to support a single type
5
+ # of GraphQL API call for a Shopify store - sending a Shopify Flow trigger.
6
+ #
7
+ # We use this simple approach rather than using an existing GraphQL client
8
+ # library such as https://github.com/github/graphql-client (either standalone
9
+ # or as bundled with the Shopify API gem) for a couple of reasons:
10
+ #
11
+ # - These libraries tend to presume that a single client instance is
12
+ # instantiated once and then reused across the application, which isn't the
13
+ # case when we're making API calls once per trigger for each background
14
+ # job.
15
+ # - These libraries make an API call to fetch the Shopify GraphQL schema on
16
+ # initialisation. The schema is very large, so the API call takes a number
17
+ # of seconds to complete and when parsed consumes a large amount of memory.
18
+ # - These libraries do not natively work well with the idea of a dynamic API
19
+ # endpoint (ie, changing the request URL frequently), which is required
20
+ # when making many requests to different Shopify stores.
21
+ #
22
+ module DiscoApp
23
+ class GraphqlClient
24
+
25
+ def initialize(shop)
26
+ @shop = shop
27
+ end
28
+
29
+ ##
30
+ # Fire a Shopify Flow Trigger.
31
+ # Returns a tuple {Boolean, Array} representing {success, errors}.
32
+ def create_flow_trigger(title, resource_name, resource_url, properties)
33
+ body = {
34
+ trigger_title: title,
35
+ resources: [
36
+ {
37
+ name: resource_name,
38
+ url: resource_url
39
+ }
40
+ ],
41
+ properties: properties
42
+ }
43
+
44
+ # The double .to_json.to_json below looks odd but is required to properly escape the JSON hash
45
+ # when inserting it into the GraphQL mutation call.
46
+ response = execute(%(
47
+ mutation {
48
+ flowTriggerReceive(body: #{body.to_json.to_json}) {
49
+ userErrors {
50
+ field,
51
+ message
52
+ }
53
+ }
54
+ }
55
+ ))
56
+
57
+ errors = response.dig(:data, :flowTriggerReceive, :userErrors)
58
+ [errors.empty?, errors]
59
+ end
60
+
61
+ private
62
+
63
+ def execute(query)
64
+ response = RestClient::Request.execute(
65
+ method: :post,
66
+ headers: headers,
67
+ url: url,
68
+ payload: { query: query }.to_json
69
+ )
70
+ JSON.parse(response.body).with_indifferent_access
71
+ end
72
+
73
+ def headers
74
+ {
75
+ 'Content-Type' => 'application/json',
76
+ 'X-Shopify-Access-Token' => @shop.shopify_token
77
+ }
78
+ end
79
+
80
+ def url
81
+ "https://#{@shop.shopify_domain}/admin/api/graphql.json"
82
+ end
83
+
84
+ end
85
+ end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Admin::AppSettingsController < DiscoApp::Admin::ApplicationController
2
+
2
3
  include DiscoApp::Admin::Concerns::AppSettingsController
4
+
3
5
  end
@@ -1,10 +1,12 @@
1
1
  class DiscoApp::Admin::ApplicationController < ActionController::Base
2
+
2
3
  include DiscoApp::Admin::Concerns::AuthenticatedController
3
4
 
4
5
  private
5
6
 
6
7
  helper_method :current_shop
7
8
  def current_shop
8
- @current_shop ||= @shop
9
+ @shop
9
10
  end
11
+
10
12
  end
@@ -1,4 +1,5 @@
1
1
  module DiscoApp::Admin::Concerns::AppSettingsController
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  def edit
@@ -7,7 +8,7 @@ module DiscoApp::Admin::Concerns::AppSettingsController
7
8
 
8
9
  def update
9
10
  @app_settings = DiscoApp::AppSettings.instance
10
- if @app_settings.update_attributes(app_settings_params)
11
+ if @app_settings.update(app_settings_params)
11
12
  flash[:success] = 'Settings updated.'
12
13
  redirect_to edit_admin_app_settings_path
13
14
  else
@@ -1,19 +1,21 @@
1
1
  module DiscoApp::Admin::Concerns::AuthenticatedController
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
-
6
6
  protect_from_forgery with: :exception
7
7
  before_action :authenticate_administrator
8
8
  layout 'admin'
9
-
10
9
  end
11
10
 
12
11
  private
13
12
 
14
13
  def authenticate_administrator
15
14
  authenticate_or_request_with_http_basic do |username, password|
16
- (not username.blank?) && (not password.blank?) && username == ENV['ADMIN_APP_USERNAME'] && password == ENV['ADMIN_APP_PASSWORD']
15
+ username.present? &&
16
+ password.present? &&
17
+ username == ENV['ADMIN_APP_USERNAME'] &&
18
+ password == ENV['ADMIN_APP_PASSWORD']
17
19
  end
18
20
  end
19
21
 
@@ -1,4 +1,5 @@
1
1
  module DiscoApp::Admin::Concerns::PlansController
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
@@ -26,7 +27,7 @@ module DiscoApp::Admin::Concerns::PlansController
26
27
  end
27
28
 
28
29
  def update
29
- if @plan.update_attributes(plan_params)
30
+ if @plan.update(plan_params)
30
31
  redirect_to edit_admin_plan_path(@plan)
31
32
  else
32
33
  render 'edit'
@@ -47,7 +48,7 @@ module DiscoApp::Admin::Concerns::PlansController
47
48
  def plan_params
48
49
  params.require(:plan).permit(
49
50
  :name, :status, :plan_type, :trial_period_days, :amount,
50
- :plan_codes_attributes => [:id, :_destroy, :code, :trial_period_days, :amount]
51
+ plan_codes_attributes: %i[id _destroy code trial_period_days amount]
51
52
  )
52
53
  end
53
54
 
@@ -1,4 +1,5 @@
1
1
  module DiscoApp::Admin::Concerns::ShopsController
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  def index
@@ -0,0 +1,52 @@
1
+ module DiscoApp::Admin::Concerns::SourcesController
2
+
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_action :find_source, only: [:edit, :update, :destroy]
7
+ end
8
+
9
+ def index
10
+ @sources = DiscoApp::Source.all
11
+ end
12
+
13
+ def new
14
+ @source = DiscoApp::Source.new
15
+ end
16
+
17
+ def create
18
+ @source = DiscoApp::Source.new(source_params)
19
+ if @source.save
20
+ redirect_to admin_sources_path
21
+ else
22
+ render 'new'
23
+ end
24
+ end
25
+
26
+ def edit
27
+ end
28
+
29
+ def update
30
+ if @source.update(source_params)
31
+ redirect_to edit_admin_plan_path(@source)
32
+ else
33
+ render 'edit'
34
+ end
35
+ end
36
+
37
+ def destroy
38
+ source.destroy
39
+ redirect_to admin_sources_path
40
+ end
41
+
42
+ private
43
+
44
+ def find_source
45
+ @source = DiscoApp::Source.find(params[:id])
46
+ end
47
+
48
+ def source_params
49
+ params.require(:source).permit(:source, :name)
50
+ end
51
+
52
+ end
@@ -1,4 +1,5 @@
1
1
  module DiscoApp::Admin::Concerns::SubscriptionsController
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
@@ -9,7 +10,7 @@ module DiscoApp::Admin::Concerns::SubscriptionsController
9
10
  end
10
11
 
11
12
  def update
12
- if @subscription.update_attributes(subscription_params)
13
+ if @subscription.update(subscription_params)
13
14
  redirect_to edit_admin_shop_subscription_path(@subscription.shop, @subscription)
14
15
  else
15
16
  render 'edit'
@@ -19,7 +20,7 @@ module DiscoApp::Admin::Concerns::SubscriptionsController
19
20
  private
20
21
 
21
22
  def find_subscription
22
- @subscription = DiscoApp::Subscription.find_by_id(params[:id])
23
+ @subscription = DiscoApp::Subscription.find_by(id: params[:id])
23
24
  end
24
25
 
25
26
  def subscription_params
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Admin::PlansController < DiscoApp::Admin::ApplicationController
2
+
2
3
  include DiscoApp::Admin::Concerns::PlansController
4
+
3
5
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Admin::Resources::ShopsController < JSONAPI::ResourceController
2
+
2
3
  include DiscoApp::Admin::Concerns::AuthenticatedController
4
+
3
5
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Admin::ShopsController < DiscoApp::Admin::ApplicationController
2
+
2
3
  include DiscoApp::Admin::Concerns::ShopsController
4
+
3
5
  end
@@ -0,0 +1,5 @@
1
+ class DiscoApp::Admin::SourcesController < DiscoApp::Admin::ApplicationController
2
+
3
+ include DiscoApp::Admin::Concerns::SourcesController
4
+
5
+ end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Admin::SubscriptionsController < DiscoApp::Admin::ApplicationController
2
+
2
3
  include DiscoApp::Admin::Concerns::SubscriptionsController
4
+
3
5
  end
@@ -1,4 +1,5 @@
1
1
  class DiscoApp::ChargesController < ApplicationController
2
+
2
3
  include DiscoApp::Concerns::AuthenticatedController
3
4
 
4
5
  skip_before_action :check_active_charge
@@ -13,20 +14,25 @@ class DiscoApp::ChargesController < ApplicationController
13
14
  # subscription. If successful, redirect to the (external) charge confirmation
14
15
  # URL. If it fails, redirect back to the new charge page.
15
16
  def create
16
- if(charge = DiscoApp::ChargesService.create(@shop, @subscription)).nil?
17
+ if (charge = DiscoApp::ChargesService.create(@shop, @subscription)).nil?
17
18
  redirect_to action: :new
18
19
  else
19
20
  redirect_to charge.confirmation_url
20
21
  end
21
22
  end
22
23
 
23
- # Attempt to activate a charge after a user has accepted or declined it.
24
+ # Attempt to activate a charge (locally) after a user has accepted or declined it.
24
25
  # Redirect to the main application's root URL immediately afterwards - if the
25
26
  # charge wasn't accepted, the flow will start again.
27
+ #
28
+ # Previously, the activation of a charge also required updating Shopify via the
29
+ # API, but that requirement has been removed.
30
+ #
31
+ # See https://shopify.dev/changelog/auto-activation-of-charges-and-subscriptions
26
32
  def activate
27
33
  # First attempt to find a matching charge.
28
- if(charge = @subscription.charges.find_by(id: params[:id], shopify_id: params[:charge_id])).nil?
29
- redirect_to action: :new and return
34
+ if (charge = @subscription.charges.find_by(id: params[:id], shopify_id: params[:charge_id])).nil?
35
+ redirect_to(action: :new) && return
30
36
  end
31
37
  if DiscoApp::ChargesService.activate(@shop, charge)
32
38
  redirect_to main_app.root_url
@@ -38,10 +44,8 @@ class DiscoApp::ChargesController < ApplicationController
38
44
  private
39
45
 
40
46
  def find_subscription
41
- @subscription = @shop.subscriptions.find_by_id!(params[:subscription_id])
42
- unless @subscription.requires_active_charge? and not @subscription.active_charge?
43
- redirect_to main_app.root_url
44
- end
47
+ @subscription = @shop.subscriptions.find_by!(id: params[:subscription_id])
48
+ redirect_to main_app.root_url unless @subscription.requires_active_charge? && !@subscription.active_charge?
45
49
  end
46
50
 
47
51
  end
@@ -1,4 +1,5 @@
1
1
  module DiscoApp::Concerns::AppProxyController
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
@@ -6,7 +7,7 @@ module DiscoApp::Concerns::AppProxyController
6
7
  before_action :shopify_shop
7
8
  after_action :add_liquid_header
8
9
 
9
- rescue_from ActiveRecord::RecordNotFound do |exception|
10
+ rescue_from ActiveRecord::RecordNotFound do |_exception|
10
11
  render_error 404
11
12
  end
12
13
  end
@@ -14,18 +15,17 @@ module DiscoApp::Concerns::AppProxyController
14
15
  private
15
16
 
16
17
  def verify_proxy_signature
17
- unless proxy_signature_is_valid?
18
- head :unauthorized
19
- end
18
+ head :unauthorized unless proxy_signature_is_valid?
20
19
  end
21
20
 
22
21
  def proxy_signature_is_valid?
23
- return true if Rails.env.development? and DiscoApp.configuration.skip_proxy_verification?
22
+ return true if (Rails.env.development? || Rails.env.test?) && DiscoApp.configuration.skip_proxy_verification?
23
+
24
24
  DiscoApp::ProxyService.proxy_signature_is_valid?(request.query_string, ShopifyApp.configuration.secret)
25
25
  end
26
26
 
27
27
  def shopify_shop
28
- @shop = DiscoApp::Shop.find_by_shopify_domain!(params[:shop])
28
+ @shop = DiscoApp::Shop.find_by!(shopify_domain: params[:shop])
29
29
  end
30
30
 
31
31
  def add_liquid_header