disco_app 0.15.2 → 0.18.1

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 (310) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -5
  3. data/app/clients/disco_app/api_client.rb +25 -19
  4. data/app/clients/disco_app/graphql_client.rb +85 -0
  5. data/app/controllers/disco_app/admin/app_settings_controller.rb +2 -0
  6. data/app/controllers/disco_app/admin/application_controller.rb +1 -0
  7. data/app/controllers/disco_app/admin/concerns/app_settings_controller.rb +2 -1
  8. data/app/controllers/disco_app/admin/concerns/authenticated_controller.rb +5 -3
  9. data/app/controllers/disco_app/admin/concerns/plans_controller.rb +3 -2
  10. data/app/controllers/disco_app/admin/concerns/shops_controller.rb +1 -0
  11. data/app/controllers/disco_app/admin/concerns/sources_controller.rb +2 -1
  12. data/app/controllers/disco_app/admin/concerns/subscriptions_controller.rb +3 -2
  13. data/app/controllers/disco_app/admin/plans_controller.rb +2 -0
  14. data/app/controllers/disco_app/admin/resources/shops_controller.rb +2 -0
  15. data/app/controllers/disco_app/admin/shops_controller.rb +2 -0
  16. data/app/controllers/disco_app/admin/sources_controller.rb +2 -0
  17. data/app/controllers/disco_app/admin/subscriptions_controller.rb +2 -0
  18. data/app/controllers/disco_app/charges_controller.rb +6 -7
  19. data/app/controllers/disco_app/concerns/app_proxy_controller.rb +6 -6
  20. data/app/controllers/disco_app/concerns/authenticated_controller.rb +26 -27
  21. data/app/controllers/disco_app/concerns/carrier_request_controller.rb +22 -11
  22. data/app/controllers/disco_app/concerns/user_authenticated_controller.rb +1 -0
  23. data/app/controllers/disco_app/concerns/webhooks_controller.rb +13 -12
  24. data/app/controllers/disco_app/flow/actions_controller.rb +9 -0
  25. data/app/controllers/disco_app/flow/concerns/actions_controller.rb +23 -0
  26. data/app/controllers/disco_app/flow/concerns/trigger_usage_controller.rb +29 -0
  27. data/app/controllers/disco_app/flow/concerns/verifies_flow_payload.rb +39 -0
  28. data/app/controllers/disco_app/flow/trigger_usage_controller.rb +9 -0
  29. data/app/controllers/disco_app/frame_controller.rb +0 -1
  30. data/app/controllers/disco_app/install_controller.rb +3 -6
  31. data/app/controllers/disco_app/subscriptions_controller.rb +12 -4
  32. data/app/controllers/disco_app/user_sessions_controller.rb +1 -0
  33. data/app/controllers/disco_app/webhooks_controller.rb +2 -0
  34. data/app/controllers/sessions_controller.rb +5 -6
  35. data/app/helpers/disco_app/application_helper.rb +7 -7
  36. data/app/jobs/disco_app/app_installed_job.rb +2 -0
  37. data/app/jobs/disco_app/app_uninstalled_job.rb +2 -0
  38. data/app/jobs/disco_app/concerns/app_installed_job.rb +2 -3
  39. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +2 -1
  40. data/app/jobs/disco_app/concerns/customers_data_request_job.rb +13 -0
  41. data/app/jobs/disco_app/concerns/customers_redact_job.rb +13 -0
  42. data/app/jobs/disco_app/concerns/render_asset_group_job.rb +1 -0
  43. data/app/jobs/disco_app/concerns/shop_redact_job.rb +13 -0
  44. data/app/jobs/disco_app/concerns/shop_update_job.rb +9 -2
  45. data/app/jobs/disco_app/concerns/subscription_changed_job.rb +2 -1
  46. data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +8 -7
  47. data/app/jobs/disco_app/concerns/synchronise_resources_job.rb +1 -0
  48. data/app/jobs/disco_app/concerns/synchronise_users_job.rb +6 -3
  49. data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +24 -11
  50. data/app/jobs/disco_app/customers_data_request_job.rb +5 -0
  51. data/app/jobs/disco_app/customers_redact_job.rb +5 -0
  52. data/app/jobs/disco_app/flow/process_action_job.rb +11 -0
  53. data/app/jobs/disco_app/flow/process_trigger_job.rb +11 -0
  54. data/app/jobs/disco_app/render_asset_group_job.rb +2 -0
  55. data/app/jobs/disco_app/shop_job.rb +10 -10
  56. data/app/jobs/disco_app/shop_redact_job.rb +5 -0
  57. data/app/jobs/disco_app/shop_update_job.rb +2 -0
  58. data/app/jobs/disco_app/subscription_changed_job.rb +2 -0
  59. data/app/jobs/disco_app/synchronise_carrier_service_job.rb +2 -0
  60. data/app/jobs/disco_app/synchronise_resources_job.rb +2 -0
  61. data/app/jobs/disco_app/synchronise_users_job.rb +2 -0
  62. data/app/jobs/disco_app/synchronise_webhooks_job.rb +2 -0
  63. data/app/models/application_record.rb +2 -0
  64. data/app/models/disco_app/app_settings.rb +2 -0
  65. data/app/models/disco_app/application_charge.rb +1 -1
  66. data/app/models/disco_app/concerns/app_settings.rb +2 -0
  67. data/app/models/disco_app/concerns/can_be_liquified.rb +29 -14
  68. data/app/models/disco_app/concerns/has_metafields.rb +1 -2
  69. data/app/models/disco_app/concerns/plan.rb +3 -4
  70. data/app/models/disco_app/concerns/plan_code.rb +1 -2
  71. data/app/models/disco_app/concerns/renders_assets.rb +15 -21
  72. data/app/models/disco_app/concerns/shop.rb +20 -14
  73. data/app/models/disco_app/concerns/source.rb +2 -3
  74. data/app/models/disco_app/concerns/subscription.rb +3 -3
  75. data/app/models/disco_app/concerns/synchronises.rb +10 -15
  76. data/app/models/disco_app/concerns/taggable.rb +1 -0
  77. data/app/models/disco_app/concerns/user.rb +3 -2
  78. data/app/models/disco_app/flow/action.rb +9 -0
  79. data/app/models/disco_app/flow/concerns/action.rb +27 -0
  80. data/app/models/disco_app/flow/concerns/trigger.rb +28 -0
  81. data/app/models/disco_app/flow/concerns/trigger_usage.rb +17 -0
  82. data/app/models/disco_app/flow/trigger.rb +9 -0
  83. data/app/models/disco_app/flow/trigger_usage.rb +9 -0
  84. data/app/models/disco_app/plan.rb +2 -0
  85. data/app/models/disco_app/plan_code.rb +2 -0
  86. data/app/models/disco_app/session_storage.rb +5 -2
  87. data/app/models/disco_app/shop.rb +2 -0
  88. data/app/models/disco_app/source.rb +2 -0
  89. data/app/models/disco_app/subscription.rb +2 -0
  90. data/app/models/disco_app/user.rb +2 -0
  91. data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +12 -15
  92. data/app/resources/disco_app/admin/resources/shop_resource.rb +1 -0
  93. data/app/services/disco_app/carrier_request_service.rb +3 -3
  94. data/app/services/disco_app/charges_service.rb +26 -34
  95. data/app/services/disco_app/flow/create_action.rb +35 -0
  96. data/app/services/disco_app/flow/create_trigger.rb +34 -0
  97. data/app/services/disco_app/flow/process_action.rb +50 -0
  98. data/app/services/disco_app/flow/process_trigger.rb +72 -0
  99. data/app/services/disco_app/flow/update_trigger_usage.rb +42 -0
  100. data/app/services/disco_app/partner_app_service.rb +1 -1
  101. data/app/services/disco_app/proxy_service.rb +2 -2
  102. data/app/services/disco_app/request_validation_service.rb +2 -2
  103. data/app/services/disco_app/subscription_service.rb +60 -32
  104. data/app/services/disco_app/webhook_service.rb +9 -11
  105. data/app/views/layouts/admin.html.erb +1 -2
  106. data/app/views/layouts/application.html.erb +1 -2
  107. data/app/views/layouts/embedded_app.html.erb +2 -4
  108. data/app/views/layouts/embedded_app_modal.html.erb +2 -3
  109. data/app/views/shopify_app/sessions/new.html.erb +2 -4
  110. data/config/routes.rb +11 -3
  111. data/db/migrate/20150525000000_create_shops_if_not_existent.rb +80 -80
  112. data/db/migrate/20170315062548_create_disco_app_sources.rb +2 -0
  113. data/db/migrate/20170315062629_add_sources_to_shop_subscriptions.rb +3 -1
  114. data/db/migrate/20170327214540_create_disco_app_users.rb +2 -1
  115. data/db/migrate/20170606160751_fix_disco_app_users_index.rb +2 -0
  116. data/db/migrate/20181229100327_create_flow_actions_and_triggers.rb +32 -0
  117. data/db/migrate/20200405000000_create_flow_trigger_usages.rb +16 -0
  118. data/lib/disco_app/configuration.rb +12 -5
  119. data/lib/disco_app/constants.rb +4 -2
  120. data/lib/disco_app/engine.rb +1 -1
  121. data/lib/disco_app/session.rb +1 -0
  122. data/lib/disco_app/support/file_fixtures.rb +2 -1
  123. data/lib/disco_app/version.rb +3 -1
  124. data/lib/generators/disco_app/install/USAGE +5 -0
  125. data/lib/generators/disco_app/install/install_generator.rb +297 -0
  126. data/lib/generators/disco_app/{templates → install/templates}/assets/javascripts/application.js +0 -0
  127. data/lib/generators/disco_app/{templates → install/templates}/assets/javascripts/components.js +0 -0
  128. data/lib/generators/disco_app/{templates → install/templates}/assets/stylesheets/application.scss +0 -0
  129. data/lib/generators/disco_app/install/templates/config/appsignal.yml +12 -0
  130. data/lib/generators/disco_app/install/templates/config/cable.yml.tt +11 -0
  131. data/lib/generators/disco_app/{templates → install/templates}/config/database.yml.tt +6 -3
  132. data/lib/generators/disco_app/install/templates/config/environments/staging.rb +108 -0
  133. data/lib/generators/disco_app/{templates → install/templates}/config/puma.rb +0 -0
  134. data/lib/generators/disco_app/{templates → install/templates}/controllers/home_controller.rb +1 -0
  135. data/lib/generators/disco_app/{templates → install/templates}/initializers/disco_app.rb +5 -0
  136. data/lib/generators/disco_app/install/templates/initializers/session_store.rb +2 -0
  137. data/lib/generators/disco_app/install/templates/initializers/shopify_app.rb +11 -0
  138. data/lib/generators/disco_app/{templates → install/templates}/initializers/shopify_session_repository.rb +0 -0
  139. data/lib/generators/disco_app/install/templates/initializers/timber.rb +4 -0
  140. data/lib/generators/disco_app/{templates → install/templates}/root/.editorconfig +0 -0
  141. data/lib/generators/disco_app/{templates → install/templates}/root/.env +7 -0
  142. data/lib/generators/disco_app/{templates → install/templates}/root/.env.local +4 -0
  143. data/lib/generators/disco_app/{templates → install/templates}/root/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  144. data/lib/generators/disco_app/{templates → install/templates}/root/.gitignore +6 -0
  145. data/lib/generators/disco_app/install/templates/root/.rspec +1 -0
  146. data/lib/generators/disco_app/{templates → install/templates}/root/.rubocop.yml +315 -217
  147. data/lib/generators/disco_app/install/templates/root/.tool-versions +2 -0
  148. data/lib/generators/disco_app/{templates → install/templates}/root/CHECKS +0 -0
  149. data/lib/generators/disco_app/{templates → install/templates}/root/Procfile +0 -0
  150. data/lib/generators/disco_app/{templates → install/templates}/root/README.md +0 -0
  151. data/lib/generators/disco_app/install/templates/root/package.json.tt +17 -0
  152. data/lib/generators/disco_app/install/templates/spec/rails_helper.rb +40 -0
  153. data/lib/generators/disco_app/install/templates/spec/spec_helper.rb +24 -0
  154. data/lib/generators/disco_app/install/templates/spec/support/active_job.rb +13 -0
  155. data/lib/generators/disco_app/install/templates/spec/support/coveralls.rb +3 -0
  156. data/lib/generators/disco_app/install/templates/spec/support/database_cleaner.rb +17 -0
  157. data/lib/generators/disco_app/install/templates/spec/support/factory_bot.rb +3 -0
  158. data/lib/generators/disco_app/install/templates/spec/support/helpers/json_helper.rb +13 -0
  159. data/lib/generators/disco_app/install/templates/spec/support/shared_examples/a_synchronise_job.rb +12 -0
  160. data/lib/generators/disco_app/install/templates/spec/support/shoulda.rb +6 -0
  161. data/lib/generators/disco_app/install/templates/spec/support/vcr.rb +14 -0
  162. data/lib/generators/disco_app/install/templates/spec/support/webmock.rb +8 -0
  163. data/lib/generators/disco_app/{templates → install/templates}/views/home/index.html.erb +0 -0
  164. data/lib/generators/disco_app/react/USAGE +5 -0
  165. data/lib/generators/disco_app/react/react_generator.rb +108 -0
  166. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/base_controller.rb +18 -0
  167. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/home_controller.rb +10 -0
  168. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/shops_controller.rb +11 -0
  169. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/users_controller.rb +11 -0
  170. data/lib/generators/disco_app/react/templates/app/controllers/embedded/home_controller.rb +13 -0
  171. data/lib/generators/disco_app/react/templates/app/models/api_response.rb +107 -0
  172. data/lib/generators/disco_app/react/templates/app/serializers/disco_app/shop_serializer.rb +13 -0
  173. data/lib/generators/disco_app/react/templates/app/serializers/disco_app/user_serializer.rb +13 -0
  174. data/lib/generators/disco_app/react/templates/app/serializers/empty_serializer.rb +5 -0
  175. data/lib/generators/disco_app/react/templates/app/serializers/error_serializer.rb +76 -0
  176. data/lib/generators/disco_app/react/templates/app/views/embedded/home/index.html.erb +12 -0
  177. data/lib/generators/disco_app/react/templates/app/views/layouts/embedded.html.erb +10 -0
  178. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/App.jsx +77 -0
  179. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/HomePage.jsx +34 -0
  180. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/EmbeddedPage.jsx +70 -0
  181. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/ErrorBanner.jsx +58 -0
  182. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/PaginationWrapper.jsx +10 -0
  183. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/ScrollToTop.jsx +23 -0
  184. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/withApi.jsx +125 -0
  185. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/index.jsx +39 -0
  186. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/utils.js +19 -0
  187. data/lib/generators/disco_app/react/templates/app/webpack/packs/embedded.js +2 -0
  188. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/banners.scss +7 -0
  189. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/busy.scss +3 -0
  190. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/index.scss +3 -0
  191. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/pagination.scss +5 -0
  192. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded.scss +2 -0
  193. data/lib/generators/disco_app/react/templates/config/initializers/mime_types.rb +13 -0
  194. data/lib/generators/disco_app/react/templates/config/initializers/omniauth.rb +27 -0
  195. data/lib/generators/disco_app/react/templates/config/initializers/version.rb.tt +7 -0
  196. data/lib/generators/disco_app/react/templates/config/webpack/staging.js +5 -0
  197. data/lib/generators/disco_app/react/templates/config/webpack/test.js +5 -0
  198. data/lib/generators/disco_app/react/templates/config/webpacker.yml +96 -0
  199. data/lib/generators/disco_app/react/templates/root/.eslintignore +5 -0
  200. data/lib/generators/disco_app/react/templates/root/.eslintrc +69 -0
  201. data/lib/generators/disco_app/react/templates/root/.prettierrc +3 -0
  202. data/lib/generators/disco_app/react/templates/root/VERSION +1 -0
  203. data/lib/generators/disco_app/react/templates/root/babel.config.js +72 -0
  204. data/lib/generators/disco_app/react/templates/root/package.json.tt +84 -0
  205. data/lib/generators/disco_app/react/templates/root/postcss.config.js +14 -0
  206. data/lib/tasks/api.rake +0 -2
  207. data/lib/tasks/carrier_service.rake +0 -2
  208. data/lib/tasks/database.rake +1 -1
  209. data/lib/tasks/sessions.rake +0 -2
  210. data/lib/tasks/shops.rake +0 -2
  211. data/lib/tasks/users.rake +0 -2
  212. data/lib/tasks/webhooks.rake +0 -2
  213. data/test/clients/disco_app/api_client_test.rb +3 -3
  214. data/test/controllers/disco_app/admin/shops_controller_test.rb +1 -0
  215. data/test/controllers/disco_app/charges_controller_test.rb +8 -9
  216. data/test/controllers/disco_app/flow/trigger_usage_controller_test.rb +41 -0
  217. data/test/controllers/disco_app/install_controller_test.rb +2 -1
  218. data/test/controllers/disco_app/subscriptions_controller_test.rb +2 -1
  219. data/test/controllers/disco_app/webhooks_controller_test.rb +1 -0
  220. data/test/controllers/home_controller_test.rb +1 -1
  221. data/test/disco_app_test.rb +3 -1
  222. data/test/dummy/Rakefile +1 -1
  223. data/test/dummy/app/assets/config/manifest.js +2 -0
  224. data/test/dummy/app/controllers/application_controller.rb +2 -0
  225. data/test/dummy/app/controllers/carrier_request_controller.rb +1 -0
  226. data/test/dummy/app/controllers/disco_app/admin/shops_controller.rb +1 -0
  227. data/test/dummy/app/controllers/home_controller.rb +1 -0
  228. data/test/dummy/app/controllers/proxy_controller.rb +1 -0
  229. data/test/dummy/app/javascript/packs/application.js +18 -0
  230. data/test/dummy/app/jobs/disco_app/app_installed_job.rb +2 -3
  231. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +1 -0
  232. data/test/dummy/app/models/application_record.rb +2 -0
  233. data/test/dummy/app/models/cart.rb +4 -3
  234. data/test/dummy/app/models/disco_app/shop.rb +4 -5
  235. data/test/dummy/app/models/js_configuration.rb +1 -0
  236. data/test/dummy/app/models/product.rb +3 -2
  237. data/test/dummy/app/models/widget_configuration.rb +1 -0
  238. data/test/dummy/babel.config.js +72 -0
  239. data/test/dummy/bin/bundle +1 -1
  240. data/test/dummy/bin/rails +1 -1
  241. data/test/dummy/bin/setup +8 -8
  242. data/test/dummy/bin/webpack +19 -0
  243. data/test/dummy/bin/webpack-dev-server +19 -0
  244. data/test/dummy/config/application.rb +4 -3
  245. data/test/dummy/config/boot.rb +2 -2
  246. data/test/dummy/config/database.yml +3 -0
  247. data/test/dummy/config/environment.rb +1 -1
  248. data/test/dummy/config/environments/staging.rb +85 -0
  249. data/test/dummy/config/initializers/disco_app.rb +8 -1
  250. data/test/dummy/config/initializers/omniauth.rb +3 -4
  251. data/test/dummy/config/initializers/session_store.rb +1 -1
  252. data/test/dummy/config/initializers/shopify_app.rb +1 -0
  253. data/test/dummy/config/routes.rb +0 -2
  254. data/test/dummy/config/secrets.yml +3 -0
  255. data/test/dummy/config/webpack/development.js +5 -0
  256. data/test/dummy/config/webpack/environment.js +3 -0
  257. data/test/dummy/config/webpack/production.js +5 -0
  258. data/test/dummy/config/webpack/test.js +5 -0
  259. data/test/dummy/config/webpacker.yml +95 -0
  260. data/test/dummy/db/migrate/20160307182229_create_products.rb +3 -1
  261. data/test/dummy/db/migrate/20160530160739_create_asset_models.rb +3 -1
  262. data/test/dummy/db/migrate/20161105054746_create_carts.rb +2 -1
  263. data/test/dummy/db/schema.rb +45 -6
  264. data/test/dummy/package.json +8 -0
  265. data/test/dummy/postcss.config.js +12 -0
  266. data/test/dummy/yarn.lock +7244 -0
  267. data/test/fixtures/api/subscriptions/valid_request.json +1 -1
  268. data/test/fixtures/api/widget_store/empty_webhooks.json +3 -0
  269. data/test/fixtures/api/widget_store/existing_webhooks.json +43 -0
  270. data/test/fixtures/disco_app/shops.yml +3 -0
  271. data/test/fixtures/webhooks/flow/trigger_usage.json +7 -0
  272. data/test/integration/synchronises_test.rb +2 -1
  273. data/test/jobs/disco_app/app_installed_job_test.rb +28 -9
  274. data/test/jobs/disco_app/app_uninstalled_job_test.rb +5 -2
  275. data/test/jobs/disco_app/send_subscription_job_test.rb +3 -2
  276. data/test/jobs/disco_app/synchronise_carrier_service_job_test.rb +1 -0
  277. data/test/jobs/disco_app/synchronise_users_job_test.rb +1 -0
  278. data/test/jobs/disco_app/synchronise_webhooks_job_test.rb +70 -13
  279. data/test/models/disco_app/can_be_liquified_test.rb +3 -1
  280. data/test/models/disco_app/has_metafields_test.rb +37 -18
  281. data/test/models/disco_app/renders_assets_test.rb +2 -1
  282. data/test/models/disco_app/session_test.rb +2 -2
  283. data/test/models/disco_app/shop_test.rb +1 -1
  284. data/test/services/disco_app/charges_service_test.rb +7 -8
  285. data/test/services/disco_app/flow/create_action_test.rb +51 -0
  286. data/test/services/disco_app/flow/create_trigger_test.rb +56 -0
  287. data/test/services/disco_app/flow/process_action_test.rb +68 -0
  288. data/test/services/disco_app/flow/process_trigger_test.rb +94 -0
  289. data/test/services/disco_app/flow/update_trigger_usage_test.rb +87 -0
  290. data/test/services/disco_app/subscription_service_test.rb +3 -2
  291. data/test/support/test_file_fixtures.rb +2 -2
  292. data/test/support/test_shopify_api.rb +1 -1
  293. data/test/test_helper.rb +10 -7
  294. data/test/vcr/flow_trigger_invalid_title.yml +35 -0
  295. data/test/vcr/flow_trigger_valid.yml +38 -0
  296. data/test/vcr/webhook_failure.yml +13 -13
  297. metadata +282 -148
  298. data/app/clients/disco_app/disco_api_error.rb +0 -2
  299. data/app/clients/disco_app/rollbar_client.rb +0 -53
  300. data/app/clients/disco_app/rollbar_client_error.rb +0 -2
  301. data/lib/generators/disco_app/USAGE +0 -5
  302. data/lib/generators/disco_app/disco_app_generator.rb +0 -236
  303. data/lib/generators/disco_app/templates/config/newrelic.yml +0 -26
  304. data/lib/generators/disco_app/templates/initializers/rollbar.rb +0 -23
  305. data/lib/generators/disco_app/templates/initializers/session_store.rb +0 -2
  306. data/lib/generators/disco_app/templates/initializers/shopify_app.rb +0 -6
  307. data/lib/generators/disco_app/templates/root/.codeclimate.yml +0 -7
  308. data/lib/generators/disco_app/templates/root/.ruby-version +0 -1
  309. data/lib/tasks/rollbar.rake +0 -24
  310. data/test/fixtures/api/widget_store/webhooks.json +0 -1
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+ require 'interactor'
3
+
4
+ class TestActionId
5
+
6
+ include Interactor
7
+
8
+ def call
9
+ # noop
10
+ end
11
+
12
+ end
13
+
14
+ module DiscoApp
15
+ module Flow
16
+ class ProcessActionTest < ActiveSupport::TestCase
17
+
18
+ include ActiveJob::TestHelper
19
+
20
+ def setup
21
+ @shop = disco_app_shops(:widget_store)
22
+ @action = @shop.flow_actions.create(
23
+ action_id: 'test_action_id',
24
+ action_run_id: 'bdb15e45-4f9d-4c80-88c8-7b43a24edaac-30892-cc8eb62a-14db-43fc-bc33-d6dea41ae623',
25
+ properties: { 'customer_email' => 'name@example.com' }
26
+ )
27
+ @now = Time.zone.parse('2018-12-29T00:00:00Z')
28
+ Timecop.freeze(@now)
29
+ end
30
+
31
+ def teardown
32
+ @shop = nil
33
+ @action = nil
34
+ @now = nil
35
+ Timecop.return
36
+ end
37
+
38
+ test 'call to process action that has already succeeded fails' do
39
+ @action.succeeded!
40
+ result = ProcessAction.call(action: @action)
41
+ assert_not result.success?
42
+ end
43
+
44
+ test 'call to process trigger that has already failed fails' do
45
+ @action.failed!
46
+ result = ProcessAction.call(action: @action)
47
+ assert_not result.success?
48
+ end
49
+
50
+ test 'processing pending action with existing service class succeeds' do
51
+ result = ProcessAction.call(action: @action)
52
+ assert result.success?
53
+ assert @action.succeeded?
54
+ assert_equal @now, @action.processed_at
55
+ end
56
+
57
+ test 'processing pending action with non-existent service class does not succeed' do
58
+ @action.update!(action_id: 'unknown_test_action_id')
59
+ result = ProcessAction.call(action: @action)
60
+ assert_not result.success?
61
+ assert @action.failed?
62
+ assert_equal @now, @action.processed_at
63
+ assert_equal ['Could not find service class for unknown_test_action_id'], @action.processing_errors
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,94 @@
1
+ require 'test_helper'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class ProcessTriggerTest < ActiveSupport::TestCase
6
+
7
+ include ActiveJob::TestHelper
8
+
9
+ def setup
10
+ @shop = disco_app_shops(:widget_store)
11
+ @trigger = @shop.flow_triggers.create(
12
+ title: 'Test trigger',
13
+ resource_name: 'test_resource_name',
14
+ resource_url: 'https://example.com/test-resource-url',
15
+ properties: { 'Customer email' => 'name@example.com' }
16
+ )
17
+ @now = Time.zone.parse('2018-12-29T00:00:00Z')
18
+ Timecop.freeze(@now)
19
+ end
20
+
21
+ def teardown
22
+ @shop = nil
23
+ @trigger = nil
24
+ @now = nil
25
+ Timecop.return
26
+ end
27
+
28
+ test 'call to process trigger that has already succeeded fails' do
29
+ @trigger.succeeded!
30
+ result = ProcessTrigger.call(trigger: @trigger)
31
+ assert_not result.success?
32
+ end
33
+
34
+ test 'call to process trigger that has already failed fails' do
35
+ @trigger.failed!
36
+ result = ProcessTrigger.call(trigger: @trigger)
37
+ assert_not result.success?
38
+ end
39
+
40
+ test 'call to process trigger that has already been skipped fails' do
41
+ @trigger.skipped!
42
+ result = ProcessTrigger.call(trigger: @trigger)
43
+ assert_not result.success?
44
+ end
45
+
46
+ test 'call to process trigger that we know is not being used succeeds with skipped status logged' do
47
+ @shop.flow_trigger_usages.create(
48
+ flow_trigger_definition_id: @trigger.title,
49
+ has_enabled_flow: false,
50
+ timestamp: @now
51
+ )
52
+ result = ProcessTrigger.call(trigger: @trigger)
53
+ assert result.success?
54
+ assert @trigger.skipped?
55
+ assert_equal @now, @trigger.processed_at
56
+ end
57
+
58
+ test 'processing valid pending trigger succeeds and makes the expected api call' do
59
+ VCR.use_cassette('flow_trigger_valid') do
60
+ result = ProcessTrigger.call(trigger: @trigger)
61
+ assert result.success?
62
+ assert @trigger.succeeded?
63
+ assert_equal @now, @trigger.processed_at
64
+ end
65
+ end
66
+
67
+ test 'processing valid pending trigger that we know is being used succeeds and makes the expected api call' do
68
+ @shop.flow_trigger_usages.create(
69
+ flow_trigger_definition_id: @trigger.title,
70
+ has_enabled_flow: true,
71
+ timestamp: @now
72
+ )
73
+
74
+ VCR.use_cassette('flow_trigger_valid') do
75
+ result = ProcessTrigger.call(trigger: @trigger)
76
+ assert result.success?
77
+ assert @trigger.succeeded?
78
+ assert_equal @now, @trigger.processed_at
79
+ end
80
+ end
81
+
82
+ test 'processing invalid pending trigger makes the expected api call with errors logged' do
83
+ VCR.use_cassette('flow_trigger_invalid_title') do
84
+ result = ProcessTrigger.call(trigger: @trigger)
85
+ assert_not result.success?
86
+ assert @trigger.failed?
87
+ assert_equal @now, @trigger.processed_at
88
+ assert_equal 1, @trigger.processing_errors.size
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,87 @@
1
+ require 'test_helper'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class UpdateTriggerUsageTest < ActiveSupport::TestCase
6
+
7
+ include ActiveJob::TestHelper
8
+
9
+ def setup
10
+ @shop = disco_app_shops(:widget_store)
11
+ end
12
+
13
+ def teardown
14
+ @shop = nil
15
+ end
16
+
17
+ test 'when no usage record exists and usage is true, record is persisted as expected' do
18
+ result = UpdateTriggerUsage.call(
19
+ shop: @shop,
20
+ flow_trigger_definition_id: flow_trigger_definition_id,
21
+ has_enabled_flow: true,
22
+ timestamp: timestamp
23
+ )
24
+
25
+ assert result.success?
26
+ assert result.trigger_usage.persisted?
27
+ assert result.trigger_usage.has_enabled_flow?
28
+ assert_equal timestamp, result.trigger_usage.timestamp
29
+ end
30
+
31
+ test 'when usage record exists and timestamp is older, record is updated as expected' do
32
+ older_timestamp = timestamp - 7.days
33
+
34
+ trigger_usage = @shop.flow_trigger_usages.create!(
35
+ flow_trigger_definition_id: flow_trigger_definition_id,
36
+ has_enabled_flow: true,
37
+ timestamp: older_timestamp
38
+ )
39
+
40
+ result = UpdateTriggerUsage.call(
41
+ shop: @shop,
42
+ flow_trigger_definition_id: flow_trigger_definition_id,
43
+ has_enabled_flow: false,
44
+ timestamp: timestamp
45
+ )
46
+
47
+ assert result.success?
48
+ assert_equal trigger_usage, result.trigger_usage
49
+ assert_not result.trigger_usage.has_enabled_flow?
50
+ assert_equal timestamp, result.trigger_usage.timestamp
51
+ end
52
+
53
+ test 'when usage record exists and timestamp is newer, record is not updated' do
54
+ newer_timestamp = timestamp + 7.days
55
+
56
+ trigger_usage = @shop.flow_trigger_usages.create!(
57
+ flow_trigger_definition_id: flow_trigger_definition_id,
58
+ has_enabled_flow: true,
59
+ timestamp: newer_timestamp
60
+ )
61
+
62
+ result = UpdateTriggerUsage.call(
63
+ shop: @shop,
64
+ flow_trigger_definition_id: flow_trigger_definition_id,
65
+ has_enabled_flow: false,
66
+ timestamp: timestamp
67
+ )
68
+
69
+ assert result.success?
70
+ assert_equal trigger_usage, result.trigger_usage
71
+ assert result.trigger_usage.has_enabled_flow?
72
+ assert_equal newer_timestamp, result.trigger_usage.timestamp
73
+ end
74
+
75
+ private
76
+
77
+ def flow_trigger_definition_id
78
+ 'Test trigger'
79
+ end
80
+
81
+ def timestamp
82
+ @timestamp ||= Time.parse('2020-04-05T00:34:00Z')
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -1,6 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class DiscoApp::SubscriptionServiceTest < ActiveSupport::TestCase
4
+
4
5
  include ActiveJob::TestHelper
5
6
 
6
7
  def setup
@@ -44,14 +45,14 @@ class DiscoApp::SubscriptionServiceTest < ActiveSupport::TestCase
44
45
  test 'new subscription for a plan with a trial period created correctly' do
45
46
  new_subscription = DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium))
46
47
  assert new_subscription.trial?
47
- assert_equal Time.now, new_subscription.trial_start_at
48
+ assert_equal Time.zone.now, new_subscription.trial_start_at
48
49
  assert_equal 28.days.from_now, new_subscription.trial_end_at
49
50
  end
50
51
 
51
52
  test 'new subscription for a plan with a plan code created correctly' do
52
53
  new_subscription = DiscoApp::SubscriptionService.subscribe(@shop, disco_app_plans(:premium), 'PODCAST')
53
54
  assert new_subscription.trial?
54
- assert_equal Time.now, new_subscription.trial_start_at
55
+ assert_equal Time.zone.now, new_subscription.trial_start_at
55
56
  assert_equal 60.days.from_now, new_subscription.trial_end_at
56
57
  assert_equal 60, new_subscription.trial_period_days
57
58
  assert_equal 8999, new_subscription.amount
@@ -10,13 +10,13 @@ module DiscoApp::Test
10
10
  # Return a JSON fixture as an indifferent hash.
11
11
  def json_fixture(path)
12
12
  filename = File.join(File.dirname(File.dirname(__FILE__)), 'fixtures', 'json', "#{path}.json")
13
- HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(File.read(filename)))
13
+ HashWithIndifferentAccess.new(JSON.parse(File.read(filename)))
14
14
  end
15
15
 
16
16
  # API fixtures are special-case JSON fixtures.
17
17
  def api_fixture(path)
18
18
  filename = File.join(File.dirname(File.dirname(__FILE__)), 'fixtures', 'api', "#{path}.json")
19
- HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(File.read(filename)))
19
+ HashWithIndifferentAccess.new(JSON.parse(File.read(filename)))
20
20
  end
21
21
 
22
22
  # Webhook fixtures are special-case JSON fixtures.
@@ -5,7 +5,7 @@ module DiscoApp::Test
5
5
  if method == :get
6
6
  stub_request(method, endpoint)
7
7
  .to_return(status: 200, body: api_fixture("#{fixture_name}_response").to_json)
8
- elsif method == :post or method == :put
8
+ elsif (method == :post) || (method == :put)
9
9
  stub_request(method, endpoint)
10
10
  .with(body: api_fixture("#{fixture_name}_request").to_json)
11
11
  .to_return(status: 201, body: api_fixture("#{fixture_name}_response").to_json)
data/test/test_helper.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # Prevent warnings from showing up during testing.
2
- $VERBOSE=nil
2
+ $VERBOSE = nil
3
3
 
4
4
  # Configure Rails Environment
5
5
  ENV['RAILS_ENV'] = 'test'
@@ -11,11 +11,12 @@ ENV['SHOPIFY_APP_REDIRECT_URI'] = 'https://test.example.com/shopify/auth/callbac
11
11
  ENV['SHOPIFY_APP_SCOPE'] = 'read_products'
12
12
  ENV['SHOPIFY_CHARGES_REAL'] = 'false'
13
13
  ENV['DISCO_API_URL'] = 'https://api.discolabs.com/v1/'
14
+ ENV['SHOPIFY_APP_API_VERSION'] = '2019-10'
14
15
 
15
- require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
16
- ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
17
- ActiveRecord::Migrator.migrations_paths << File.expand_path('../../db/migrate', __FILE__)
18
- require "rails/test_help"
16
+ require File.expand_path('../test/dummy/config/environment.rb', __dir__)
17
+ ActiveRecord::Migrator.migrations_paths = [File.expand_path('../test/dummy/db/migrate', __dir__)]
18
+ ActiveRecord::Migrator.migrations_paths << File.expand_path('../db/migrate', __dir__)
19
+ require 'rails/test_help'
19
20
 
20
21
  # Require our additional test support helpers.
21
22
  require 'support/test_file_fixtures'
@@ -33,7 +34,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
33
34
 
34
35
  # Load fixtures from the engine
35
36
  if ActiveSupport::TestCase.respond_to?(:fixture_path=)
36
- ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
37
+ ActiveSupport::TestCase.fixture_path = File.expand_path('fixtures', __dir__)
37
38
  ActiveSupport::TestCase.fixtures :all
38
39
  end
39
40
 
@@ -48,7 +49,7 @@ end
48
49
  # Minitest helpers to give a better formatted and more helpful output in Rubymine
49
50
  require 'minitest/reporters'
50
51
  require 'minitest/autorun'
51
- MiniTest::Reporters.use!
52
+ MiniTest::Reporters.use! Minitest::Reporters::SpecReporter.new
52
53
 
53
54
  # Set up the base test class.
54
55
  class ActiveSupport::TestCase
@@ -61,11 +62,13 @@ class ActiveSupport::TestCase
61
62
  def log_in_as(shop)
62
63
  session[:shopify] = shop.id
63
64
  session[:shopify_domain] = shop.shopify_domain
65
+ session[:api_version] = shop.api_version
64
66
  end
65
67
 
66
68
  def log_out
67
69
  session[:shopify] = nil
68
70
  session[:shopify_domain] = nil
71
+ session[:api_version] = nil
69
72
  end
70
73
 
71
74
  end
@@ -0,0 +1,35 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://widgets.myshopify.com/admin/api/graphql.json
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"query":"\n mutation {\n flowTriggerReceive(body: \"{\\\"trigger_title\\\":\\\"Test trigger\\\",\\\"resources\\\":[{\\\"name\\\":\\\"test_resource_name\\\",\\\"url\\\":\\\"https://example.com/test-resource-url\\\"}],\\\"properties\\\":{\\\"Customer email\\\":\\\"name@example.com\\\"}}\") {\n userErrors {\n field,\n message\n }\n }\n }\n "}'
9
+ headers:
10
+ Accept:
11
+ - "*/*"
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ X-Shopify-Access-Token:
17
+ - 00000000000000000000000000000000
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx
25
+ Date:
26
+ - Sat, 29 Dec 2018 11:44:11 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ body:
30
+ encoding: ASCII-8BIT
31
+ string: '{"data":{"flowTriggerReceive":{"userErrors":[{"field":["body"],"message":"Errors
32
+ validating schema:\n Invalid trigger_title ''Test trigger''.\n"}]}},"extensions":{"cost":{"requestedQueryCost":1,"actualQueryCost":1,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1999,"restoreRate":100.0}}}}'
33
+ http_version:
34
+ recorded_at: Sat, 29 Dec 2018 11:44:11 GMT
35
+ recorded_with: VCR 3.0.3
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://widgets.myshopify.com/admin/api/graphql.json
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"query":"\n mutation {\n flowTriggerReceive(body: \"{\\\"trigger_title\\\":\\\"Test trigger\\\",\\\"resources\\\":[{\\\"name\\\":\\\"test_resource_name\\\",\\\"url\\\":\\\"https://example.com/test-resource-url\\\"}],\\\"properties\\\":{\\\"Customer email\\\":\\\"name@example.com\\\"}}\") {\n userErrors {\n field,\n message\n }\n }\n }\n "}'
9
+ headers:
10
+ Accept:
11
+ - "*/*"
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ X-Shopify-Access-Token:
17
+ - 00000000000000000000000000000000
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx
25
+ Date:
26
+ - Sat, 29 Dec 2018 11:46:27 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ body:
34
+ encoding: ASCII-8BIT
35
+ string: '{"data":{"flowTriggerReceive":{"userErrors":[]}},"extensions":{"cost":{"requestedQueryCost":1,"actualQueryCost":1,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1999,"restoreRate":100.0}}}}'
36
+ http_version:
37
+ recorded_at: Sat, 29 Dec 2018 11:46:27 GMT
38
+ recorded_with: VCR 3.0.3
@@ -2,7 +2,7 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://widgets.myshopify.com/admin/webhooks.json
5
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
6
6
  body:
7
7
  encoding: US-ASCII
8
8
  string: ''
@@ -95,10 +95,10 @@ http_interactions:
95
95
  recorded_at: Sun, 07 Jan 2018 22:02:25 GMT
96
96
  - request:
97
97
  method: post
98
- uri: https://widgets.myshopify.com/admin/webhooks.json
98
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
99
99
  body:
100
100
  encoding: UTF-8
101
- string: '{"webhook":{"topic":"app/uninstalled","address":"https://test.example.com/webhooks","format":"json"}}'
101
+ string: '{"webhook":{"topic":"app/uninstalled","fields":[],"address":"https://test.example.com/webhooks","format":"json"}}'
102
102
  headers:
103
103
  Content-Type:
104
104
  - application/json
@@ -185,10 +185,10 @@ http_interactions:
185
185
  recorded_at: Sun, 07 Jan 2018 22:02:26 GMT
186
186
  - request:
187
187
  method: post
188
- uri: https://widgets.myshopify.com/admin/webhooks.json
188
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
189
189
  body:
190
190
  encoding: UTF-8
191
- string: '{"webhook":{"topic":"shop/update","address":"https://test.example.com/webhooks","format":"json"}}'
191
+ string: '{"webhook":{"topic":"shop/update","fields":[],"address":"https://test.example.com/webhooks","format":"json"}}'
192
192
  headers:
193
193
  Content-Type:
194
194
  - application/json
@@ -275,10 +275,10 @@ http_interactions:
275
275
  recorded_at: Sun, 07 Jan 2018 22:02:28 GMT
276
276
  - request:
277
277
  method: post
278
- uri: https://widgets.myshopify.com/admin/webhooks.json
278
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
279
279
  body:
280
280
  encoding: UTF-8
281
- string: '{"webhook":{"topic":"orders/create","address":"https://test.example.com/webhooks","format":"json"}}'
281
+ string: '{"webhook":{"topic":"orders/create","fields":[],"address":"https://test.example.com/webhooks","format":"json"}}'
282
282
  headers:
283
283
  Content-Type:
284
284
  - application/json
@@ -366,10 +366,10 @@ http_interactions:
366
366
  recorded_at: Sun, 07 Jan 2018 22:02:29 GMT
367
367
  - request:
368
368
  method: post
369
- uri: https://widgets.myshopify.com/admin/webhooks.json
369
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
370
370
  body:
371
371
  encoding: UTF-8
372
- string: '{"webhook":{"topic":"orders/paid","address":"https://test.example.com/webhooks","format":"json"}}'
372
+ string: '{"webhook":{"topic":"orders/paid","fields":["id"],"address":"https://test.example.com/webhooks","format":"json"}}'
373
373
  headers:
374
374
  Content-Type:
375
375
  - application/json
@@ -457,10 +457,10 @@ http_interactions:
457
457
  recorded_at: Sun, 07 Jan 2018 22:02:30 GMT
458
458
  - request:
459
459
  method: post
460
- uri: https://widgets.myshopify.com/admin/webhooks.json
460
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
461
461
  body:
462
462
  encoding: UTF-8
463
- string: '{"webhook":{"topic":"carts/create","address":"https://test.example.com/webhooks","format":"json"}}'
463
+ string: '{"webhook":{"topic":"carts/create","fields":[],"address":"https://test.example.com/webhooks","format":"json"}}'
464
464
  headers:
465
465
  Content-Type:
466
466
  - application/json
@@ -548,10 +548,10 @@ http_interactions:
548
548
  recorded_at: Sun, 07 Jan 2018 22:02:31 GMT
549
549
  - request:
550
550
  method: post
551
- uri: https://widgets.myshopify.com/admin/webhooks.json
551
+ uri: https://widgets.myshopify.com/admin/api/2019-10/webhooks.json
552
552
  body:
553
553
  encoding: UTF-8
554
- string: '{"webhook":{"topic":"carts/update","address":"https://test.example.com/webhooks","format":"json"}}'
554
+ string: '{"webhook":{"topic":"carts/update","fields":[],"address":"https://test.example.com/webhooks","format":"json"}}'
555
555
  headers:
556
556
  Content-Type:
557
557
  - application/json