stripe_saas 0.0.1 → 0.0.2

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.
@@ -0,0 +1,36 @@
1
+ require 'rails_helper'
2
+
3
+ describe Feature, type: :model do
4
+
5
+ it { is_expected.to have_many(:plan_features) }
6
+ it { is_expected.to have_many(:plans) }
7
+
8
+ before do
9
+ @feature = Feature.find_or_create_by(name: 'signals')
10
+ @feature.update({
11
+ description: "Inbound Signals",
12
+ feature_type: :number,
13
+ display_order: 1
14
+ })
15
+ end
16
+
17
+ describe '#feature_type' do
18
+ it 'correctly assigns the feature type and unit given a symbol' do
19
+ expect(@feature.feature_type).to eq('number')
20
+ expect(@feature.unit).to eq('Number')
21
+ end
22
+
23
+ it 'throws an error given an invalid feature type' do
24
+ feature = Feature.new
25
+
26
+ expect { feature.feature_type = :foo }.to raise_error(ArgumentError, "foo is not a valid feature type")
27
+ end
28
+ end
29
+
30
+ describe '#to_s' do
31
+ it 'returns the feature\'s name' do
32
+ expect(@feature.to_s).to eq('signals')
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,89 @@
1
+ require 'rails_helper'
2
+
3
+ describe PlanFeature, type: :model do
4
+
5
+ it { is_expected.to belong_to(:feature) }
6
+ it { is_expected.to belong_to(:plan) }
7
+
8
+ before(:all) do
9
+ @number_feature = Feature.find_or_create_by(name: 'number_feature')
10
+ @number_feature.update({
11
+ description: "Data Retention",
12
+ feature_type: :number,
13
+ unit: "months",
14
+ display_order: 1
15
+ })
16
+
17
+ @boolean_feature = Feature.find_or_create_by(name: 'boolean_feature')
18
+ @boolean_feature.update({
19
+ description: "My boolean feature",
20
+ feature_type: :boolean,
21
+ display_order: 2
22
+ })
23
+
24
+ @another_number_feature = Feature.find_or_create_by(name: 'another_number_feature')
25
+ @another_number_feature.update({
26
+ description: "Data Retention",
27
+ feature_type: :number,
28
+ unit: "month",
29
+ use_unit: true,
30
+ display_order: 3
31
+ })
32
+
33
+ @plan = Plan.find_or_create_by(stripe_id: 'my_plan')
34
+ @plan.update({
35
+ name: 'My Plan',
36
+ price: 0.0,
37
+ interval: 'month',
38
+ interval_count: 1,
39
+ statement_descriptor: 'My Awesome Plan',
40
+ trial_period_days: 30,
41
+ display_order: 1
42
+ })
43
+
44
+ @plan.add_feature(:number_feature, 100)
45
+ @plan.add_feature(:boolean_feature, true)
46
+ @plan.add_feature(:another_number_feature, 314)
47
+ end
48
+
49
+ describe '#value=' do
50
+ it 'correctly marshalls the given type to a string for storage' do
51
+ boolean_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'boolean_feature'})
52
+ number_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'number_feature'})
53
+
54
+ expect(boolean_plan_feature['value']).to eq('true')
55
+ expect(number_plan_feature['value']).to eq('100')
56
+ end
57
+ end
58
+
59
+ describe '#value' do
60
+ it 'correctly un-marshalls to the correct data type' do
61
+ boolean_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'boolean_feature'})
62
+ number_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'number_feature'})
63
+
64
+ expect(boolean_plan_feature.value).to eq(true)
65
+ expect(number_plan_feature.value).to eq(100)
66
+ end
67
+ end
68
+
69
+ describe '#to_s' do
70
+ it 'returns the qty and description for non-boolean features' do
71
+ number_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'number_feature'})
72
+
73
+ expect(number_plan_feature.to_s).to eq('100 Data Retention')
74
+ end
75
+
76
+ it 'returns the description for boolean features' do
77
+ boolean_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'boolean_feature'})
78
+
79
+ expect(boolean_plan_feature.to_s).to eq('boolean_feature')
80
+ end
81
+
82
+ it 'returns the qty and description for non-boolean features' do
83
+ number_plan_feature = @plan.plan_features.joins(:feature).find_by(features: { name: 'another_number_feature'})
84
+
85
+ expect(number_plan_feature.to_s).to eq('314 Months Data Retention')
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,137 @@
1
+ require 'rails_helper'
2
+
3
+ describe Plan, type: :model do
4
+
5
+ it { is_expected.to have_many(:subscriptions) }
6
+ it { is_expected.to have_many(:plan_features) }
7
+ it { is_expected.to have_many(:features) }
8
+
9
+ describe '#is_upgrade_from?' do
10
+
11
+ it 'returns true if the price is higher' do
12
+ plan = Plan.new(price: 123.23)
13
+ cheaper_plan = Plan.new(price: 61.61)
14
+
15
+ expect(plan.is_upgrade_from?(cheaper_plan)).to be true
16
+ end
17
+
18
+ it 'returns true if the price is the same' do
19
+ plan = Plan.new(price: 123.23)
20
+
21
+ expect(plan.is_upgrade_from?(plan)).to be true
22
+ end
23
+
24
+ it 'returns false if the price is the same or higher' do
25
+ plan = Plan.new(price: 61.61)
26
+ more_expensive_plan = Plan.new(price: 123.23)
27
+
28
+ expect(plan.is_upgrade_from?(more_expensive_plan)).to be false
29
+ end
30
+
31
+ it 'handles a nil value gracefully' do
32
+ plan = Plan.new(price: 123.23)
33
+ cheaper_plan = Plan.new
34
+
35
+ expect(plan.is_upgrade_from?(cheaper_plan)).to be true
36
+ end
37
+ end
38
+
39
+ describe 'metadata' do
40
+ it 'can set plan JSON metadata as a hash' do
41
+ plan = Plan.new(price: 0.0)
42
+ plan.metadata = { 'foo': 'bar' }
43
+
44
+ expect(plan.metadata).to eq({'foo' => 'bar'})
45
+ end
46
+ end
47
+
48
+ describe '#free?' do
49
+ it 'returns whether the plan is a free plan' do
50
+ plan = Plan.new(price: 0.0)
51
+ expect(plan).to be_free
52
+ end
53
+ end
54
+
55
+ describe '#is_downgrade_from?' do
56
+ it 'is the opposite of #is_upgrade_from?' do
57
+ plan = Plan.new(price: 123.23)
58
+ cheaper_plan = Plan.new
59
+ more_expensive_plan = Plan.new(price: 123.23)
60
+
61
+ expect(plan.is_downgrade_from?(cheaper_plan)).to be false
62
+ expect(plan.is_downgrade_from?(more_expensive_plan)).to be false
63
+ end
64
+ end
65
+
66
+ describe 'features' do
67
+ before(:all) do
68
+ @number_feature = Feature.find_or_create_by(name: 'number_feature')
69
+ @number_feature.update({
70
+ description: "My numeric feature",
71
+ feature_type: :number,
72
+ unit: "some_unit",
73
+ display_order: 1
74
+ })
75
+
76
+ @boolean_feature = Feature.find_or_create_by(name: 'boolean_feature')
77
+ @boolean_feature.update({
78
+ description: "My boolean feature",
79
+ feature_type: :boolean,
80
+ display_order: 2
81
+ })
82
+
83
+ @plan = Plan.find_or_create_by(stripe_id: 'my_plan')
84
+ @plan.update({
85
+ name: 'My Plan',
86
+ price: 0.0,
87
+ interval: 'month',
88
+ interval_count: 1,
89
+ statement_descriptor: 'My Awesome Plan',
90
+ trial_period_days: 30,
91
+ display_order: 1
92
+ })
93
+
94
+ @plan.add_feature(:number_feature, 100)
95
+ @plan.add_feature(:boolean_feature, true)
96
+ end
97
+
98
+ describe '#add_feature' do
99
+ it 'adds a PlanFeature to a Plan' do
100
+ expect(@plan.features.map(&:name)).to include('boolean_feature', 'number_feature')
101
+ end
102
+ end
103
+
104
+ describe '#has_feature?' do
105
+ it 'determines if a plan as certain feature' do
106
+ expect(@plan.has_feature?('boolean_feature')).to be true
107
+ end
108
+ end
109
+
110
+ describe '#feature_value' do
111
+ it 'returns the value of a PlanFeature' do
112
+ expect(@plan.feature_value('number_feature')).to eq(100)
113
+ expect(@plan.feature_value('boolean_feature')).to be true
114
+ end
115
+ end
116
+
117
+ describe '#allows?' do
118
+ it 'returns whether a feature is enabled' do
119
+ expect(@plan.allows?('number_feature')).to be true
120
+ expect(@plan.allows?('boolean_feature')).to be true
121
+ end
122
+ end
123
+
124
+ describe '#boolean_plan_features' do
125
+ it 'returns the plan features of boolean type' do
126
+ expect(@plan.boolean_plan_features.map { |pf| pf.feature.name }).to contain_exactly('boolean_feature')
127
+ end
128
+ end
129
+
130
+ describe '#non_boolean_plan_features' do
131
+ it 'returns the plan features that are not of boolean type' do
132
+ expect(@plan.non_boolean_plan_features.map { |pf| pf.feature.name }).to contain_exactly('number_feature')
133
+ end
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,73 @@
1
+ require 'rails_helper'
2
+
3
+ describe Subscription, type: :model do
4
+
5
+ it { is_expected.to belong_to(:plan) }
6
+
7
+ let(:user) { User.new({email: 'bsbodden@integrallis.com'}) }
8
+
9
+ let(:less_expensive_plan) { Plan.new({
10
+ stripe_id: 'free_plan',
11
+ name: 'My Plan',
12
+ price: 0.0,
13
+ interval: 'month',
14
+ interval_count: 1,
15
+ statement_descriptor: 'Cheaper Awesome Plan',
16
+ trial_period_days: 30,
17
+ display_order: 1
18
+ })}
19
+
20
+ let(:plan) { Plan.new({
21
+ stripe_id: 'my_plan',
22
+ name: 'My Plan',
23
+ price: 10.0,
24
+ interval: 'month',
25
+ interval_count: 1,
26
+ statement_descriptor: 'My Awesome Plan',
27
+ trial_period_days: 30,
28
+ display_order: 1
29
+ })}
30
+
31
+ let(:more_expensive_plan) { Plan.new({
32
+ stripe_id: 'another_plan',
33
+ name: 'Another Plan',
34
+ price: 100.0,
35
+ interval: 'month',
36
+ interval_count: 1,
37
+ statement_descriptor: 'More Expensive Awesome Plan',
38
+ trial_period_days: 30,
39
+ display_order: 2
40
+ })}
41
+
42
+ let(:subscription) { Subscription.new(user: user, plan: plan) }
43
+
44
+ describe '#subscription_owner' do
45
+ it 'returns the owner of the subscription' do
46
+ expect(subscription.subscription_owner).to be(user)
47
+ end
48
+ end
49
+
50
+ describe '#subscription_owner_email' do
51
+ it 'returns the owner of the subscription' do
52
+ expect(subscription.subscription_owner_email).to eq(user.email)
53
+ end
54
+ end
55
+
56
+ describe '#subscription_owner_description' do
57
+ it 'returns a descriptive field for the owner of the subscription' do
58
+ expect(subscription.subscription_owner_description).to eq(user.email)
59
+ end
60
+ end
61
+
62
+ describe '#describe_difference' do
63
+ it 'returns whether it would be an Upgrade to a given plan' do
64
+ expect(subscription.describe_difference(more_expensive_plan)).to eq('Upgrade')
65
+ end
66
+
67
+ it 'returns whether it would be a Downgrade to a given plan' do
68
+ expect(subscription.describe_difference(less_expensive_plan)).to eq('Downgrade')
69
+ end
70
+ end
71
+
72
+
73
+ end
@@ -1,8 +1,16 @@
1
- ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__)
2
- require "bundler"
3
- Bundler.setup
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
6
+ # ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__)
7
+ # require "bundler"
8
+ require "shoulda-matchers"
9
+ # Bundler.setup
4
10
 
5
11
  RSpec.configure do |config|
12
+ config.include(Shoulda::Matchers::ActiveModel, type: :model)
13
+ config.include(Shoulda::Matchers::ActiveRecord, type: :model)
6
14
 
7
15
  config.expect_with :rspec do |expectations|
8
16
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe_saas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Sam-Bodden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-16 00:00:00.000000000 Z
11
+ date: 2015-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -106,7 +106,8 @@ dependencies:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
108
  version: 3.4.1
109
- description: Stripe Payments/Subscription Engine for Rails 4.
109
+ description: A Rails Engine that provides everything you need to Stripe enable your
110
+ app.
110
111
  email:
111
112
  - bsbodden@integrallis.com
112
113
  executables: []
@@ -147,14 +148,15 @@ files:
147
148
  - lib/stripe_saas/engine.rb
148
149
  - lib/stripe_saas/version.rb
149
150
  - lib/tasks/stripe_saas_tasks.rake
150
- - spec/concerns/plan_spec.rb
151
151
  - spec/dummy/README.rdoc
152
152
  - spec/dummy/Rakefile
153
153
  - spec/dummy/app/assets/javascripts/application.js
154
154
  - spec/dummy/app/assets/stylesheets/application.css
155
155
  - spec/dummy/app/controllers/application_controller.rb
156
156
  - spec/dummy/app/helpers/application_helper.rb
157
+ - spec/dummy/app/models/feature.rb
157
158
  - spec/dummy/app/models/plan.rb
159
+ - spec/dummy/app/models/plan_feature.rb
158
160
  - spec/dummy/app/models/subscription.rb
159
161
  - spec/dummy/app/models/user.rb
160
162
  - spec/dummy/app/views/layouts/application.html.erb
@@ -188,15 +190,19 @@ files:
188
190
  - spec/dummy/db/migrate/20150101233243_devise_create_users.rb
189
191
  - spec/dummy/db/migrate/20150102001921_create_subscriptions.rb
190
192
  - spec/dummy/db/migrate/20150102001930_create_plans.rb
193
+ - spec/dummy/db/migrate/20151220161809_create_features.rb
194
+ - spec/dummy/db/migrate/20151220161817_create_plan_features.rb
191
195
  - spec/dummy/db/schema.rb
192
196
  - spec/dummy/db/test.sqlite3
193
- - spec/dummy/log/development.log
194
197
  - spec/dummy/log/test.log
195
198
  - spec/dummy/public/404.html
196
199
  - spec/dummy/public/422.html
197
200
  - spec/dummy/public/500.html
198
201
  - spec/dummy/public/favicon.ico
199
- - spec/integration/navigation_test.rb
202
+ - spec/models/feature_spec.rb
203
+ - spec/models/plan_feature_spec.rb
204
+ - spec/models/plan_spec.rb
205
+ - spec/models/subscription_spec.rb
200
206
  - spec/rails_helper.rb
201
207
  - spec/spec_helper.rb
202
208
  homepage: https://github.com/integrallis/stripe_saas
@@ -224,12 +230,13 @@ signing_key:
224
230
  specification_version: 4
225
231
  summary: Stripe Payments/Subscription Engine for Rails 4.
226
232
  test_files:
227
- - spec/concerns/plan_spec.rb
228
233
  - spec/dummy/app/assets/javascripts/application.js
229
234
  - spec/dummy/app/assets/stylesheets/application.css
230
235
  - spec/dummy/app/controllers/application_controller.rb
231
236
  - spec/dummy/app/helpers/application_helper.rb
237
+ - spec/dummy/app/models/feature.rb
232
238
  - spec/dummy/app/models/plan.rb
239
+ - spec/dummy/app/models/plan_feature.rb
233
240
  - spec/dummy/app/models/subscription.rb
234
241
  - spec/dummy/app/models/user.rb
235
242
  - spec/dummy/app/views/layouts/application.html.erb
@@ -263,9 +270,10 @@ test_files:
263
270
  - spec/dummy/db/migrate/20150101233243_devise_create_users.rb
264
271
  - spec/dummy/db/migrate/20150102001921_create_subscriptions.rb
265
272
  - spec/dummy/db/migrate/20150102001930_create_plans.rb
273
+ - spec/dummy/db/migrate/20151220161809_create_features.rb
274
+ - spec/dummy/db/migrate/20151220161817_create_plan_features.rb
266
275
  - spec/dummy/db/schema.rb
267
276
  - spec/dummy/db/test.sqlite3
268
- - spec/dummy/log/development.log
269
277
  - spec/dummy/log/test.log
270
278
  - spec/dummy/public/404.html
271
279
  - spec/dummy/public/422.html
@@ -273,6 +281,9 @@ test_files:
273
281
  - spec/dummy/public/favicon.ico
274
282
  - spec/dummy/Rakefile
275
283
  - spec/dummy/README.rdoc
276
- - spec/integration/navigation_test.rb
284
+ - spec/models/feature_spec.rb
285
+ - spec/models/plan_feature_spec.rb
286
+ - spec/models/plan_spec.rb
287
+ - spec/models/subscription_spec.rb
277
288
  - spec/rails_helper.rb
278
289
  - spec/spec_helper.rb