stripe_saas 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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