disco_app 0.7.0

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 (166) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +37 -0
  3. data/app/assets/images/disco_app/icon.svg +1 -0
  4. data/app/assets/javascripts/disco_app/components/shopify_admin_link.js.jsx +29 -0
  5. data/app/assets/javascripts/disco_app/components.js +5 -0
  6. data/app/assets/javascripts/disco_app/disco_app.js +7 -0
  7. data/app/assets/javascripts/disco_app/frame.js +152 -0
  8. data/app/assets/javascripts/disco_app/shopify-turbolinks.js +7 -0
  9. data/app/assets/stylesheets/disco_app/bootstrap/_custom.scss +54 -0
  10. data/app/assets/stylesheets/disco_app/bootstrap/_variables.scss +872 -0
  11. data/app/assets/stylesheets/disco_app/disco/_buttons.scss +31 -0
  12. data/app/assets/stylesheets/disco_app/disco/_cards.scss +51 -0
  13. data/app/assets/stylesheets/disco_app/disco/_forms.scss +23 -0
  14. data/app/assets/stylesheets/disco_app/disco/_grid.scss +58 -0
  15. data/app/assets/stylesheets/disco_app/disco/_sections.scss +61 -0
  16. data/app/assets/stylesheets/disco_app/disco/_tables.scss +57 -0
  17. data/app/assets/stylesheets/disco_app/disco/_tabs.scss +61 -0
  18. data/app/assets/stylesheets/disco_app/disco/_type.scss +39 -0
  19. data/app/assets/stylesheets/disco_app/disco/mixins/_flexbox.scss +394 -0
  20. data/app/assets/stylesheets/disco_app/disco_app.scss +16 -0
  21. data/app/assets/stylesheets/disco_app/frame/_buttons.scss +54 -0
  22. data/app/assets/stylesheets/disco_app/frame/_forms.scss +26 -0
  23. data/app/assets/stylesheets/disco_app/frame/_layout.scss +77 -0
  24. data/app/assets/stylesheets/disco_app/frame/_type.scss +32 -0
  25. data/app/assets/stylesheets/disco_app/frame.scss +9 -0
  26. data/app/controllers/disco_app/app_proxy_controller.rb +41 -0
  27. data/app/controllers/disco_app/authenticated_controller.rb +44 -0
  28. data/app/controllers/disco_app/carrier_request_controller.rb +28 -0
  29. data/app/controllers/disco_app/charges_controller.rb +30 -0
  30. data/app/controllers/disco_app/frame_controller.rb +9 -0
  31. data/app/controllers/disco_app/install_controller.rb +26 -0
  32. data/app/controllers/disco_app/webhooks_controller.rb +42 -0
  33. data/app/helpers/disco_app/application_helper.rb +28 -0
  34. data/app/jobs/disco_app/app_installed_job.rb +3 -0
  35. data/app/jobs/disco_app/app_uninstalled_job.rb +3 -0
  36. data/app/jobs/disco_app/concerns/app_installed_job.rb +22 -0
  37. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +23 -0
  38. data/app/jobs/disco_app/concerns/shop_update_job.rb +16 -0
  39. data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +51 -0
  40. data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +53 -0
  41. data/app/jobs/disco_app/shop_job.rb +27 -0
  42. data/app/jobs/disco_app/shop_update_job.rb +3 -0
  43. data/app/jobs/disco_app/synchronise_carrier_service_job.rb +3 -0
  44. data/app/jobs/disco_app/synchronise_webhooks_job.rb +3 -0
  45. data/app/models/disco_app/concerns/plan.rb +14 -0
  46. data/app/models/disco_app/concerns/shop.rb +71 -0
  47. data/app/models/disco_app/concerns/subscription.rb +14 -0
  48. data/app/models/disco_app/plan.rb +3 -0
  49. data/app/models/disco_app/session_storage.rb +18 -0
  50. data/app/models/disco_app/shop.rb +3 -0
  51. data/app/models/disco_app/subscription.rb +3 -0
  52. data/app/services/disco_app/charges_service.rb +73 -0
  53. data/app/services/disco_app/subscription_service.rb +25 -0
  54. data/app/services/disco_app/webhook_service.rb +30 -0
  55. data/app/views/disco_app/charges/activate.html.erb +1 -0
  56. data/app/views/disco_app/charges/create.html.erb +1 -0
  57. data/app/views/disco_app/charges/new.html.erb +45 -0
  58. data/app/views/disco_app/frame/frame.html.erb +36 -0
  59. data/app/views/disco_app/install/installing.html.erb +7 -0
  60. data/app/views/disco_app/install/uninstalling.html.erb +1 -0
  61. data/app/views/disco_app/proxy_errors/404.html.erb +1 -0
  62. data/app/views/disco_app/shared/_card.html.erb +14 -0
  63. data/app/views/disco_app/shared/_section.html.erb +17 -0
  64. data/app/views/layouts/application.html.erb +18 -0
  65. data/app/views/layouts/embedded_app.html.erb +41 -0
  66. data/app/views/layouts/embedded_app_modal.html.erb +17 -0
  67. data/app/views/sessions/new.html.erb +26 -0
  68. data/config/routes.rb +26 -0
  69. data/db/migrate/20150525000000_create_shops_if_not_existent.rb +15 -0
  70. data/db/migrate/20150525162112_add_status_to_shops.rb +5 -0
  71. data/db/migrate/20150525171422_add_meta_to_shops.rb +11 -0
  72. data/db/migrate/20150629210346_add_charge_status_to_shop.rb +5 -0
  73. data/db/migrate/20150814214025_add_more_meta_to_shops.rb +15 -0
  74. data/db/migrate/20151017231302_create_disco_app_plans.rb +13 -0
  75. data/db/migrate/20151017232027_create_disco_app_subscriptions.rb +15 -0
  76. data/db/migrate/20151017234409_move_shop_to_disco_app_engine.rb +5 -0
  77. data/db/migrate/20160112233706_create_disco_app_sessions.rb +12 -0
  78. data/db/migrate/20160113194418_add_shop_id_to_disco_app_sessions.rb +6 -0
  79. data/lib/disco_app/engine.rb +25 -0
  80. data/lib/disco_app/session.rb +12 -0
  81. data/lib/disco_app/support/file_fixtures.rb +23 -0
  82. data/lib/disco_app/test_help.rb +11 -0
  83. data/lib/disco_app/version.rb +3 -0
  84. data/lib/disco_app.rb +4 -0
  85. data/lib/generators/disco_app/USAGE +5 -0
  86. data/lib/generators/disco_app/disco_app_generator.rb +161 -0
  87. data/lib/generators/disco_app/mailify/mailify_generator.rb +54 -0
  88. data/lib/generators/disco_app/reactify/reactify_generator.rb +45 -0
  89. data/lib/generators/disco_app/rollbarify/rollbarify_generator.rb +26 -0
  90. data/lib/generators/disco_app/rollbarify/templates/initializers/rollbar.rb +12 -0
  91. data/lib/generators/disco_app/templates/assets/javascripts/application.js +17 -0
  92. data/lib/generators/disco_app/templates/assets/stylesheets/application.scss +5 -0
  93. data/lib/generators/disco_app/templates/config/puma.rb +15 -0
  94. data/lib/generators/disco_app/templates/controllers/home_controller.rb +7 -0
  95. data/lib/generators/disco_app/templates/initializers/disco_app.rb +1 -0
  96. data/lib/generators/disco_app/templates/initializers/session_store.rb +2 -0
  97. data/lib/generators/disco_app/templates/initializers/shopify_app.rb +7 -0
  98. data/lib/generators/disco_app/templates/initializers/shopify_session_repository.rb +7 -0
  99. data/lib/generators/disco_app/templates/root/Procfile +2 -0
  100. data/lib/generators/disco_app/templates/views/home/index.html.erb +2 -0
  101. data/lib/tasks/carrier_service.rake +10 -0
  102. data/lib/tasks/sessions.rake +9 -0
  103. data/lib/tasks/start.rake +3 -0
  104. data/lib/tasks/webhooks.rake +10 -0
  105. data/test/controllers/disco_app/install_controller_test.rb +50 -0
  106. data/test/controllers/disco_app/webhooks_controller_test.rb +58 -0
  107. data/test/controllers/home_controller_test.rb +61 -0
  108. data/test/disco_app_test.rb +7 -0
  109. data/test/dummy/Rakefile +6 -0
  110. data/test/dummy/app/assets/javascripts/application.js +17 -0
  111. data/test/dummy/app/assets/stylesheets/application.scss +5 -0
  112. data/test/dummy/app/controllers/application_controller.rb +6 -0
  113. data/test/dummy/app/controllers/home_controller.rb +7 -0
  114. data/test/dummy/app/helpers/application_helper.rb +2 -0
  115. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +11 -0
  116. data/test/dummy/app/models/disco_app/shop.rb +15 -0
  117. data/test/dummy/app/views/home/index.html.erb +2 -0
  118. data/test/dummy/bin/bundle +3 -0
  119. data/test/dummy/bin/rails +4 -0
  120. data/test/dummy/bin/rake +4 -0
  121. data/test/dummy/bin/setup +29 -0
  122. data/test/dummy/config/application.rb +41 -0
  123. data/test/dummy/config/boot.rb +5 -0
  124. data/test/dummy/config/database.yml +25 -0
  125. data/test/dummy/config/environment.rb +5 -0
  126. data/test/dummy/config/environments/development.rb +41 -0
  127. data/test/dummy/config/environments/production.rb +85 -0
  128. data/test/dummy/config/environments/test.rb +42 -0
  129. data/test/dummy/config/initializers/assets.rb +11 -0
  130. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  131. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  132. data/test/dummy/config/initializers/disco_app.rb +1 -0
  133. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  134. data/test/dummy/config/initializers/inflections.rb +16 -0
  135. data/test/dummy/config/initializers/mime_types.rb +4 -0
  136. data/test/dummy/config/initializers/omniauth.rb +9 -0
  137. data/test/dummy/config/initializers/session_store.rb +2 -0
  138. data/test/dummy/config/initializers/shopify_app.rb +7 -0
  139. data/test/dummy/config/initializers/shopify_session_repository.rb +7 -0
  140. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  141. data/test/dummy/config/locales/en.yml +23 -0
  142. data/test/dummy/config/routes.rb +8 -0
  143. data/test/dummy/config/secrets.yml +22 -0
  144. data/test/dummy/config.ru +4 -0
  145. data/test/dummy/db/schema.rb +81 -0
  146. data/test/dummy/public/404.html +67 -0
  147. data/test/dummy/public/422.html +67 -0
  148. data/test/dummy/public/500.html +66 -0
  149. data/test/dummy/public/favicon.ico +0 -0
  150. data/test/fixtures/api/widget_store/shop.json +46 -0
  151. data/test/fixtures/api/widget_store/webhooks.json +1 -0
  152. data/test/fixtures/disco_app/plans.yml +32 -0
  153. data/test/fixtures/disco_app/shops.yml +10 -0
  154. data/test/fixtures/disco_app/subscriptions.yml +26 -0
  155. data/test/fixtures/webhooks/app_uninstalled.json +46 -0
  156. data/test/integration/navigation_test.rb +10 -0
  157. data/test/jobs/disco_app/app_installed_job_test.rb +30 -0
  158. data/test/jobs/disco_app/app_uninstalled_job_test.rb +32 -0
  159. data/test/models/disco_app/plan_test.rb +5 -0
  160. data/test/models/disco_app/session_test.rb +31 -0
  161. data/test/models/disco_app/shop_test.rb +26 -0
  162. data/test/models/disco_app/subscription_test.rb +6 -0
  163. data/test/services/disco_app/subscription_service_test.rb +28 -0
  164. data/test/support/test_file_fixtures.rb +29 -0
  165. data/test/test_helper.rb +51 -0
  166. metadata +507 -0
@@ -0,0 +1,45 @@
1
+ <% provide(:title, 'Thankyou') %>
2
+
3
+ <div class="row">
4
+ <% if @shop.charge_declined? %>
5
+ <div class="alert alert-warning">
6
+ <p>
7
+ Oops! Looks like you declined the charge.
8
+ Unfortunately, you'll have to accept the charge on the next screen in order to continue installing the application.
9
+ </p>
10
+ </div>
11
+ <% elsif @shop.charge_cancelled? %>
12
+ <div class="alert alert-warning">
13
+ <p>
14
+ Your authorized charge for this application has expired.
15
+ This could have occurred if:
16
+ </p>
17
+ <ul>
18
+ <li>You uninstalled and reinstalled the application; or</li>
19
+ <li>Your plan level has changed.</li>
20
+ </ul>
21
+ <p>
22
+ In either case, it's no problem!
23
+ Simply click okay and you'll be asked to authorize a new charge.
24
+ Don't worry - you *wont'* be billed twice.
25
+ </p>
26
+ </div>
27
+ <% else %>
28
+ <div class="alert alert-success">
29
+ <p>
30
+ Thanks for installing <%= Rails.configuration.x.shopify_app_name %>!
31
+ </p>
32
+ <p>
33
+ Before we start setting things up, we need you to authorize a charge for the application.
34
+ </p>
35
+ </div>
36
+ <% end %>
37
+ </div>
38
+
39
+ <div class="row">
40
+ <%= form_tag disco_app.create_charge_path, method: 'POST', target: '_parent' do %>
41
+ <div class="form-group">
42
+ <%= submit_tag 'Okay', class: 'form-input' %>
43
+ </div>
44
+ <% end %>
45
+ </div>
@@ -0,0 +1,36 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dev Frame</title>
5
+ <%= stylesheet_link_tag 'disco_app/frame', media: 'all' %>
6
+ <%= javascript_include_tag 'disco_app/frame' %>
7
+ </head>
8
+ <body>
9
+ <!-- Left Sidebar -->
10
+ <aside id="sidebar"></aside>
11
+
12
+ <!-- Header Bar -->
13
+ <header id="header">
14
+ <h1 id="header-title">
15
+ <img id="header-title-icon" src="<%= image_path('disco_app/icon.svg') %>" width="20" height="20" />
16
+ Shopify Dev Frame
17
+ </h1>
18
+ <div id="header-actions">
19
+ <!-- No action. -->
20
+ </div>
21
+ </header>
22
+
23
+ <!-- Content iFrame -->
24
+ <section id="content-wrapper">
25
+ <iframe id="content" src="/"></iframe>
26
+ </section>
27
+
28
+ <!-- Setup FrameApp. -->
29
+ <script type="text/javascript">
30
+ FrameApp.init({
31
+ debug: true,
32
+ iframe: document.getElementById('content')
33
+ });
34
+ </script>
35
+ </body>
36
+ </html>
@@ -0,0 +1,7 @@
1
+ <% content_for :extra_head do %>
2
+ <meta http-equiv="refresh" content="5">
3
+ <% end %>
4
+
5
+ <p>
6
+ Installing, please wait...
7
+ </p>
@@ -0,0 +1 @@
1
+ uninstalling
@@ -0,0 +1 @@
1
+ 404 Not Found
@@ -0,0 +1,14 @@
1
+ <% disabled ||= false %>
2
+ <div class="next-card <% if disabled %>next-card--disabled<% end %>">
3
+ <% if content_for?(:card_header) %>
4
+ <header class="next-card__header">
5
+ <%= content_for :card_header %>
6
+ </header>
7
+ <% end %>
8
+ <%= content_for :card_content %>
9
+ <% if content_for?(:card_footer) %>
10
+ <footer class="next-card__footer">
11
+ <%= content_for :card_footer %>
12
+ </footer>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,17 @@
1
+ <section class="section">
2
+ <div class="layout-content">
3
+
4
+ <aside class="layout-content__sidebar layout-content__first">
5
+ <% if content_for?(:section_summary) %>
6
+ <div class="section-summary">
7
+ <%= content_for :section_summary %>
8
+ </div>
9
+ <% end %>
10
+ </aside>
11
+
12
+ <section class="layout-content__main">
13
+ <%= content_for :section_content %>
14
+ </section>
15
+
16
+ </div>
17
+ </section>
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= yield(:title) %></title>
5
+
6
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
7
+
8
+ <%= csrf_meta_tags %>
9
+
10
+ <%= yield :extra_head %>
11
+ </head>
12
+ <body>
13
+
14
+ <%= yield %>
15
+
16
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
17
+ </body>
18
+ </html>
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= yield(:title) %></title>
5
+
6
+ <script src="//cdn.shopify.com/s/assets/external/app.js?<%= Time.now.strftime('%Y%m%d%H') %>"></script>
7
+ <script type="text/javascript">
8
+ // Initialise the Shopify App.
9
+ ShopifyApp.init({
10
+ "apiKey": "<%= ShopifyApp.configuration.api_key %>",
11
+ "shopOrigin": "<%= "https://#{ @shop_session.url }" if @shop_session %>",
12
+ "debug": <%= Rails.env.development? ? 'true' : 'false' %>
13
+ });
14
+ </script>
15
+
16
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
17
+
18
+ <%= csrf_meta_tags %>
19
+
20
+ <%= yield :extra_head %>
21
+ </head>
22
+ <body>
23
+ <script type="text/javascript">
24
+ ShopifyApp.Bar.initialize({
25
+ title: "<%= yield(:title) %>",
26
+ icon: "<%= image_url("disco_app/icon.svg") %>",
27
+ buttons: <%= content_for?(:buttons) ? content_for(:buttons) : '{}' %>
28
+ });
29
+ </script>
30
+
31
+ <%= yield %>
32
+
33
+ <% flash.each do |key, message| %>
34
+ <script type="text/javascript">
35
+ ShopifyApp.flash<%= (key == 'error') ? 'Error' : 'Notice' %>('<%= message %>');
36
+ </script>
37
+ <% end %>
38
+
39
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true, 'data-turbolinks-eval' => false %>
40
+ </body>
41
+ </html>
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= yield(:title) %></title>
5
+
6
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
7
+
8
+ <%= csrf_meta_tags %>
9
+
10
+ <%= yield :extra_head %>
11
+ </head>
12
+ <body>
13
+
14
+ <%= yield %>
15
+
16
+ </body>
17
+ </html>
@@ -0,0 +1,26 @@
1
+ <% provide(:title, 'Install') %>
2
+
3
+ <%= form_tag shopify_app.login_path do %>
4
+ <div class="modal-dialog">
5
+ <div class="modal-content">
6
+ <div class="modal-body">
7
+
8
+ <% flash.each do |message_type, message| %>
9
+ <div class="alert alert-<%= message_type %>"><%= message %></div>
10
+ <% end %>
11
+
12
+ <div class="form-group">
13
+ <div class="input-group">
14
+ <div class="input-group-addon">http://</div>
15
+ <input type="text" class="form-control" id="shop" name="shop" placeholder="your-store" autocomplete="off" autofocus="on" />
16
+ <div class="input-group-addon">.myshopify.com</div>
17
+ </div>
18
+ </div>
19
+
20
+ </div>
21
+ <div class="modal-footer">
22
+ <button type="submit" class="btn btn-primary">Install</button>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,26 @@
1
+ DiscoApp::Engine.routes.draw do
2
+
3
+ controller :webhooks do
4
+ post 'webhooks' => :process_webhook, as: :webhooks
5
+ end
6
+
7
+ controller :charges do
8
+ get 'charges/new' => :new, as: :new_charge
9
+ post 'charges/create' => :create, as: :create_charge
10
+ get 'charges/activate' => :activate, as: :activate_charge
11
+ end
12
+
13
+ controller :install do
14
+ get 'install' => :install, as: :install
15
+ get 'installing' => :installing, as: :installing
16
+ get 'uninstalling' => :uninstalling, as: :uninstalling
17
+ end
18
+
19
+ # Make the embedded app frame emulator available in development.
20
+ if Rails.env.development?
21
+ controller :frame do
22
+ get 'frame' => :frame, as: :frame
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,15 @@
1
+ class CreateShopsIfNotExistent < ActiveRecord::Migration
2
+
3
+ def change
4
+ unless table_exists? :shops or table_exists? :disco_app_shops
5
+ create_table :shops do |t|
6
+ t.string :shopify_domain, null: false
7
+ t.string :shopify_token, null: false
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :shops, :shopify_domain, unique: true
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,5 @@
1
+ class AddStatusToShops < ActiveRecord::Migration
2
+ def change
3
+ add_column :shops, :status, :integer, default: 0
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class AddMetaToShops < ActiveRecord::Migration
2
+ def change
3
+ add_column :shops, :email, :string
4
+ add_column :shops, :country_name, :string
5
+ add_column :shops, :currency, :string
6
+ add_column :shops, :money_format, :string
7
+ add_column :shops, :money_with_currency_format, :string
8
+ add_column :shops, :domain, :string
9
+ add_column :shops, :plan_name, :string
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddChargeStatusToShop < ActiveRecord::Migration
2
+ def change
3
+ add_column :shops, :charge_status, :integer, default: 6
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class AddMoreMetaToShops < ActiveRecord::Migration
2
+ def change
3
+ add_column :shops, :plan_display_name, :string
4
+ add_column :shops, :latitude, :decimal
5
+ add_column :shops, :longitude, :decimal
6
+ add_column :shops, :customer_email, :string
7
+ add_column :shops, :password_enabled, :boolean
8
+ add_column :shops, :phone, :string
9
+ add_column :shops, :primary_locale, :string
10
+ add_column :shops, :ships_to_countries, :string
11
+ add_column :shops, :timezone, :string
12
+ add_column :shops, :iana_timezone, :string
13
+ add_column :shops, :has_storefront, :boolean
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ class CreateDiscoAppPlans < ActiveRecord::Migration
2
+ def change
3
+ create_table :disco_app_plans do |t|
4
+ t.integer :status
5
+ t.string :name
6
+ t.integer :charge_type
7
+ t.decimal :default_price
8
+ t.integer :default_trial_days
9
+
10
+ t.timestamps null: false
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ class CreateDiscoAppSubscriptions < ActiveRecord::Migration
2
+ def change
3
+ create_table :disco_app_subscriptions do |t|
4
+ t.belongs_to :shop, index: true
5
+ t.belongs_to :plan, index: true
6
+ t.integer :status
7
+ t.string :name
8
+ t.integer :charge_type
9
+ t.decimal :price
10
+ t.integer :trial_days
11
+
12
+ t.timestamps null: false
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ class MoveShopToDiscoAppEngine < ActiveRecord::Migration
2
+ def change
3
+ rename_table :shops, :disco_app_shops
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ class CreateDiscoAppSessions < ActiveRecord::Migration
2
+ def change
3
+ create_table :disco_app_sessions do |t|
4
+ t.string :session_id, :null => false
5
+ t.text :data
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :disco_app_sessions, :session_id, :unique => true
10
+ add_index :disco_app_sessions, :updated_at
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ class AddShopIdToDiscoAppSessions < ActiveRecord::Migration
2
+ def change
3
+ add_column :disco_app_sessions, :shop_id, :integer, null: true
4
+ add_foreign_key :disco_app_sessions, :disco_app_shops, column: :shop_id, on_delete: :cascade
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ require 'shopify_app'
2
+ require 'bootstrap-sass'
3
+ require 'jquery-rails'
4
+ require 'turbolinks'
5
+ require 'activerecord/session_store'
6
+ require 'disco_app/session'
7
+
8
+ module DiscoApp
9
+ class Engine < ::Rails::Engine
10
+
11
+ isolate_namespace DiscoApp
12
+ engine_name 'disco_app'
13
+
14
+ # Ensure DiscoApp helpers are available throughout application.
15
+ config.to_prepare do
16
+ ApplicationController.helper(DiscoApp::ApplicationHelper)
17
+ end
18
+
19
+ # Ensure our frame assets are included for precompilation.
20
+ initializer 'disco_app.assets.precompile' do |app|
21
+ app.config.assets.precompile += %w(disco_app/icon.svg disco_app/frame.css disco_app/frame.js)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ class DiscoApp::Session < ActiveRecord::SessionStore::Session
2
+
3
+ before_save :set_shop_id!
4
+
5
+ private
6
+
7
+ def set_shop_id!
8
+ return false unless loaded?
9
+ write_attribute(:shop_id, data[:shopify] || data['shopify'])
10
+ end
11
+
12
+ end
@@ -0,0 +1,23 @@
1
+ module DiscoApp::Test
2
+ module FileFixtures
3
+
4
+ # Return an XML fixture as an XML string.
5
+ def xml_fixture(path)
6
+ filename = Rails.root.join('test', 'fixtures', 'xml', "#{path}.xml")
7
+ File.read(filename)
8
+ end
9
+
10
+ # Return a JSON fixture as an indifferent hash.
11
+ def json_fixture(path, dir: 'json', parse: true)
12
+ filename = Rails.root.join('test', 'fixtures', dir, "#{path}.json")
13
+ return File.read(filename) unless parse
14
+ HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(File.read(filename)))
15
+ end
16
+
17
+ # Webhook fixtures are special-case JSON fixtures.
18
+ def webhook_fixture(path, parse: true)
19
+ json_fixture(path, dir: 'webhooks', parse: parse)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ require 'disco_app/support/file_fixtures'
2
+
3
+ # Make our helper modules available inside fixtures.
4
+ ActiveRecord::FixtureSet.context_class.send :include, DiscoApp::Test::FileFixtures
5
+
6
+ # Include FileFixture helpers in base TestCase class.
7
+ class ActiveSupport::TestCase
8
+
9
+ include DiscoApp::Test::FileFixtures
10
+
11
+ end
@@ -0,0 +1,3 @@
1
+ module DiscoApp
2
+ VERSION = '0.7.0'
3
+ end
data/lib/disco_app.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "disco_app/engine"
2
+
3
+ module DiscoApp
4
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Generate a new Shopify application.
3
+
4
+ Example:
5
+ rails generate disco_app
@@ -0,0 +1,161 @@
1
+ class DiscoAppGenerator < Rails::Generators::Base
2
+
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ # Copy a number of template files to the top-level directory of our application:
6
+ #
7
+ # - .env and .env.local for settings environment variables in development with dotenv-rails;
8
+ # - Slightly customised version of the default Rails .gitignore;
9
+ # - Default simple Procfile for Heroku.
10
+ #
11
+ def copy_root_files
12
+ %w(.env .env.local .gitignore Procfile).each do |file|
13
+ copy_file "root/#{file}", file
14
+ end
15
+ end
16
+
17
+ # Remove a number of root files.
18
+ def remove_root_files
19
+ %w(README.rdoc).each do |file|
20
+ remove_file file
21
+ end
22
+ end
23
+
24
+ # Configure the application's Gemfile.
25
+ def configure_gems
26
+ # Remove sqlite from the general Gemfile.
27
+ gsub_file 'Gemfile', /^# Use sqlite3 as the database for Active Record\ngem 'sqlite3'/m, ''
28
+
29
+ # Add gems common to all environments.
30
+ gem 'shopify_app', '~> 6.4.1'
31
+ gem 'sidekiq', '~> 3.5.1'
32
+ gem 'puma', '~> 2.14.0'
33
+ gem 'bootstrap-sass', '~> 3.3.5.1'
34
+ gem 'activerecord-session_store', '~> 0.1.2'
35
+
36
+ # Add gems for development and testing only.
37
+ gem_group :development, :test do
38
+ gem 'sqlite3', '~> 1.3.11'
39
+ gem 'dotenv-rails', '~> 2.0.2'
40
+ gem 'minitest-reporters', '~> 1.0.19'
41
+ gem 'guard', '~> 2.13.0'
42
+ gem 'guard-minitest', '~> 2.4.4'
43
+ end
44
+
45
+ # Add gems for production only.
46
+ gem_group :production do
47
+ gem 'pg', '~> 0.18.3'
48
+ gem 'rails_12factor', '~> 0.0.3'
49
+ end
50
+ end
51
+
52
+ # Make any required adjustments to the application configuration.
53
+ def configure_application
54
+ # The force_ssl flag is commented by default for production.
55
+ # Uncomment to ensure config.force_ssl = true in production.
56
+ uncomment_lines 'config/environments/production.rb', /force_ssl/
57
+
58
+ # Set defaults for various charge attributes.
59
+ application "config.x.shopify_charges_default_trial_days = 14\n"
60
+ application "config.x.shopify_charges_default_price = 10.00"
61
+ application "config.x.shopify_charges_default_type = :recurring"
62
+ application "# Set defaults for charges created by the application"
63
+
64
+ # Set the "real charges" config variable to false explicitly by default.
65
+ # Only in production do we read from the environment variable and
66
+ # potentially have it become true.
67
+ application "config.x.shopify_charges_real = false\n"
68
+ application "# Explicitly prevent real charges being created by default"
69
+ application "config.x.shopify_charges_real = ENV['SHOPIFY_CHARGES_REAL'] == 'true'\n", env: :production
70
+ application "# Allow real charges in production with an ENV variable", env: :production
71
+
72
+ # Configure session storage.
73
+ application "ActiveRecord::SessionStore::Session.table_name = 'disco_app_sessions'"
74
+ application "ActionDispatch::Session::ActiveRecordStore.session_class = DiscoApp::Session"
75
+ application "# Configure custom session storage"
76
+
77
+ # Set Sidekiq as the queue adapter in production.
78
+ application "config.active_job.queue_adapter = :sidekiq\n", env: :production
79
+ application "# Use Sidekiq as the active job backend", env: :production
80
+
81
+ # Ensure the application configuration uses the DEFAULT_HOST environment
82
+ # variable to set up support for reverse routing absolute URLS (needed when
83
+ # generating Webhook URLs for example).
84
+ application "routes.default_url_options[:host] = ENV['DEFAULT_HOST']\n"
85
+ application "# Set the default host for absolute URL routing purposes"
86
+
87
+ # Add loading of the default application proxy prefix to set up support for
88
+ # reverse routings absolute proxy URLS.
89
+ application "config.x.shopify_app_proxy_prefix = ENV['SHOPIFY_APP_PROXY_PREFIX']\n"
90
+ application "# Set the application proxy path for absolute URL routing purposes"
91
+
92
+ # Add the Shopify application name to the configuration.
93
+ application "config.x.shopify_app_name = ENV['SHOPIFY_APP_NAME']\n"
94
+ application "# Set the name of the application"
95
+
96
+ # Copy over the default puma configuration.
97
+ copy_file 'config/puma.rb', 'config/puma.rb'
98
+ end
99
+
100
+ # Set up routes.
101
+ def setup_routes
102
+ route "mount DiscoApp::Engine, at: '/'"
103
+ end
104
+
105
+ # Run shopify_app:install
106
+ def shopify_app_install
107
+ generate 'shopify_app:install'
108
+ end
109
+
110
+ # Copy template files to the appropriate location. In some cases, we'll be
111
+ # overwriting or removing existing files or those created by ShopifyApp.
112
+ def copy_and_remove_files
113
+ # Copy initializers
114
+ copy_file 'initializers/shopify_app.rb', 'config/initializers/shopify_app.rb'
115
+ copy_file 'initializers/disco_app.rb', 'config/initializers/disco_app.rb'
116
+ copy_file 'initializers/shopify_session_repository.rb', 'config/initializers/shopify_session_repository.rb'
117
+ copy_file 'initializers/session_store.rb', 'config/initializers/session_store.rb'
118
+
119
+ # Copy default home controller and view
120
+ copy_file 'controllers/home_controller.rb', 'app/controllers/home_controller.rb'
121
+ copy_file 'views/home/index.html.erb', 'app/views/home/index.html.erb'
122
+
123
+ # Copy assets
124
+ copy_file 'assets/javascripts/application.js', 'app/assets/javascripts/application.js'
125
+ copy_file 'assets/stylesheets/application.scss', 'app/assets/stylesheets/application.scss'
126
+
127
+ # Remove application.css
128
+ remove_file 'app/assets/stylesheets/application.css'
129
+
130
+ # Remove the layout files created by ShopifyApp
131
+ remove_file 'app/views/layouts/application.html.erb'
132
+ remove_file 'app/views/layouts/embedded_app.html.erb'
133
+ end
134
+
135
+ # Add the Disco App test helper to test/test_helper.rb
136
+ def add_test_helper
137
+ inject_into_file 'test/test_helper.rb', "require 'disco_app/test_help'\n", { after: "require 'rails/test_help'\n" }
138
+ end
139
+
140
+ # Copy engine migrations over.
141
+ def install_migrations
142
+ rake 'disco_app:install:migrations'
143
+ end
144
+
145
+ # Run migrations.
146
+ def migrate
147
+ rake 'db:migrate'
148
+ end
149
+
150
+ # Lock down the application to a specific Ruby version:
151
+ #
152
+ # - Via .ruby-version file for rbenv in development;
153
+ # - Via a Gemfile line in production.
154
+ #
155
+ # This should be the last operation, to allow all other operations to run in the initial Ruby version.
156
+ def set_ruby_version
157
+ copy_file 'root/.ruby-version', '.ruby-version'
158
+ prepend_to_file 'Gemfile', "ruby '2.2.2'\n"
159
+ end
160
+
161
+ end