workarea-yotpo 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +20 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +54 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +3 -0
- data/.travis.yml +27 -0
- data/CHANGELOG.md +20 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE.md +3 -0
- data/README.md +86 -0
- data/Rakefile +60 -0
- data/app/assets/images/yotpo/.keep +0 -0
- data/app/assets/javascripts/yotpo/.keep +0 -0
- data/app/assets/stylesheets/yotpo/.keep +0 -0
- data/app/controllers/.keep +0 -0
- data/app/helpers/.keep +0 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/services/yotpo/order.rb +81 -0
- data/app/views/workarea/storefront/_yotpo_tracking.html.haml +3 -0
- data/app/views/workarea/storefront/checkouts/_yotpo_order_tracking.html.haml +7 -0
- data/app/views/workarea/storefront/products/_yotpo_product_summary.html.haml +2 -0
- data/app/views/workarea/storefront/products/_yotpo_reviews.html.haml +2 -0
- data/app/views/workarea/storefront/products/_yotpo_summary.html.haml +2 -0
- data/app/workers/workarea/yotpo/save_order.rb +20 -0
- data/bin/rails +25 -0
- data/config/initializers/appends.rb +24 -0
- data/config/initializers/workarea.rb +11 -0
- data/config/routes.rb +2 -0
- data/lib/workarea/yotpo.rb +41 -0
- data/lib/workarea/yotpo/authentication.rb +45 -0
- data/lib/workarea/yotpo/bogus_gateway.rb +33 -0
- data/lib/workarea/yotpo/engine.rb +10 -0
- data/lib/workarea/yotpo/gateway.rb +64 -0
- data/lib/workarea/yotpo/response.rb +17 -0
- data/lib/workarea/yotpo/version.rb +5 -0
- data/script/static_analysis +29 -0
- data/script/travis +6 -0
- data/test/dummy/.ruby-version +1 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +14 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +15 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -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 +28 -0
- data/test/dummy/bin/update +28 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +34 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +52 -0
- data/test/dummy/config/environments/production.rb +83 -0
- data/test/dummy/config/environments/test.rb +45 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +14 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/content_security_policy.rb +25 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -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/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +34 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/integration/workarea/yotpo/yotpo_integration_test.rb +44 -0
- data/test/services/yotpo/order_test.rb +61 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/test/workers/workarea/yotpo/save_order_test.rb +13 -0
- data/workarea-yotpo.gemspec +20 -0
- metadata +163 -0
@@ -0,0 +1,3 @@
|
|
1
|
+
- if Workarea::Yotpo.app_key.present?
|
2
|
+
%script{ type: "text/javascript" }
|
3
|
+
(function e(){var e=document.createElement("script");e.type="text/javascript",e.async=true,e.src="//staticw2.yotpo.com/#{Workarea::Yotpo.app_key}/widget.js";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();
|
@@ -0,0 +1,7 @@
|
|
1
|
+
- if Workarea::Yotpo.app_key.present?
|
2
|
+
:javascript
|
3
|
+
(function e(){var e=document.createElement("script");e.type="text/javascript",e.async=true,e.src="//staticw2.yotpo.com/#{Workarea::Yotpo.app_key}/widget.js";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();
|
4
|
+
:javascript
|
5
|
+
yotpoTrackConversionData = {orderId: "#{@order.id}", orderAmount: "#{@order.total_price}", orderCurrency: "#{@order.total_price.currency.iso_code}"}
|
6
|
+
%noscript
|
7
|
+
%img{:height => "1", :src => "//api.yotpo.com/conversion_tracking.gif?app_key=#{Workarea::Yotpo.app_key}&order_id=#{@order.id}&order_amount=#{@order.total_price}&order_currency=#{@order.total_price.currency.iso_code}", :width => "1"}/
|
@@ -0,0 +1,2 @@
|
|
1
|
+
- if Workarea::Yotpo.app_key.present?
|
2
|
+
.yotpo.yotpo-main-widget{"data-currency" => "#{product.sell_min_price.currency}", "data-image-url" => "#{product_image_url(product.primary_image, :small)}", "data-name" => "#{product.name}", "data-price" => "#{product.pricing.sell_min_price}", "data-product-id" => "#{product.id}", "data-url" => "#{product_url(product)}" }
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Yotpo
|
3
|
+
class SaveOrder
|
4
|
+
include Sidekiq::Worker
|
5
|
+
include Sidekiq::CallbacksWorker
|
6
|
+
|
7
|
+
sidekiq_options(
|
8
|
+
enqueue_on: { Workarea::Order => [:place] },
|
9
|
+
unique: :until_executing
|
10
|
+
)
|
11
|
+
|
12
|
+
def perform(id)
|
13
|
+
order = Workarea::Order.find(id)
|
14
|
+
yotpo_order = Workarea::Yotpo::Order.new(order.id)
|
15
|
+
|
16
|
+
Workarea::Yotpo.gateway.create_order(yotpo_order.to_h)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
+
# installed from the root of your application.
|
4
|
+
|
5
|
+
ENGINE_ROOT = File.expand_path('..', __dir__)
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/workarea/yotpo/engine', __dir__)
|
7
|
+
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
|
8
|
+
|
9
|
+
# Set up gems listed in the Gemfile.
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
12
|
+
|
13
|
+
require "rails"
|
14
|
+
# Pick the frameworks you want:
|
15
|
+
require "active_model/railtie"
|
16
|
+
require "active_job/railtie"
|
17
|
+
# require "active_record/railtie"
|
18
|
+
# require "active_storage/engine"
|
19
|
+
require "action_controller/railtie"
|
20
|
+
require "action_mailer/railtie"
|
21
|
+
require "action_view/railtie"
|
22
|
+
# require "action_cable/engine"
|
23
|
+
require "sprockets/railtie"
|
24
|
+
require "rails/test_unit/railtie"
|
25
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Workarea.append_partials(
|
2
|
+
'storefront.document_head',
|
3
|
+
'workarea/storefront/yotpo_tracking'
|
4
|
+
)
|
5
|
+
|
6
|
+
Workarea.append_partials(
|
7
|
+
'storefront.product_show',
|
8
|
+
'workarea/storefront/products/yotpo_reviews'
|
9
|
+
)
|
10
|
+
|
11
|
+
Workarea.append_partials(
|
12
|
+
'storefront.product_details',
|
13
|
+
'workarea/storefront/products/yotpo_product_summary'
|
14
|
+
)
|
15
|
+
|
16
|
+
Workarea.append_partials(
|
17
|
+
'storefront.product_summary',
|
18
|
+
'workarea/storefront/products/yotpo_summary'
|
19
|
+
)
|
20
|
+
|
21
|
+
Workarea.append_partials(
|
22
|
+
'storefront.checkout_confirmation',
|
23
|
+
'workarea/storefront/checkouts/yotpo_order_tracking'
|
24
|
+
)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Workarea.configure do |config|
|
2
|
+
config.yotpo = ActiveSupport::Configurable::Configuration.new
|
3
|
+
config.yotpo.app_key = nil # js sdk integration
|
4
|
+
|
5
|
+
# show review summary on PDP
|
6
|
+
config.yotpo.show_review_summary_on_pdp = true
|
7
|
+
|
8
|
+
# show review summaries on product summaries in search,
|
9
|
+
# browse, and recomendation
|
10
|
+
config.yotpo.show_review_summary_on_product_summary = true
|
11
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'workarea'
|
2
|
+
require 'workarea/storefront'
|
3
|
+
require 'workarea/admin'
|
4
|
+
|
5
|
+
require 'workarea/yotpo/engine'
|
6
|
+
require 'workarea/yotpo/version'
|
7
|
+
|
8
|
+
require 'workarea/yotpo/authentication'
|
9
|
+
require 'workarea/yotpo/gateway'
|
10
|
+
require 'workarea/yotpo/bogus_gateway'
|
11
|
+
require 'workarea/yotpo/response'
|
12
|
+
|
13
|
+
require 'faraday'
|
14
|
+
|
15
|
+
module Workarea
|
16
|
+
module Yotpo
|
17
|
+
def self.credentials
|
18
|
+
(Rails.application.secrets.yotpo || {}).deep_symbolize_keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.config
|
22
|
+
Workarea.config.yotpo
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.app_key
|
26
|
+
config.app_key
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.secret_key
|
30
|
+
credentials[:secret_key]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.gateway
|
34
|
+
if credentials.present?
|
35
|
+
Workarea::Yotpo::Gateway.new(app_key: app_key, secret_key: secret_key)
|
36
|
+
else
|
37
|
+
Workarea::Yotpo::BogusGateway.new
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Yotpo
|
3
|
+
module Authentication
|
4
|
+
class NoTokenError < StandardError; end
|
5
|
+
|
6
|
+
def token
|
7
|
+
response = get_token
|
8
|
+
raise NoTokenError unless response.present? && response.success?
|
9
|
+
|
10
|
+
body = JSON.parse(response.body)
|
11
|
+
body['access_token']
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def get_token
|
17
|
+
conn = Faraday.new(url: auth_endpoint)
|
18
|
+
conn.post do |req|
|
19
|
+
req.url '/oauth/token', token_params
|
20
|
+
req.headers['Content-Type'] = 'application/json'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def token_params
|
25
|
+
{
|
26
|
+
client_id: client_id,
|
27
|
+
client_secret: client_secret,
|
28
|
+
grant_type: 'client_credentials'
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def auth_endpoint
|
33
|
+
"https://api.yotpo.com"
|
34
|
+
end
|
35
|
+
|
36
|
+
def client_id
|
37
|
+
options[:app_key]
|
38
|
+
end
|
39
|
+
|
40
|
+
def client_secret
|
41
|
+
options[:secret_key]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Yotpo
|
3
|
+
class BogusGateway
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_order(order_details)
|
11
|
+
Response.new(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def response
|
16
|
+
response = Faraday.new do |builder|
|
17
|
+
builder.adapter :test do |stub|
|
18
|
+
stub.get('/rest/bogus.json') { |env| [ 200, {}, response_body ] }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
response.get('/rest/bogus.json')
|
22
|
+
end
|
23
|
+
|
24
|
+
def response_body
|
25
|
+
{
|
26
|
+
code: 200,
|
27
|
+
message: "OK",
|
28
|
+
uuid: "4161933d-9213-45ee-beb4-cb3ac2844345"
|
29
|
+
}.to_json
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Yotpo
|
3
|
+
class Gateway
|
4
|
+
include Yotpo::Authentication
|
5
|
+
class YotpoGatewayError < StandardError; end
|
6
|
+
|
7
|
+
attr_reader :options
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
requires!(options, :app_key, :secret_key)
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_order(order_details)
|
15
|
+
auth_creds = {
|
16
|
+
utoken: token,
|
17
|
+
app_key: client_id
|
18
|
+
}
|
19
|
+
|
20
|
+
body = order_details.merge(auth_creds).to_json
|
21
|
+
|
22
|
+
response = connection.post do |req|
|
23
|
+
req.url "apps/#{client_id}/purchases/"
|
24
|
+
req.body = body
|
25
|
+
end
|
26
|
+
|
27
|
+
Response.new(response)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def rest_endpoint
|
33
|
+
'https://api.yotpo.com'
|
34
|
+
end
|
35
|
+
|
36
|
+
def connection
|
37
|
+
headers = {
|
38
|
+
'Content-Type' => 'application/json',
|
39
|
+
'Authorization' => "Bearer #{token}"
|
40
|
+
}
|
41
|
+
|
42
|
+
request_timeouts = {
|
43
|
+
timeout: Workarea.config.yotpo.api_timeout,
|
44
|
+
open_timeout: Workarea.config.yotpo.open_timeout
|
45
|
+
}
|
46
|
+
|
47
|
+
Faraday.new(url: rest_endpoint, headers: headers, request: request_timeouts)
|
48
|
+
end
|
49
|
+
|
50
|
+
def requires!(hash, *params)
|
51
|
+
params.each do |param|
|
52
|
+
if param.is_a?(Array)
|
53
|
+
raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first)
|
54
|
+
|
55
|
+
valid_options = param[1..-1]
|
56
|
+
raise ArgumentError.new("Parameter: #{param.first} must be one of #{valid_options.to_sentence(words_connector: 'or')}") unless valid_options.include?(hash[param.first])
|
57
|
+
else
|
58
|
+
raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
echo "*************************************************************************"
|
4
|
+
echo "Running Bundler Audit..."
|
5
|
+
bundle exec bundle-audit check --update
|
6
|
+
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
|
7
|
+
|
8
|
+
echo ""
|
9
|
+
echo ""
|
10
|
+
echo "*************************************************************************"
|
11
|
+
echo "Running Rubocop..."
|
12
|
+
bundle exec rubocop
|
13
|
+
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
|
14
|
+
|
15
|
+
yarn init -yp --silent
|
16
|
+
|
17
|
+
echo ""
|
18
|
+
echo ""
|
19
|
+
echo "*************************************************************************"
|
20
|
+
echo "Running ESLint..."
|
21
|
+
yarn add --silent --dev eslint@4.19.1 --loglevel error
|
22
|
+
yarn run eslint admin/app/**/*.js admin/**/test/**/*.js core/app/**/*.js core/**/test/**/*.js storefront/app/**/*.js storefront/**/test/**/*.js
|
23
|
+
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
|
24
|
+
|
25
|
+
echo ""
|
26
|
+
echo "*************************************************************************"
|
27
|
+
echo "Running Stylelint..."
|
28
|
+
yarn add --silent --dev stylelint@9.2.1 stylelint-scss@3.1.0 stylelint-config-recommended-scss@3.2.0
|
29
|
+
yarn run stylelint admin/app/**/*.scss core/app/**/*.scss storefront/app/**/*.scss
|
data/script/travis
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.3
|
data/test/dummy/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,14 @@
|
|
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. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require rails-ujs
|
14
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
File without changes
|