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.
- checksums.yaml +7 -0
- data/Rakefile +37 -0
- data/app/assets/images/disco_app/icon.svg +1 -0
- data/app/assets/javascripts/disco_app/components/shopify_admin_link.js.jsx +29 -0
- data/app/assets/javascripts/disco_app/components.js +5 -0
- data/app/assets/javascripts/disco_app/disco_app.js +7 -0
- data/app/assets/javascripts/disco_app/frame.js +152 -0
- data/app/assets/javascripts/disco_app/shopify-turbolinks.js +7 -0
- data/app/assets/stylesheets/disco_app/bootstrap/_custom.scss +54 -0
- data/app/assets/stylesheets/disco_app/bootstrap/_variables.scss +872 -0
- data/app/assets/stylesheets/disco_app/disco/_buttons.scss +31 -0
- data/app/assets/stylesheets/disco_app/disco/_cards.scss +51 -0
- data/app/assets/stylesheets/disco_app/disco/_forms.scss +23 -0
- data/app/assets/stylesheets/disco_app/disco/_grid.scss +58 -0
- data/app/assets/stylesheets/disco_app/disco/_sections.scss +61 -0
- data/app/assets/stylesheets/disco_app/disco/_tables.scss +57 -0
- data/app/assets/stylesheets/disco_app/disco/_tabs.scss +61 -0
- data/app/assets/stylesheets/disco_app/disco/_type.scss +39 -0
- data/app/assets/stylesheets/disco_app/disco/mixins/_flexbox.scss +394 -0
- data/app/assets/stylesheets/disco_app/disco_app.scss +16 -0
- data/app/assets/stylesheets/disco_app/frame/_buttons.scss +54 -0
- data/app/assets/stylesheets/disco_app/frame/_forms.scss +26 -0
- data/app/assets/stylesheets/disco_app/frame/_layout.scss +77 -0
- data/app/assets/stylesheets/disco_app/frame/_type.scss +32 -0
- data/app/assets/stylesheets/disco_app/frame.scss +9 -0
- data/app/controllers/disco_app/app_proxy_controller.rb +41 -0
- data/app/controllers/disco_app/authenticated_controller.rb +44 -0
- data/app/controllers/disco_app/carrier_request_controller.rb +28 -0
- data/app/controllers/disco_app/charges_controller.rb +30 -0
- data/app/controllers/disco_app/frame_controller.rb +9 -0
- data/app/controllers/disco_app/install_controller.rb +26 -0
- data/app/controllers/disco_app/webhooks_controller.rb +42 -0
- data/app/helpers/disco_app/application_helper.rb +28 -0
- data/app/jobs/disco_app/app_installed_job.rb +3 -0
- data/app/jobs/disco_app/app_uninstalled_job.rb +3 -0
- data/app/jobs/disco_app/concerns/app_installed_job.rb +22 -0
- data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +23 -0
- data/app/jobs/disco_app/concerns/shop_update_job.rb +16 -0
- data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +51 -0
- data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +53 -0
- data/app/jobs/disco_app/shop_job.rb +27 -0
- data/app/jobs/disco_app/shop_update_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_carrier_service_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_webhooks_job.rb +3 -0
- data/app/models/disco_app/concerns/plan.rb +14 -0
- data/app/models/disco_app/concerns/shop.rb +71 -0
- data/app/models/disco_app/concerns/subscription.rb +14 -0
- data/app/models/disco_app/plan.rb +3 -0
- data/app/models/disco_app/session_storage.rb +18 -0
- data/app/models/disco_app/shop.rb +3 -0
- data/app/models/disco_app/subscription.rb +3 -0
- data/app/services/disco_app/charges_service.rb +73 -0
- data/app/services/disco_app/subscription_service.rb +25 -0
- data/app/services/disco_app/webhook_service.rb +30 -0
- data/app/views/disco_app/charges/activate.html.erb +1 -0
- data/app/views/disco_app/charges/create.html.erb +1 -0
- data/app/views/disco_app/charges/new.html.erb +45 -0
- data/app/views/disco_app/frame/frame.html.erb +36 -0
- data/app/views/disco_app/install/installing.html.erb +7 -0
- data/app/views/disco_app/install/uninstalling.html.erb +1 -0
- data/app/views/disco_app/proxy_errors/404.html.erb +1 -0
- data/app/views/disco_app/shared/_card.html.erb +14 -0
- data/app/views/disco_app/shared/_section.html.erb +17 -0
- data/app/views/layouts/application.html.erb +18 -0
- data/app/views/layouts/embedded_app.html.erb +41 -0
- data/app/views/layouts/embedded_app_modal.html.erb +17 -0
- data/app/views/sessions/new.html.erb +26 -0
- data/config/routes.rb +26 -0
- data/db/migrate/20150525000000_create_shops_if_not_existent.rb +15 -0
- data/db/migrate/20150525162112_add_status_to_shops.rb +5 -0
- data/db/migrate/20150525171422_add_meta_to_shops.rb +11 -0
- data/db/migrate/20150629210346_add_charge_status_to_shop.rb +5 -0
- data/db/migrate/20150814214025_add_more_meta_to_shops.rb +15 -0
- data/db/migrate/20151017231302_create_disco_app_plans.rb +13 -0
- data/db/migrate/20151017232027_create_disco_app_subscriptions.rb +15 -0
- data/db/migrate/20151017234409_move_shop_to_disco_app_engine.rb +5 -0
- data/db/migrate/20160112233706_create_disco_app_sessions.rb +12 -0
- data/db/migrate/20160113194418_add_shop_id_to_disco_app_sessions.rb +6 -0
- data/lib/disco_app/engine.rb +25 -0
- data/lib/disco_app/session.rb +12 -0
- data/lib/disco_app/support/file_fixtures.rb +23 -0
- data/lib/disco_app/test_help.rb +11 -0
- data/lib/disco_app/version.rb +3 -0
- data/lib/disco_app.rb +4 -0
- data/lib/generators/disco_app/USAGE +5 -0
- data/lib/generators/disco_app/disco_app_generator.rb +161 -0
- data/lib/generators/disco_app/mailify/mailify_generator.rb +54 -0
- data/lib/generators/disco_app/reactify/reactify_generator.rb +45 -0
- data/lib/generators/disco_app/rollbarify/rollbarify_generator.rb +26 -0
- data/lib/generators/disco_app/rollbarify/templates/initializers/rollbar.rb +12 -0
- data/lib/generators/disco_app/templates/assets/javascripts/application.js +17 -0
- data/lib/generators/disco_app/templates/assets/stylesheets/application.scss +5 -0
- data/lib/generators/disco_app/templates/config/puma.rb +15 -0
- data/lib/generators/disco_app/templates/controllers/home_controller.rb +7 -0
- data/lib/generators/disco_app/templates/initializers/disco_app.rb +1 -0
- data/lib/generators/disco_app/templates/initializers/session_store.rb +2 -0
- data/lib/generators/disco_app/templates/initializers/shopify_app.rb +7 -0
- data/lib/generators/disco_app/templates/initializers/shopify_session_repository.rb +7 -0
- data/lib/generators/disco_app/templates/root/Procfile +2 -0
- data/lib/generators/disco_app/templates/views/home/index.html.erb +2 -0
- data/lib/tasks/carrier_service.rake +10 -0
- data/lib/tasks/sessions.rake +9 -0
- data/lib/tasks/start.rake +3 -0
- data/lib/tasks/webhooks.rake +10 -0
- data/test/controllers/disco_app/install_controller_test.rb +50 -0
- data/test/controllers/disco_app/webhooks_controller_test.rb +58 -0
- data/test/controllers/home_controller_test.rb +61 -0
- data/test/disco_app_test.rb +7 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +17 -0
- data/test/dummy/app/assets/stylesheets/application.scss +5 -0
- data/test/dummy/app/controllers/application_controller.rb +6 -0
- data/test/dummy/app/controllers/home_controller.rb +7 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +11 -0
- data/test/dummy/app/models/disco_app/shop.rb +15 -0
- data/test/dummy/app/views/home/index.html.erb +2 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +41 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +85 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/disco_app.rb +1 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/omniauth.rb +9 -0
- data/test/dummy/config/initializers/session_store.rb +2 -0
- data/test/dummy/config/initializers/shopify_app.rb +7 -0
- data/test/dummy/config/initializers/shopify_session_repository.rb +7 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +8 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +81 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fixtures/api/widget_store/shop.json +46 -0
- data/test/fixtures/api/widget_store/webhooks.json +1 -0
- data/test/fixtures/disco_app/plans.yml +32 -0
- data/test/fixtures/disco_app/shops.yml +10 -0
- data/test/fixtures/disco_app/subscriptions.yml +26 -0
- data/test/fixtures/webhooks/app_uninstalled.json +46 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/jobs/disco_app/app_installed_job_test.rb +30 -0
- data/test/jobs/disco_app/app_uninstalled_job_test.rb +32 -0
- data/test/models/disco_app/plan_test.rb +5 -0
- data/test/models/disco_app/session_test.rb +31 -0
- data/test/models/disco_app/shop_test.rb +26 -0
- data/test/models/disco_app/subscription_test.rb +6 -0
- data/test/services/disco_app/subscription_service_test.rb +28 -0
- data/test/support/test_file_fixtures.rb +29 -0
- data/test/test_helper.rb +51 -0
- metadata +507 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module DiscoApp
|
|
2
|
+
module Generators
|
|
3
|
+
class MailifyGenerator < Rails::Generators::Base
|
|
4
|
+
|
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
6
|
+
|
|
7
|
+
def install_gem
|
|
8
|
+
# Add premailer gem to Gemfile.
|
|
9
|
+
gem 'premailer-rails', '~> 1.8.2'
|
|
10
|
+
|
|
11
|
+
# Add explicit dependency on Nokogiri
|
|
12
|
+
gem 'nokogiri', '~> 1.6.6.1'
|
|
13
|
+
|
|
14
|
+
# Add the Mailgun rails gem (production only)
|
|
15
|
+
gem_group :production do
|
|
16
|
+
gem 'mailgun_rails', '~> 0.7.0'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Install gem.
|
|
20
|
+
Bundler.with_clean_env do
|
|
21
|
+
run 'bundle install'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Set application configuration
|
|
26
|
+
def configure_application
|
|
27
|
+
configuration = <<-CONFIG.strip_heredoc
|
|
28
|
+
|
|
29
|
+
# Configure ActionMailer to use MailGun
|
|
30
|
+
if ENV['MAILGUN_API_KEY']
|
|
31
|
+
config.action_mailer.delivery_method = :mailgun
|
|
32
|
+
config.action_mailer.mailgun_settings = {
|
|
33
|
+
api_key: ENV['MAILGUN_API_KEY'],
|
|
34
|
+
domain: ENV['MAILGUN_API_DOMAIN']
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
CONFIG
|
|
38
|
+
application configuration, env: :production
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Add entries to .env and .env.local
|
|
42
|
+
def add_env_variables
|
|
43
|
+
configuration = <<-CONFIG.strip_heredoc
|
|
44
|
+
|
|
45
|
+
MAILGUN_API_KEY=
|
|
46
|
+
MAILGUN_API_DOMAIN=
|
|
47
|
+
CONFIG
|
|
48
|
+
append_to_file '.env', configuration
|
|
49
|
+
append_to_file '.env.local', configuration
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module DiscoApp
|
|
2
|
+
module Generators
|
|
3
|
+
class ReactifyGenerator < Rails::Generators::Base
|
|
4
|
+
|
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
6
|
+
|
|
7
|
+
# Install the react-rails gem and run its setup.
|
|
8
|
+
def install_gem
|
|
9
|
+
# Add gem to Gemfile
|
|
10
|
+
gem 'react-rails', '~> 1.4.0'
|
|
11
|
+
|
|
12
|
+
# Install gem.
|
|
13
|
+
Bundler.with_clean_env do
|
|
14
|
+
run 'bundle install'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Run the gem's generator.
|
|
18
|
+
generate 'react:install'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Set application configuration
|
|
22
|
+
def configure_application
|
|
23
|
+
application "config.react.variant = :development", env: :development
|
|
24
|
+
application "# Use development variant of React in development.", env: :development
|
|
25
|
+
application "config.react.variant = :production", env: :production
|
|
26
|
+
application "# Use production variant of React in production.", env: :production
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Include the DiscoApp component library in the application.js manifest.
|
|
30
|
+
def add_to_manifest
|
|
31
|
+
inject_into_file manifest, "//= require disco_app/components\n", { before: "//= require components\n" }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# This method of finding the application.js manifest taken from the
|
|
37
|
+
# install generator in react-rails.
|
|
38
|
+
# See https://github.com/reactjs/react-rails/blob/3f0af13fa755d6e95969c17728d0354c234f3a37/lib/generators/react/install_generator.rb#L53-L55
|
|
39
|
+
def manifest
|
|
40
|
+
Pathname.new(destination_root).join('app/assets/javascripts', 'application.js')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module DiscoApp
|
|
2
|
+
module Generators
|
|
3
|
+
class RollbarifyGenerator < Rails::Generators::Base
|
|
4
|
+
|
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
6
|
+
|
|
7
|
+
# Install the Rollbar and OJ gems.
|
|
8
|
+
def install_gems
|
|
9
|
+
# Add gem to Gemfile
|
|
10
|
+
gem 'rollbar', '~> 2.7.1'
|
|
11
|
+
gem 'oj', '~> 2.14.3'
|
|
12
|
+
|
|
13
|
+
# Install gem.
|
|
14
|
+
Bundler.with_clean_env do
|
|
15
|
+
run 'bundle install'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Copy initializer.
|
|
20
|
+
def configure
|
|
21
|
+
copy_file 'initializers/rollbar.rb', 'config/initializers/rollbar.rb'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Rollbar.configure do |config|
|
|
2
|
+
# Fetch the access token from the environment.
|
|
3
|
+
config.access_token = ENV['ROLLBAR_ACCESS_TOKEN']
|
|
4
|
+
|
|
5
|
+
# Only use Rollbar in production when there's a token configured.
|
|
6
|
+
unless config.access_token and Rails.env.production?
|
|
7
|
+
config.enabled = false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Enable delayed reporting (using Sidekiq)
|
|
11
|
+
config.use_sidekiq
|
|
12
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// compiled file.
|
|
9
|
+
//
|
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
|
+
// about supported directives.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require turbolinks
|
|
16
|
+
//= require disco_app/disco_app
|
|
17
|
+
//= require_tree .
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
|
|
2
|
+
threads_count = Integer(ENV['MAX_THREADS'] || 5)
|
|
3
|
+
threads threads_count, threads_count
|
|
4
|
+
|
|
5
|
+
preload_app!
|
|
6
|
+
|
|
7
|
+
rackup DefaultRackup
|
|
8
|
+
port ENV['PORT'] || 3000
|
|
9
|
+
environment ENV['RACK_ENV'] || 'development'
|
|
10
|
+
|
|
11
|
+
on_worker_boot do
|
|
12
|
+
# Worker specific setup for Rails 4.1+
|
|
13
|
+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
|
|
14
|
+
ActiveRecord::Base.establish_connection
|
|
15
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DiscoApp::Engine.routes.default_url_options[:host] = ENV['DEFAULT_HOST']
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
namespace :carrier_service do
|
|
2
|
+
|
|
3
|
+
desc 'Synchronise carrier service across all installed shops.'
|
|
4
|
+
task sync: :environment do
|
|
5
|
+
DiscoApp::Shop.installed.has_active_shopify_plan.each do |shop|
|
|
6
|
+
DiscoApp::SynchroniseCarrierServiceJob.perform_later(shop.shopify_domain)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
namespace :sessions do
|
|
2
|
+
|
|
3
|
+
desc 'Clean out any stale sessions.'
|
|
4
|
+
task clean: [:environment, 'db:load_config'] do
|
|
5
|
+
threshold = (ENV['SESSIONS_CLEAN_THRESHOLD_DAYS'] || 30).to_i.days.ago
|
|
6
|
+
ActiveRecord::Base.connection.execute("DELETE FROM #{ActiveRecord::SessionStore::Session.table_name} WHERE updated_at < '#{threshold}'")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
namespace :webhooks do
|
|
2
|
+
|
|
3
|
+
desc 'Synchronise webhooks across all installed shops.'
|
|
4
|
+
task sync: :environment do
|
|
5
|
+
DiscoApp::Shop.installed.has_active_shopify_plan.each do |shop|
|
|
6
|
+
DiscoApp::SynchroniseWebhooksJob.perform_later(shop.shopify_domain)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::InstallControllerTest < ActionController::TestCase
|
|
4
|
+
include ActiveJob::TestHelper
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@shop = disco_app_shops(:widget_store)
|
|
8
|
+
@routes = DiscoApp::Engine.routes
|
|
9
|
+
log_in_as(@shop)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def teardown
|
|
13
|
+
@shop = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'logged-in but uninstalled user triggers installation from install page' do
|
|
17
|
+
get(:install)
|
|
18
|
+
assert_redirected_to :installing
|
|
19
|
+
assert_enqueued_jobs 1
|
|
20
|
+
@shop.reload
|
|
21
|
+
assert @shop.awaiting_install?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'logged-in and installed user is redirected to installing url for install/uninstalling actions' do
|
|
25
|
+
@shop.installed!
|
|
26
|
+
[:install, :uninstalling].each do |action|
|
|
27
|
+
get(:install)
|
|
28
|
+
assert_redirected_to :installing
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test 'logged-in and installed user is redirected to root url for installing' do
|
|
33
|
+
@shop.installed!
|
|
34
|
+
get(:installing)
|
|
35
|
+
assert_redirected_to Rails.application.routes.url_helpers.root_path
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'logged-in and uninstalling user sees uninstalling page' do
|
|
39
|
+
@shop.uninstalling!
|
|
40
|
+
get(:uninstalling)
|
|
41
|
+
assert_response :success
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test 'logged-in and uninstalled user starts install process again' do
|
|
45
|
+
@shop.uninstalled!
|
|
46
|
+
get(:uninstalling)
|
|
47
|
+
assert_redirected_to :install
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::WebhooksControllerTest < ActionController::TestCase
|
|
4
|
+
include ActiveJob::TestHelper
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@shop = disco_app_shops(:widget_store)
|
|
8
|
+
@routes = DiscoApp::Engine.routes
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def teardown
|
|
12
|
+
@shop = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test 'webhook request without authentication information returns unauthorized' do
|
|
16
|
+
body = webhook_fixture('app_uninstalled')
|
|
17
|
+
post(:process_webhook, body)
|
|
18
|
+
assert_response :unauthorized
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'webhook request with no HMAC returns unauthorized' do
|
|
22
|
+
body = webhook_fixture('app_uninstalled')
|
|
23
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
24
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
25
|
+
post(:process_webhook, body)
|
|
26
|
+
assert_response :unauthorized
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test 'webhook request with invalid HMAC returns unauthorized' do
|
|
30
|
+
body = webhook_fixture('app_uninstalled')
|
|
31
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
32
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
33
|
+
@request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = '0000'
|
|
34
|
+
post(:process_webhook, body)
|
|
35
|
+
assert_response :unauthorized
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'webhook request with valid HMAC returns OK' do
|
|
39
|
+
body = webhook_fixture('app_uninstalled')
|
|
40
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
41
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
42
|
+
@request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = DiscoApp::WebhookService.calculated_hmac(body, ShopifyApp.configuration.secret)
|
|
43
|
+
post(:process_webhook, body)
|
|
44
|
+
assert_response :ok
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
test 'app uninstalled job queued when app/uninstalled webhook arrives' do
|
|
48
|
+
body = webhook_fixture('app_uninstalled')
|
|
49
|
+
@request.headers['HTTP_X_SHOPIFY_TOPIC'] = :'app/uninstalled'
|
|
50
|
+
@request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN'] = @shop.shopify_domain
|
|
51
|
+
@request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = DiscoApp::WebhookService.calculated_hmac(body, ShopifyApp.configuration.secret)
|
|
52
|
+
|
|
53
|
+
assert_enqueued_with(job: DiscoApp::AppUninstalledJob) do
|
|
54
|
+
post(:process_webhook, body)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class HomeControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@shop = disco_app_shops(:widget_store)
|
|
7
|
+
log_in_as(@shop)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def teardown
|
|
11
|
+
@shop = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
test 'non-logged in user is redirected to the login page' do
|
|
15
|
+
log_out
|
|
16
|
+
get(:index)
|
|
17
|
+
assert_redirected_to ShopifyApp::Engine.routes.url_helpers.login_path
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test 'logged-in, never installed user is redirected to the install page' do
|
|
21
|
+
get(:index)
|
|
22
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.install_path
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test 'logged-in, awaiting install user is redirected to the installing page' do
|
|
26
|
+
@shop.awaiting_install!
|
|
27
|
+
get(:index)
|
|
28
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.installing_path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'logged-in, installing user is redirected to the installing page' do
|
|
32
|
+
@shop.installing!
|
|
33
|
+
get(:index)
|
|
34
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.installing_path
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test 'logged-in, installed user is able to access the page' do
|
|
38
|
+
@shop.installed!
|
|
39
|
+
get(:index)
|
|
40
|
+
assert_response :success
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test 'logged-in, awaiting uninstall user is redirected to the uninstalling page' do
|
|
44
|
+
@shop.awaiting_uninstall!
|
|
45
|
+
get(:index)
|
|
46
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.uninstalling_path
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test 'logged-in, uninstalling user is redirected to the uninstalling page' do
|
|
50
|
+
@shop.uninstalling!
|
|
51
|
+
get(:index)
|
|
52
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.uninstalling_path
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test 'logged-in, uninstalled user is redirected to the install page' do
|
|
56
|
+
@shop.uninstalled!
|
|
57
|
+
get(:index)
|
|
58
|
+
assert_redirected_to DiscoApp::Engine.routes.url_helpers.install_path
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
data/test/dummy/Rakefile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// compiled file.
|
|
9
|
+
//
|
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
|
+
// about supported directives.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require turbolinks
|
|
16
|
+
//= require disco_app/disco_app
|
|
17
|
+
//= require_tree .
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class DiscoApp::AppUninstalledJob < DiscoApp::ShopJob
|
|
2
|
+
include DiscoApp::Concerns::AppUninstalledJob
|
|
3
|
+
|
|
4
|
+
# Extend the perform method to change the country name of the shop to
|
|
5
|
+
# 'Nowhere' on uninstallation.
|
|
6
|
+
def perform(domain, shop_data)
|
|
7
|
+
super(domain, shop_data)
|
|
8
|
+
@shop.update(country_name: 'Nowhere')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'active_utils'
|
|
2
|
+
|
|
3
|
+
class DiscoApp::Shop < ActiveRecord::Base
|
|
4
|
+
include DiscoApp::Concerns::Shop
|
|
5
|
+
|
|
6
|
+
# Extend the Shop model to return the Shop's country as an ActiveUtils country.
|
|
7
|
+
def country
|
|
8
|
+
begin
|
|
9
|
+
ActiveUtils::Country.find(country_name)
|
|
10
|
+
rescue ActiveUtils::InvalidCountryCodeError
|
|
11
|
+
nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
data/test/dummy/bin/rake
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
# path to your application root.
|
|
5
|
+
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
|
|
6
|
+
|
|
7
|
+
Dir.chdir APP_ROOT do
|
|
8
|
+
# This script is a starting point to setup your application.
|
|
9
|
+
# Add necessary setup steps to this file:
|
|
10
|
+
|
|
11
|
+
puts "== Installing dependencies =="
|
|
12
|
+
system "gem install bundler --conservative"
|
|
13
|
+
system "bundle check || bundle install"
|
|
14
|
+
|
|
15
|
+
# puts "\n== Copying sample files =="
|
|
16
|
+
# unless File.exist?("config/database.yml")
|
|
17
|
+
# system "cp config/database.yml.sample config/database.yml"
|
|
18
|
+
# end
|
|
19
|
+
|
|
20
|
+
puts "\n== Preparing database =="
|
|
21
|
+
system "bin/rake db:setup"
|
|
22
|
+
|
|
23
|
+
puts "\n== Removing old logs and tempfiles =="
|
|
24
|
+
system "rm -f log/*"
|
|
25
|
+
system "rm -rf tmp/cache"
|
|
26
|
+
|
|
27
|
+
puts "\n== Restarting application server =="
|
|
28
|
+
system "touch tmp/restart.txt"
|
|
29
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'rails/all'
|
|
4
|
+
|
|
5
|
+
Bundler.require(*Rails.groups)
|
|
6
|
+
require "disco_app"
|
|
7
|
+
|
|
8
|
+
module Dummy
|
|
9
|
+
class Application < Rails::Application
|
|
10
|
+
config.action_dispatch.default_headers['P3P'] = 'CP="Not used"'
|
|
11
|
+
config.action_dispatch.default_headers.delete('X-Frame-Options')
|
|
12
|
+
# Settings in config/environments/* take precedence over those specified here.
|
|
13
|
+
# Application configuration should go into files in config/initializers
|
|
14
|
+
# -- all .rb files in that directory are automatically loaded.
|
|
15
|
+
|
|
16
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
|
17
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
|
18
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
|
19
|
+
|
|
20
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
|
21
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
|
22
|
+
# config.i18n.default_locale = :de
|
|
23
|
+
|
|
24
|
+
# Set the name of the application
|
|
25
|
+
config.x.shopify_app_name = ENV['SHOPIFY_APP_NAME']
|
|
26
|
+
|
|
27
|
+
# Set the default host for absolute URL routing purposes
|
|
28
|
+
routes.default_url_options[:host] = ENV['DEFAULT_HOST']
|
|
29
|
+
|
|
30
|
+
# Configure custom session storage
|
|
31
|
+
ActionDispatch::Session::ActiveRecordStore.session_class = DiscoApp::Session
|
|
32
|
+
ActiveRecord::SessionStore::Session.table_name = 'disco_app_sessions'
|
|
33
|
+
|
|
34
|
+
# Explicitly prevent real charges being created by default
|
|
35
|
+
config.x.shopify_charges_real = false
|
|
36
|
+
|
|
37
|
+
# Do not swallow errors in after_commit/after_rollback callbacks.
|
|
38
|
+
config.active_record.raise_in_transactional_callbacks = true
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SQLite version 3.x
|
|
2
|
+
# gem install sqlite3
|
|
3
|
+
#
|
|
4
|
+
# Ensure the SQLite 3 gem is defined in your Gemfile
|
|
5
|
+
# gem 'sqlite3'
|
|
6
|
+
#
|
|
7
|
+
default: &default
|
|
8
|
+
adapter: sqlite3
|
|
9
|
+
pool: 5
|
|
10
|
+
timeout: 5000
|
|
11
|
+
|
|
12
|
+
development:
|
|
13
|
+
<<: *default
|
|
14
|
+
database: db/development.sqlite3
|
|
15
|
+
|
|
16
|
+
# Warning: The database defined as "test" will be erased and
|
|
17
|
+
# re-generated from your development database when you run "rake".
|
|
18
|
+
# Do not set this db to the same as development or production.
|
|
19
|
+
test:
|
|
20
|
+
<<: *default
|
|
21
|
+
database: db/test.sqlite3
|
|
22
|
+
|
|
23
|
+
production:
|
|
24
|
+
<<: *default
|
|
25
|
+
database: db/production.sqlite3
|