reji 1.0.0 → 1.1.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 (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