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
@@ -1,7 +1,9 @@
1
1
  module DiscoApp::Concerns::AppSettings
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
6
  acts_as_singleton
6
7
  end
8
+
7
9
  end
@@ -1,10 +1,11 @@
1
1
  module DiscoApp::Concerns::CanBeLiquified
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
- SPLIT_ARRAY_SEPARATOR = '@!@'
5
+ SPLIT_ARRAY_SEPARATOR = '@!@'.freeze
6
+ NIL_VALUE = 'nil'.freeze
5
7
 
6
8
  included do
7
-
8
9
  # Return this model as a hash for use with `to_liquid`. Returns `as_json` by default but is provided here as a hook
9
10
  # for potential overrides.
10
11
  def as_liquid
@@ -26,21 +27,35 @@ module DiscoApp::Concerns::CanBeLiquified
26
27
 
27
28
  # Return given value as a string expression that will be evaluated in Liquid to result in the correct value type.
28
29
  def as_liquid_value(key, value)
29
- if value.is_a? Numeric or (!!value == value)
30
- return value.to_s
31
- end
32
- if value.nil?
33
- return 'nil'
34
- end
35
- if value.is_a? Array
36
- return "'#{value.map { |e| (e.is_a? String) ? CGI::escapeHTML(e) : e }.join(SPLIT_ARRAY_SEPARATOR)}' | split: '#{SPLIT_ARRAY_SEPARATOR}'"
37
- end
38
- if value.is_a? String and key.end_with? '_html'
39
- return "'#{value.to_s.gsub("'", "'")}'"
30
+ html_string = ->(val) { val.is_a?(String) && key.end_with?('_html') }
31
+
32
+ case value
33
+ when Numeric, TrueClass, FalseClass
34
+ value.to_s
35
+ when NilClass
36
+ NIL_VALUE
37
+ when Array
38
+ as_liquid_array_value(value)
39
+ when html_string
40
+ as_liquid_html_value(value)
41
+ else
42
+ "'#{CGI.escapeHTML(value.to_s)}'"
40
43
  end
41
- "'#{CGI::escapeHTML(value.to_s)}'"
42
44
  end
43
45
 
46
+ def as_liquid_array_value(value)
47
+ split_array = value.map do |element|
48
+ CGI.escapeHTML(element) if element.is_a? String
49
+
50
+ element
51
+ end.join(SPLIT_ARRAY_SEPARATOR)
52
+
53
+ "'#{split_array}' | split: '#{SPLIT_ARRAY_SEPARATOR}'"
54
+ end
55
+
56
+ def as_liquid_html_value(value)
57
+ "'#{value.to_s.gsub("'", ''')}'"
58
+ end
44
59
  end
45
60
 
46
61
  end
@@ -1,8 +1,8 @@
1
1
  module DiscoApp::Concerns::HasMetafields
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
-
6
6
  # Write multiple metafields for this object in a single call.
7
7
  #
8
8
  # Expects an argument in a nested hash structure with :namespace => :key =>
@@ -42,7 +42,6 @@ module DiscoApp::Concerns::HasMetafields
42
42
  end
43
43
  end.flatten
44
44
  end
45
-
46
45
  end
47
46
 
48
47
  end
@@ -1,9 +1,9 @@
1
1
  module DiscoApp::Concerns::Plan
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
-
6
- has_many :subscriptions
6
+ has_many :subscriptions, dependent: :restrict_with_exception
7
7
  has_many :shops, through: :subscriptions
8
8
  has_many :plan_codes, dependent: :destroy
9
9
 
@@ -25,11 +25,10 @@ module DiscoApp::Concerns::Plan
25
25
  scope :available, -> { where status: statuses[:available] }
26
26
 
27
27
  validates_presence_of :name
28
-
29
28
  end
30
29
 
31
30
  def has_trial?
32
- trial_period_days.present? and trial_period_days > 0
31
+ trial_period_days.present? && trial_period_days.positive?
33
32
  end
34
33
 
35
34
  end
@@ -1,8 +1,8 @@
1
1
  module DiscoApp::Concerns::PlanCode
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
-
6
6
  belongs_to :plan
7
7
 
8
8
  enum status: {
@@ -12,7 +12,6 @@ module DiscoApp::Concerns::PlanCode
12
12
 
13
13
  validates_presence_of :code
14
14
  validates_presence_of :amount
15
-
16
15
  end
17
16
 
18
17
  end
@@ -1,16 +1,14 @@
1
- require 'render_anywhere'
2
1
  require 'uglifier'
3
2
 
4
3
  module DiscoApp::Concerns::RendersAssets
4
+
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- include RenderAnywhere
9
8
  after_commit :queue_render_asset_group_job
10
9
  end
11
10
 
12
11
  class_methods do
13
-
14
12
  # Ruby "macro" that allows the definition of a number of Shopify assets that
15
13
  # should be rendered and uploaded when certain attributes on the including
16
14
  # class change. This assumes that the including class (1) is an ActiveRecord
@@ -67,10 +65,9 @@ module DiscoApp::Concerns::RendersAssets
67
65
  assets: nil,
68
66
  triggered_by: nil,
69
67
  script_tags: nil,
70
- minify: Rails.env.production?
68
+ minify: Rails.env.production? || Rails.env.staging?
71
69
  }
72
70
  end
73
-
74
71
  end
75
72
 
76
73
  # Callback, triggered after a model save. Iterates through each asset group
@@ -78,9 +75,7 @@ module DiscoApp::Concerns::RendersAssets
78
75
  # attributes are found in the asset group's triggered_by list.
79
76
  def queue_render_asset_group_job
80
77
  renderable_asset_groups.each do |asset_group, options|
81
- unless (previous_changes.keys & options[:triggered_by]).empty?
82
- DiscoApp::RenderAssetGroupJob.perform_later(shop, self, asset_group.to_s)
83
- end
78
+ DiscoApp::RenderAssetGroupJob.perform_later(shop, self, asset_group.to_s) unless (previous_changes.keys & options[:triggered_by]).empty?
84
79
  end
85
80
  end
86
81
 
@@ -97,26 +92,22 @@ module DiscoApp::Concerns::RendersAssets
97
92
 
98
93
  options[:assets].each do |asset|
99
94
  # Create/replace the asset via the Shopify API.
100
- shopify_asset = shop.with_api_context {
95
+ shopify_asset = shop.with_api_context do
101
96
  ShopifyAPI::Asset.create(
102
97
  key: asset,
103
98
  value: render_asset_group_asset(asset, public_urls, options)
104
99
  )
105
- }
100
+ end
106
101
 
107
102
  # Store the public URL to this asset, so that we're able to use it in
108
103
  # subsequent template renders. Adds a .css suffix to .scss assets, so that
109
104
  # we use the Shopify-compiled version of any SCSS stylesheets.
110
- if shopify_asset.public_url.present?
111
- public_urls[asset] = shopify_asset.public_url.gsub(/\.scss\?/, '.scss.css?')
112
- end
105
+ public_urls[asset] = shopify_asset.public_url.gsub(/\.scss\?/, '.scss.css?') if shopify_asset.public_url.present?
113
106
  end
114
107
 
115
108
  # If we specified the creation of any script tags based on newly rendered
116
109
  # assets, do that now.
117
- unless options[:script_tags].empty?
118
- render_asset_script_tags(options, public_urls)
119
- end
110
+ render_asset_script_tags(options, public_urls) unless options[:script_tags].empty?
120
111
  end
121
112
 
122
113
  private
@@ -141,11 +132,11 @@ module DiscoApp::Concerns::RendersAssets
141
132
 
142
133
  # Return true if the given asset should be minified with Uglifier.
143
134
  def should_be_minified?(asset, options)
144
- asset.to_s.end_with?('.js') and options[:minify]
135
+ asset.to_s.end_with?('.js') && options[:minify]
145
136
  end
146
137
 
147
138
  def render_asset_renderer
148
- @render_asset_renderer ||= self.class.const_get('RenderingController').new
139
+ @render_asset_renderer ||= self.class.const_get('ApplicationController').new
149
140
  end
150
141
 
151
142
  # Render any script tags defined by the :script_tags options that we have
@@ -157,9 +148,12 @@ module DiscoApp::Concerns::RendersAssets
157
148
  # Iterate each script tag for which we have a known public URL and create
158
149
  # or update the corresponding script tag resource.
159
150
  public_urls.slice(*options[:script_tags]).each do |asset, public_url|
160
- script_tag = current_script_tags.find(lambda { ShopifyAPI::ScriptTag.new(event: 'onload') }) { |script_tag| script_tag.src.include?("#{asset}?") }
161
- script_tag.src = public_url
162
- shop.with_api_context { script_tag.save }
151
+ generate_new_script_tag = -> { ShopifyAPI::ScriptTag.new(event: 'onload') }
152
+
153
+ current_script_tags
154
+ .find(generate_new_script_tag) { |script_tag| script_tag.src.include?("#{asset}?") }
155
+ .tap { |script_tag| script_tag.src = public_url }
156
+ .yield_self { |script_tag| shop.with_api_context { script_tag.save } }
163
157
  end
164
158
  end
165
159
 
@@ -1,20 +1,26 @@
1
1
  module DiscoApp::Concerns::Shop
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
- include ShopifyApp::Shop
6
+ include ShopifyApp::SessionStorage
6
7
  include ActionView::Helpers::DateHelper
7
8
 
8
9
  # Define relationships to plans and subscriptions.
9
- has_many :subscriptions
10
+ has_many :subscriptions, dependent: :restrict_with_exception
10
11
  has_many :plans, through: :subscriptions
11
12
 
12
13
  # Define relationship to users.
13
- has_many :users
14
+ has_many :users, dependent: :restrict_with_exception
14
15
 
15
16
  # Define relationship to sessions.
16
17
  has_many :sessions, class_name: 'DiscoApp::Session', dependent: :destroy
17
18
 
19
+ # Define relationship to Flow actions and triggers.
20
+ has_many :flow_actions, class_name: 'DiscoApp::Flow::Action', dependent: :destroy
21
+ has_many :flow_triggers, class_name: 'DiscoApp::Flow::Trigger', dependent: :destroy
22
+ has_many :flow_trigger_usages, class_name: 'DiscoApp::Flow::TriggerUsage', dependent: :destroy
23
+
18
24
  # Define possible installation statuses as an enum.
19
25
  enum status: {
20
26
  never_installed: 0,
@@ -27,7 +33,7 @@ module DiscoApp::Concerns::Shop
27
33
  }
28
34
 
29
35
  # Define some useful scopes.
30
- scope :status, -> (status) { where status: status }
36
+ scope :status, ->(status) { where status: status }
31
37
  scope :installed, -> { where status: statuses[:installed] }
32
38
  scope :has_active_shopify_plan, -> { where.not(plan_name: [:cancelled, :frozen, :fraudulent]) }
33
39
  scope :shopify_plus, -> { where(plan_name: :shopify_plus) }
@@ -70,12 +76,12 @@ module DiscoApp::Concerns::Shop
70
76
 
71
77
  # Return the absolute URL to the shop's admin.
72
78
  def admin_url
73
- "https://#{shopify_domain}/admin"
79
+ "https://#{shopify_domain}/admin/api/#{api_version}"
74
80
  end
75
81
 
76
- # Convenience method to get the email of the shop's admin, to display in Rollbar.
77
- def email
78
- data[:email]
82
+ # Return the absolutely URL to the shop's admin.
83
+ def shopify_url
84
+ "https://#{shopify_domain}"
79
85
  end
80
86
 
81
87
  def installed_duration
@@ -85,11 +91,7 @@ module DiscoApp::Concerns::Shop
85
91
  # Return the shop's configured timezone. If none can be parsed from the
86
92
  # shop's "data" hash, return the default Rails zone (which should be UTC).
87
93
  def time_zone
88
- @time_zone ||= begin
89
- Time.find_zone!(data[:timezone].to_s.gsub(/^\(.+\)\s/, ''))
90
- rescue ArgumentError
91
- Time.zone
92
- end
94
+ @time_zone ||= Time.find_zone!(data[:iana_timezone]) || Time.zone
93
95
  end
94
96
 
95
97
  # Return the shop's configured locale as a symbol. If none exists for some
@@ -100,7 +102,7 @@ module DiscoApp::Concerns::Shop
100
102
 
101
103
  # Return an instance of the Disco API client.
102
104
  def disco_api_client
103
- @api_client ||= DiscoApp::ApiClient.new(self, ENV['DISCO_API_URL'])
105
+ @disco_api_client ||= DiscoApp::ApiClient.new(self, ENV['DISCO_API_URL'])
104
106
  end
105
107
 
106
108
  # Override the "read" data attribute to allow indifferent access.
@@ -108,6 +110,10 @@ module DiscoApp::Concerns::Shop
108
110
  read_attribute(:data).with_indifferent_access
109
111
  end
110
112
 
113
+ def api_version
114
+ ShopifyApp.configuration.api_version
115
+ end
116
+
111
117
  end
112
118
 
113
119
  end
@@ -1,14 +1,13 @@
1
1
  module DiscoApp::Concerns::Source
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
-
6
- has_many :subscriptions
6
+ has_many :subscriptions, dependent: :restrict_with_exception
7
7
  has_many :shops, through: :subscriptions
8
8
 
9
9
  validates_presence_of :source
10
10
  validates_presence_of :name
11
-
12
11
  end
13
12
 
14
13
  end
@@ -1,8 +1,8 @@
1
1
  module DiscoApp::Concerns::Subscription
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
-
6
6
  belongs_to :shop
7
7
  belongs_to :plan
8
8
  belongs_to :plan_code, optional: true
@@ -23,12 +23,11 @@ module DiscoApp::Concerns::Subscription
23
23
  scope :current, -> { where status: [statuses[:trial], statuses[:active]] }
24
24
 
25
25
  after_commit :cancel_charge
26
-
27
26
  end
28
27
 
29
28
  # Only require an active charge if the amount to be charged is > 0.
30
29
  def requires_active_charge?
31
- amount > 0
30
+ amount.positive?
32
31
  end
33
32
 
34
33
  # Convenience method to check if this subscription has an active charge.
@@ -67,6 +66,7 @@ module DiscoApp::Concerns::Subscription
67
66
  def cancel_charge
68
67
  return if (previous_changes.keys & ['amount', 'trial_period_days']).empty?
69
68
  return unless active_charge?
69
+
70
70
  active_charge.cancelled!
71
71
  end
72
72
 
@@ -1,31 +1,29 @@
1
1
  module DiscoApp::Concerns::Synchronises
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  class_methods do
5
-
6
6
  # Define the number of resources per page to fetch.
7
7
  SYNCHRONISES_PAGE_LIMIT = 250
8
8
 
9
- def should_synchronise?(shop, data)
9
+ def should_synchronise?(_shop, _data)
10
10
  true
11
11
  end
12
12
 
13
- def synchronise_by(shop, data)
13
+ def synchronise_by(_shop, data)
14
14
  { id: data[:id] }
15
15
  end
16
16
 
17
17
  def synchronise(shop, data)
18
- if data.is_a?(ShopifyAPI::Base)
19
- data = ActiveSupport::JSON.decode(data.to_json)
20
- end
18
+ data = JSON.parse(data.to_json) if data.is_a?(ShopifyAPI::Base)
21
19
  data = data.with_indifferent_access
22
20
 
23
21
  return unless should_synchronise?(shop, data)
24
22
 
25
23
  begin
26
- instance = self.find_or_create_by!(self.synchronise_by(shop, data)) do |instance|
27
- instance.shop = shop
28
- instance.data = data
24
+ instance = find_or_create_by!(synchronise_by(shop, data)) do |new_instance|
25
+ new_instance.shop = shop
26
+ new_instance.data = data
29
27
  end
30
28
  rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation
31
29
  retry
@@ -36,7 +34,7 @@ module DiscoApp::Concerns::Synchronises
36
34
  instance
37
35
  end
38
36
 
39
- def should_synchronise_deletion?(shop, data)
37
+ def should_synchronise_deletion?(_shop, _data)
40
38
  true
41
39
  end
42
40
 
@@ -45,26 +43,23 @@ module DiscoApp::Concerns::Synchronises
45
43
 
46
44
  return unless should_synchronise_deletion?(shop, data)
47
45
 
48
- self.where(shop: shop, id: data[:id]).destroy_all
46
+ where(shop: shop, id: data[:id]).destroy_all
49
47
  end
50
48
 
51
49
  def synchronise_all(shop, params = {})
52
50
  resource_count = shop.with_api_context { self::SHOPIFY_API_CLASS.count(params) }
53
51
 
54
52
  (1..(resource_count / SYNCHRONISES_PAGE_LIMIT.to_f).ceil).each do |page|
55
- DiscoApp::SynchroniseResourcesJob.perform_later(shop, self.name, params.merge(page: page, limit: SYNCHRONISES_PAGE_LIMIT))
53
+ DiscoApp::SynchroniseResourcesJob.perform_later(shop, name, params.merge(page: page, limit: SYNCHRONISES_PAGE_LIMIT))
56
54
  end
57
55
  end
58
-
59
56
  end
60
57
 
61
58
  included do
62
-
63
59
  # Override the "read" data attribute to allow indifferent access.
64
60
  def data
65
61
  read_attribute(:data).with_indifferent_access
66
62
  end
67
-
68
63
  end
69
64
 
70
65
  end
@@ -1,4 +1,5 @@
1
1
  module DiscoApp::Concerns::Taggable
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  def tags
@@ -1,11 +1,12 @@
1
1
  module DiscoApp::Concerns::User
2
+
2
3
  extend ActiveSupport::Concern
3
4
 
4
5
  included do
5
6
  belongs_to :shop
6
7
 
7
8
  def self.create_user(shopify_user, shop)
8
- user = self.find_or_create_by!(id: shopify_user.id, shop: shop)
9
+ user = find_or_create_by!(id: shopify_user.id, shop: shop)
9
10
  user.update(
10
11
  first_name: shopify_user.first_name || '',
11
12
  last_name: shopify_user.last_name || '',
@@ -15,6 +16,6 @@ module DiscoApp::Concerns::User
15
16
  rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation
16
17
  retry
17
18
  end
18
-
19
19
  end
20
+
20
21
  end
@@ -0,0 +1,9 @@
1
+ module DiscoApp
2
+ module Flow
3
+ class Action < ApplicationRecord
4
+
5
+ include DiscoApp::Flow::Concerns::Action
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module DiscoApp
2
+ module Flow
3
+ module Concerns
4
+ module Action
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ belongs_to :shop
10
+
11
+ self.table_name = :disco_app_flow_actions
12
+
13
+ enum status: {
14
+ pending: 0,
15
+ succeeded: 1,
16
+ failed: 2
17
+ }
18
+
19
+ def properties
20
+ read_attribute(:properties).with_indifferent_access
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ module DiscoApp
2
+ module Flow
3
+ module Concerns
4
+ module Trigger
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ belongs_to :shop
10
+
11
+ self.table_name = :disco_app_flow_triggers
12
+
13
+ enum status: {
14
+ pending: 0,
15
+ succeeded: 1,
16
+ failed: 2,
17
+ skipped: 3
18
+ }
19
+
20
+ def properties
21
+ read_attribute(:properties).with_indifferent_access
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module DiscoApp
2
+ module Flow
3
+ module Concerns
4
+ module TriggerUsage
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ belongs_to :shop
10
+
11
+ self.table_name = :disco_app_flow_trigger_usages
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module DiscoApp
2
+ module Flow
3
+ class Trigger < ApplicationRecord
4
+
5
+ include DiscoApp::Flow::Concerns::Trigger
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module DiscoApp
2
+ module Flow
3
+ class TriggerUsage < ApplicationRecord
4
+
5
+ include DiscoApp::Flow::Concerns::TriggerUsage
6
+
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Plan < ApplicationRecord
2
+
2
3
  include DiscoApp::Concerns::Plan
4
+
3
5
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::PlanCode < ApplicationRecord
2
+
2
3
  include DiscoApp::Concerns::PlanCode
4
+
3
5
  end
@@ -1,6 +1,7 @@
1
1
  module DiscoApp
2
2
  class SessionStorage
3
- def self.store(session)
3
+
4
+ def self.store(session, *args)
4
5
  shop = Shop.find_or_initialize_by(shopify_domain: session.url)
5
6
  shop.shopify_token = session.token
6
7
  shop.save!
@@ -9,10 +10,12 @@ module DiscoApp
9
10
 
10
11
  def self.retrieve(id)
11
12
  return unless id
13
+
12
14
  shop = Shop.find(id)
13
- ShopifyAPI::Session.new(shop.shopify_domain, shop.shopify_token)
15
+ ShopifyAPI::Session.new(domain: shop.shopify_domain, token: shop.shopify_token, api_version: shop.api_version)
14
16
  rescue ActiveRecord::RecordNotFound
15
17
  nil
16
18
  end
19
+
17
20
  end
18
21
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Shop < ApplicationRecord
2
+
2
3
  include DiscoApp::Concerns::Shop
4
+
3
5
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Source < ApplicationRecord
2
+
2
3
  include DiscoApp::Concerns::Source
4
+
3
5
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::Subscription < ApplicationRecord
2
+
2
3
  include DiscoApp::Concerns::Subscription
4
+
3
5
  end
@@ -1,3 +1,5 @@
1
1
  class DiscoApp::User < ApplicationRecord
2
+
2
3
  include DiscoApp::Concerns::User
4
+
3
5
  end