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
@@ -7,7 +7,7 @@ require 'dummy/application'
7
7
 
8
8
  require 'rspec/rails'
9
9
 
10
- Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
10
+ Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
11
11
 
12
12
  Dummy::Application.initialize!
13
13
 
@@ -21,7 +21,7 @@ RSpec.configure do |config|
21
21
 
22
22
  config.infer_spec_type_from_file_location!
23
23
 
24
- %i(request).each do |type|
24
+ %i[request].each do |type|
25
25
  config.include(Reji::Test::FeatureHelpers, type: type)
26
26
  end
27
27
  end
@@ -17,23 +17,17 @@ module Reji
17
17
 
18
18
  sleep(2)
19
19
 
20
- protected
21
-
22
- def delete_stripe_resource(resource)
23
- begin
24
- resource.delete
25
- rescue Stripe::InvalidRequestError => e
26
- #
27
- end
20
+ protected def delete_stripe_resource(resource)
21
+ resource.delete
22
+ rescue Stripe::InvalidRequestError => _e
23
+ #
28
24
  end
29
25
 
30
- def create_customer(description = 'cuong', options = {})
26
+ protected def create_customer(description = 'cuong', options = {})
31
27
  User.create({
32
- :email => "#{description}@reji-test.com",
28
+ email: "#{description}@reji-test.com",
33
29
  }.merge(options))
34
30
  end
35
31
  end
36
32
  end
37
33
  end
38
-
39
-
@@ -3,52 +3,52 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'customer', type: :unit do
6
- it 'test_customer_can_be_put_on_a_generic_trial' do
6
+ it 'can_be_put_on_a_generic_trial' do
7
7
  user = User.new
8
8
 
9
9
  expect(user.on_generic_trial).to be false
10
10
 
11
- user.trial_ends_at = Time.now + 1.day
11
+ user.trial_ends_at = Time.current + 1.day
12
12
 
13
13
  expect(user.on_generic_trial).to be true
14
14
 
15
- user.trial_ends_at = Time.now - 5.days
15
+ user.trial_ends_at = Time.current - 5.days
16
16
 
17
17
  expect(user.on_generic_trial).to be false
18
18
  end
19
19
 
20
- it 'test_we_can_determine_if_it_has_a_payment_method' do
20
+ it 'can_determine_if_the_user_has_a_default_payment_method' do
21
21
  user = User.new
22
22
 
23
23
  user.card_brand = 'visa'
24
24
 
25
- expect(user.has_default_payment_method).to be true
25
+ expect(user.default_payment_method?).to be true
26
26
 
27
27
  user = User.new
28
28
 
29
- expect(user.has_default_payment_method).to be false
29
+ expect(user.default_payment_method?).to be false
30
30
  end
31
31
 
32
- it 'test_default_payment_method_returns_nil_when_the_user_is_not_a_customer_yet' do
32
+ it 'returns_nil_default_payment_method_when_the_user_is_not_a_customer_yet' do
33
33
  user = User.new
34
34
 
35
35
  expect(user.default_payment_method).to be_nil
36
36
  end
37
37
 
38
- it 'test_stripe_customer_method_throws_exception_when_stripe_id_is_not_set' do
38
+ it 'cannot_return_stripe_customer_when_stripe_id_is_not_set' do
39
39
  user = User.new
40
40
 
41
- expect {
41
+ expect do
42
42
  user.as_stripe_customer
43
- }.to raise_error(Reji::InvalidCustomerError)
43
+ end.to raise_error(Reji::InvalidCustomerError)
44
44
  end
45
45
 
46
- it 'test_stripe_customer_cannot_be_created_when_stripe_id_is_already_set' do
46
+ it 'cannot_create_stripe_customer_when_stripe_id_is_already_set' do
47
47
  user = User.new
48
48
  user.stripe_id = 'foo'
49
49
 
50
- expect {
50
+ expect do
51
51
  user.create_as_stripe_customer
52
- }.to raise_error(Reji::CustomerAlreadyCreatedError)
52
+ end.to raise_error(Reji::CustomerAlreadyCreatedError)
53
53
  end
54
54
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Reji::InvoiceLineItem, type: :unit do
5
+ describe 'invoice line item' do
6
6
  it 'can_calculate_the_inclusive_tax_percentage' do
7
7
  customer = User.new
8
8
  customer.stripe_id = 'foo'
@@ -15,9 +15,9 @@ describe Reji::InvoiceLineItem, type: :unit do
15
15
 
16
16
  stripe_invoice_line_item = Stripe::InvoiceLineItem.new
17
17
  stripe_invoice_line_item.tax_amounts = [
18
- {:inclusive => true, :tax_rate => self.inclusive_tax_rate(5.0)},
19
- {:inclusive => true, :tax_rate => self.inclusive_tax_rate(15.0)},
20
- {:inclusive => false, :tax_rate => self.inclusive_tax_rate(21.0)},
18
+ { inclusive: true, tax_rate: inclusive_tax_rate(5.0) },
19
+ { inclusive: true, tax_rate: inclusive_tax_rate(15.0) },
20
+ { inclusive: false, tax_rate: inclusive_tax_rate(21.0) },
21
21
  ]
22
22
 
23
23
  item = Reji::InvoiceLineItem.new(invoice, stripe_invoice_line_item)
@@ -37,9 +37,9 @@ describe Reji::InvoiceLineItem, type: :unit do
37
37
 
38
38
  stripe_invoice_line_item = Stripe::InvoiceLineItem.new
39
39
  stripe_invoice_line_item.tax_amounts = [
40
- {:inclusive => true, :tax_rate => self.inclusive_tax_rate(5.0)},
41
- {:inclusive => false, :tax_rate => self.exclusive_tax_rate(15.0)},
42
- {:inclusive => false, :tax_rate => self.exclusive_tax_rate(21.0)},
40
+ { inclusive: true, tax_rate: inclusive_tax_rate(5.0) },
41
+ { inclusive: false, tax_rate: exclusive_tax_rate(15.0) },
42
+ { inclusive: false, tax_rate: exclusive_tax_rate(21.0) },
43
43
  ]
44
44
 
45
45
  item = Reji::InvoiceLineItem.new(invoice, stripe_invoice_line_item)
@@ -49,20 +49,18 @@ describe Reji::InvoiceLineItem, type: :unit do
49
49
  expect(result).to eq(36)
50
50
  end
51
51
 
52
- protected
53
-
54
52
  # Get a test inclusive Tax Rate.
55
- def inclusive_tax_rate(percentage)
56
- self.tax_rate(percentage)
53
+ protected def inclusive_tax_rate(percentage)
54
+ tax_rate(percentage)
57
55
  end
58
56
 
59
57
  # Get a test exclusive Tax Rate.
60
- def exclusive_tax_rate(percentage)
61
- self.tax_rate(percentage, false)
58
+ protected def exclusive_tax_rate(percentage)
59
+ tax_rate(percentage, false)
62
60
  end
63
61
 
64
62
  # Get a test exclusive Tax Rate.
65
- def tax_rate(percentage, inclusive = true)
63
+ protected def tax_rate(percentage, inclusive = true)
66
64
  inclusive_tax_rate = Stripe::TaxRate.new
67
65
  inclusive_tax_rate.inclusive = inclusive
68
66
  inclusive_tax_rate.percentage = percentage
@@ -2,20 +2,18 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe 'invoice', type: :unit do
5
+ describe 'invoice' do
6
6
  it 'can_return_the_invoice_date' do
7
7
  stripe_invoice = Stripe::Invoice.new
8
8
  stripe_invoice.customer = 'foo'
9
- stripe_invoice.created = 1560541724
9
+ stripe_invoice.created = 1_560_541_724
10
10
 
11
11
  user = User.new
12
12
  user.stripe_id = 'foo'
13
13
 
14
14
  invoice = Reji::Invoice.new(user, stripe_invoice)
15
15
 
16
- date = invoice.date
17
-
18
- expect(invoice.date.to_i).to eq(1560541724)
16
+ expect(invoice.date.to_i).to eq(1_560_541_724)
19
17
  end
20
18
 
21
19
  it 'can_return_its_total' do
@@ -85,7 +83,7 @@ describe 'invoice', type: :unit do
85
83
 
86
84
  invoice = Reji::Invoice.new(user, stripe_invoice)
87
85
 
88
- expect(invoice.has_starting_balance).to be true
86
+ expect(invoice.starting_balance?).to be true
89
87
  end
90
88
 
91
89
  it 'can_determine_when_the_customer_does_not_have_a_starting_balance' do
@@ -98,7 +96,7 @@ describe 'invoice', type: :unit do
98
96
 
99
97
  invoice = Reji::Invoice.new(user, stripe_invoice)
100
98
 
101
- expect(invoice.has_starting_balance).to be false
99
+ expect(invoice.starting_balance?).to be false
102
100
  end
103
101
 
104
102
  it 'can_return_its_starting_balance' do
@@ -147,7 +145,7 @@ describe 'invoice', type: :unit do
147
145
 
148
146
  invoice = Reji::Invoice.new(user, stripe_invoice)
149
147
 
150
- expect(invoice.has_discount).to be true
148
+ expect(invoice.discount?).to be true
151
149
  end
152
150
 
153
151
  it 'can_return_its_tax' do
@@ -174,7 +172,7 @@ describe 'invoice', type: :unit do
174
172
 
175
173
  invoice = Reji::Invoice.new(user, stripe_invoice)
176
174
 
177
- expect(invoice.is_tax_exempt).to be true
175
+ expect(invoice.tax_exempt?).to be true
178
176
  end
179
177
 
180
178
  it 'can_determine_if_reverse_charge_applies' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe 'payment', type: :unit do
5
+ describe 'payment' do
6
6
  it 'can_return_its_requires_payment_method_status' do
7
7
  payment_intent = Stripe::PaymentIntent.new
8
8
  payment_intent.status = 'requires_payment_method'
@@ -21,13 +21,13 @@ describe 'payment', type: :unit do
21
21
  payment_intent = Stripe::PaymentIntent.new
22
22
  payment_intent.status = 'canceled'
23
23
  payment = Reji::Payment.new(payment_intent)
24
- expect(payment.is_cancelled).to be true
24
+ expect(payment.cancelled?).to be true
25
25
  end
26
26
 
27
27
  it 'can_return_its_succeeded_status' do
28
28
  payment_intent = Stripe::PaymentIntent.new
29
29
  payment_intent.status = 'succeeded'
30
30
  payment = Reji::Payment.new(payment_intent)
31
- expect(payment.is_succeeded).to be true
31
+ expect(payment.succeeded?).to be true
32
32
  end
33
33
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe 'subscription', type: :unit do
6
- it 'can_check_if_a_subscription_is_incomplete' do
5
+ describe 'subscription' do
6
+ it 'can_determine_if_it_is_incomplete' do
7
7
  subscription = Reji::Subscription.new(stripe_status: 'incomplete')
8
8
 
9
9
  expect(subscription.incomplete).to be true
@@ -11,15 +11,14 @@ describe 'subscription', type: :unit do
11
11
  expect(subscription.active).to be false
12
12
  end
13
13
 
14
- it 'can_check_if_a_subscription_is_past_due' do
14
+ it 'can_determine_if_it_is_past_due' do
15
15
  subscription = Reji::Subscription.new(stripe_status: 'past_due')
16
-
17
16
  expect(subscription.incomplete).to be false
18
17
  expect(subscription.past_due).to be true
19
18
  expect(subscription.active).to be false
20
19
  end
21
20
 
22
- it 'can_check_if_a_subscription_is_active' do
21
+ it 'can_determine_if_it_is_active' do
23
22
  subscription = Reji::Subscription.new(stripe_status: 'active')
24
23
 
25
24
  expect(subscription.incomplete).to be false
@@ -27,77 +26,77 @@ describe 'subscription', type: :unit do
27
26
  expect(subscription.active).to be true
28
27
  end
29
28
 
30
- it 'can_check_if_an_incomplete_subscription_is_not_valid' do
29
+ it 'is_not_valid_when_status_is_incomplete' do
31
30
  subscription = Reji::Subscription.new(stripe_status: 'incomplete')
32
31
 
33
32
  expect(subscription.valid).to be false
34
33
  end
35
34
 
36
- it 'can_check_if_a_past_due_subscription_is_not_valid' do
35
+ it 'is_not_valid_when_status_is_past_due' do
37
36
  subscription = Reji::Subscription.new(stripe_status: 'past_due')
38
37
 
39
38
  expect(subscription.valid).to be false
40
39
  end
41
40
 
42
- it 'can_check_if_an_active_subscription_is_valid' do
41
+ it 'is_valid_when_status_is_active' do
43
42
  subscription = Reji::Subscription.new(stripe_status: 'active')
44
43
 
45
44
  expect(subscription.valid).to be true
46
45
  end
47
46
 
48
- it 'test_payment_is_incomplete_when_status_is_incomplete' do
47
+ it 'has_incomplete_payment_when_status_is_incomplete' do
49
48
  subscription = Reji::Subscription.new(stripe_status: 'incomplete')
50
49
 
51
- expect(subscription.has_incomplete_payment).to be true
50
+ expect(subscription.incomplete_payment?).to be true
52
51
  end
53
52
 
54
- it 'test_payment_is_incomplete_when_status_is_past_due' do
53
+ it 'has_incomplete_payment_when_status_is_past_due' do
55
54
  subscription = Reji::Subscription.new(stripe_status: 'past_due')
56
55
 
57
- expect(subscription.has_incomplete_payment).to be true
56
+ expect(subscription.incomplete_payment?).to be true
58
57
  end
59
58
 
60
- it 'test_payment_is_not_incomplete_when_status_is_active' do
59
+ it 'has_not_incomplete_payment_when_status_is_active' do
61
60
  subscription = Reji::Subscription.new(stripe_status: 'active')
62
61
 
63
- expect(subscription.has_incomplete_payment).to be false
62
+ expect(subscription.incomplete_payment?).to be false
64
63
  end
65
64
 
66
- it 'test_incomplete_subscriptions_cannot_be_swapped' do
65
+ it 'cannot_swap_when_it_is_incomplete' do
67
66
  subscription = Reji::Subscription.new(stripe_status: 'incomplete')
68
67
 
69
- expect {
68
+ expect do
70
69
  subscription.swap('premium_plan')
71
- }.to raise_error(Reji::SubscriptionUpdateFailureError)
70
+ end.to raise_error(Reji::SubscriptionUpdateFailureError)
72
71
  end
73
72
 
74
- it 'test_incomplete_subscriptions_cannot_update_their_quantity' do
73
+ it 'cannot_update_their_quantity_when_it_is_incomplete' do
75
74
  subscription = Reji::Subscription.new(stripe_status: 'incomplete')
76
75
 
77
- expect {
76
+ expect do
78
77
  subscription.update_quantity(5)
79
- }.to raise_error(Reji::SubscriptionUpdateFailureError)
78
+ end.to raise_error(Reji::SubscriptionUpdateFailureError)
80
79
  end
81
80
 
82
- it 'test_extending_a_trial_requires_a_date_in_the_future' do
81
+ it 'requires_a_date_in_the_future_when_extending_a_trial' do
83
82
  subscription = Reji::Subscription.new
84
83
 
85
- expect {
86
- subscription.extend_trial(Time.now - 1.day)
87
- }.to raise_error(ArgumentError)
84
+ expect do
85
+ subscription.extend_trial(Time.current - 1.day)
86
+ end.to raise_error(ArgumentError)
88
87
  end
89
88
 
90
- it 'can_check_if_it_has_a_single_plan' do
89
+ it 'can_determine_if_it_has_a_single_plan' do
91
90
  subscription = Reji::Subscription.new(stripe_plan: 'foo')
92
91
 
93
- expect(subscription.has_single_plan).to be true
94
- expect(subscription.has_multiple_plans).to be false
92
+ expect(subscription.single_plan?).to be true
93
+ expect(subscription.multiple_plans?).to be false
95
94
  end
96
95
 
97
- it 'can_check_if_it_has_multiple_plans' do
96
+ it 'can_determine_if_it_has_multiple_plans' do
98
97
  subscription = Reji::Subscription.new(stripe_plan: nil)
99
98
 
100
- expect(subscription.has_single_plan).to be false
101
- expect(subscription.has_multiple_plans).to be true
99
+ expect(subscription.single_plan?).to be false
100
+ expect(subscription.multiple_plans?).to be true
102
101
  end
103
102
  end
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reji
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cuong Giang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-09 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: stripe
14
+ name: actionmailer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
@@ -53,7 +67,7 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: '5.0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: activerecord
70
+ name: stripe
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
@@ -67,21 +81,21 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '5.0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: actionmailer
84
+ name: wicked_pdf
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '5.0'
89
+ version: '0'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '5.0'
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: wicked_pdf
98
+ name: wkhtmltopdf-binary
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -95,13 +109,13 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: wkhtmltopdf-binary
112
+ name: appraisal
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
- type: :runtime
118
+ type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
@@ -147,10 +161,11 @@ files:
147
161
  - ".editorconfig"
148
162
  - ".gitattributes"
149
163
  - ".gitignore"
164
+ - ".rubocop.yml"
165
+ - ".rubocop_todo.yml"
150
166
  - ".travis.yml"
151
167
  - Appraisals
152
168
  - Gemfile
153
- - Gemfile.lock
154
169
  - LICENSE
155
170
  - README.md
156
171
  - Rakefile