payola-payments 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Rakefile +7 -11
- data/app/assets/javascripts/payola.js +1 -0
- data/app/assets/javascripts/payola/checkout_button.js +62 -0
- data/app/controllers/payola/application_controller.rb +2 -0
- data/app/controllers/payola/transactions_controller.rb +48 -58
- data/app/helpers/payola/price_helper.rb +7 -0
- data/{lib → app/models/concerns}/payola/sellable.rb +11 -1
- data/app/models/payola/affiliate.rb +5 -0
- data/app/models/payola/coupon.rb +5 -0
- data/app/models/payola/sale.rb +15 -4
- data/app/models/payola/stripe_webhook.rb +5 -0
- data/app/services/payola/charge_card.rb +6 -5
- data/app/services/payola/create_sale.rb +9 -5
- data/app/views/payola/transactions/_checkout.html.erb +48 -0
- data/app/views/payola/transactions/_form.html.erb +141 -0
- data/app/views/payola/transactions/iframe.html.erb +2 -0
- data/app/views/payola/transactions/new.html.erb +1 -0
- data/app/views/payola/transactions/show.html.erb +5 -0
- data/app/views/payola/transactions/wait.html.erb +25 -0
- data/config/routes.rb +0 -3
- data/db/migrate/20141001170138_create_payola_sales.rb +4 -4
- data/db/migrate/20141001203541_create_payola_stripe_webhooks.rb +9 -0
- data/db/migrate/20141002013618_create_payola_coupons.rb +10 -0
- data/db/migrate/20141002013701_create_payola_affiliates.rb +11 -0
- data/db/migrate/20141002203725_add_stripe_customer_id_to_sale.rb +6 -0
- data/lib/payola.rb +30 -5
- data/lib/payola/engine.rb +8 -0
- data/lib/payola/version.rb +1 -1
- data/lib/payola/worker.rb +22 -4
- data/spec/concerns/sellable_spec.rb +32 -0
- data/spec/controllers/payola/transactions_controller_spec.rb +7 -0
- data/{test → spec}/dummy/README.rdoc +0 -0
- data/{test → spec}/dummy/Rakefile +0 -0
- data/{test → spec}/dummy/app/assets/javascripts/application.js +1 -0
- data/spec/dummy/app/assets/javascripts/buy.js +2 -0
- data/{test → spec}/dummy/app/assets/stylesheets/application.css +0 -0
- data/spec/dummy/app/assets/stylesheets/buy.css +4 -0
- data/{test → spec}/dummy/app/controllers/application_controller.rb +0 -0
- data/spec/dummy/app/controllers/buy_controller.rb +7 -0
- data/{test → spec}/dummy/app/helpers/application_helper.rb +0 -0
- data/spec/dummy/app/helpers/buy_helper.rb +2 -0
- data/spec/dummy/app/models/product.rb +7 -0
- data/spec/dummy/app/views/buy/index.html.erb +1 -0
- data/{test → spec}/dummy/app/views/layouts/application.html.erb +2 -1
- data/{test → spec}/dummy/bin/bundle +0 -0
- data/{test → spec}/dummy/bin/rails +0 -0
- data/{test → spec}/dummy/bin/rake +0 -0
- data/{test → spec}/dummy/config.ru +0 -0
- data/{test → spec}/dummy/config/application.rb +0 -0
- data/{test → spec}/dummy/config/boot.rb +0 -0
- data/{test → spec}/dummy/config/database.yml +0 -0
- data/{test → spec}/dummy/config/environment.rb +0 -0
- data/{test → spec}/dummy/config/environments/development.rb +0 -0
- data/{test → spec}/dummy/config/environments/production.rb +0 -0
- data/{test → spec}/dummy/config/environments/test.rb +0 -0
- data/{test → spec}/dummy/config/initializers/assets.rb +0 -0
- data/{test → spec}/dummy/config/initializers/backtrace_silencers.rb +0 -0
- data/{test → spec}/dummy/config/initializers/cookies_serializer.rb +0 -0
- data/{test → spec}/dummy/config/initializers/filter_parameter_logging.rb +0 -0
- data/{test → spec}/dummy/config/initializers/inflections.rb +0 -0
- data/{test → spec}/dummy/config/initializers/mime_types.rb +0 -0
- data/spec/dummy/config/initializers/payola.rb +5 -0
- data/{test → spec}/dummy/config/initializers/session_store.rb +0 -0
- data/{test → spec}/dummy/config/initializers/wrap_parameters.rb +0 -0
- data/{test → spec}/dummy/config/locales/en.yml +0 -0
- data/{test → spec}/dummy/config/routes.rb +1 -1
- data/{test → spec}/dummy/config/secrets.yml +0 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20141001230848_create_products.rb +11 -0
- data/spec/dummy/db/schema.rb +76 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +7452 -0
- data/spec/dummy/log/test.log +9849 -0
- data/{test → spec}/dummy/public/404.html +0 -0
- data/{test → spec}/dummy/public/422.html +0 -0
- data/{test → spec}/dummy/public/500.html +0 -0
- data/{test → spec}/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/controllers/buy_controller_spec.rb +5 -0
- data/spec/dummy/spec/factories/products.rb +9 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0e585aeb88c1555ae8f5292f7c7a9068 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0f0c99469c51f1b2d76b08f481781d09 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1b54952339cbc96811097cee5f8923b4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1cbc4f4790f2067a2c161c1eb480f276 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5afa4bc970e0bc781b3500c696ba25ff +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/664efeb51d1b486dcfc30d142db56f3c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/68a3bbdc64a0729b5896fa1e33fce4b1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/aea159adbc0944b120d91d5b578612ba +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b83da90cb58011313e13a97a4a41cb6e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c0b954b40f2881a6d286061bc069643e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c5b3877d49b39932a7557611cefca9a6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ca491e325ff6948be9292f701aa4ce64 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d9856638a3c7b9cfd9d1b884e3b33982 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ddba6e841f28d3005e828fbfffd18b74 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/df935e399019055729aa968bd7062096 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ef82c31948061751bb026663b54484e1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f0b5d4bea0c6cdd1904e1e9a0a45532f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f8018075b7aca72974f4014bbbc75ab5 +0 -0
- data/spec/factories/payola_affiliates.rb +9 -0
- data/spec/factories/payola_coupons.rb +8 -0
- data/spec/factories/product.rb +7 -0
- data/spec/factories/sales.rb +7 -0
- data/spec/models/payola/sale_spec.rb +71 -0
- data/spec/models/payola/stripe_webhook_spec.rb +17 -0
- data/spec/payola_spec.rb +93 -0
- data/spec/services/payola/charge_card_spec.rb +37 -0
- data/spec/services/payola/create_sale_spec.rb +64 -0
- data/spec/spec_helper.rb +73 -0
- data/spec/worker_spec.rb +36 -0
- metadata +275 -81
- data/test/fixtures/payola/sales.yml +0 -11
- data/test/integration/navigation_test.rb +0 -10
- data/test/models/payola/sale_test.rb +0 -9
- data/test/payola_test.rb +0 -7
- data/test/test_helper.rb +0 -15
@@ -0,0 +1,141 @@
|
|
1
|
+
<div class="well payment-well" style="margin-bottom: 0px;">
|
2
|
+
<%= form_tag payola.buy_path(product_class: sale.product.product_class, permalink: permalink), :class => '', :id => 'payment-form' do %>
|
3
|
+
<% if coupon %>
|
4
|
+
<input type="hidden" name="coupon_code" value="<%= coupon.code %>" />
|
5
|
+
<% end %>
|
6
|
+
<div class="row">
|
7
|
+
<label class="control-label" for="email">Email Address <span class="label pull-right" style="margin-right: 8px">Secure <img src="<%= asset_path('lock.png') %>" style="height: 13px"></span></label>
|
8
|
+
<input autofocus="true" type="email" name="email" id="email" placeholder="you@example.com" class="payment-input"/>
|
9
|
+
</div>
|
10
|
+
<div class="row">
|
11
|
+
<label class="control-label" for="number">Card Number <span class="pull-right" style="margin-right: 8px"><img src="<%= asset_path('visa.png') %>" style="height: 15px;"><img src="<%= asset_path('mastercard.png') %>" style="height: 15px;"><img src="<%= asset_path('amex.png') %>" style="height: 15px;"><img src="<%= asset_path('discover.png') %>" style="height: 15px;"></span></label>
|
12
|
+
<input type="text" size="20" data-stripe="number" id="number" placeholder="1234 5678 9012 3456" pattern="[\d ]*" class="payment-input"/>
|
13
|
+
</div>
|
14
|
+
<div class="row">
|
15
|
+
<div style="float: left">
|
16
|
+
<label class="control-label" for="cvc">CV Code</label>
|
17
|
+
<input type="text" style="width: 3em" size="3" data-stripe="cvc" id="cvc" placeholder="123" pattern="\d*"/>
|
18
|
+
<img id="card-image" src="<%= asset_path('credit.png') %>" style="height: 30px; padding-left: 10px; margin-top: -10px">
|
19
|
+
</div>
|
20
|
+
<div style="float: right; margin-right: 8px">
|
21
|
+
<label class="control-label">Expiry Date</label>
|
22
|
+
<input style="width: 2em" type="text" size="2" id="exp-month" data-stripe="exp-month" placeholder="MM" pattern="\d*"/>
|
23
|
+
<span> / </span>
|
24
|
+
<input style="width: 3em" type="text" size="4" id="exp-year" data-stripe="exp-year" placeholder="YYYY" pattern="\d*"/>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
<div class="row" style="margin-top: 20px">
|
28
|
+
<div class="price" style="margin-top: 20px; float: left"><%= price %></div>
|
29
|
+
<div style="float: right; margin-right: 8px;text-align:center">
|
30
|
+
<div class="btn btn-success btn-large" disabled="disabled" style="display: none; width: 70px; height: 20px;" id="spinner-button"><img src="<%= asset_path('green_spinner_2.gif') %>" style="height: 15px;"></div>
|
31
|
+
<button type="submit" class="btn btn-success btn-large" id="pay-button">Pay Now</button><br>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
36
|
+
<div class="payment-well" style="margin-top: 0px; margin-bottom: 0px;">
|
37
|
+
<div class="row">
|
38
|
+
<div id="powered-by-stripe" style="<%= sale.errors.any? ? 'display: none;' : '' %> margin-left: auto; margin-right: auto; text-align: center; margin-top: 15px;">
|
39
|
+
<img src="<%= asset_path('powered_by_stripe.png') %>">
|
40
|
+
</div>
|
41
|
+
<div id="payment-errors" class="alert payment-alert" style="<%= sale.errors.any? ? '' : 'display: none;' %> margin-bottom: 0px;">
|
42
|
+
<% sale.errors.full_messages.each do |msg| %>
|
43
|
+
<span><%= msg %></span>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
|
49
|
+
<script type="text/javascript">
|
50
|
+
$(function(){
|
51
|
+
|
52
|
+
Stripe.setPublishableKey('<%= stripe_key %>');
|
53
|
+
|
54
|
+
$('#number').payment('formatCardNumber');
|
55
|
+
$('#cvc').payment('formatCardCVC');
|
56
|
+
$('#exp-month').payment('restrictNumeric');
|
57
|
+
$('#exp-year').payment('restrictNumeric');
|
58
|
+
$('#number').keyup(function(event) {
|
59
|
+
var number = $('#number').val();
|
60
|
+
var cardType = $.payment.cardType(number);
|
61
|
+
var img = $('#card-image')[0];
|
62
|
+
if (cardType === 'visa') {
|
63
|
+
$('#cvc').attr("placeholder", "123");
|
64
|
+
img.src = "<%= asset_path('visa.png') %>";
|
65
|
+
} else if (cardType === 'mastercard') {
|
66
|
+
$('#cvc').attr("placeholder", "123");
|
67
|
+
img.src = "<%= asset_path('mastercard.png') %>";
|
68
|
+
} else if (cardType === 'discover') {
|
69
|
+
$('#cvc').attr("placeholder", "123");
|
70
|
+
img.src = "<%= asset_path('discover.png') %>";
|
71
|
+
} else if (cardType === 'amex') {
|
72
|
+
$('#cvc').attr("placeholder", "1234");
|
73
|
+
img.src = "<%= asset_path('amex.png') %>";
|
74
|
+
} else if (cardType === 'dinersclub') {
|
75
|
+
$('#cvc').attr("placeholder", "123");
|
76
|
+
img.src = "<%= asset_path('diners.png') %>";
|
77
|
+
} else if (cardType === 'maestro') {
|
78
|
+
$('#cvc').attr("placeholder", "123");
|
79
|
+
img.src = "<%= asset_path('maestro.png') %>";
|
80
|
+
} else if (cardType === 'laser') {
|
81
|
+
$('#cvc').attr("placeholder", "123");
|
82
|
+
img.src = "<%= asset_path('laser.png') %>";
|
83
|
+
} else {
|
84
|
+
$('#cvc').attr("placeholder", "123");
|
85
|
+
img.src = "<%= asset_path('credit.png')%>";
|
86
|
+
}
|
87
|
+
});
|
88
|
+
|
89
|
+
$('#payment-form').submit(function(event) {
|
90
|
+
var form = $(this);
|
91
|
+
form.find('button').prop('disabled', true);
|
92
|
+
Stripe.createToken(form, stripeResponseHandler);
|
93
|
+
$('#pay-button').hide();
|
94
|
+
$('#spinner-button').show();
|
95
|
+
$('#pay-button').prop('disabled', false);
|
96
|
+
return false;
|
97
|
+
});
|
98
|
+
|
99
|
+
function stripeResponseHandler(status, response) {
|
100
|
+
var form = $('#payment-form');
|
101
|
+
if (response.error) {
|
102
|
+
showError(response.error.message);
|
103
|
+
} else {
|
104
|
+
var token = response.id;
|
105
|
+
form.append($('<input type="hidden" name="stripeToken">').val(token));
|
106
|
+
$.ajax({
|
107
|
+
type: "POST",
|
108
|
+
url: "<%= payola.buy_url(product_class: sale.product.product_class, permalink: sale.product.permalink) %>",
|
109
|
+
data: $('#payment-form').serialize(),
|
110
|
+
success: function(data) { poll(data.guid, 60) },
|
111
|
+
error: function(data) { showError(data.responseJSON.error) }
|
112
|
+
});
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
function showError(error) {
|
117
|
+
var form = $('#payment-form');
|
118
|
+
$('#payment-errors').html(error);
|
119
|
+
$('#payment-errors').show();
|
120
|
+
$('#pay-button').show();
|
121
|
+
$('#powered-by-stripe').hide();
|
122
|
+
$('#spinner-button').hide();
|
123
|
+
}
|
124
|
+
|
125
|
+
function poll(guid, num_retries_left) {
|
126
|
+
if (num_retries_left == 0) {
|
127
|
+
showError("This seems to be taking too long. Email <a href=\"mailto:<%= Payola.support_email %>\"><%= Payola.support_email %></a> and reference transaction <strong>" + guid + "</strong>.");
|
128
|
+
return;
|
129
|
+
}
|
130
|
+
$.get("/payola/status/" + guid, function(data) {
|
131
|
+
if (data.status === "finished") {
|
132
|
+
window.location = "/payola/confirm/" + guid;
|
133
|
+
} else if (data.status === "errored") {
|
134
|
+
showError(data.error)
|
135
|
+
} else {
|
136
|
+
setTimeout(function() { poll(guid, num_retries_left - 1) }, 500);
|
137
|
+
}
|
138
|
+
});
|
139
|
+
}
|
140
|
+
});
|
141
|
+
</script>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'form', stripe_key: Payola.publishable_key, permalink: @product.permalink, sale: @sale, price: formatted_price(@price), coupon: @coupon %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Please wait...
|
2
|
+
|
3
|
+
<div id="errors" style="display:none;"></div>
|
4
|
+
|
5
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
|
6
|
+
|
7
|
+
<script type="text/javascript">
|
8
|
+
$(function() {
|
9
|
+
function poll(guid, num_retries_left) {
|
10
|
+
if (num_retries_left == 0) {
|
11
|
+
$('#errors').html('Taking too long...');
|
12
|
+
}
|
13
|
+
$.get("/payola/status/" + guid, function(data) {
|
14
|
+
if (data.status === "finished") {
|
15
|
+
window.location = "/payola/confirm/" + guid;
|
16
|
+
} else if (data.status === "errored") {
|
17
|
+
$('#errors').html(data.error)
|
18
|
+
} else {
|
19
|
+
setTimeout(function() { poll(guid, num_retries_left - 1) }, 500);
|
20
|
+
}
|
21
|
+
});
|
22
|
+
}
|
23
|
+
poll("<%= @guid %>", 60);
|
24
|
+
});
|
25
|
+
</script>
|
data/config/routes.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
Payola::Engine.routes.draw do
|
2
|
-
match '/buy/:product_class/:permalink' => 'transactions#new', via: :get, as: :show_buy
|
3
2
|
match '/buy/:product_class/:permalink' => 'transactions#create', via: :post, as: :buy
|
4
3
|
match '/confirm/:guid' => 'transactions#show', via: :get, as: :confirm
|
5
|
-
match '/pickup/:guid' => 'transactions#pickup', via: :get, as: :pickup
|
6
|
-
match '/iframe/:username/:permalink' => 'transactions#iframe', via: :get, as: :buy_iframe
|
7
4
|
match '/status/:guid' => 'transactions#status', via: :get, as: :status
|
8
5
|
|
9
6
|
mount StripeEvent::Engine => '/events'
|
@@ -25,9 +25,9 @@ class CreatePayolaSales < ActiveRecord::Migration
|
|
25
25
|
t.timestamps
|
26
26
|
end
|
27
27
|
|
28
|
-
add_index "
|
29
|
-
add_index "
|
30
|
-
add_index "
|
31
|
-
add_index "
|
28
|
+
add_index "payola_sales", ["coupon_id"], name: "index_payola_sales_on_coupon_id", using: :btree
|
29
|
+
add_index "payola_sales", ["product_id", "product_type"], name: "index_payola_sales_on_product", using: :btree
|
30
|
+
add_index "payola_sales", ["email"], name: "index_payola_sales_on_email", using: :btree
|
31
|
+
add_index "payola_sales", ["guid"], name: "index_payola_sales_on_guid", using: :btree
|
32
32
|
end
|
33
33
|
end
|
data/lib/payola.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "payola/engine"
|
2
2
|
require "payola/worker"
|
3
|
+
require 'stripe_event'
|
4
|
+
require 'jquery-rails'
|
3
5
|
|
4
6
|
module Payola
|
5
7
|
class << self
|
6
|
-
attr_accessor :publishable_key, :secret_key, :secret_key_retriever, :background_worker
|
8
|
+
attr_accessor :publishable_key, :secret_key, :secret_key_retriever, :background_worker, :event_filter, :support_email, :sellables
|
7
9
|
|
8
10
|
def configure(&block)
|
9
11
|
raise ArgumentError, "must provide a block" unless block_given?
|
@@ -28,16 +30,39 @@ module Payola
|
|
28
30
|
|
29
31
|
def queue!(sale)
|
30
32
|
if background_worker.is_a? Symbol
|
31
|
-
Payola::Worker.find(
|
33
|
+
Payola::Worker.find(background_worker).call(sale)
|
32
34
|
elsif background_worker.respond_to?(:call)
|
33
35
|
background_worker.call(sale)
|
34
36
|
else
|
35
37
|
Payola::Worker.autofind.call(sale)
|
36
38
|
end
|
37
39
|
end
|
40
|
+
|
41
|
+
def reset!
|
42
|
+
StripeEvent.event_retriever = Retriever
|
43
|
+
|
44
|
+
self.background_worker = nil
|
45
|
+
self.event_filter = lambda { |event| event }
|
46
|
+
self.publishable_key = ENV['STRIPE_PUBLISHABLE_KEY']
|
47
|
+
self.secret_key = ENV['STRIPE_SECRET_KEY']
|
48
|
+
self.secret_key_retriever = lambda { |sale| Payola.secret_key }
|
49
|
+
self.support_email = 'sales@example.com'
|
50
|
+
self.sellables = {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def register_sellable(klass)
|
54
|
+
sellables[klass.product_class] = klass
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Retriever
|
59
|
+
def self.call(params)
|
60
|
+
return nil if StripeWebhook.exists?(stripe_id: params[:id])
|
61
|
+
StripeWebhook.create!(stripe_id: params[:id])
|
62
|
+
event = Stripe::Event.retrieve(params[:id])
|
63
|
+
Payola.event_filter(event)
|
64
|
+
end
|
38
65
|
end
|
39
66
|
|
40
|
-
self.
|
41
|
-
self.secret_key = ENV['STRIPE_SECRET_KEY']
|
42
|
-
self.secret_key_retriever = lambda { |sale| Payola.secret_key }
|
67
|
+
self.reset!
|
43
68
|
end
|
data/lib/payola/engine.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
module Payola
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
isolate_namespace Payola
|
4
|
+
engine_name 'payola'
|
5
|
+
|
6
|
+
config.generators do |g|
|
7
|
+
g.test_framework :rspec, fixture: false
|
8
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
9
|
+
g.assets false
|
10
|
+
g.helper false
|
11
|
+
end
|
4
12
|
end
|
5
13
|
end
|
data/lib/payola/version.rb
CHANGED
data/lib/payola/worker.rb
CHANGED
@@ -4,7 +4,7 @@ module Payola
|
|
4
4
|
attr_accessor :registry
|
5
5
|
|
6
6
|
def find(symbol)
|
7
|
-
if registry.has_key?
|
7
|
+
if registry.has_key? symbol
|
8
8
|
return registry[symbol]
|
9
9
|
else
|
10
10
|
raise "No such worker type: #{symbol}"
|
@@ -22,7 +22,13 @@ module Payola
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class
|
25
|
+
class BaseWorker
|
26
|
+
def perform(guid)
|
27
|
+
Sale.where(guid: guid).first.process!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Sidekiq < BaseWorker
|
26
32
|
def self.can_run?
|
27
33
|
defined?(::Sidekiq::Worker)
|
28
34
|
end
|
@@ -33,8 +39,20 @@ module Payola
|
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
class SuckerPunch < BaseWorker
|
43
|
+
def self.can_run?
|
44
|
+
defined?(::SuckerPunch::Job)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.call(sale)
|
48
|
+
self.send(:include, ::SuckerPunch::Job)
|
49
|
+
self.new.async.perform(sale.guid)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
self.registry = {
|
54
|
+
sidekiq: Payola::Worker::Sidekiq,
|
55
|
+
sucker_punch: Payola::Worker::SuckerPunch
|
38
56
|
}
|
39
57
|
end
|
40
58
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Payola
|
4
|
+
describe Sellable do
|
5
|
+
describe "validations" do
|
6
|
+
it "should validate" do
|
7
|
+
product = build(:product)
|
8
|
+
expect(product.valid?).to be true
|
9
|
+
end
|
10
|
+
it "should validate name" do
|
11
|
+
product = build(:product, name: nil)
|
12
|
+
expect(product.valid?).to be false
|
13
|
+
end
|
14
|
+
it "should validate permalink" do
|
15
|
+
product = build(:product, permalink: false)
|
16
|
+
expect(product.valid?).to be false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#product_class" do
|
21
|
+
it "should return the underscore'd version of the class" do
|
22
|
+
expect(build(:product).product_class).to eq 'product'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#sellable?" do
|
27
|
+
it "should return true" do
|
28
|
+
expect(Product.sellable?).to be true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
File without changes
|
File without changes
|
File without changes
|