reji 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +73 -0
  4. data/.rubocop_todo.yml +31 -0
  5. data/Appraisals +2 -0
  6. data/Gemfile +1 -1
  7. data/README.md +41 -17
  8. data/Rakefile +8 -2
  9. data/app/controllers/reji/payment_controller.rb +4 -4
  10. data/app/controllers/reji/webhook_controller.rb +51 -62
  11. data/app/views/payment.html.erb +4 -4
  12. data/app/views/receipt.html.erb +16 -16
  13. data/config/routes.rb +2 -0
  14. data/gemfiles/rails_5.0.gemfile +9 -9
  15. data/gemfiles/rails_5.1.gemfile +7 -9
  16. data/gemfiles/rails_5.2.gemfile +7 -9
  17. data/gemfiles/rails_6.0.gemfile +7 -9
  18. data/lib/generators/reji/install/install_generator.rb +20 -24
  19. data/lib/generators/reji/install/templates/reji.rb +2 -2
  20. data/lib/reji.rb +12 -8
  21. data/lib/reji/concerns/manages_customer.rb +25 -29
  22. data/lib/reji/concerns/manages_invoices.rb +37 -44
  23. data/lib/reji/concerns/manages_payment_methods.rb +45 -62
  24. data/lib/reji/concerns/manages_subscriptions.rb +13 -13
  25. data/lib/reji/concerns/performs_charges.rb +7 -7
  26. data/lib/reji/concerns/prorates.rb +1 -1
  27. data/lib/reji/configuration.rb +2 -2
  28. data/lib/reji/engine.rb +2 -0
  29. data/lib/reji/errors.rb +9 -9
  30. data/lib/reji/invoice.rb +57 -56
  31. data/lib/reji/invoice_line_item.rb +21 -23
  32. data/lib/reji/payment.rb +9 -5
  33. data/lib/reji/payment_method.rb +8 -4
  34. data/lib/reji/subscription.rb +165 -183
  35. data/lib/reji/subscription_builder.rb +41 -49
  36. data/lib/reji/subscription_item.rb +26 -26
  37. data/lib/reji/tax.rb +8 -10
  38. data/lib/reji/version.rb +1 -1
  39. data/reji.gemspec +5 -4
  40. data/spec/dummy/app/models/user.rb +3 -7
  41. data/spec/dummy/application.rb +3 -7
  42. data/spec/dummy/db/schema.rb +3 -4
  43. data/spec/feature/charges_spec.rb +1 -1
  44. data/spec/feature/customer_spec.rb +1 -1
  45. data/spec/feature/invoices_spec.rb +6 -6
  46. data/spec/feature/multiplan_subscriptions_spec.rb +51 -53
  47. data/spec/feature/payment_methods_spec.rb +25 -25
  48. data/spec/feature/pending_updates_spec.rb +26 -26
  49. data/spec/feature/subscriptions_spec.rb +78 -78
  50. data/spec/feature/webhooks_spec.rb +72 -72
  51. data/spec/spec_helper.rb +2 -2
  52. data/spec/support/feature_helpers.rb +6 -12
  53. data/spec/unit/customer_spec.rb +13 -13
  54. data/spec/unit/invoice_line_item_spec.rb +12 -14
  55. data/spec/unit/invoice_spec.rb +7 -9
  56. data/spec/unit/payment_spec.rb +3 -3
  57. data/spec/unit/subscription_spec.rb +29 -30
  58. metadata +26 -11
  59. data/Gemfile.lock +0 -133
@@ -55,7 +55,7 @@ describe 'charges', type: :request do
55
55
  begin
56
56
  user.charge(1000, 'pm_card_threeDSecure2Required')
57
57
 
58
- raise RSpec::Expectations::ExpectationNotMetError.new('Expected exception PaymentActionRequiredError was not thrown.')
58
+ raise RSpec::Expectations::ExpectationNotMetError, 'Expected exception PaymentActionRequiredError was not thrown.'
59
59
  rescue Reji::PaymentActionRequiredError => e
60
60
  # Assert that the payment needs an extra action.
61
61
  expect(e.payment.requires_action).to be true
@@ -7,7 +7,7 @@ describe 'customer', type: :request do
7
7
  user = create_customer('customers_in_stripe_can_be_updated')
8
8
  user.create_as_stripe_customer
9
9
 
10
- customer = user.update_stripe_customer({:description => 'Van Cam'})
10
+ customer = user.update_stripe_customer({ description: 'Van Cam' })
11
11
 
12
12
  expect(customer.description).to eq('Van Cam')
13
13
  end
@@ -6,9 +6,9 @@ describe 'invoices', type: :request do
6
6
  it 'test_require_stripe_customer_for_invoicing' do
7
7
  user = create_customer('require_stripe_customer_for_invoicing')
8
8
 
9
- expect {
9
+ expect do
10
10
  user.invoice
11
- }.to raise_error(Reji::InvalidCustomerError)
11
+ end.to raise_error(Reji::InvalidCustomerError)
12
12
  end
13
13
 
14
14
  it 'test_invoicing_fails_with_nothing_to_invoice' do
@@ -53,9 +53,9 @@ describe 'invoices', type: :request do
53
53
  user.update_default_payment_method('pm_card_visa')
54
54
  invoice = user.invoice_for('Rails Reji', 1000)
55
55
 
56
- expect {
56
+ expect do
57
57
  other_user.find_invoice(invoice.id)
58
- }.to raise_error(Reji::InvalidInvoiceError, "The invoice `#{invoice.id}` does not belong to this customer `#{other_user.stripe_id}`.")
58
+ end.to raise_error(Reji::InvalidInvoiceError, "The invoice `#{invoice.id}` does not belong to this customer `#{other_user.stripe_id}`.")
59
59
  end
60
60
 
61
61
  it 'test_find_invoice_by_id_or_fail' do
@@ -66,8 +66,8 @@ describe 'invoices', type: :request do
66
66
  user.update_default_payment_method('pm_card_visa')
67
67
  invoice = user.invoice_for('Rails Reji', 1000)
68
68
 
69
- expect {
69
+ expect do
70
70
  other_user.find_invoice_or_fail(invoice.id)
71
- }.to raise_error(Reji::AccessDeniedHttpError)
71
+ end.to raise_error(Reji::AccessDeniedHttpError)
72
72
  end
73
73
  end
@@ -10,47 +10,47 @@ describe 'multiplan subscriptions', type: :request do
10
10
  @premium_plan_id = "#{stripe_prefix}monthly-20-premium-#{SecureRandom.hex(5)}"
11
11
 
12
12
  Stripe::Product.create({
13
- :id => @product_id,
14
- :name => 'Rails Reji Test Product',
15
- :type => 'service',
13
+ id: @product_id,
14
+ name: 'Rails Reji Test Product',
15
+ type: 'service',
16
16
  })
17
17
 
18
18
  Stripe::Plan.create({
19
- :id => @plan_id,
20
- :nickname => 'Monthly $10',
21
- :currency => 'USD',
22
- :interval => 'month',
23
- :billing_scheme => 'per_unit',
24
- :amount => 1000,
25
- :product => @product_id,
19
+ id: @plan_id,
20
+ nickname: 'Monthly $10',
21
+ currency: 'USD',
22
+ interval: 'month',
23
+ billing_scheme: 'per_unit',
24
+ amount: 1000,
25
+ product: @product_id,
26
26
  })
27
27
 
28
28
  Stripe::Plan.create({
29
- :id => @other_plan_id,
30
- :nickname => 'Monthly $10 Other',
31
- :currency => 'USD',
32
- :interval => 'month',
33
- :billing_scheme => 'per_unit',
34
- :amount => 1000,
35
- :product => @product_id,
29
+ id: @other_plan_id,
30
+ nickname: 'Monthly $10 Other',
31
+ currency: 'USD',
32
+ interval: 'month',
33
+ billing_scheme: 'per_unit',
34
+ amount: 1000,
35
+ product: @product_id,
36
36
  })
37
37
 
38
38
  Stripe::Plan.create({
39
- :id => @premium_plan_id,
40
- :nickname => 'Monthly $20 Premium',
41
- :currency => 'USD',
42
- :interval => 'month',
43
- :billing_scheme => 'per_unit',
44
- :amount => 2000,
45
- :product => @product_id,
39
+ id: @premium_plan_id,
40
+ nickname: 'Monthly $20 Premium',
41
+ currency: 'USD',
42
+ interval: 'month',
43
+ billing_scheme: 'per_unit',
44
+ amount: 2000,
45
+ product: @product_id,
46
46
  })
47
47
 
48
48
  @tax_rate_id = Stripe::TaxRate.create({
49
- :display_name => 'VAT',
50
- :description => 'VAT Belgium',
51
- :jurisdiction => 'BE',
52
- :percentage => 21,
53
- :inclusive => false,
49
+ display_name: 'VAT',
50
+ description: 'VAT Belgium',
51
+ jurisdiction: 'BE',
52
+ percentage: 21,
53
+ inclusive: false,
54
54
  }).id
55
55
  end
56
56
 
@@ -64,7 +64,7 @@ describe 'multiplan subscriptions', type: :request do
64
64
  it 'test_customers_can_have_multiplan_subscriptions' do
65
65
  user = create_customer('customers_can_have_multiplan_subscriptions')
66
66
 
67
- user.plan_tax_rates = {@other_plan_id => [@tax_rate_id]}
67
+ user.plan_tax_rates = { @other_plan_id => [@tax_rate_id] }
68
68
 
69
69
  subscription = user.new_subscription('main', [@plan_id, @other_plan_id])
70
70
  .plan(@premium_plan_id, 5)
@@ -124,11 +124,11 @@ describe 'multiplan subscriptions', type: :request do
124
124
  it 'test_customers_cannot_remove_the_last_plan' do
125
125
  user = create_customer('customers_cannot_remove_the_last_plan')
126
126
 
127
- subscription = self.create_subscription_with_single_plan(user)
127
+ subscription = create_subscription_with_single_plan(user)
128
128
 
129
- expect {
129
+ expect do
130
130
  subscription.remove_plan(@plan_id)
131
- }.to raise_error(Reji::SubscriptionUpdateFailureError)
131
+ end.to raise_error(Reji::SubscriptionUpdateFailureError)
132
132
  end
133
133
 
134
134
  it 'test_multiplan_subscriptions_can_be_resumed' do
@@ -152,11 +152,11 @@ describe 'multiplan subscriptions', type: :request do
152
152
  it 'test_plan_is_required_when_updating_quantities_for_multiplan_subscriptions' do
153
153
  user = create_customer('plan_is_required_when_updating_quantities_for_multiplan_subscriptions')
154
154
 
155
- subscription = self.create_subscription_with_multiple_plans(user)
155
+ subscription = create_subscription_with_multiple_plans(user)
156
156
 
157
- expect {
157
+ expect do
158
158
  subscription.update_quantity(5)
159
- }.to raise_error(ArgumentError)
159
+ end.to raise_error(ArgumentError)
160
160
  end
161
161
 
162
162
  it 'test_subscription_item_quantities_can_be_updated' do
@@ -227,7 +227,7 @@ describe 'multiplan subscriptions', type: :request do
227
227
 
228
228
  subscription = user.new_subscription('main', @plan_id).create('pm_card_visa')
229
229
 
230
- item = subscription.items.first.swap(@other_plan_id, {:quantity => 3})
230
+ item = subscription.items.first.swap(@other_plan_id, { quantity: 3 })
231
231
 
232
232
  expect(subscription.items.count).to eq(1)
233
233
  expect(subscription.stripe_plan).to eq(@other_plan_id)
@@ -279,39 +279,37 @@ describe 'multiplan subscriptions', type: :request do
279
279
  expect(user.upcoming_invoice.raw_total).to eq(2000)
280
280
  end
281
281
 
282
- protected
283
-
284
282
  # Create a subscription with a single plan.
285
- def create_subscription_with_single_plan(user)
283
+ protected def create_subscription_with_single_plan(user)
286
284
  subscription = user.subscriptions.create({
287
- :name => 'main',
288
- :stripe_id => 'sub_foo',
289
- :stripe_plan => @plan_id,
290
- :quantity => 1,
291
- :stripe_status => 'active',
285
+ name: 'main',
286
+ stripe_id: 'sub_foo',
287
+ stripe_plan: @plan_id,
288
+ quantity: 1,
289
+ stripe_status: 'active',
292
290
  })
293
291
 
294
292
  subscription.items.create({
295
- :stripe_id => 'it_foo',
296
- :stripe_plan => @plan_id,
297
- :quantity => 1,
293
+ stripe_id: 'it_foo',
294
+ stripe_plan: @plan_id,
295
+ quantity: 1,
298
296
  })
299
297
 
300
298
  subscription
301
299
  end
302
300
 
303
301
  # Create a subscription with multiple plans.
304
- def create_subscription_with_multiple_plans(user)
305
- subscription = self.create_subscription_with_single_plan(user)
302
+ protected def create_subscription_with_multiple_plans(user)
303
+ subscription = create_subscription_with_single_plan(user)
306
304
 
307
305
  subscription.stripe_plan = nil
308
306
  subscription.quantity = nil
309
307
  subscription.save
310
308
 
311
309
  subscription.items.new({
312
- :stripe_id => 'it_foo',
313
- :stripe_plan => @other_plan_id,
314
- :quantity => 1,
310
+ stripe_id: 'it_foo',
311
+ stripe_plan: @other_plan_id,
312
+ quantity: 1,
315
313
  })
316
314
 
317
315
  subscription
@@ -3,13 +3,13 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'payment_methods', type: :request do
6
- it 'can_start_a_new_setup_intent_session' do
6
+ it 'test_we_can_start_a_new_setup_intent_session' do
7
7
  user = create_customer('we_can_start_a_new_setup_intent_session')
8
8
  setup_intent = user.create_setup_intent
9
9
  expect(setup_intent).to be_an_instance_of(Stripe::SetupIntent)
10
10
  end
11
11
 
12
- it 'can_add_payment_methods' do
12
+ it 'test_we_can_add_payment_methods' do
13
13
  user = create_customer('we_can_add_payment_methods')
14
14
  user.create_as_stripe_customer
15
15
 
@@ -18,34 +18,34 @@ describe 'payment_methods', type: :request do
18
18
  expect(payment_method).to be_an_instance_of(Reji::PaymentMethod)
19
19
  expect(payment_method.card.brand).to eq('visa')
20
20
  expect(payment_method.card.last4).to eq('4242')
21
- expect(user.has_payment_method).to be true
22
- expect(user.has_default_payment_method).to be false
21
+ expect(user.payment_method?).to be true
22
+ expect(user.default_payment_method?).to be false
23
23
  end
24
24
 
25
- it 'can_remove_payment_methods' do
25
+ it 'test_we_can_remove_payment_methods' do
26
26
  user = create_customer('we_can_remove_payment_methods')
27
27
  user.create_as_stripe_customer
28
28
 
29
29
  payment_method = user.add_payment_method('pm_card_visa')
30
30
 
31
31
  expect(user.payment_methods.count).to eq(1)
32
- expect(user.has_payment_method).to be true
32
+ expect(user.payment_method?).to be true
33
33
 
34
34
  user.remove_payment_method(payment_method.as_stripe_payment_method)
35
35
 
36
36
  expect(user.payment_methods.count).to eq(0)
37
- expect(user.has_payment_method).to be false
37
+ expect(user.payment_method?).to be false
38
38
  end
39
39
 
40
- it 'can_remove_the_default_payment_method' do
40
+ it 'test_we_can_remove_the_default_payment_method' do
41
41
  user = create_customer('we_can_remove_the_default_payment_method')
42
42
  user.create_as_stripe_customer
43
43
 
44
44
  payment_method = user.update_default_payment_method('pm_card_visa')
45
45
 
46
46
  expect(user.payment_methods.count).to eq(1)
47
- expect(user.has_payment_method).to be true
48
- expect(user.has_default_payment_method).to be true
47
+ expect(user.payment_method?).to be true
48
+ expect(user.default_payment_method?).to be true
49
49
 
50
50
  user.remove_payment_method(payment_method.as_stripe_payment_method)
51
51
 
@@ -53,11 +53,11 @@ describe 'payment_methods', type: :request do
53
53
  expect(user.default_payment_method).to be_nil
54
54
  expect(user.card_brand).to be_nil
55
55
  expect(user.card_last_four).to be_nil
56
- expect(user.has_payment_method).to be false
57
- expect(user.has_default_payment_method).to be false
56
+ expect(user.payment_method?).to be false
57
+ expect(user.default_payment_method?).to be false
58
58
  end
59
59
 
60
- it 'can_set_a_default_payment_method' do
60
+ it 'test_we_can_set_a_default_payment_method' do
61
61
  user = create_customer('we_can_set_a_default_payment_method')
62
62
  user.create_as_stripe_customer
63
63
 
@@ -66,7 +66,7 @@ describe 'payment_methods', type: :request do
66
66
  expect(payment_method).to be_an_instance_of(Reji::PaymentMethod)
67
67
  expect(payment_method.card.brand).to eq('visa')
68
68
  expect(payment_method.card.last4).to eq('4242')
69
- expect(user.has_default_payment_method).to be true
69
+ expect(user.default_payment_method?).to be true
70
70
 
71
71
  payment_method = user.default_payment_method
72
72
 
@@ -75,10 +75,10 @@ describe 'payment_methods', type: :request do
75
75
  expect(payment_method.card.last4).to eq('4242')
76
76
  end
77
77
 
78
- it 'can_retrieve_an_old_default_source_as_a_default_payment_method' do
78
+ it 'test_legacy_we_can_retrieve_an_old_default_source_as_a_default_payment_method' do
79
79
  user = create_customer('we_can_retrieve_an_old_default_source_as_a_default_payment_method')
80
80
  customer = user.create_as_stripe_customer
81
- card = Stripe::Customer.create_source(customer.id, {:source => 'tok_visa'}, user.stripe_options)
81
+ card = Stripe::Customer.create_source(customer.id, { source: 'tok_visa' }, user.stripe_options)
82
82
  customer.default_source = card.id
83
83
  customer.save
84
84
 
@@ -89,15 +89,15 @@ describe 'payment_methods', type: :request do
89
89
  expect(payment_method.last4).to eq('4242')
90
90
  end
91
91
 
92
- it 'can_retrieve_all_payment_methods' do
92
+ it 'test_we_can_retrieve_all_payment_methods' do
93
93
  user = create_customer('we_can_retrieve_all_payment_methods')
94
94
  customer = user.create_as_stripe_customer
95
95
 
96
96
  payment_method = Stripe::PaymentMethod.retrieve('pm_card_visa', user.stripe_options)
97
- payment_method.attach({:customer => customer.id})
97
+ payment_method.attach({ customer: customer.id })
98
98
 
99
99
  payment_method = Stripe::PaymentMethod.retrieve('pm_card_mastercard', user.stripe_options)
100
- payment_method.attach({:customer => customer.id})
100
+ payment_method.attach({ customer: customer.id })
101
101
 
102
102
  payment_methods = user.payment_methods
103
103
 
@@ -106,14 +106,14 @@ describe 'payment_methods', type: :request do
106
106
  expect(payment_methods.last.card.brand).to eq('visa')
107
107
  end
108
108
 
109
- it 'can_sync_the_payment_method_from_stripe' do
109
+ it 'test_we_can_sync_the_default_payment_method_from_stripe' do
110
110
  user = create_customer('we_can_sync_the_payment_method_from_stripe')
111
111
  customer = user.create_as_stripe_customer
112
112
 
113
113
  payment_method = Stripe::PaymentMethod.retrieve('pm_card_visa', user.stripe_options)
114
- payment_method.attach({:customer => customer.id})
114
+ payment_method.attach({ customer: customer.id })
115
115
 
116
- customer.invoice_settings = {:default_payment_method => payment_method.id}
116
+ customer.invoice_settings = { default_payment_method: payment_method.id }
117
117
 
118
118
  customer.save
119
119
 
@@ -126,15 +126,15 @@ describe 'payment_methods', type: :request do
126
126
  expect(user.card_last_four).to eq('4242')
127
127
  end
128
128
 
129
- it 'delete_all_payment_methods' do
129
+ it 'test_we_delete_all_payment_methods' do
130
130
  user = create_customer('we_delete_all_payment_methods')
131
131
  customer = user.create_as_stripe_customer
132
132
 
133
133
  payment_method = Stripe::PaymentMethod.retrieve('pm_card_visa', user.stripe_options)
134
- payment_method.attach({:customer => customer.id})
134
+ payment_method.attach({ customer: customer.id })
135
135
 
136
136
  payment_method = Stripe::PaymentMethod.retrieve('pm_card_mastercard', user.stripe_options)
137
- payment_method.attach({:customer => customer.id})
137
+ payment_method.attach({ customer: customer.id })
138
138
 
139
139
  payment_methods = user.payment_methods
140
140
 
@@ -10,39 +10,39 @@ describe 'pending updates', type: :request do
10
10
  @premium_plan_id = "#{stripe_prefix}monthly-20-premium-#{SecureRandom.hex(5)}"
11
11
 
12
12
  Stripe::Product.create({
13
- :id => @product_id,
14
- :name => 'Rails Reji Test Product',
15
- :type => 'service',
13
+ id: @product_id,
14
+ name: 'Rails Reji Test Product',
15
+ type: 'service',
16
16
  })
17
17
 
18
18
  Stripe::Plan.create({
19
- :id => @plan_id,
20
- :nickname => 'Monthly $10',
21
- :currency => 'USD',
22
- :interval => 'month',
23
- :billing_scheme => 'per_unit',
24
- :amount => 1000,
25
- :product => @product_id,
19
+ id: @plan_id,
20
+ nickname: 'Monthly $10',
21
+ currency: 'USD',
22
+ interval: 'month',
23
+ billing_scheme: 'per_unit',
24
+ amount: 1000,
25
+ product: @product_id,
26
26
  })
27
27
 
28
28
  Stripe::Plan.create({
29
- :id => @other_plan_id,
30
- :nickname => 'Monthly $10 Other',
31
- :currency => 'USD',
32
- :interval => 'month',
33
- :billing_scheme => 'per_unit',
34
- :amount => 1000,
35
- :product => @product_id,
29
+ id: @other_plan_id,
30
+ nickname: 'Monthly $10 Other',
31
+ currency: 'USD',
32
+ interval: 'month',
33
+ billing_scheme: 'per_unit',
34
+ amount: 1000,
35
+ product: @product_id,
36
36
  })
37
37
 
38
38
  Stripe::Plan.create({
39
- :id => @premium_plan_id,
40
- :nickname => 'Monthly $20 Premium',
41
- :currency => 'USD',
42
- :interval => 'month',
43
- :billing_scheme => 'per_unit',
44
- :amount => 2000,
45
- :product => @product_id,
39
+ id: @premium_plan_id,
40
+ nickname: 'Monthly $20 Premium',
41
+ currency: 'USD',
42
+ interval: 'month',
43
+ billing_scheme: 'per_unit',
44
+ amount: 2000,
45
+ product: @product_id,
46
46
  })
47
47
  end
48
48
 
@@ -65,8 +65,8 @@ describe 'pending updates', type: :request do
65
65
  # Attempt to swap and pay with a faulty card.
66
66
  subscription = subscription.error_if_payment_fails.swap_and_invoice(@premium_plan_id)
67
67
 
68
- raise RSpec::Expectations::ExpectationNotMetError.new('Expected exception PaymentFailureError was not thrown.')
69
- rescue Stripe::CardError => e
68
+ raise RSpec::Expectations::ExpectationNotMetError, 'Expected exception PaymentFailureError was not thrown.'
69
+ rescue Stripe::CardError => _e
70
70
  # Assert that the plan was not swapped.
71
71
  expect(subscription.stripe_plan).to eq(@plan_id)
72
72