disco_app 0.9.3 → 0.9.4

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/disco_app/install_controller.rb +1 -1
  3. data/app/jobs/disco_app/concerns/app_installed_job.rb +4 -4
  4. data/app/jobs/disco_app/concerns/render_asset_group_job.rb +8 -0
  5. data/app/jobs/disco_app/concerns/shop_update_job.rb +1 -1
  6. data/app/jobs/disco_app/concerns/subscription_changed_job.rb +1 -1
  7. data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +1 -1
  8. data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +1 -1
  9. data/app/jobs/disco_app/render_asset_group_job.rb +3 -0
  10. data/app/jobs/disco_app/shop_job.rb +1 -1
  11. data/app/models/disco_app/concerns/renders_assets.rb +148 -0
  12. data/app/services/disco_app/subscription_service.rb +1 -1
  13. data/lib/disco_app/version.rb +1 -1
  14. data/lib/generators/disco_app/disco_app_generator.rb +1 -2
  15. data/lib/tasks/carrier_service.rake +1 -1
  16. data/lib/tasks/shops.rake +1 -1
  17. data/lib/tasks/webhooks.rake +1 -1
  18. data/test/dummy/app/jobs/products_create_job.rb +1 -1
  19. data/test/dummy/app/jobs/products_delete_job.rb +1 -1
  20. data/test/dummy/app/jobs/products_update_job.rb +1 -1
  21. data/test/dummy/app/models/js_configuration.rb +8 -0
  22. data/test/dummy/app/models/widget_configuration.rb +10 -0
  23. data/test/dummy/app/views/assets/script_tag.js.erb +1 -0
  24. data/test/dummy/app/views/assets/test.js.erb +1 -0
  25. data/test/dummy/app/views/assets/widget.js.erb +2 -0
  26. data/test/dummy/app/views/assets/widget.scss.erb +3 -0
  27. data/test/dummy/db/migrate/20160530160739_create_asset_models.rb +19 -0
  28. data/test/dummy/db/schema.rb +16 -1
  29. data/test/fixtures/api/widget_store/assets/create_script_tag_js_request.json +6 -0
  30. data/test/fixtures/api/widget_store/assets/create_script_tag_js_response.json +12 -0
  31. data/test/fixtures/api/widget_store/assets/create_script_tag_request.json +6 -0
  32. data/test/fixtures/api/widget_store/assets/create_script_tag_response.json +10 -0
  33. data/test/fixtures/api/widget_store/assets/create_test_js_request.json +6 -0
  34. data/test/fixtures/api/widget_store/assets/create_test_js_response.json +12 -0
  35. data/test/fixtures/api/widget_store/assets/create_widget_js_request.json +6 -0
  36. data/test/fixtures/api/widget_store/assets/create_widget_js_response.json +12 -0
  37. data/test/fixtures/api/widget_store/assets/create_widget_scss_request.json +6 -0
  38. data/test/fixtures/api/widget_store/assets/create_widget_scss_response.json +12 -0
  39. data/test/fixtures/api/widget_store/assets/get_script_tags_empty_request.json +1 -0
  40. data/test/fixtures/api/widget_store/assets/get_script_tags_empty_response.json +1 -0
  41. data/test/fixtures/api/widget_store/assets/get_script_tags_preexisting_request.json +1 -0
  42. data/test/fixtures/api/widget_store/assets/get_script_tags_preexisting_response.json +12 -0
  43. data/test/fixtures/api/widget_store/assets/update_script_tag_request.json +10 -0
  44. data/test/fixtures/api/widget_store/assets/update_script_tag_response.json +10 -0
  45. data/test/fixtures/assets/test.js +1 -0
  46. data/test/fixtures/js_configurations.yml +3 -0
  47. data/test/fixtures/widget_configurations.yml +4 -0
  48. data/test/jobs/disco_app/app_installed_job_test.rb +3 -3
  49. data/test/jobs/disco_app/app_uninstalled_job_test.rb +1 -1
  50. data/test/models/disco_app/renders_assets_test.rb +100 -0
  51. data/test/support/test_shopify_api.rb +1 -1
  52. metadata +72 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e11c5ff7beaece5d87fda19c4d06bcc08ded718b71ce4050a5380c15e638be0
4
- data.tar.gz: 7a1ceffb9b2c33f6dffe4a31b6877cbab52946cd3d37ad4396270c397dd99805
3
+ metadata.gz: 7b67b4667e899a379d0cc4152f228bfe7a80bef4aa6b35c26f54ee76c20c967f
4
+ data.tar.gz: d421b6283198d07e8ddc9a902e71a13320745e84f8fd5b3dbc981e6e88b70062
5
5
  SHA512:
6
- metadata.gz: 6da76ea6fd5ac63a77fe4acaf4552946416841228994d4cf6b431a094180aa63d6d07a1ef586c71c44eeca0cfc38a4da30d6f0ed1a5b62c54b28b109fcdb485f
7
- data.tar.gz: 1a96f567be81a5bc6189bb43bb98fd34181009459b2ec085ded5ad820ea662fa7a3780a40e3103a480debe70b74914d224e20cc90a21df3a5c5e949a74801ba4
6
+ metadata.gz: b713f8e47aefe3614a2016bad8046d91fdee669fa5635f3768d167d9c6768622af51ec5f6cb711040f7d712dc2cdac2e9f879f4d752956c008444de52ad326ec
7
+ data.tar.gz: df1e8549d1e7474f137bc7d6a483f7e06450f26273181bdb4724b79003d6a3f51e19b4b29c6d0736f2f390e9d2c8dcd922d5b7e1785717166e70f6e152b4ebdd
@@ -6,7 +6,7 @@ class DiscoApp::InstallController < ApplicationController
6
6
 
7
7
  # Start the installation process for the current shop, then redirect to the installing screen.
8
8
  def install
9
- DiscoApp::AppInstalledJob.perform_later(@shop.shopify_domain, cookies[DiscoApp::CODE_COOKIE_KEY], cookies[DiscoApp::SOURCE_COOKIE_KEY])
9
+ DiscoApp::AppInstalledJob.perform_later(@shop, cookies[DiscoApp::CODE_COOKIE_KEY], cookies[DiscoApp::SOURCE_COOKIE_KEY])
10
10
  redirect_to action: :installing
11
11
  end
12
12
 
@@ -14,10 +14,10 @@ module DiscoApp::Concerns::AppInstalledJob
14
14
  # - Perform initial update of shop information.
15
15
  # - Subscribe to default plan, if any exists.
16
16
  #
17
- def perform(shopify_domain, plan_code = nil, source = nil)
18
- DiscoApp::SynchroniseWebhooksJob.perform_now(shopify_domain)
19
- DiscoApp::SynchroniseCarrierServiceJob.perform_now(shopify_domain)
20
- DiscoApp::ShopUpdateJob.perform_now(shopify_domain)
17
+ def perform(shop, plan_code = nil, source = nil)
18
+ DiscoApp::SynchroniseWebhooksJob.perform_now(@shop)
19
+ DiscoApp::SynchroniseCarrierServiceJob.perform_now(@shop)
20
+ DiscoApp::ShopUpdateJob.perform_now(@shop)
21
21
 
22
22
  @shop.reload
23
23
 
@@ -0,0 +1,8 @@
1
+ module DiscoApp::Concerns::RenderAssetGroupJob
2
+ extend ActiveSupport::Concern
3
+
4
+ def perform(shop, instance, asset_group)
5
+ instance.render_asset_group(asset_group.to_sym)
6
+ end
7
+
8
+ end
@@ -2,7 +2,7 @@ module DiscoApp::Concerns::ShopUpdateJob
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  # Perform an update of the current shop's information.
5
- def perform(shopify_domain, shop_data = nil)
5
+ def perform(shop, shop_data = nil)
6
6
  # If we weren't provided with shop data (eg from a webhook), fetch it.
7
7
  shop_data ||= ActiveSupport::JSON::decode(ShopifyAPI::Shop.current.to_json)
8
8
 
@@ -1,7 +1,7 @@
1
1
  module DiscoApp::Concerns::SubscriptionChangedJob
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def perform(shopify_domain, subscription)
4
+ def perform(shop, subscription)
5
5
  end
6
6
 
7
7
  end
@@ -2,7 +2,7 @@ module DiscoApp::Concerns::SynchroniseCarrierServiceJob
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  # Ensure that any carrier service required by our app is registered.
5
- def perform(shopify_domain)
5
+ def perform(shop)
6
6
  # Don't proceed unless we have a name and callback url.
7
7
  return unless carrier_service_name and callback_url
8
8
 
@@ -3,7 +3,7 @@ module DiscoApp::Concerns::SynchroniseWebhooksJob
3
3
 
4
4
  # Ensure the webhooks registered with our shop are the same as those listed
5
5
  # in our application configuration.
6
- def perform(shopify_domain)
6
+ def perform(shop)
7
7
  # Get the full list of expected webhook topics.
8
8
  expected_topics = [:'app/uninstalled', :'shop/update'] + topics
9
9
 
@@ -0,0 +1,3 @@
1
+ class DiscoApp::RenderAssetGroupJob < DiscoApp::ShopJob
2
+ include DiscoApp::Concerns::RenderAssetGroupJob
3
+ end
@@ -15,7 +15,7 @@ class DiscoApp::ShopJob < ActiveJob::Base
15
15
  private
16
16
 
17
17
  def find_shop(job)
18
- @shop ||= DiscoApp::Shop.find_by!(shopify_domain: job.arguments.first)
18
+ @shop ||= job.arguments.first.is_a?(DiscoApp::Shop) ? job.arguments.first : DiscoApp::Shop.find_by!(shopify_domain: job.arguments.first)
19
19
  end
20
20
 
21
21
  def shop_context(job, block)
@@ -0,0 +1,148 @@
1
+ require 'render_anywhere'
2
+
3
+ module DiscoApp::Concerns::RendersAssets
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include RenderAnywhere
8
+ after_commit :queue_render_asset_group_job
9
+ end
10
+
11
+ class_methods do
12
+
13
+ # Ruby "macro" that allows the definition of a number of Shopify assets that
14
+ # should be rendered and uploaded when certain attributes on the including
15
+ # class change. This assumes that the including class (1) is an ActiveRecord
16
+ # model that supports an `after_commit` callback; and (2) that the model has
17
+ # a `shop` method (or attribute) that references the DiscoApp::Shop instance
18
+ # associated with the current model.
19
+ #
20
+ # Options
21
+ #
22
+ # assets: Required. A list of asset templates to be rendered and
23
+ # uploaded to Shopify. The order of assets matters only
24
+ # in that subsequent asset templates will have access to
25
+ # the public CDN url of earlier-rendered assets through
26
+ # a "@public_urls" context variable.
27
+ #
28
+ # triggered_by: Optional. A list of attributes that should trigger the
29
+ # re-rendering and upload of the assets defined by the
30
+ # `assets` option, provided as a list of string. If
31
+ # empty or nil, nothing will be triggered.
32
+ #
33
+ # script_tags: Optional. A list of assets that should have script
34
+ # tags created or updated after being rendered to the
35
+ # storefront.
36
+ #
37
+ # compress: Optional. Whether Javascript and SCSS assets should be
38
+ # compressed after being rendered. Defaults to true in
39
+ # production environments, false otherwise.
40
+ #
41
+ def renders_assets(*asset_groups)
42
+ options = asset_groups.last.is_a?(Hash) ? asset_groups.pop : {}
43
+ options = renders_assets_default_options.merge(options)
44
+
45
+ # Ensure assets, triggered by and script tag options are arrays.
46
+ options[:assets] = options[:assets] ? Array(options[:assets]).map(&:to_sym) : []
47
+ options[:triggered_by] = options[:triggered_by] ? Array(options[:triggered_by]).map(&:to_s) : []
48
+ options[:script_tags] = options[:script_tags] ? Array(options[:script_tags]).map(&:to_sym) : []
49
+
50
+ asset_groups.each do |asset_group|
51
+ renderable_asset_groups[asset_group.to_sym] = options
52
+ end
53
+ end
54
+
55
+ # Return a list of renderable asset groups, along with their options.
56
+ def renderable_asset_groups
57
+ @renderable_asset_groups ||= {}
58
+ end
59
+
60
+ # Return the default options for the `renders_assets` macro.
61
+ def renders_assets_default_options
62
+ {
63
+ assets: nil,
64
+ triggered_by: nil,
65
+ compress: Rails.env.production?
66
+ }
67
+ end
68
+
69
+ end
70
+
71
+ # Callback, triggered after a model save. Iterates through each asset group
72
+ # defined on the model and queues a render job if any of the changed
73
+ # attributes are found in the asset group's triggered_by list.
74
+ def queue_render_asset_group_job
75
+ renderable_asset_groups.each do |asset_group, options|
76
+ unless (previous_changes.keys & options[:triggered_by]).empty?
77
+ DiscoApp::RenderAssetGroupJob.perform_later(shop, self, asset_group.to_s)
78
+ end
79
+ end
80
+ end
81
+
82
+ # Copies the class-level hash of assets with symbol asset name as keys and
83
+ # their corresponding options as values to the instance.
84
+ def renderable_asset_groups
85
+ @renderable_asset_groups ||= self.class.renderable_asset_groups.dup
86
+ end
87
+
88
+ # Render the specified asset group and upload the result to Shopify.
89
+ def render_asset_group(asset_group)
90
+ options = renderable_asset_groups[asset_group]
91
+ public_urls = {}
92
+
93
+ options[:assets].each do |asset|
94
+ # Create/replace the asset via the Shopify API.
95
+ shopify_asset = shop.temp {
96
+ ShopifyAPI::Asset.create(
97
+ key: "assets/#{asset}",
98
+ value: render_asset_group_asset(asset, public_urls)
99
+ )
100
+ }
101
+
102
+ # Store the public URL to this asset, so that we're able to use it in
103
+ # subsequent template renders. Adds a .css suffix to .scss assets, so that
104
+ # we use the Shopify-compiled version of any SCSS stylesheets.
105
+ public_urls[asset] = shopify_asset.public_url.gsub(/\.scss\?/, '.scss.css?')
106
+ end
107
+
108
+ # If we specified the creation of any script tags based on newly rendered
109
+ # assets, do that now.
110
+ unless options[:script_tags].empty?
111
+ render_asset_script_tags(options, public_urls)
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ # Render an individual asset within an asset group.
118
+ def render_asset_group_asset(asset, public_urls)
119
+ render_asset_renderer.render_to_string(
120
+ template: "assets/#{asset}",
121
+ layout: nil,
122
+ locals: {
123
+ :"@#{self.class.name.underscore}" => self,
124
+ :@public_urls => public_urls
125
+ }
126
+ )
127
+ end
128
+
129
+ def render_asset_renderer
130
+ @render_asset_renderer ||= self.class.const_get('RenderingController').new
131
+ end
132
+
133
+ # Render any script tags defined by the :script_tags options that we have
134
+ # a public URL for.
135
+ def render_asset_script_tags(options, public_urls)
136
+ # Fetch the current set of script tags for the store.
137
+ current_script_tags = shop.temp { ShopifyAPI::ScriptTag.find(:all) }
138
+
139
+ # Iterate each script tag for which we have a known public URL and create
140
+ # or update the corresponding script tag resource.
141
+ public_urls.slice(*options[:script_tags]).each do |asset, public_url|
142
+ script_tag = current_script_tags.find(lambda { ShopifyAPI::ScriptTag.new(event: 'onload') }) { |script_tag| script_tag.src.include?("#{asset}?") }
143
+ script_tag.src = public_url
144
+ shop.temp { script_tag.save }
145
+ end
146
+ end
147
+
148
+ end
@@ -37,7 +37,7 @@ class DiscoApp::SubscriptionService
37
37
  )
38
38
 
39
39
  # Enqueue the subscription changed background job.
40
- DiscoApp::SubscriptionChangedJob.perform_later(shop.shopify_domain, new_subscription)
40
+ DiscoApp::SubscriptionChangedJob.perform_later(shop, new_subscription)
41
41
 
42
42
  # Return the new subscription.
43
43
  new_subscription
@@ -1,3 +1,3 @@
1
1
  module DiscoApp
2
- VERSION = '0.9.3'
2
+ VERSION = '0.9.4'
3
3
  end
@@ -38,10 +38,9 @@ class DiscoAppGenerator < Rails::Generators::Base
38
38
  gem 'react-rails', '~> 1.6.0'
39
39
  gem 'classnames-rails', '~> 2.1.5'
40
40
  gem 'active_link_to', '~> 1.0.2'
41
- # Add premailer gem to Gemfile.
42
41
  gem 'premailer-rails', '~> 1.8.2'
43
- # Add explicit dependency on Nokogiri
44
42
  gem 'nokogiri', '~> 1.6.7.2'
43
+ gem 'render_anywhere', '~> 0.0.12', require: false
45
44
 
46
45
  # Add gems for development and testing only.
47
46
  gem_group :development, :test do
@@ -3,7 +3,7 @@ namespace :carrier_service do
3
3
  desc 'Synchronise carrier service across all installed shops.'
4
4
  task sync: :environment do
5
5
  DiscoApp::Shop.installed.has_active_shopify_plan.each do |shop|
6
- DiscoApp::SynchroniseCarrierServiceJob.perform_later(shop.shopify_domain)
6
+ DiscoApp::SynchroniseCarrierServiceJob.perform_later(shop)
7
7
  end
8
8
  end
9
9
 
data/lib/tasks/shops.rake CHANGED
@@ -3,7 +3,7 @@ namespace :shops do
3
3
  desc 'Synchronise shop data across all installed shops.'
4
4
  task sync: :environment do
5
5
  DiscoApp::Shop.installed.has_active_shopify_plan.each do |shop|
6
- DiscoApp::ShopUpdateJob.perform_later(shop.shopify_domain)
6
+ DiscoApp::ShopUpdateJob.perform_later(shop)
7
7
  end
8
8
  end
9
9
 
@@ -3,7 +3,7 @@ namespace :webhooks do
3
3
  desc 'Synchronise webhooks across all installed shops.'
4
4
  task sync: :environment do
5
5
  DiscoApp::Shop.installed.has_active_shopify_plan.each do |shop|
6
- DiscoApp::SynchroniseWebhooksJob.perform_later(shop.shopify_domain)
6
+ DiscoApp::SynchroniseWebhooksJob.perform_later(shop)
7
7
  end
8
8
  end
9
9
 
@@ -1,6 +1,6 @@
1
1
  class ProductsCreateJob < DiscoApp::ShopJob
2
2
 
3
- def perform(shopify_domain, product_data)
3
+ def perform(shop, product_data)
4
4
  Product.synchronise(@shop, product_data)
5
5
  end
6
6
 
@@ -1,6 +1,6 @@
1
1
  class ProductsDeleteJob < DiscoApp::ShopJob
2
2
 
3
- def perform(shopify_domain, product_data)
3
+ def perform(shop, product_data)
4
4
  Product.synchronise_deletion(@shop, product_data)
5
5
  end
6
6
 
@@ -1,6 +1,6 @@
1
1
  class ProductsUpdateJob < DiscoApp::ShopJob
2
2
 
3
- def perform(shopify_domain, product_data)
3
+ def perform(shop, product_data)
4
4
  Product.synchronise(@shop, product_data)
5
5
  end
6
6
 
@@ -0,0 +1,8 @@
1
+ class JsConfiguration < ActiveRecord::Base
2
+ include DiscoApp::Concerns::RendersAssets
3
+
4
+ belongs_to :shop, class_name: 'DiscoApp::Shop'
5
+
6
+ renders_assets :js_assets, assets: 'test.js', triggered_by: 'locale'
7
+
8
+ end
@@ -0,0 +1,10 @@
1
+ class WidgetConfiguration < ActiveRecord::Base
2
+ include DiscoApp::Concerns::RendersAssets
3
+
4
+ belongs_to :shop, class_name: 'DiscoApp::Shop'
5
+
6
+ renders_assets :widget_assets, assets: ['widget.scss', 'widget.js'], triggered_by: ['locale', 'background_color']
7
+ renders_assets :liquid_assets, assets: 'widget.liquid', triggered_by: ['locale']
8
+ renders_assets :script_tag_assets, assets: 'script_tag.js', script_tags: 'script_tag.js'
9
+
10
+ end
@@ -0,0 +1 @@
1
+ (function() { console.log('Script Tag!') });
@@ -0,0 +1 @@
1
+ var locale = '<%= @js_configuration.locale %>';
@@ -0,0 +1,2 @@
1
+ var locale = '<%= @widget_configuration.locale %>';
2
+ var cssUrl = '<%= @public_urls[:'widget.scss'] %>';
@@ -0,0 +1,3 @@
1
+ #widget {
2
+ background-color: <%= @widget_configuration.background_color %>;
3
+ }
@@ -0,0 +1,19 @@
1
+ class CreateAssetModels < ActiveRecord::Migration
2
+ def change
3
+ create_table :js_configurations do |t|
4
+ t.integer :shop_id, limit: 8
5
+ t.string :label, default: 'Default'
6
+ t.string :locale, default: 'en'
7
+ end
8
+
9
+ create_table :widget_configurations do |t|
10
+ t.integer :shop_id, limit: 8
11
+ t.string :label, default: 'Default'
12
+ t.string :locale, default: 'en'
13
+ t.string :background_color, default: '#FFFFFF'
14
+ end
15
+
16
+ add_foreign_key :js_configurations, :disco_app_shops, column: :shop_id
17
+ add_foreign_key :widget_configurations, :disco_app_shops, column: :shop_id
18
+ end
19
+ end
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20160521135510) do
14
+ ActiveRecord::Schema.define(version: 20160530160739) do
15
15
 
16
16
  # These are extensions that must be enabled in order to support this database
17
17
  enable_extension "plpgsql"
@@ -108,6 +108,12 @@ ActiveRecord::Schema.define(version: 20160521135510) do
108
108
  add_index "disco_app_subscriptions", ["plan_id"], name: "index_disco_app_subscriptions_on_plan_id", using: :btree
109
109
  add_index "disco_app_subscriptions", ["shop_id"], name: "index_disco_app_subscriptions_on_shop_id", using: :btree
110
110
 
111
+ create_table "js_configurations", force: :cascade do |t|
112
+ t.integer "shop_id", limit: 8
113
+ t.string "label", default: "Default"
114
+ t.string "locale", default: "en"
115
+ end
116
+
111
117
  create_table "products", force: :cascade do |t|
112
118
  t.integer "shop_id", limit: 8
113
119
  t.jsonb "data"
@@ -115,6 +121,13 @@ ActiveRecord::Schema.define(version: 20160521135510) do
115
121
  t.datetime "updated_at", null: false
116
122
  end
117
123
 
124
+ create_table "widget_configurations", force: :cascade do |t|
125
+ t.integer "shop_id", limit: 8
126
+ t.string "label", default: "Default"
127
+ t.string "locale", default: "en"
128
+ t.string "background_color", default: "#FFFFFF"
129
+ end
130
+
118
131
  add_foreign_key "disco_app_application_charges", "disco_app_shops", column: "shop_id"
119
132
  add_foreign_key "disco_app_application_charges", "disco_app_subscriptions", column: "subscription_id"
120
133
  add_foreign_key "disco_app_plan_codes", "disco_app_plans", column: "plan_id"
@@ -122,5 +135,7 @@ ActiveRecord::Schema.define(version: 20160521135510) do
122
135
  add_foreign_key "disco_app_recurring_application_charges", "disco_app_subscriptions", column: "subscription_id"
123
136
  add_foreign_key "disco_app_sessions", "disco_app_shops", column: "shop_id", on_delete: :cascade
124
137
  add_foreign_key "disco_app_subscriptions", "disco_app_plan_codes", column: "plan_code_id"
138
+ add_foreign_key "js_configurations", "disco_app_shops", column: "shop_id"
125
139
  add_foreign_key "products", "disco_app_shops", column: "shop_id"
140
+ add_foreign_key "widget_configurations", "disco_app_shops", column: "shop_id"
126
141
  end
@@ -0,0 +1,6 @@
1
+ {
2
+ "asset":{
3
+ "key":"assets/script_tag.js",
4
+ "value":"(function() { console.log('Script Tag!') });\n"
5
+ }
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "asset": {
3
+ "key": "assets/script_tag.js",
4
+ "public_url": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/script_tag.js?8557426387360348643",
5
+ "created_at": "2016-05-31T10:58:51-04:00",
6
+ "updated_at": "2016-05-31T10:58:51-04:00",
7
+ "content_type": "application/javascript",
8
+ "size": 45,
9
+ "theme_id": 106913286,
10
+ "warnings": []
11
+ }
12
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "script_tag":{
3
+ "event":"onload",
4
+ "src":"https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/script_tag.js?8557426387360348643"
5
+ }
6
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "script_tag": {
3
+ "id": 38138886,
4
+ "src": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/script_tag.js?8557426387360348643",
5
+ "event": "onload",
6
+ "created_at": "2016-05-31T11:09:17-04:00",
7
+ "updated_at": "2016-05-31T11:09:17-04:00",
8
+ "display_scope": "all"
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "asset":{
3
+ "key":"assets/test.js",
4
+ "value":"var locale = 'sv';\n"
5
+ }
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "asset": {
3
+ "key": "assets/test.js",
4
+ "public_url": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/test.js?8565972447222863489",
5
+ "created_at": "2016-05-31T08:22:07-04:00",
6
+ "updated_at": "2016-05-31T08:22:07-04:00",
7
+ "content_type": "application/javascript",
8
+ "size": 19,
9
+ "theme_id": 106913286,
10
+ "warnings": []
11
+ }
12
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "asset":{
3
+ "key":"assets/widget.js",
4
+ "value":"var locale = 'sv';\nvar cssUrl = 'https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/widget.scss.css?12368054146898033463';\n"
5
+ }
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "asset": {
3
+ "key": "assets/widget.js",
4
+ "public_url": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/widget.js?14127703044459766029",
5
+ "created_at": "2016-05-31T10:15:25-04:00",
6
+ "updated_at": "2016-05-31T10:15:25-04:00",
7
+ "content_type": "application/javascript",
8
+ "size": 123,
9
+ "theme_id": 106913286,
10
+ "warnings": []
11
+ }
12
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "asset":{
3
+ "key":"assets/widget.scss",
4
+ "value":"#widget {\n background-color: #006AA7;\n}\n"
5
+ }
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "asset": {
3
+ "key": "assets/widget.scss",
4
+ "public_url": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/widget.scss?12368054146898033463",
5
+ "created_at": "2016-05-31T08:40:24-04:00",
6
+ "updated_at": "2016-05-31T08:40:24-04:00",
7
+ "content_type": "text/css",
8
+ "size": 41,
9
+ "theme_id": 106913286,
10
+ "warnings": []
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "script_tags": [
3
+ {
4
+ "id": 38138886,
5
+ "src": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/script_tag.js?8557426387360348000",
6
+ "event": "onload",
7
+ "created_at": "2016-05-31T11:09:17-04:00",
8
+ "updated_at": "2016-05-31T11:09:17-04:00",
9
+ "display_scope": "all"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "script_tag":{
3
+ "id":38138886,
4
+ "src":"https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/script_tag.js?8557426387360348643",
5
+ "event":"onload",
6
+ "created_at":"2016-05-31T11:09:17-04:00",
7
+ "updated_at":"2016-05-31T11:09:17-04:00",
8
+ "display_scope":"all"
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "script_tag": {
3
+ "id": 38138886,
4
+ "src": "https://cdn.shopify.com/s/files/1/1308/2083/t/1/assets/script_tag.js?8557426387360348643",
5
+ "event": "onload",
6
+ "created_at": "2016-05-31T11:09:17-04:00",
7
+ "updated_at": "2016-05-31T11:09:17-04:00",
8
+ "display_scope": "all"
9
+ }
10
+ }
@@ -0,0 +1 @@
1
+ var locale = 'sv';
@@ -0,0 +1,3 @@
1
+ js_swedish:
2
+ shop: widget_store
3
+ locale: sv
@@ -0,0 +1,4 @@
1
+ widget_swedish:
2
+ shop: widget_store
3
+ locale: sv
4
+ background_color: '#006AA7'
@@ -20,7 +20,7 @@ class DiscoApp::AppInstalledJobTest < ActionController::TestCase
20
20
  test 'app installed job performs shop update job' do
21
21
  # Assert the main install job can be enqueued and performed.
22
22
  perform_enqueued_jobs do
23
- DiscoApp::AppInstalledJob.perform_later(@shop.shopify_domain)
23
+ DiscoApp::AppInstalledJob.perform_later(@shop)
24
24
  end
25
25
 
26
26
  # Assert the update shop job was performed.
@@ -32,7 +32,7 @@ class DiscoApp::AppInstalledJobTest < ActionController::TestCase
32
32
  @shop.current_subscription.destroy
33
33
 
34
34
  perform_enqueued_jobs do
35
- DiscoApp::AppInstalledJob.perform_later(@shop.shopify_domain)
35
+ DiscoApp::AppInstalledJob.perform_later(@shop)
36
36
  end
37
37
 
38
38
  # Assert the shop was subscribed to the development plan.
@@ -43,7 +43,7 @@ class DiscoApp::AppInstalledJobTest < ActionController::TestCase
43
43
  @shop.current_subscription.destroy
44
44
 
45
45
  perform_enqueued_jobs do
46
- DiscoApp::AppInstalledJob.perform_later(@shop.shopify_domain, 'PODCAST', 'smpodcast')
46
+ DiscoApp::AppInstalledJob.perform_later(@shop, 'PODCAST', 'smpodcast')
47
47
  end
48
48
 
49
49
  # Assert the shop was subscribed to the development plan.
@@ -7,7 +7,7 @@ class DiscoApp::AppUninstalledJobTest < ActionController::TestCase
7
7
  @shop = disco_app_shops(:widget_store)
8
8
 
9
9
  perform_enqueued_jobs do
10
- DiscoApp::AppUninstalledJob.perform_later(@shop.shopify_domain, {})
10
+ DiscoApp::AppUninstalledJob.perform_later(@shop, {})
11
11
  end
12
12
  end
13
13
 
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ class DiscoApp::RendersAssetsTest < ActiveSupport::TestCase
4
+ include ActiveJob::TestHelper
5
+ include DiscoApp::Test::ShopifyAPI
6
+
7
+ def setup
8
+ @shop = disco_app_shops(:widget_store)
9
+ @js_configuration = js_configurations(:js_swedish)
10
+ @widget_configuration = widget_configurations(:widget_swedish)
11
+ end
12
+
13
+ def teardown
14
+ @shop = nil
15
+ @js_configuration = nil
16
+ @widget_configuration = nil
17
+ end
18
+
19
+ ##
20
+ # Test queueing behaviour.
21
+ ##
22
+
23
+ test 'rendering of javascript asset group queued when locale changed' do
24
+ assert_enqueued_with(job: DiscoApp::RenderAssetGroupJob) do
25
+ @js_configuration.update(locale: :no)
26
+ end
27
+ end
28
+
29
+ test 'rendering of javascript asset group not queued when label changed' do
30
+ assert_no_enqueued_jobs do
31
+ @js_configuration.update(label: 'Sample')
32
+ end
33
+ end
34
+
35
+ test 'rendering of widget asset group queued when locale changed' do
36
+ assert_enqueued_with(job: DiscoApp::RenderAssetGroupJob, args: [@widget_configuration.shop, @widget_configuration, 'widget_assets']) do
37
+ @widget_configuration.update(locale: :no)
38
+ end
39
+ end
40
+
41
+ test 'rendering of liquid asset group queued when locale changed' do
42
+ assert_enqueued_with(job: DiscoApp::RenderAssetGroupJob, args: [@widget_configuration.shop, @widget_configuration, 'liquid_assets']) do
43
+ @widget_configuration.update(locale: :no)
44
+ end
45
+ end
46
+
47
+ test 'rendering of widget asset group queued when background color changed' do
48
+ assert_enqueued_with(job: DiscoApp::RenderAssetGroupJob, args: [@widget_configuration.shop, @widget_configuration, 'widget_assets']) do
49
+ @widget_configuration.update(background_color: '#FF0000')
50
+ end
51
+ end
52
+
53
+ test 'rendering of liquid asset group not queued when background color changed' do
54
+ assert_enqueued_jobs 1 do
55
+ @widget_configuration.update(background_color: '#FF0000')
56
+ end
57
+ end
58
+
59
+ ##
60
+ # Test rendering behaviour.
61
+ ##
62
+
63
+ test 'individual js asset renders correctly' do
64
+ assert_equal asset_fixture('test.js'), @js_configuration.send('render_asset_group_asset', 'test.js', {})
65
+ end
66
+
67
+ test 'js asset group renders and uploads to shopify' do
68
+ stub_api_request(:put, "#{@shop.admin_url}/assets.json", 'widget_store/assets/create_test_js')
69
+ @js_configuration.render_asset_group(:js_assets)
70
+ end
71
+
72
+ test 'widget asset group renders and uploads to shopify' do
73
+ stub_api_request(:put, "#{@shop.admin_url}/assets.json", 'widget_store/assets/create_widget_scss')
74
+ stub_api_request(:put, "#{@shop.admin_url}/assets.json", 'widget_store/assets/create_widget_js')
75
+ @widget_configuration.render_asset_group(:widget_assets)
76
+ end
77
+
78
+ test 'script tag asset group renders, uploads to shopify and creates new script tag' do
79
+ stub_api_request(:put, "#{@shop.admin_url}/assets.json", 'widget_store/assets/create_script_tag_js')
80
+ stub_api_request(:get, "#{@shop.admin_url}/script_tags.json", 'widget_store/assets/get_script_tags_empty')
81
+ stub_api_request(:post, "#{@shop.admin_url}/script_tags.json", 'widget_store/assets/create_script_tag')
82
+ @widget_configuration.render_asset_group(:script_tag_assets)
83
+ end
84
+
85
+ test 'script tag asset group renders, uploads to shopify and updates existing script tag' do
86
+ stub_api_request(:put, "#{@shop.admin_url}/assets.json", 'widget_store/assets/create_script_tag_js')
87
+ stub_api_request(:get, "#{@shop.admin_url}/script_tags.json", 'widget_store/assets/get_script_tags_preexisting')
88
+ stub_api_request(:put, "#{@shop.admin_url}/script_tags/38138886.json", 'widget_store/assets/update_script_tag')
89
+ @widget_configuration.render_asset_group(:script_tag_assets)
90
+ end
91
+
92
+ private
93
+
94
+ # Return an asset fixture as a string.
95
+ def asset_fixture(path)
96
+ filename = File.join(File.dirname(File.dirname(File.dirname(__FILE__))), 'fixtures', 'assets', "#{path}")
97
+ File.read(filename)
98
+ end
99
+
100
+ end
@@ -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
8
+ elsif method == :post or 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)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: disco_app
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gavin Ballard
@@ -220,6 +220,20 @@ dependencies:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
222
  version: 2.1.5
223
+ - !ruby/object:Gem::Dependency
224
+ name: render_anywhere
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: 0.0.12
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: 0.0.12
223
237
  - !ruby/object:Gem::Dependency
224
238
  name: sqlite3
225
239
  requirement: !ruby/object:Gem::Requirement
@@ -389,10 +403,12 @@ files:
389
403
  - app/jobs/disco_app/app_uninstalled_job.rb
390
404
  - app/jobs/disco_app/concerns/app_installed_job.rb
391
405
  - app/jobs/disco_app/concerns/app_uninstalled_job.rb
406
+ - app/jobs/disco_app/concerns/render_asset_group_job.rb
392
407
  - app/jobs/disco_app/concerns/shop_update_job.rb
393
408
  - app/jobs/disco_app/concerns/subscription_changed_job.rb
394
409
  - app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb
395
410
  - app/jobs/disco_app/concerns/synchronise_webhooks_job.rb
411
+ - app/jobs/disco_app/render_asset_group_job.rb
396
412
  - app/jobs/disco_app/shop_job.rb
397
413
  - app/jobs/disco_app/shop_update_job.rb
398
414
  - app/jobs/disco_app/subscription_changed_job.rb
@@ -403,6 +419,7 @@ files:
403
419
  - app/models/disco_app/concerns/app_settings.rb
404
420
  - app/models/disco_app/concerns/plan.rb
405
421
  - app/models/disco_app/concerns/plan_code.rb
422
+ - app/models/disco_app/concerns/renders_assets.rb
406
423
  - app/models/disco_app/concerns/shop.rb
407
424
  - app/models/disco_app/concerns/subscription.rb
408
425
  - app/models/disco_app/concerns/synchronises.rb
@@ -522,7 +539,13 @@ files:
522
539
  - test/dummy/app/jobs/products_delete_job.rb
523
540
  - test/dummy/app/jobs/products_update_job.rb
524
541
  - test/dummy/app/models/disco_app/shop.rb
542
+ - test/dummy/app/models/js_configuration.rb
525
543
  - test/dummy/app/models/product.rb
544
+ - test/dummy/app/models/widget_configuration.rb
545
+ - test/dummy/app/views/assets/script_tag.js.erb
546
+ - test/dummy/app/views/assets/test.js.erb
547
+ - test/dummy/app/views/assets/widget.js.erb
548
+ - test/dummy/app/views/assets/widget.scss.erb
526
549
  - test/dummy/app/views/home/index.html.erb
527
550
  - test/dummy/bin/bundle
528
551
  - test/dummy/bin/rails
@@ -554,11 +577,28 @@ files:
554
577
  - test/dummy/config/routes.rb
555
578
  - test/dummy/config/secrets.yml
556
579
  - test/dummy/db/migrate/20160307182229_create_products.rb
580
+ - test/dummy/db/migrate/20160530160739_create_asset_models.rb
557
581
  - test/dummy/db/schema.rb
558
582
  - test/dummy/public/404.html
559
583
  - test/dummy/public/422.html
560
584
  - test/dummy/public/500.html
561
585
  - test/dummy/public/favicon.ico
586
+ - test/fixtures/api/widget_store/assets/create_script_tag_js_request.json
587
+ - test/fixtures/api/widget_store/assets/create_script_tag_js_response.json
588
+ - test/fixtures/api/widget_store/assets/create_script_tag_request.json
589
+ - test/fixtures/api/widget_store/assets/create_script_tag_response.json
590
+ - test/fixtures/api/widget_store/assets/create_test_js_request.json
591
+ - test/fixtures/api/widget_store/assets/create_test_js_response.json
592
+ - test/fixtures/api/widget_store/assets/create_widget_js_request.json
593
+ - test/fixtures/api/widget_store/assets/create_widget_js_response.json
594
+ - test/fixtures/api/widget_store/assets/create_widget_scss_request.json
595
+ - test/fixtures/api/widget_store/assets/create_widget_scss_response.json
596
+ - test/fixtures/api/widget_store/assets/get_script_tags_empty_request.json
597
+ - test/fixtures/api/widget_store/assets/get_script_tags_empty_response.json
598
+ - test/fixtures/api/widget_store/assets/get_script_tags_preexisting_request.json
599
+ - test/fixtures/api/widget_store/assets/get_script_tags_preexisting_response.json
600
+ - test/fixtures/api/widget_store/assets/update_script_tag_request.json
601
+ - test/fixtures/api/widget_store/assets/update_script_tag_response.json
562
602
  - test/fixtures/api/widget_store/charges/activate_application_charge_request.json
563
603
  - test/fixtures/api/widget_store/charges/activate_application_charge_response.json
564
604
  - test/fixtures/api/widget_store/charges/activate_recurring_application_charge_request.json
@@ -577,21 +617,25 @@ files:
577
617
  - test/fixtures/api/widget_store/charges/get_pending_recurring_application_charge_response.json
578
618
  - test/fixtures/api/widget_store/shop.json
579
619
  - test/fixtures/api/widget_store/webhooks.json
620
+ - test/fixtures/assets/test.js
580
621
  - test/fixtures/disco_app/application_charges.yml
581
622
  - test/fixtures/disco_app/plan_codes.yml
582
623
  - test/fixtures/disco_app/plans.yml
583
624
  - test/fixtures/disco_app/recurring_application_charges.yml
584
625
  - test/fixtures/disco_app/shops.yml
585
626
  - test/fixtures/disco_app/subscriptions.yml
627
+ - test/fixtures/js_configurations.yml
586
628
  - test/fixtures/products.yml
587
629
  - test/fixtures/webhooks/app_uninstalled.json
588
630
  - test/fixtures/webhooks/product_created.json
589
631
  - test/fixtures/webhooks/product_deleted.json
590
632
  - test/fixtures/webhooks/product_updated.json
633
+ - test/fixtures/widget_configurations.yml
591
634
  - test/integration/synchronises_test.rb
592
635
  - test/jobs/disco_app/app_installed_job_test.rb
593
636
  - test/jobs/disco_app/app_uninstalled_job_test.rb
594
637
  - test/models/disco_app/plan_test.rb
638
+ - test/models/disco_app/renders_assets_test.rb
595
639
  - test/models/disco_app/session_test.rb
596
640
  - test/models/disco_app/shop_test.rb
597
641
  - test/models/disco_app/subscription_test.rb
@@ -649,7 +693,14 @@ test_files:
649
693
  - test/dummy/app/helpers/application_helper.rb
650
694
  - test/dummy/app/models/disco_app/shop.rb
651
695
  - test/dummy/app/models/product.rb
696
+ - test/dummy/app/models/widget_configuration.rb
697
+ - test/dummy/app/models/js_configuration.rb
698
+ - test/dummy/app/views/assets/script_tag.js.erb
699
+ - test/dummy/app/views/assets/widget.scss.erb
700
+ - test/dummy/app/views/assets/test.js.erb
701
+ - test/dummy/app/views/assets/widget.js.erb
652
702
  - test/dummy/app/views/home/index.html.erb
703
+ - test/dummy/db/migrate/20160530160739_create_asset_models.rb
653
704
  - test/dummy/db/migrate/20160307182229_create_products.rb
654
705
  - test/dummy/db/schema.rb
655
706
  - test/dummy/config/locales/en.yml
@@ -676,6 +727,22 @@ test_files:
676
727
  - test/dummy/config/database.yml
677
728
  - test/dummy/config/database.gitlab-ci.yml
678
729
  - test/dummy/config/application.rb
730
+ - test/fixtures/api/widget_store/assets/create_test_js_response.json
731
+ - test/fixtures/api/widget_store/assets/create_widget_js_response.json
732
+ - test/fixtures/api/widget_store/assets/create_test_js_request.json
733
+ - test/fixtures/api/widget_store/assets/update_script_tag_request.json
734
+ - test/fixtures/api/widget_store/assets/create_script_tag_response.json
735
+ - test/fixtures/api/widget_store/assets/create_script_tag_js_response.json
736
+ - test/fixtures/api/widget_store/assets/create_widget_scss_request.json
737
+ - test/fixtures/api/widget_store/assets/update_script_tag_response.json
738
+ - test/fixtures/api/widget_store/assets/create_script_tag_js_request.json
739
+ - test/fixtures/api/widget_store/assets/create_script_tag_request.json
740
+ - test/fixtures/api/widget_store/assets/get_script_tags_preexisting_response.json
741
+ - test/fixtures/api/widget_store/assets/create_widget_scss_response.json
742
+ - test/fixtures/api/widget_store/assets/get_script_tags_preexisting_request.json
743
+ - test/fixtures/api/widget_store/assets/get_script_tags_empty_response.json
744
+ - test/fixtures/api/widget_store/assets/get_script_tags_empty_request.json
745
+ - test/fixtures/api/widget_store/assets/create_widget_js_request.json
679
746
  - test/fixtures/api/widget_store/webhooks.json
680
747
  - test/fixtures/api/widget_store/charges/create_application_charge_response.json
681
748
  - test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_response.json
@@ -694,6 +761,9 @@ test_files:
694
761
  - test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_request.json
695
762
  - test/fixtures/api/widget_store/charges/activate_application_charge_request.json
696
763
  - test/fixtures/api/widget_store/shop.json
764
+ - test/fixtures/assets/test.js
765
+ - test/fixtures/widget_configurations.yml
766
+ - test/fixtures/js_configurations.yml
697
767
  - test/fixtures/disco_app/plan_codes.yml
698
768
  - test/fixtures/disco_app/shops.yml
699
769
  - test/fixtures/disco_app/application_charges.yml
@@ -723,5 +793,6 @@ test_files:
723
793
  - test/models/disco_app/shop_test.rb
724
794
  - test/models/disco_app/session_test.rb
725
795
  - test/models/disco_app/subscription_test.rb
796
+ - test/models/disco_app/renders_assets_test.rb
726
797
  - test/services/disco_app/charges_service_test.rb
727
798
  - test/services/disco_app/subscription_service_test.rb