Private Repos
diff --git a/app/assets/javascripts/components/repos_container.jsx b/app/assets/javascripts/components/repos_container.jsx
index 049ad30b7..933e16e80 100644
--- a/app/assets/javascripts/components/repos_container.jsx
+++ b/app/assets/javascripts/components/repos_container.jsx
@@ -92,7 +92,7 @@ class ReposContainer extends React.Component {
updateSubscribedRepoCount() {
this.getUser().then(user => {
const subscribedRepoCount = user.subscribed_repo_count;
- const tierAllowance = user.tier_allowance;
+ const tierAllowance = user.plan_max;
if (subscribedRepoCount === 0) {
$("[data-role='allowance-container']").remove();
@@ -123,7 +123,7 @@ class ReposContainer extends React.Component {
onSubscriptionError(repo, error) {
if (error.status === 402) {
- document.location.href = `/pricings?repo_id=${repo.id}`;
+ document.location.href = `/plans?repo_id=${repo.id}`;
} else {
alert("Your subscription could not be activated.");
}
diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb
new file mode 100644
index 000000000..bb289e543
--- /dev/null
+++ b/app/controllers/plans_controller.rb
@@ -0,0 +1,16 @@
+class PlansController < ApplicationController
+ def index
+ @plans = ActiveModel::ArraySerializer.new(
+ Plan.all,
+ each_serializer: PlanSerializer,
+ scope: current_user,
+ )
+ @repo = Repo.find(plan_params[:repo_id])
+ end
+
+ private
+
+ def plan_params
+ params.permit(:repo_id)
+ end
+end
diff --git a/app/controllers/pricings_controller.rb b/app/controllers/pricings_controller.rb
deleted file mode 100644
index 17693d954..000000000
--- a/app/controllers/pricings_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class PricingsController < ApplicationController
- def index
- @pricings = ActiveModel::ArraySerializer.new(
- Pricing.all,
- each_serializer: PricingSerializer,
- scope: current_user,
- )
- @repo = Repo.find(pricing_params[:repo_id])
- end
-
- private
-
- def pricing_params
- params.permit(:repo_id)
- end
-end
diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb
index 6edefc9fb..88f18fe6f 100644
--- a/app/controllers/subscriptions_controller.rb
+++ b/app/controllers/subscriptions_controller.rb
@@ -5,7 +5,7 @@ class FailedToActivate < StandardError; end
before_action :update_email
def create
- if Tier.new(current_user).full?
+ if current_user.plan_upgrade?
render json: {}, status: :payment_required
elsif activator.activate && create_subscription
render json: repo, status: :created
diff --git a/app/models/analytics.rb b/app/models/analytics.rb
index 3b7a41e52..67dde6a3c 100644
--- a/app/models/analytics.rb
+++ b/app/models/analytics.rb
@@ -26,7 +26,7 @@ def track_repo_deactivated(repo)
properties: {
name: repo.name,
private: repo.private,
- revenue: -repo.plan_price,
+ revenue: lost_revenue,
}
)
end
@@ -53,6 +53,8 @@ def track_build_completed(repo)
private
+ attr_reader :user
+
def track(options)
backend.track({
active_repos_count: user.repos.active.count,
@@ -60,5 +62,11 @@ def track(options)
}.merge(options))
end
- attr_reader :user
+ def lost_revenue
+ if user.current_plan == user.next_plan
+ 0
+ else
+ user.current_plan_price - user.next_plan_price
+ end
+ end
end
diff --git a/app/models/home.rb b/app/models/home.rb
index bcc88ecf3..c6abe3c66 100644
--- a/app/models/home.rb
+++ b/app/models/home.rb
@@ -5,29 +5,29 @@ def initialize(user)
@user = user
end
- def open_source_pricings
- open_source_repos.map { |pricing| present(pricing) }
+ def open_source_plans
+ open_source_repos.map { |plan| present(plan) }
end
- def private_pricings
- private_repos.map { |pricing| present(pricing) }
+ def private_plans
+ private_repos.map { |plan| present(plan) }
end
private
- def present(pricing)
- PricingPresenter.new(pricing: pricing, user: user)
+ def present(plan)
+ PlanPresenter.new(plan: plan, user: user)
end
- def pricings
- Pricing.all
+ def plans
+ Plan.all
end
def private_repos
- pricings.reject(&:open_source?)
+ plans.reject(&:open_source?)
end
def open_source_repos
- pricings.select(&:open_source?)
+ plans.select(&:open_source?)
end
end
diff --git a/app/models/payment_gateway_customer.rb b/app/models/payment_gateway_customer.rb
index 2f2494e31..4348b7cde 100644
--- a/app/models/payment_gateway_customer.rb
+++ b/app/models/payment_gateway_customer.rb
@@ -32,7 +32,7 @@ def subscription
def retrieve_subscription(subscription_id)
PaymentGatewaySubscription.new(
stripe_subscription: customer.subscriptions.retrieve(subscription_id),
- tier: tier,
+ user: user,
)
end
@@ -54,7 +54,7 @@ def update_email(email)
def create_subscription(options)
PaymentGatewaySubscription.new(
stripe_subscription: customer.subscriptions.create(options),
- tier: tier,
+ user: user,
)
end
@@ -67,15 +67,11 @@ def subscriptions
customer.subscriptions.map do |subscription|
PaymentGatewaySubscription.new(
stripe_subscription: subscription,
- tier: tier,
+ user: user,
)
end
end
- def tier
- Tier.new(user)
- end
-
class NoRecord
def email
""
diff --git a/app/models/payment_gateway_subscription.rb b/app/models/payment_gateway_subscription.rb
index d5effe40f..93d28b253 100644
--- a/app/models/payment_gateway_subscription.rb
+++ b/app/models/payment_gateway_subscription.rb
@@ -1,5 +1,5 @@
class PaymentGatewaySubscription
- attr_reader :stripe_subscription, :tier
+ attr_reader :stripe_subscription, :user
delegate(
:id,
@@ -11,14 +11,14 @@ class PaymentGatewaySubscription
to: :stripe_subscription,
)
- def initialize(stripe_subscription:, tier:)
+ def initialize(stripe_subscription:, user:)
@stripe_subscription = stripe_subscription
- @tier = tier
+ @user = user
end
def subscribe(repo_id)
append_repo_id_to_metadata(repo_id)
- self.plan = tier.next.id
+ self.plan = user.next_plan.id
save
end
@@ -51,11 +51,7 @@ def current_repo_ids
end
def downgraded_plan
- previous_tier.id
- end
-
- def previous_tier
- tier.previous
+ user.previous_plan.id
end
def stripe_plan
diff --git a/app/models/plan.rb b/app/models/plan.rb
index 96efa9661..5033a9237 100644
--- a/app/models/plan.rb
+++ b/app/models/plan.rb
@@ -1,37 +1,44 @@
class Plan
- PRICES = {
- bulk: 0,
- public: 0,
- private: 12
- }
-
- TYPES = {
- bulk: "bulk",
- public: "public",
- private: "private"
- }
-
- def initialize(repo)
- @repo = repo
+ include ActiveModel::Serialization
+
+ PLANS = [
+ { id: "basic", price: 0, range: 0..0, title: "Hound" },
+ { id: "tier1", price: 49, range: 1..4, title: "Chihuahua" },
+ { id: "tier2", price: 99, range: 5..10, title: "Labrador" },
+ { id: "tier3", price: 249, range: 11..30, title: "Great Dane" },
+ ].freeze
+
+ attr_reader :id, :price, :title
+
+ def initialize(id:, range:, price:, title:)
+ @id = id
+ @range = range
+ @price = price
+ @title = title
end
- def type
- if @repo.bulk?
- TYPES[:bulk]
- elsif @repo.private?
- TYPES[:private]
- else
- TYPES[:public]
- end
+ def self.all
+ PLANS.map { |plan| new(plan) }
end
- def price
- if @repo.bulk?
- PRICES[:bulk]
- elsif @repo.private?
- PRICES[:private]
- else
- PRICES[:public]
- end
+ def self.find_by(count:)
+ found = PLANS.detect { |plan| plan.fetch(:range).include?(count) }
+ new(found)
end
+
+ def ==(other)
+ id == other.id
+ end
+
+ def allowance
+ range.max
+ end
+
+ def open_source?
+ price.zero?
+ end
+
+ private
+
+ attr_reader :range
end
diff --git a/app/models/plan_selector.rb b/app/models/plan_selector.rb
new file mode 100644
index 000000000..9818dba85
--- /dev/null
+++ b/app/models/plan_selector.rb
@@ -0,0 +1,39 @@
+class PlanSelector
+ BULK_ID = "bulk".freeze
+
+ def initialize(user)
+ @user = user
+ end
+
+ def current_plan
+ find_plan(repo_count)
+ end
+
+ def next_plan
+ find_plan(repo_count.succ)
+ end
+
+ def previous_plan
+ find_plan(repo_count.pred)
+ end
+
+ def upgrade?
+ current_plan != next_plan
+ end
+
+ private
+
+ attr_reader :user
+
+ def repo_count
+ @_repo_count ||= repos.size
+ end
+
+ def find_plan(count)
+ Plan.find_by(count: count)
+ end
+
+ def repos
+ user.subscribed_repos
+ end
+end
diff --git a/app/models/pricing.rb b/app/models/pricing.rb
deleted file mode 100644
index c92c90042..000000000
--- a/app/models/pricing.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-class Pricing
- include ActiveModel::SerializerSupport
-
- PRICINGS = [
- { id: "basic", price: 0, range: 0..0, title: "Hound" },
- { id: "tier1", price: 49, range: 1..4, title: "Chihuahua" },
- { id: "tier2", price: 99, range: 5..10, title: "Labrador" },
- { id: "tier3", price: 249, range: 11..30, title: "Great Dane" },
- ].freeze
-
- attr_reader :id, :price, :title
-
- def self.all
- PRICINGS.map { |pricing| new(pricing) }
- end
-
- def self.find_by(count:)
- found = PRICINGS.detect { |pricing| pricing.fetch(:range).include?(count) }
- new(found)
- end
-
- def initialize(id:, range:, price:, title:)
- @id = id
- @range = range
- @price = price
- @title = title
- end
-
- def ==(other)
- id == other.id
- end
-
- def allowance
- range.max
- end
-
- def open_source?
- price.zero?
- end
-
- private
-
- attr_reader :range
-end
diff --git a/app/models/repo.rb b/app/models/repo.rb
index 4e1c51f68..dc1f46fbc 100644
--- a/app/models/repo.rb
+++ b/app/models/repo.rb
@@ -5,9 +5,6 @@ class Repo < ApplicationRecord
has_one :subscription
has_many :users, through: :memberships
- delegate :type, :price, to: :plan, prefix: true
- delegate :price, to: :subscription, prefix: true
-
validates :github_id, uniqueness: true, presence: true
def self.active
diff --git a/app/models/tier.rb b/app/models/tier.rb
deleted file mode 100644
index 5a98ca916..000000000
--- a/app/models/tier.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-class Tier
- BULK_ID = "bulk".freeze
-
- def initialize(user)
- @user = user
- end
-
- def current
- select(count)
- end
-
- def full?
- pricing_changes?
- end
-
- def next
- select(succ)
- end
-
- def previous
- select(previous_repo_count)
- end
-
- private
-
- attr_reader :user
-
- def count
- @count ||= repos.count
- end
-
- def previous_repo_count
- count.pred
- end
-
- def pricing_changes?
- self.next != current
- end
-
- def select(count)
- Pricing.find_by(count: count)
- end
-
- def succ
- count.succ
- end
-
- def repos
- user.subscribed_repos
- end
-end
diff --git a/app/models/user.rb b/app/models/user.rb
index 89bfa3fbb..14c980f3f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -11,16 +11,22 @@ class User < ApplicationRecord
before_create :generate_remember_token
- def current_tier
- tier.current
+ delegate :current_plan, :next_plan, :previous_plan, to: :plan_selector
+
+ def plan_upgrade?
+ plan_selector.upgrade?
+ end
+
+ def current_plan_price
+ current_plan.price
end
- def next_tier
- tier.next
+ def next_plan_price
+ next_plan.price
end
- def tier_price
- next_tier.price
+ def plan_max
+ current_plan.allowance
end
def to_s
@@ -31,10 +37,6 @@ def active_repos
repos.active
end
- def tier_max
- current_tier.allowance
- end
-
def billable_email
payment_gateway_customer.email
end
@@ -89,8 +91,8 @@ def payment_gateway_customer
@payment_gateway_customer ||= PaymentGatewayCustomer.new(self)
end
- def tier
- @_tier ||= Tier.new(self)
+ def plan_selector
+ @_plan_selector ||= PlanSelector.new(self)
end
def generate_remember_token
diff --git a/app/presenters/account_page.rb b/app/presenters/account_page.rb
index 0bc3d1e45..8f64323e7 100644
--- a/app/presenters/account_page.rb
+++ b/app/presenters/account_page.rb
@@ -4,7 +4,7 @@ def initialize(user)
end
def allowance
- current_tier.allowance
+ current_plan.allowance
end
def billable_email
@@ -16,12 +16,12 @@ def monthly_line_item
end
def plan
- current_tier.title
+ current_plan.title
end
- def pricings
- Pricing.all.map do |pricing|
- PricingPresenter.new(pricing: pricing, user: user)
+ def plans
+ Plan.all.map do |plan|
+ PlanPresenter.new(plan: plan, user: user)
end
end
@@ -45,8 +45,8 @@ def total_monthly_cost
attr_reader :user
- def current_tier
- tier.current
+ def current_plan
+ user.current_plan
end
def repo_count
@@ -56,8 +56,4 @@ def repo_count
def subscribed_repos
user.subscribed_repos
end
-
- def tier
- Tier.new(user)
- end
end
diff --git a/app/presenters/plan_presenter.rb b/app/presenters/plan_presenter.rb
new file mode 100644
index 000000000..d64c7d847
--- /dev/null
+++ b/app/presenters/plan_presenter.rb
@@ -0,0 +1,28 @@
+class PlanPresenter
+ delegate :allowance, :open_source?, :price, :title, to: :plan
+
+ def initialize(plan:, user:)
+ @plan = plan
+ @user = user
+ end
+
+ def current?
+ user.current_plan == plan
+ end
+
+ def next?
+ user.next_plan == plan
+ end
+
+ def to_partial_path
+ if open_source?
+ "plans/open_source"
+ else
+ "plans/private"
+ end
+ end
+
+ private
+
+ attr_reader :plan, :user
+end
diff --git a/app/presenters/pricing_presenter.rb b/app/presenters/pricing_presenter.rb
deleted file mode 100644
index a21e78097..000000000
--- a/app/presenters/pricing_presenter.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class PricingPresenter
- delegate :allowance, :open_source?, :price, :title, to: :pricing
-
- def initialize(pricing:, user:)
- @pricing = pricing
- @user = user
- end
-
- def current?
- tier.current == pricing
- end
-
- def next?
- tier.next == pricing
- end
-
- def to_partial_path
- if open_source?
- "pricings/open_source"
- else
- "pricings/private"
- end
- end
-
- private
-
- attr_reader :pricing, :user
-
- def tier
- @_tier ||= Tier.new(user)
- end
-end
diff --git a/app/serializers/plan_serializer.rb b/app/serializers/plan_serializer.rb
new file mode 100644
index 000000000..65f662dce
--- /dev/null
+++ b/app/serializers/plan_serializer.rb
@@ -0,0 +1,11 @@
+class PlanSerializer < ActiveModel::Serializer
+ attributes :current, :name, :price, :allowance
+
+ def current
+ scope.current_plan == object
+ end
+
+ def name
+ object.title
+ end
+end
diff --git a/app/serializers/pricing_serializer.rb b/app/serializers/pricing_serializer.rb
deleted file mode 100644
index 219c7d9b0..000000000
--- a/app/serializers/pricing_serializer.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class PricingSerializer < ActiveModel::Serializer
- attributes :current, :name, :price, :allowance
-
- def current
- current_tier == object
- end
-
- def name
- object.title
- end
-
- private
-
- def current_tier
- scope.current_tier
- end
-end
diff --git a/app/serializers/repo_serializer.rb b/app/serializers/repo_serializer.rb
index aacd61acc..0a63aac0e 100644
--- a/app/serializers/repo_serializer.rb
+++ b/app/serializers/repo_serializer.rb
@@ -16,7 +16,7 @@ def price_in_cents
if object.public? || object.bulk?
0
else
- scope.tier_price * 100
+ scope.next_plan_price * 100
end
end
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index f076f827d..692e6df43 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -3,7 +3,7 @@ class UserSerializer < ActiveModel::Serializer
:id,
:refreshing_repos,
:subscribed_repo_count,
- :tier_allowance,
+ :plan_max,
:username,
)
@@ -14,8 +14,4 @@ def card_exists
def subscribed_repo_count
object.subscribed_repos.count
end
-
- def tier_allowance
- object.current_tier.allowance
- end
end
diff --git a/app/services/repo_subscriber.rb b/app/services/repo_subscriber.rb
index 67015f975..de0078d2c 100644
--- a/app/services/repo_subscriber.rb
+++ b/app/services/repo_subscriber.rb
@@ -29,7 +29,7 @@ def unsubscribe
def create_subscription
payment_gateway_subscription = customer.find_or_create_subscription(
- plan: user.current_tier.id,
+ plan: user.current_plan.id,
repo_id: repo.id,
)
@@ -38,7 +38,7 @@ def create_subscription
repo.create_subscription!(
user_id: user.id,
stripe_subscription_id: payment_gateway_subscription.id,
- price: repo.plan_price,
+ price: user.next_plan_price,
)
rescue => error
report_exception(error)
diff --git a/app/views/accounts/show.haml b/app/views/accounts/show.haml
index 5db21ca9f..d5be9ae92 100644
--- a/app/views/accounts/show.haml
+++ b/app/views/accounts/show.haml
@@ -7,13 +7,13 @@
%h3
Plans
- - @account_page.pricings.each do |pricing|
+ - @account_page.plans.each do |plan|
= render("shared/plan_vertical",
- allowance: pricing.allowance,
- current: pricing.current?,
- name: pricing.title,
- new: pricing.next?,
- price: pricing.price,
+ allowance: plan.allowance,
+ current: plan.current?,
+ name: plan.title,
+ new: plan.next?,
+ price: plan.price,
)
.account-content
diff --git a/app/views/application/_header.haml b/app/views/application/_header.haml
index b0fca8a4a..9714f6435 100644
--- a/app/views/application/_header.haml
+++ b/app/views/application/_header.haml
@@ -23,7 +23,7 @@
#{current_user.subscribed_repos.count}
\/
%span{ "data-role" => "tier-allowance" }
- #{current_user.tier_max}
+ #{current_user.plan_max}
%li
= link_to account_path, class: "account" do
- if current_user.email.present?
diff --git a/app/views/home/index.haml b/app/views/home/index.haml
index 535b8579d..9f50f9128 100644
--- a/app/views/home/index.haml
+++ b/app/views/home/index.haml
@@ -136,13 +136,13 @@
%i.fa.fa-book
Private Repos
- = render(partial: @home.private_pricings, as: :plan)
+ = render(partial: @home.private_plans, as: :plan)
%h4.plan-category.open-source
%i.fa.fa-code-fork
Open Source
- = render(partial: @home.open_source_pricings, as: :plan)
+ = render(partial: @home.open_source_plans, as: :plan)
%section.home-security
.section-content
diff --git a/app/views/pricings/_open_source.html.erb b/app/views/plans/_open_source.html.erb
similarity index 100%
rename from app/views/pricings/_open_source.html.erb
rename to app/views/plans/_open_source.html.erb
diff --git a/app/views/pricings/_private.html.erb b/app/views/plans/_private.html.erb
similarity index 100%
rename from app/views/pricings/_private.html.erb
rename to app/views/plans/_private.html.erb
diff --git a/app/views/pricings/index.html.erb b/app/views/plans/index.html.erb
similarity index 80%
rename from app/views/pricings/index.html.erb
rename to app/views/plans/index.html.erb
index 962dfb8c5..e1522cd3e 100644
--- a/app/views/pricings/index.html.erb
+++ b/app/views/plans/index.html.erb
@@ -3,8 +3,8 @@
<%= react_component(
"app.NotifyTierChange",
authenticity_token: form_authenticity_token,
- next_tier: current_user.next_tier,
- plans: @pricings,
+ next_tier: current_user.next_plan,
+ plans: @plans,
repo_id: @repo.id,
repo_name: @repo.name,
user_has_card: current_user.stripe_customer_id.present?,
diff --git a/config/locales/en.yml b/config/locales/en.yml
index d9657be73..4befe7c88 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -22,9 +22,6 @@ en:
billable_email:
invalid: "Email is invalid"
- tier_change:
- title: "Pricing: A Change of Plans"
-
onboarding:
title: "Let's keep that code in style:"
step_one_title: "Activate Hound on a repo."
@@ -44,9 +41,9 @@ en:
comment inline on the violation in your GitHub pull
request."
- pricings:
+ plans:
open_source:
- allowance: "Unlimited"
+ allowance: "Unlimited Public Repos"
price_html: "$%{price} month"
private:
diff --git a/config/routes.rb b/config/routes.rb
index 199bf6600..d2d540a1d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -16,12 +16,11 @@
get "/sign_out", to: "sessions#destroy"
get "/configuration", to: "pages#configuration"
get "/faq", to: "pages#show", id: "faq"
- get "/tier_change", to: "pages#show", id: "tier_change"
resource :account, only: [:show, :update]
resources :builds, only: [:create, :index]
resources :owners, only: [:update]
- resources :pricings, only: [:index]
+ resources :plans, only: [:index]
resources :repos, only: [:index] do
with_options(defaults: { format: :json }) do
diff --git a/spec/controllers/deactivations_controller_spec.rb b/spec/controllers/deactivations_controller_spec.rb
index b455b83e6..3ef9c004a 100644
--- a/spec/controllers/deactivations_controller_spec.rb
+++ b/spec/controllers/deactivations_controller_spec.rb
@@ -27,7 +27,7 @@
properties: {
name: repo.name,
private: false,
- revenue: 0,
+ revenue: -membership.user.next_plan_price,
}
)
end
diff --git a/spec/controllers/subscriptions_controller_spec.rb b/spec/controllers/subscriptions_controller_spec.rb
index 3f3eee885..12b3de62d 100644
--- a/spec/controllers/subscriptions_controller_spec.rb
+++ b/spec/controllers/subscriptions_controller_spec.rb
@@ -68,13 +68,11 @@
end
end
- context "when the current tier is full" do
+ context "when the current plan is full" do
it "notifies that payment is required" do
membership = create(:membership)
repo = membership.repo
- tier = instance_double("Tier", full?: true)
user = membership.user
- allow(Tier).to receive(:new).once.with(user).and_return(tier)
stub_sign_in(user)
post :create, params: { repo_id: repo.id }
@@ -173,7 +171,7 @@
properties: {
name: repo.name,
private: true,
- revenue: -repo.plan_price,
+ revenue: -subscribed_user.next_plan_price,
}
)
end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 0cf358a2e..a54f70e18 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -13,7 +13,7 @@
id: user.id,
refreshing_repos: user.refreshing_repos,
subscribed_repo_count: 0,
- tier_allowance: 0,
+ plan_max: 0,
username: user.username,
}.to_json
)
diff --git a/spec/factories.rb b/spec/factories.rb
index 7de4996a3..68b4b4299 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -24,13 +24,13 @@
linter_name "ruby"
end
- factory :pricing do
+ factory :plan do
id "tier1"
price 49
range 1..4
title "Chihuahua"
- trait :tier2 do
+ trait :plan2 do
id "tier2"
price 99
range 5..10
@@ -76,7 +76,7 @@
sequence(:stripe_subscription_id) { |n| "stripesubscription#{n}" }
- price { repo.plan_price }
+ price Plan::PLANS[1][:price]
repo
user
end
diff --git a/spec/features/account_spec.rb b/spec/features/account_spec.rb
index 09a4803df..c02640548 100644
--- a/spec/features/account_spec.rb
+++ b/spec/features/account_spec.rb
@@ -20,7 +20,7 @@
expect(page).to have_text("Update Credit Card")
end
- scenario "returns a list of all pricings", :js do
+ scenario "returns a list of all plans", :js do
user = create(:user)
sign_in_as(user, "letmein")
diff --git a/spec/features/listing_pricings_spec.rb b/spec/features/plans_spec.rb
similarity index 94%
rename from spec/features/listing_pricings_spec.rb
rename to spec/features/plans_spec.rb
index 54d11f768..318f7731f 100644
--- a/spec/features/listing_pricings_spec.rb
+++ b/spec/features/plans_spec.rb
@@ -1,12 +1,12 @@
require "rails_helper"
-feature "Listing Pricings" do
+feature "Plans" do
scenario "shows all available plans", :js do
user = create(:user)
repo = create(:repo)
sign_in_as(user, "letmein")
- visit pricings_path(repo_id: repo.id)
+ visit plans_path(repo_id: repo.id)
plans = page.all(".plan")
expect(plans.count).to eq 4
@@ -56,7 +56,7 @@
stub_customer_find_request
stub_subscription_create_request(plan: "tier1", repo_ids: repo.id)
stub_subscription_update_request(plan: "tier2", repo_ids: repo.id)
- visit pricings_path(repo_id: repo.id)
+ visit plans_path(repo_id: repo.id)
click_on "Upgrade"
wait_for_ajax
diff --git a/spec/features/user_activates_a_repo_spec.rb b/spec/features/user_activates_a_repo_spec.rb
index ac3373adc..d851a8499 100644
--- a/spec/features/user_activates_a_repo_spec.rb
+++ b/spec/features/user_activates_a_repo_spec.rb
@@ -13,12 +13,12 @@
expect(page).to have_text "Active"
end
- scenario "user upgrades from free tier" do
+ scenario "user upgrades from free plan" do
user = create(:user, :with_github_scopes, :stripe)
repo = create(:repo, :private)
create(:membership, :admin, repo: repo, user: user)
- current_plan = user.current_tier.id
- upgraded_plan = user.next_tier.id
+ current_plan = user.current_plan.id
+ upgraded_plan = user.next_plan.id
stub_customer_find_request
stub_subscription_create_request(plan: current_plan, repo_ids: repo.id)
stub_subscription_update_request(plan: upgraded_plan, repo_ids: repo.id)
@@ -26,16 +26,16 @@
sign_in_as(user, "letmein")
click_on "Activate"
- expect(page).to have_text "Pricing: Change of Plans"
+ expect(page).to have_text "Change of Plans"
end
- scenario "user upgrades within a tier" do
+ scenario "user upgrades within a plan" do
user = create(:user, :with_github_scopes, :stripe)
repo = create(:repo, :private)
create(:membership, :admin, repo: repo, user: user)
create(:subscription, :active, user: user)
- current_plan = user.current_tier.id
- upgraded_plan = user.next_tier.id
+ current_plan = user.current_plan.id
+ upgraded_plan = user.next_plan.id
stub_customer_find_request
stub_subscription_create_request(plan: current_plan, repo_ids: repo.id)
stub_subscription_update_request(plan: upgraded_plan, repo_ids: repo.id)
diff --git a/spec/features/user_deactivates_a_repo_spec.rb b/spec/features/user_deactivates_a_repo_spec.rb
index 66e76d30e..45a2cdf9a 100644
--- a/spec/features/user_deactivates_a_repo_spec.rb
+++ b/spec/features/user_deactivates_a_repo_spec.rb
@@ -33,17 +33,14 @@
end
end
- scenario "user downgrades within a tier" do
+ scenario "user deactivates within a plan" do
user = create(:user, :with_github_scopes, :stripe)
first_subscription = create(:subscription, :active, user: user)
second_subscription = create(:subscription, :active, user: user)
- tier = Tier.new(user)
- previous_tier = tier.previous
- downgraded_plan = previous_tier.id
stub_customer_find_request
stub_subscription_find_request(first_subscription)
stub_subscription_find_request(second_subscription)
- stub_subscription_update_request(plan: downgraded_plan, repo_ids: "")
+ stub_subscription_update_request(plan: "tier1", repo_ids: "")
sign_in_as(user, "letmein")
find(".repo--active:nth-of-type(1) .repo-toggle").click
@@ -51,19 +48,14 @@
expect(page).to have_text "Private Repos 1 / 4"
end
- scenario "user downgrades from another tier" do
+ scenario "user downgrades to lower plan" do
user = create(:user, :with_github_scopes, :stripe)
- 4.times do
+ 5.times do
subscription = create(:subscription, :active, user: user)
stub_subscription_find_request(subscription)
end
- subscription = create(:subscription, :active, user: user)
- stub_subscription_find_request(subscription)
- tier = Tier.new(user)
- previous_tier = tier.previous
- downgraded_plan = previous_tier.id
stub_customer_find_request
- stub_subscription_update_request(plan: downgraded_plan, repo_ids: "")
+ stub_subscription_update_request(plan: "tier1", repo_ids: "")
sign_in_as(user, "letmein")
find(".repo--active:nth-of-type(1) .repo-toggle").click
@@ -75,11 +67,8 @@
user = create(:user, :with_github_scopes, :stripe)
subscription = create(:subscription, :active, user: user)
stub_subscription_find_request(subscription)
- tier = Tier.new(user)
- previous_tier = tier.previous
- downgraded_plan = previous_tier.id
stub_customer_find_request
- stub_subscription_update_request(plan: downgraded_plan, repo_ids: "")
+ stub_subscription_update_request(plan: "basic", repo_ids: "")
sign_in_as(user, "letmein")
find(".repo--active:nth-of-type(1) .repo-toggle").click
diff --git a/spec/models/home_spec.rb b/spec/models/home_spec.rb
index 507ad7b48..c7fd80938 100644
--- a/spec/models/home_spec.rb
+++ b/spec/models/home_spec.rb
@@ -1,45 +1,45 @@
require "spec_helper"
require "active_model/serializer_support"
-require "app/models/pricing"
-require "app/presenters/pricing_presenter"
+require "app/models/plan"
+require "app/presenters/plan_presenter"
require "app/models/home"
RSpec.describe Home do
- describe "#open_source_pricings" do
- it "returns all the presented pricings that are open source" do
- open_source_pricing = instance_double("Pricing", open_source?: true)
- presenter = instance_double("PricingPresenter")
- private_pricing = instance_double("Pricing", open_source?: false)
- pricings = [open_source_pricing, private_pricing]
+ describe "#open_source_plans" do
+ it "returns all the presented plans that are open source" do
+ open_source_plan = instance_double("Plan", open_source?: true)
+ presenter = instance_double("PlanPresenter")
+ private_plan = instance_double("Plan", open_source?: false)
+ plans = [open_source_plan, private_plan]
user = instance_double("User")
home = Home.new(user)
- allow(Pricing).to receive(:all).and_return(pricings)
- allow(PricingPresenter).to receive(:new).and_return(presenter)
+ allow(Plan).to receive(:all).and_return(plans)
+ allow(PlanPresenter).to receive(:new).and_return(presenter)
- expect(home.open_source_pricings).to eq [presenter]
- expect(Pricing).to have_received(:all).once.with(no_args)
- expect(PricingPresenter).to have_received(:new).once.with(
- pricing: open_source_pricing,
+ expect(home.open_source_plans).to eq [presenter]
+ expect(Plan).to have_received(:all).once.with(no_args)
+ expect(PlanPresenter).to have_received(:new).once.with(
+ plan: open_source_plan,
user: user,
)
end
end
- describe "#private_pricings" do
- it "returns all the presented pricings that are not open source" do
- open_source_pricing = instance_double("Pricing", open_source?: true)
- presenter = instance_double("PricingPresenter")
- private_pricing = instance_double("Pricing", open_source?: false)
- pricings = [open_source_pricing, private_pricing]
+ describe "#private_plans" do
+ it "returns all the presented plans that are not open source" do
+ open_source_plan = instance_double("Plan", open_source?: true)
+ presenter = instance_double("PlanPresenter")
+ private_plan = instance_double("Plan", open_source?: false)
+ plans = [open_source_plan, private_plan]
user = instance_double("User")
home = Home.new(user)
- allow(Pricing).to receive(:all).and_return(pricings)
- allow(PricingPresenter).to receive(:new).and_return(presenter)
+ allow(Plan).to receive(:all).and_return(plans)
+ allow(PlanPresenter).to receive(:new).and_return(presenter)
- expect(home.private_pricings).to eq [presenter]
- expect(Pricing).to have_received(:all).once.with(no_args)
- expect(PricingPresenter).to have_received(:new).once.with(
- pricing: private_pricing,
+ expect(home.private_plans).to eq [presenter]
+ expect(Plan).to have_received(:all).once.with(no_args)
+ expect(PlanPresenter).to have_received(:new).once.with(
+ plan: private_plan,
user: user,
)
end
diff --git a/spec/models/payment_gateway_subscription_spec.rb b/spec/models/payment_gateway_subscription_spec.rb
index afbbd01b4..f59998b49 100644
--- a/spec/models/payment_gateway_subscription_spec.rb
+++ b/spec/models/payment_gateway_subscription_spec.rb
@@ -3,45 +3,41 @@
describe PaymentGatewaySubscription do
describe "#subscribe" do
it "sets the plan to the upgraded tier" do
- plan = "tier1"
- succ = instance_double("Pricing")
+ plan_id = "tier1"
repo_id = 1
stripe_subscription = MockStripeSubscription.new(repo_ids: ["1"])
- tier = instance_double("Tier")
+ next_plan = instance_double("Plan", id: plan_id)
+ user = instance_double("User", next_plan: next_plan)
subscription = PaymentGatewaySubscription.new(
stripe_subscription: stripe_subscription,
- tier: tier,
+ user: user,
)
- allow(succ).to receive(:id).once.with(no_args).and_return(plan)
- allow(tier).to receive(:next).once.with(no_args).and_return(succ)
subscription.subscribe(repo_id)
expect(stripe_subscription).to be_saved
expect(stripe_subscription.metadata).to eq("repo_ids" => repo_id.to_s)
- expect(stripe_subscription.plan).to eq plan
+ expect(stripe_subscription.plan).to eq plan_id
end
end
describe "#unsubscribe" do
it "sets the plan to the downgraded tier" do
- plan = "basic"
- previous = instance_double("Pricing")
+ plan_id = "basic"
repo_id = 1
stripe_subscription = MockStripeSubscription.new(repo_ids: [repo_id])
- tier = instance_double("Tier")
+ plan = instance_double("Plan", id: plan_id)
+ user = instance_double("User", previous_plan: plan)
subscription = PaymentGatewaySubscription.new(
stripe_subscription: stripe_subscription,
- tier: tier,
+ user: user,
)
- allow(previous).to receive(:id).once.with(no_args).and_return(plan)
- allow(tier).to receive(:previous).once.with(no_args).and_return(previous)
subscription.unsubscribe(repo_id)
expect(stripe_subscription).to be_saved
expect(stripe_subscription.metadata).to eq("repo_ids" => nil)
- expect(stripe_subscription.plan).to eq plan
+ expect(stripe_subscription.plan).to eq plan_id
end
end
diff --git a/spec/models/plan_selector_spec.rb b/spec/models/plan_selector_spec.rb
new file mode 100644
index 000000000..2980d7dc2
--- /dev/null
+++ b/spec/models/plan_selector_spec.rb
@@ -0,0 +1,70 @@
+require "active_model/serialization"
+
+require "app/models/plan"
+require "app/models/plan_selector"
+
+RSpec.describe PlanSelector do
+ describe "#current_plan" do
+ it "returns user's current plan" do
+ user = instance_double("User", subscribed_repos: [double])
+ plan_selector = PlanSelector.new(user)
+
+ expect(plan_selector.current_plan).to eq Plan.new(Plan::PLANS[1])
+ end
+ end
+
+ describe "#upgrade?" do
+ context "when the next plan is different to the current plan" do
+ it "returns true" do
+ user = instance_double(
+ "User",
+ subscribed_repos: Array.new(4) { double },
+ )
+ plan_selector = PlanSelector.new(user)
+
+ expect(plan_selector).to be_upgrade
+ end
+ end
+
+ context "when the user has no repos" do
+ it "returns true" do
+ user = instance_double("User", subscribed_repos: [])
+ plan_selector = PlanSelector.new(user)
+
+ expect(plan_selector).to be_upgrade
+ end
+ end
+
+ context "when the next plan is not the same as the current plan" do
+ it "returns false" do
+ user = instance_double(
+ "User",
+ subscribed_repos: Array.new(3) { double },
+ )
+ plan_selector = PlanSelector.new(user)
+
+ expect(plan_selector).not_to be_upgrade
+ end
+ end
+ end
+
+ describe "#next_plan" do
+ context "when the user has no subscribed repos" do
+ it "returns the first paid plan" do
+ user = instance_double("User", subscribed_repos: [])
+ plan_selector = PlanSelector.new(user)
+
+ expect(plan_selector.next_plan).to eq Plan.new(Plan::PLANS[1])
+ end
+ end
+ end
+
+ describe "#previous_plan" do
+ it "returns the second paid plan" do
+ user = instance_double("User", subscribed_repos: Array.new(10) { double })
+ plan_selector = PlanSelector.new(user)
+
+ expect(plan_selector.previous_plan).to eq Plan.new(Plan::PLANS[2])
+ end
+ end
+end
diff --git a/spec/models/plan_spec.rb b/spec/models/plan_spec.rb
index 88c142d1e..90b6bc7a3 100644
--- a/spec/models/plan_spec.rb
+++ b/spec/models/plan_spec.rb
@@ -1,62 +1,164 @@
-require "spec_helper"
+require "active_model/serialization"
+
require "app/models/plan"
-describe Plan do
- describe "#type" do
- context "with public repo" do
- it "returns public" do
- public_repo = double("Repo", private?: false, bulk?: false)
- plan = Plan.new(public_repo)
+RSpec.describe Plan do
+ describe ".all" do
+ it "returns all of the plans" do
+ plans = Plan.all
+
+ expect(plans.count).to eq 4
- expect(plan.type).to eq "public"
+ [
+ [0, "basic", 0, "Hound"],
+ [4, "tier1", 49, "Chihuahua"],
+ [10, "tier2", 99, "Labrador"],
+ [30, "tier3", 249, "Great Dane"],
+ ].each_with_index do |(allowance, id, price, title), index|
+ expect(plans[index].allowance).to eq allowance
+ expect(plans[index].id).to eq id
+ expect(plans[index].price).to eq price
+ expect(plans[index].title).to eq title
end
end
+ end
+
+ describe ".find_by" do
+ it "returns the plan where the count is in range" do
+ plan = Plan.find_by(count: 7)
+
+ expect(plan.allowance).to eq 10
+ expect(plan.id).to eq "tier2"
+ expect(plan.price).to eq 99
+ expect(plan.title).to eq "Labrador"
+ end
+ end
- context "with private repo" do
- it "returns private" do
- private_repo = double("Repo", private?: true, bulk?: false)
- plan = Plan.new(private_repo)
+ describe "#==" do
+ context "when the plans have the same identifiers" do
+ it "returns true" do
+ allowance = 4
+ id = "tier1"
+ price = 49
+ range = 1..allowance
+ title = "Chihuahua"
+ plan1 = Plan.new(
+ id: id,
+ price: price,
+ range: range,
+ title: title,
+ )
+ plan2 = Plan.new(
+ id: id,
+ price: price,
+ range: range,
+ title: title,
+ )
- expect(plan.type).to eq "private"
+ expect(plan1).to eq(plan2)
end
end
- context "with bulk repo" do
- it "returns bulk" do
- bulk_repo = double("Repo", bulk?: true)
- plan = Plan.new(bulk_repo)
+ context "when the plans have different identifiers" do
+ it "returns false" do
+ allowance = 4
+ id = "tier1"
+ price = 49
+ range = 1..allowance
+ title = "Chihuahua"
+ plan1 = Plan.new(
+ id: id,
+ price: price,
+ range: range,
+ title: title,
+ )
+ plan2 = Plan.new(
+ id: "tier2",
+ price: price,
+ range: range,
+ title: title,
+ )
- expect(plan.type).to eq "bulk"
+ expect(plan1).to_not eq(plan2)
end
end
end
- describe "#price" do
- context "with public repo" do
- it "returns public price" do
- public_repo = double("Repo", private?: false, bulk?: false)
- plan = Plan.new(public_repo)
+ describe "#allowance" do
+ it "returns the upper bound of the range" do
+ allowance = 4
+ id = "tier1"
+ price = 49
+ range = 1..allowance
+ title = "Chihuahua"
+ plan = Plan.new(id: id, price: price, range: range, title: title)
- expect(plan.price).to eq 0
- end
+ expect(plan.allowance).to eq allowance
end
+ end
- context "with private repo" do
- it "returns private price" do
- private_repo = double("Repo", private?: true, bulk?: false)
- plan = Plan.new(private_repo)
+ describe "#id" do
+ it "returns the initialized identifier" do
+ allowance = 4
+ id = "tier1"
+ price = 49
+ range = 1..allowance
+ title = "Chihuahua"
+ plan = Plan.new(id: id, price: price, range: range, title: title)
- expect(plan.price).to eq 12
- end
+ expect(plan.id).to eq id
+ end
+ end
+
+ describe "#open_source?" do
+ it "returns true" do
+ plan = Plan.new(
+ id: "basic",
+ price: 0,
+ range: 0..0,
+ title: "Hound",
+ )
+
+ expect(plan).to be_open_source
end
- context "with bulk repo" do
- it "returns bulk price" do
- bulk_repo = double("Repo", bulk?: true)
- plan = Plan.new(bulk_repo)
+ context "when the price is positive" do
+ it "returns false" do
+ plan = Plan.new(
+ id: "tier1",
+ price: 49,
+ range: 1..4,
+ title: "Chihuahua",
+ )
- expect(plan.price).to eq 0
+ expect(plan).to_not be_open_source
end
end
end
+
+ describe "#price" do
+ it "returns the initialized price" do
+ allowance = 4
+ id = "tier1"
+ price = 49
+ range = 1..allowance
+ title = "Chihuahua"
+ plan = Plan.new(id: id, price: price, range: range, title: title)
+
+ expect(plan.price).to eq price
+ end
+ end
+
+ describe "#title" do
+ it "returns the initialized title" do
+ allowance = 4
+ id = "tier1"
+ price = 49
+ range = 1..allowance
+ title = "Chihuahua"
+ plan = Plan.new(id: id, price: price, range: range, title: title)
+
+ expect(plan.title).to eq title
+ end
+ end
end
diff --git a/spec/models/pricing_spec.rb b/spec/models/pricing_spec.rb
deleted file mode 100644
index 210928cfc..000000000
--- a/spec/models/pricing_spec.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-require "spec_helper"
-require "active_model/serializer_support"
-require "app/models/pricing"
-
-RSpec.describe Pricing do
- describe ".all" do
- it "returns all of the pricings" do
- pricings = Pricing.all
-
- expect(pricings.count).to eq 4
-
- [
- [0, "basic", 0, "Hound"],
- [4, "tier1", 49, "Chihuahua"],
- [10, "tier2", 99, "Labrador"],
- [30, "tier3", 249, "Great Dane"],
- ].each_with_index do |(allowance, id, price, title), index|
- expect(pricings[index].allowance).to eq allowance
- expect(pricings[index].id).to eq id
- expect(pricings[index].price).to eq price
- expect(pricings[index].title).to eq title
- end
- end
- end
-
- describe ".find_by" do
- it "returns the pricing where the count is in range" do
- pricing = Pricing.find_by(count: 7)
-
- expect(pricing.allowance).to eq 10
- expect(pricing.id).to eq "tier2"
- expect(pricing.price).to eq 99
- expect(pricing.title).to eq "Labrador"
- end
- end
-
- describe "#==" do
- context "when the pricings have the same identifiers" do
- it "returns true" do
- allowance = 4
- id = "tier1"
- price = 49
- range = 1..allowance
- title = "Chihuahua"
- pricing_1 = Pricing.new(
- id: id,
- price: price,
- range: range,
- title: title,
- )
- pricing_2 = Pricing.new(
- id: id,
- price: price,
- range: range,
- title: title,
- )
-
- expect(pricing_1).to eq(pricing_2)
- end
- end
-
- context "when the pricings have different identifiers" do
- it "returns false" do
- allowance = 4
- id = "tier1"
- price = 49
- range = 1..allowance
- title = "Chihuahua"
- pricing_1 = Pricing.new(
- id: id,
- price: price,
- range: range,
- title: title,
- )
- pricing_2 = Pricing.new(
- id: "tier2",
- price: price,
- range: range,
- title: title,
- )
-
- expect(pricing_1).to_not eq(pricing_2)
- end
- end
- end
-
- describe "#allowance" do
- it "returns the upper bound of the range" do
- allowance = 4
- id = "tier1"
- price = 49
- range = 1..allowance
- title = "Chihuahua"
- pricing = Pricing.new(id: id, price: price, range: range, title: title)
-
- expect(pricing.allowance).to eq allowance
- end
- end
-
- describe "#id" do
- it "returns the initialized identifier" do
- allowance = 4
- id = "tier1"
- price = 49
- range = 1..allowance
- title = "Chihuahua"
- pricing = Pricing.new(id: id, price: price, range: range, title: title)
-
- expect(pricing.id).to eq id
- end
- end
-
- describe "#open_source?" do
- it "returns true" do
- pricing = Pricing.new(
- id: "basic",
- price: 0,
- range: 0..0,
- title: "Hound",
- )
-
- expect(pricing).to be_open_source
- end
-
- context "when the price is positive" do
- it "returns false" do
- pricing = Pricing.new(
- id: "tier1",
- price: 49,
- range: 1..4,
- title: "Chihuahua",
- )
-
- expect(pricing).to_not be_open_source
- end
- end
- end
-
- describe "#price" do
- it "returns the initialized price" do
- allowance = 4
- id = "tier1"
- price = 49
- range = 1..allowance
- title = "Chihuahua"
- pricing = Pricing.new(id: id, price: price, range: range, title: title)
-
- expect(pricing.price).to eq price
- end
- end
-
- describe "#title" do
- it "returns the initialized title" do
- allowance = 4
- id = "tier1"
- price = 49
- range = 1..allowance
- title = "Chihuahua"
- pricing = Pricing.new(id: id, price: price, range: range, title: title)
-
- expect(pricing.title).to eq title
- end
- end
-end
diff --git a/spec/models/repo_spec.rb b/spec/models/repo_spec.rb
index ef2427518..0973b3cb2 100644
--- a/spec/models/repo_spec.rb
+++ b/spec/models/repo_spec.rb
@@ -59,24 +59,6 @@
end
end
- describe "#plan_type" do
- context "when repo is public" do
- it "returns public plan type" do
- repo = Repo.new(private: false)
-
- expect(repo.plan_type).to eq "public"
- end
- end
-
- context "when repo is private" do
- it "returns private plan type" do
- repo = Repo.new(private: true)
-
- expect(repo.plan_type).to eq "private"
- end
- end
- end
-
describe "#activate" do
it "updates repo active value to true" do
repo = create(:repo, active: false)
diff --git a/spec/models/tier_spec.rb b/spec/models/tier_spec.rb
deleted file mode 100644
index bc8462706..000000000
--- a/spec/models/tier_spec.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-require "rails_helper"
-
-RSpec.describe Tier do
- describe "#current" do
- it "returns user's current pricing" do
- count = 1
- pricing = instance_double("Pricing")
- repos = class_double(Repo, count: count)
- user = instance_double("User", subscribed_repos: repos)
- tier = Tier.new(user)
- allow(Pricing).to receive(:find_by).once.with(count: count).
- and_return(pricing)
-
- expect(tier.current).to eq pricing
- end
- end
-
- describe "#full?" do
- context "when the next tier is different to the current tier" do
- it "returns true" do
- repos = class_double(Repo, count: 4)
- user = instance_double("User", subscribed_repos: repos)
- tier = Tier.new(user)
-
- expect(tier).to be_full
- end
- end
-
- context "when the user has no repos" do
- it "is full" do
- user = create(:user)
- tier = Tier.new(user)
-
- expect(tier).to be_full
- end
- end
-
- context "when the next tier is not the same as the current tier" do
- it "returns false" do
- repos = class_double(Repo, count: 3)
- user = instance_double("User", subscribed_repos: repos)
- tier = Tier.new(user)
-
- expect(tier.full?).to be(false)
- end
- end
- end
-
- describe "#next" do
- context "when the user has no subscribed repos" do
- it "returns the 'Tier 1' tier" do
- count = 1
- pricing = instance_double("Pricing")
- repos = class_double(Repo, count: count)
- user = instance_double("User", subscribed_repos: repos)
- tier = Tier.new(user)
- allow(Pricing).to receive(:find_by).once.with(count: count.succ).
- and_return(pricing)
-
- expect(tier.next).to eq pricing
- end
- end
- end
-
- describe "#previous" do
- it "returns the pricing for the preceding count's tier" do
- count = 0
- pricing = instance_double("Pricing")
- repo = instance_double("Repo")
- user = instance_double("User")
- tier = Tier.new(user)
- allow(Pricing).to receive(:find_by).once.with(count: count).
- and_return(pricing)
- allow(user).to receive(:subscribed_repos).once.with(no_args).
- and_return([repo])
-
- expect(tier.previous).to eq pricing
- end
- end
-end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 764320bb2..9ee0c3d17 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -6,44 +6,36 @@
it { should validate_presence_of :username }
it { should have_many(:memberships).dependent(:destroy) }
- describe "#current_tier" do
- it "returns the current tier identifier" do
- pricing = Pricing.new(id: "basic", price: 0, range: 0..0, title: "Hound")
- user = create(:user)
+ describe "#current_plan" do
+ it "returns the current plan" do
+ user = User.new
- expect(user.current_tier).to eq pricing
+ expect(user.current_plan).to eq Plan.new(Plan::PLANS[0])
end
end
- describe "#next_tier" do
- it "returns the next tier identifier" do
- user = build(:user)
- id = "NEXT_TIER_ID"
- tier = instance_double("Tier", next: id)
- allow(Tier).to receive(:new).once.with(user).and_return(tier)
+ describe "#next_plan" do
+ it "returns the next plan" do
+ user = User.new
- expect(user.next_tier).to eq id
+ expect(user.next_plan).to eq Plan.new(Plan::PLANS[1])
end
end
- describe "#tier_max" do
- it "returns the current tier's allowance" do
- allowance = 10
- pricing = instance_double("Pricing", allowance: allowance)
- tier = instance_double("Tier", current: pricing)
- user = User.new
- allow(Tier).to receive(:new).once.with(user).and_return(tier)
+ describe "#plan_max" do
+ it "returns the current plan's allowance" do
+ user = User.new(subscribed_repos: Array.new(5) { Repo.new })
- expect(user.tier_max).to eq allowance
+ expect(user.plan_max).to eq Plan::PLANS[2][:range].max
end
end
- describe "#tier_price" do
- it "returns the price of the next tier" do
+ describe "#next_plan_price" do
+ it "returns the price of the next plan" do
subscription = create(:subscription)
user = subscription.user
- expect(user.tier_price).to eq 49
+ expect(user.next_plan_price).to eq 49
end
end
diff --git a/spec/presenters/account_page_spec.rb b/spec/presenters/account_page_spec.rb
index 347070789..91938d495 100644
--- a/spec/presenters/account_page_spec.rb
+++ b/spec/presenters/account_page_spec.rb
@@ -2,13 +2,11 @@
RSpec.describe AccountPage do
describe "#allowance" do
- it "returns the allowance of the current tier" do
+ it "returns the allowance of the current plan" do
allowance = 10
- pricing = instance_double("Pricing", allowance: allowance)
- tier = instance_double("Tier", current: pricing)
- user = instance_double("User")
+ plan = instance_double("Plan", allowance: allowance)
+ user = instance_double("User", current_plan: plan)
page = AccountPage.new(user)
- allow(Tier).to receive(:new).once.with(user).and_return(tier)
expect(page.allowance).to eq allowance
end
@@ -35,43 +33,43 @@
end
describe "#plan" do
- it "returns the name of the current tier" do
- plan = "Chihuahua"
- pricing = instance_double("Pricing", title: plan)
- tier = instance_double("Tier", current: pricing)
- user = instance_double("User")
+ it "returns the name of the current plan" do
+ plan_name = "Chihuahua"
+ plan = instance_double("Plan", title: plan_name)
+ user = instance_double("User", current_plan: plan)
page = AccountPage.new(user)
- allow(Tier).to receive(:new).once.with(user).and_return(tier)
- expect(page.plan).to eq plan
+ expect(page.plan).to eq plan_name
end
end
- describe "#pricings" do
- it "returns all of the presentable, available pricings" do
- presenter = instance_double("PricingPresenter")
- pricing = instance_double("Pricing")
+ describe "#plans" do
+ it "returns all of the presentable, available plans" do
+ presenter = instance_double("PlanPresenter")
+ plan = instance_double("Plan")
user = instance_double("User")
page = AccountPage.new(user)
- allow(Pricing).to receive(:all).once.with(no_args).and_return([pricing])
- allow(PricingPresenter).to receive(:new).once.with(
- pricing: pricing,
+ allow(Plan).to receive(:all).once.with(no_args).and_return([plan])
+ allow(PlanPresenter).to receive(:new).once.with(
+ plan: plan,
user: user,
).and_return(presenter)
- expect(page.pricings).to eq [presenter]
+ expect(page.plans).to eq [presenter]
end
end
describe "#remaining" do
- it "returns the number of remaining repos available in the current tier" do
- pricing = instance_double("Pricing", allowance: 10)
+ it "returns the number of remaining repos available in the current plan" do
+ plan = instance_double("Plan", allowance: 10)
remaining = 9
repos = class_double("Repo", count: 1)
- tier = instance_double("Tier", current: pricing)
- user = instance_double("User", subscribed_repos: repos)
+ user = instance_double(
+ "User",
+ current_plan: plan,
+ subscribed_repos: repos,
+ )
page = AccountPage.new(user)
- allow(Tier).to receive(:new).once.with(user).and_return(tier)
expect(page.remaining).to eq remaining
end
diff --git a/spec/presenters/plan_presenter_spec.rb b/spec/presenters/plan_presenter_spec.rb
new file mode 100644
index 000000000..4aa7f10ec
--- /dev/null
+++ b/spec/presenters/plan_presenter_spec.rb
@@ -0,0 +1,117 @@
+require "rails_helper"
+
+RSpec.describe PlanPresenter do
+ describe "#allowance" do
+ it "returns the plan's allowance" do
+ user = create(:user)
+ plan = build_stubbed(:plan)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter.allowance).to eq plan.allowance
+ end
+ end
+
+ describe "#current?" do
+ context "when the plan matches the user's current plan" do
+ it "returns true" do
+ membership = create(:membership)
+ user = membership.user
+ create(:subscription, repo: membership.repo, user: user)
+ plan = build_stubbed(:plan)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter).to be_current
+ end
+ end
+
+ context "when the plan does not match the user's current plan" do
+ it "returns false" do
+ membership = create(:membership)
+ user = membership.user
+ create(:subscription, repo: membership.repo, user: user)
+ plan = build_stubbed(:plan, :plan2)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter).to_not be_current
+ end
+ end
+ end
+
+ describe "#next?" do
+ context "when the plan matches the user's next plan" do
+ it "returns true" do
+ membership = create(:membership)
+ user = membership.user
+ create(:subscription, repo: membership.repo, user: user)
+ plan = build_stubbed(:plan)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter).to be_next
+ end
+ end
+
+ context "when the plan does not match the user's next plan" do
+ it "returns false" do
+ membership = create(:membership)
+ user = membership.user
+ create(:subscription, repo: membership.repo, user: user)
+ plan = build_stubbed(:plan, :plan2)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter).to_not be_next
+ end
+ end
+ end
+
+ describe "#open_source?" do
+ it "returns the plan's open source state" do
+ plan = instance_double("Plan", open_source?: true)
+ user = instance_double("User")
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter).to be_open_source
+ end
+ end
+
+ describe "#price" do
+ it "returns the plan's price" do
+ user = create(:user)
+ plan = build_stubbed(:plan)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter.price).to eq plan.price
+ end
+ end
+
+ describe "#to_partial_path" do
+ context "when the plan is for open source repos" do
+ it "returns 'plans/open_source'" do
+ plan = instance_double("Plan", open_source?: true)
+ user = instance_double("User")
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter.to_partial_path).to eq("plans/open_source")
+ end
+ end
+
+ context "when the plan is for private repos" do
+ it "returns 'plans/private'" do
+ plan = instance_double("Plan", open_source?: false)
+ user = instance_double("User")
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter.to_partial_path).to eq("plans/private")
+ end
+ end
+ end
+
+ describe "#title" do
+ it "returns the plan's title" do
+ user = create(:user)
+ plan = build_stubbed(:plan)
+ presenter = PlanPresenter.new(plan: plan, user: user)
+
+ expect(presenter.title).to eq plan.title
+ end
+ end
+end
diff --git a/spec/presenters/pricing_presenter_spec.rb b/spec/presenters/pricing_presenter_spec.rb
deleted file mode 100644
index 2ed48d461..000000000
--- a/spec/presenters/pricing_presenter_spec.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-require "rails_helper"
-
-RSpec.describe PricingPresenter do
- describe "#allowance" do
- it "returns the pricing's allowance" do
- user = create(:user)
- pricing = build_stubbed(:pricing)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter.allowance).to eq pricing.allowance
- end
- end
-
- describe "#current?" do
- context "when the pricing matches the user's current pricing" do
- it "returns true" do
- membership = create(:membership)
- user = membership.user
- create(:subscription, repo: membership.repo, user: user)
- pricing = build_stubbed(:pricing)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter).to be_current
- end
- end
-
- context "when the pricing does not match the user's current pricing" do
- it "returns false" do
- membership = create(:membership)
- user = membership.user
- create(:subscription, repo: membership.repo, user: user)
- pricing = build_stubbed(:pricing, :tier2)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter).to_not be_current
- end
- end
- end
-
- describe "#next?" do
- context "when the pricing matches the user's next pricing" do
- it "returns true" do
- membership = create(:membership)
- user = membership.user
- create(:subscription, repo: membership.repo, user: user)
- pricing = build_stubbed(:pricing)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter).to be_next
- end
- end
-
- context "when the pricing does not match the user's next pricing" do
- it "returns false" do
- membership = create(:membership)
- user = membership.user
- create(:subscription, repo: membership.repo, user: user)
- pricing = build_stubbed(:pricing, :tier2)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter).to_not be_next
- end
- end
- end
-
- describe "#open_source?" do
- it "returns the pricing's open source state" do
- pricing = instance_double("Pricing", open_source?: true)
- user = instance_double("User")
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter).to be_open_source
- end
- end
-
- describe "#price" do
- it "returns the pricing's price" do
- user = create(:user)
- pricing = build_stubbed(:pricing)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter.price).to eq pricing.price
- end
- end
-
- describe "#to_partial_path" do
- context "when the pricing is for open source repos" do
- it "returns 'pricings/open_source'" do
- pricing = instance_double("Pricing", open_source?: true)
- user = instance_double("User")
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter.to_partial_path).to eq("pricings/open_source")
- end
- end
-
- context "when the pricing is for private repos" do
- it "returns 'pricings/private'" do
- pricing = instance_double("Pricing", open_source?: false)
- user = instance_double("User")
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter.to_partial_path).to eq("pricings/private")
- end
- end
- end
-
- describe "#title" do
- it "returns the pricing's title" do
- user = create(:user)
- pricing = build_stubbed(:pricing)
- presenter = PricingPresenter.new(pricing: pricing, user: user)
-
- expect(presenter.title).to eq pricing.title
- end
- end
-end
diff --git a/spec/serializers/plan_serializer_spec.rb b/spec/serializers/plan_serializer_spec.rb
new file mode 100644
index 000000000..2b759f4ab
--- /dev/null
+++ b/spec/serializers/plan_serializer_spec.rb
@@ -0,0 +1,24 @@
+require "active_model_serializers"
+
+require "app/models/plan"
+require "app/serializers/plan_serializer"
+
+RSpec.describe PlanSerializer do
+ describe "#as_json" do
+ it "returns the plan as a JSON object" do
+ allowance = 0
+ price = 0
+ title = "Hound"
+ plan = Plan.new(id: "foo", title: title, range: 0..0, price: price)
+ user = instance_double("User", current_plan: plan)
+ serializer = PlanSerializer.new(plan, root: false, scope: user)
+
+ expect(serializer.as_json).to eq(
+ current: true,
+ name: title,
+ price: price,
+ allowance: allowance,
+ )
+ end
+ end
+end
diff --git a/spec/serializers/pricing_serializer_spec.rb b/spec/serializers/pricing_serializer_spec.rb
deleted file mode 100644
index 8a405cee7..000000000
--- a/spec/serializers/pricing_serializer_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require "spec_helper"
-require "active_model/serializer"
-require "app/serializers/pricing_serializer"
-
-RSpec.describe PricingSerializer do
- describe "#as_json" do
- it "returns the pricing as a JSON object" do
- allowance = 0
- price = 0
- title = "Hound"
- pricing = instance_double("Pricing", title: title)
- tier = instance_double("Tier")
- user = instance_double("User", current_tier: tier)
- serializer = PricingSerializer.new(pricing, root: false, scope: user)
- allow(pricing).to receive(:read_attribute_for_serialization).once.
- with(:allowance).and_return(allowance)
- allow(pricing).to receive(:read_attribute_for_serialization).once.
- with(:price).and_return(price)
-
- expect(serializer.as_json).to eq(
- current: false,
- name: title,
- price: price,
- allowance: allowance,
- )
- end
- end
-end
diff --git a/spec/serializers/repo_serializer_spec.rb b/spec/serializers/repo_serializer_spec.rb
index 9cc82639f..4a8659084 100644
--- a/spec/serializers/repo_serializer_spec.rb
+++ b/spec/serializers/repo_serializer_spec.rb
@@ -75,17 +75,19 @@
end
context "when the repo is private" do
- it "returns subscription price in cents if the repo were activated" do
- repo = create(:repo, private: true)
- membership = create(:membership, admin: true, repo: repo)
- user = membership.user
- serializer = RepoSerializer.new(
- repo,
- scope: user,
- scope_name: :current_user,
- )
+ context "and the repo was activated" do
+ it "returns subscription price in cents" do
+ repo = create(:repo, private: true)
+ membership = create(:membership, admin: true, repo: repo)
+ user = membership.user
+ serializer = RepoSerializer.new(
+ repo,
+ scope: user,
+ scope_name: :current_user,
+ )
- expect(serializer.price_in_cents).to eq(user.tier_price * 100)
+ expect(serializer.price_in_cents).to eq(user.next_plan_price * 100)
+ end
end
end
end
diff --git a/spec/serializers/user_serializer_spec.rb b/spec/serializers/user_serializer_spec.rb
index b37bcbd07..1eb859df2 100644
--- a/spec/serializers/user_serializer_spec.rb
+++ b/spec/serializers/user_serializer_spec.rb
@@ -11,13 +11,13 @@
end
end
- describe "#tier_allowance" do
- it "is the number of subscriptions allowed within the current tier" do
- current_tier = instance_double(Pricing, allowance: 4)
- user = instance_double(User, current_tier: current_tier)
+ describe "#plan_max" do
+ it "returns the number of subscriptions allowed within the current plan" do
+ subscription = create(:subscription)
+ user = create(:user, subscriptions: [subscription])
serializer = UserSerializer.new(user)
- expect(serializer.tier_allowance).to eq 4
+ expect(serializer.plan_max).to eq 4
end
end
end
diff --git a/spec/services/repo_subscriber_spec.rb b/spec/services/repo_subscriber_spec.rb
index 36c88d805..65fa457ad 100644
--- a/spec/services/repo_subscriber_spec.rb
+++ b/spec/services/repo_subscriber_spec.rb
@@ -14,11 +14,11 @@
stub_customer_find_request
update_request = stub_customer_update_request
subscription_request = stub_subscription_create_request(
- plan: user.current_tier.id,
+ plan: user.current_plan.id,
repo_ids: repo.id,
)
subscription_update_request = stub_subscription_update_request(
- plan: user.next_tier.id,
+ plan: user.next_plan.id,
repo_ids: repo.id,
)
@@ -29,7 +29,6 @@
expect(update_request).not_to have_been_requested
expect(repo.subscription.stripe_subscription_id).
to eq(stripe_subscription_id)
- expect(repo.subscription_price).to(eq(Plan::PRICES[:private]))
end
end
@@ -57,7 +56,6 @@
expect(subscription_update_request).to have_been_requested
expect(repo.subscription.stripe_subscription_id).
to eq(stripe_subscription_id)
- expect(repo.subscription_price).to(eq(Plan::PRICES[:private]))
end
end
end
@@ -68,11 +66,11 @@
user = create(:user, repos: [repo], stripe_customer_id: "",)
customer_request = stub_customer_create_request(user)
subscription_request = stub_subscription_create_request(
- plan: user.current_tier.id,
+ plan: user.current_plan.id,
repo_ids: repo.id,
)
update_request = stub_subscription_update_request(
- plan: user.next_tier.id,
+ plan: user.next_plan.id,
repo_ids: repo.id,
)
@@ -92,7 +90,7 @@
repo = create(:repo)
user = create(:user, repos: [repo])
stub_customer_create_request(user)
- stub_failed_subscription_create_request(user.current_tier.id)
+ stub_failed_subscription_create_request(user.current_plan.id)
result = RepoSubscriber.subscribe(repo, user, "cardtoken")
@@ -103,7 +101,7 @@
repo = build_stubbed(:repo)
user = create(:user)
stub_customer_create_request(user)
- stub_failed_subscription_create_request(user.current_tier.id)
+ stub_failed_subscription_create_request(user.current_plan.id)
allow(Raven).to receive(:capture_exception)
RepoSubscriber.subscribe(repo, user, "cardtoken")
@@ -118,11 +116,11 @@
user = create(:user, repos: [repo])
stub_customer_create_request(user)
stub_subscription_create_request(
- plan: user.current_tier.id,
+ plan: user.current_plan.id,
repo_ids: repo.id,
)
stub_subscription_update_request(
- plan: user.next_tier.id,
+ plan: user.next_plan.id,
repo_ids: repo.id,
)
stripe_delete_request = stub_subscription_delete_request
@@ -153,7 +151,7 @@
end
describe ".unsubscribe" do
- it "updates the Stripe plan" do
+ it "downgrades the Stripe plan" do
subscription = subscription_with_user
stub_customer_find_request
stub_subscription_find_request(subscription, quantity: 2)
@@ -197,12 +195,12 @@
def subscription_with_user
user = create(:user, stripe_customer_id: stripe_customer_id)
- subscription = create(
+ repo = create(:repo, :private, users: [user])
+ create(
:subscription,
stripe_subscription_id: stripe_subscription_id,
user: user,
+ repo: repo,
)
- user.repos << subscription.repo
- subscription
end
end
diff --git a/yarn.lock b/yarn.lock
index 4379b7042..4dd627216 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -204,10 +204,6 @@ async@^2.1.2, async@^2.1.4:
dependencies:
lodash "^4.14.0"
-async@~0.2.6:
- version "0.2.10"
- resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
-
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -2578,14 +2574,14 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
-
-inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1:
+inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
ini@~1.3.0:
version "1.3.4"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
@@ -5065,16 +5061,7 @@ ua-parser-js@^0.7.9:
version "0.7.12"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb"
-uglify-js@^2.6:
- version "2.7.5"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8"
- dependencies:
- async "~0.2.6"
- source-map "~0.5.1"
- uglify-to-browserify "~1.0.0"
- yargs "~3.10.0"
-
-uglify-js@^2.8.5:
+uglify-js@^2.6, uglify-js@^2.8.5:
version "2.8.14"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.14.tgz#25b15d1af39b21752ee33703adbf432e8bc8f77d"
dependencies: