parent
b9f0b282ca
commit
8f5706fcc1
22 changed files with 5 additions and 719 deletions
|
|
@ -95,7 +95,7 @@ class PagesController < ApplicationController
|
|||
set_surrogate_key_header "shecoded_page"
|
||||
end
|
||||
|
||||
private # helpers
|
||||
private
|
||||
|
||||
def latest_published_thread(tag_name)
|
||||
Article.published.
|
||||
|
|
@ -103,14 +103,4 @@ class PagesController < ApplicationController
|
|||
order("published_at ASC").
|
||||
tagged_with(tag_name).last
|
||||
end
|
||||
|
||||
def members_for_display
|
||||
Rails.cache.fetch("members-for-display-on-membership-page", expires_in: 6.hours) do
|
||||
roles = %i[level_1_member level_2_member level_3_member level_4_member triple_unicorn_member
|
||||
workshop_pass]
|
||||
members = User.select(:id, :username, :profile_image).with_any_role(*roles)
|
||||
team_ids = [1, 264, 6, 3, 31_047, 510, 560, 1075, 48_943, 13_962]
|
||||
members.reject { |user| team_ids.include?(user.id) }.shuffle
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
class StripeCancellationsController < ApplicationController
|
||||
skip_before_action :verify_authenticity_token, only: :create
|
||||
|
||||
def create
|
||||
verify_stripe_signature
|
||||
unsubscribe_customer
|
||||
end
|
||||
|
||||
def verify_stripe_signature
|
||||
payload = request.body.read
|
||||
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
|
||||
|
||||
begin
|
||||
Stripe::Webhook.construct_event(
|
||||
payload, sig_header, Rails.configuration.stripe[:stripe_cancellation_secret]
|
||||
)
|
||||
rescue JSON::ParserError
|
||||
# Invalid payload
|
||||
status 400
|
||||
return
|
||||
rescue Stripe::SignatureVerificationError
|
||||
# Invalid signature
|
||||
status 400
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def unsubscribe_customer
|
||||
event = Stripe::Event.retrieve(params[:id])
|
||||
stripe_id = event.data.object.customer
|
||||
customer = Stripe::Customer.retrieve(stripe_id)
|
||||
monthly_dues = event.data.object.items.data[0].plan.amount
|
||||
user = User.where(stripe_id_code: stripe_id).first
|
||||
MembershipService.new(customer, user, monthly_dues).unsubscribe_customer
|
||||
render body: nil, status: :ok
|
||||
rescue Stripe::APIConnectionError, Stripe::StripeError
|
||||
render body: nil, status: :bad_request
|
||||
end
|
||||
end
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
class StripeSubscriptionsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :touch_current_user
|
||||
|
||||
def create
|
||||
authorize :stripe_subscription
|
||||
amount = stripe_params[:amount]
|
||||
customer = find_or_create_customer
|
||||
if customer &&
|
||||
MembershipService.new(customer, current_user, amount).subscribe_customer
|
||||
logger.info("Stripe New Subscription Success - #{current_user.username}")
|
||||
else
|
||||
logger.error("Stripe New Subscription Failure - #{current_user.username}")
|
||||
redirect_to "/membership", flash: { error:
|
||||
"There was a problem updating your billing info." }
|
||||
end
|
||||
rescue Stripe::CardError, Stripe::InvalidRequestError => e
|
||||
logger.error("Stripe Error - #{e.message} - #{current_user.email}")
|
||||
message = if e.message.include?("This customer has no attached payment source")
|
||||
"Something went wrong! Please try again or contact members@dev.to."
|
||||
else
|
||||
e.message
|
||||
end
|
||||
redirect_to "/membership", flash: { error: message }
|
||||
end
|
||||
|
||||
def update
|
||||
authorize :stripe_subscription
|
||||
amount = stripe_params[:amount]
|
||||
customer = Stripe::Customer.retrieve(current_user.stripe_id_code)
|
||||
if MembershipService.new(customer, current_user, amount).update_subscription
|
||||
logger.info("Stripe Update Subscription Success - #{current_user.username}")
|
||||
redirect_to "/settings/membership", notice:
|
||||
"Your new membership is now active. Thanks for your support!"
|
||||
else
|
||||
logger.error("Stripe Update Subscription Failure - #{current_user.username}")
|
||||
redirect_to "/settings/membership", flash: { error:
|
||||
"There was a problem updating your new plan." }
|
||||
end
|
||||
rescue Stripe::CardError, Stripe::InvalidRequestError => e
|
||||
redirect_to "/settings/billing", flash: { error: e.message }
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize :stripe_subscription
|
||||
customer = Stripe::Customer.retrieve(current_user.stripe_id_code)
|
||||
if MembershipService.new(customer, current_user, nil).unsubscribe_customer
|
||||
logger.info("Stripe Cancel Subscription Success - #{current_user.username}")
|
||||
redirect_to "/settings", notice:
|
||||
"Your membership is cancelled. Thanks for your support."
|
||||
else
|
||||
logger.info("Stripe Cancel Subscription Failure - #{current_user.username}")
|
||||
redirect_to "/settings", flash: { error:
|
||||
"There was a problem updating your plan." }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_or_create_customer
|
||||
if current_user.stripe_id_code.present?
|
||||
customer = Stripe::Customer.retrieve(current_user.stripe_id_code)
|
||||
customer.sources.create(source: params[:stripe_token]) if params[:stripe_token].present?
|
||||
else
|
||||
customer = Stripe::Customer.create(
|
||||
email: current_user.email,
|
||||
source: params[:stripe_token],
|
||||
)
|
||||
end
|
||||
customer
|
||||
end
|
||||
|
||||
def stripe_params
|
||||
params[:amount] = convert_amount_to_cent
|
||||
raise custom_error if invalid_amount?
|
||||
|
||||
accessible = %i[amount existing_card_id stripe_token]
|
||||
params.permit(accessible)
|
||||
end
|
||||
|
||||
def custom_error
|
||||
message = <<-HTML
|
||||
Oops, something went wrong. You have not been charged.
|
||||
<br>
|
||||
Please
|
||||
#{view_context.link_to('try again', '/membership')} or #{view_context.link_to('contact us', 'mailto:members@dev.to')}.
|
||||
HTML
|
||||
Stripe::CardError.new(
|
||||
message.html_safe,
|
||||
params[:amount],
|
||||
400,
|
||||
)
|
||||
end
|
||||
|
||||
def convert_amount_to_cent
|
||||
amount = params[:amount] || params[:input_amount]
|
||||
amount ? (amount.to_d * 100).to_i : nil
|
||||
end
|
||||
|
||||
def invalid_amount?
|
||||
amount = params[:amount] || params[:input_amount]
|
||||
amount.nil? || amount < 100
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,6 @@ class MailchimpBot
|
|||
def upsert
|
||||
return true unless Rails.env.production? || Rails.env.test?
|
||||
|
||||
upsert_to_membership_newsletter
|
||||
manage_community_moderator_list
|
||||
manage_tag_moderator_list
|
||||
upsert_to_newsletter
|
||||
|
|
@ -101,41 +100,6 @@ class MailchimpBot
|
|||
success
|
||||
end
|
||||
|
||||
def upsert_to_membership_newsletter
|
||||
return false unless a_sustaining_member?
|
||||
|
||||
success = false
|
||||
# !!! user.monthly_due = 0 ? unsubscribe
|
||||
tiers = %i[ triple_unicorn_member
|
||||
level_4_member
|
||||
level_3_member
|
||||
level_2_member
|
||||
level_1_member]
|
||||
membership = tiers.each { |t| break t if user.has_role?(t) }
|
||||
status = user.email_membership_newsletter ? "subscribed" : "unsubscribed"
|
||||
|
||||
begin
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_SUSTAINING_MEMBERS_ID"]).members(target_md5_email).upsert(
|
||||
body: {
|
||||
email_address: user.email,
|
||||
status: status,
|
||||
merge_fields: {
|
||||
NAME: user.name.to_s,
|
||||
USERNAME: user.username.to_s,
|
||||
TWITTER: user.twitter_username.to_s,
|
||||
GITHUB: user.github_username.to_s,
|
||||
IMAGE_URL: user.profile_image_url.to_s,
|
||||
MEMBERSHIP: membership.to_s
|
||||
}
|
||||
},
|
||||
)
|
||||
success = true
|
||||
rescue Gibbon::MailChimpError => e
|
||||
report_error(e)
|
||||
end
|
||||
success
|
||||
end
|
||||
|
||||
def unsub_sustaining_member
|
||||
return unless user.tag_moderator?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
class MembershipMailer < ApplicationMailer
|
||||
default from: "DEV Members <members@dev.to>"
|
||||
|
||||
def new_membership_subscription_email(user, subscription_type)
|
||||
@user = user
|
||||
@subscription_type = subscription_type
|
||||
mail(to: @user.email, subject: "Thanks for subscribing!")
|
||||
end
|
||||
|
||||
def subscription_update_confirm_email(user)
|
||||
@user = user
|
||||
mail(to: @user.email, subject: "Your subscription has been updated.")
|
||||
end
|
||||
|
||||
def subscription_cancellation_email(user)
|
||||
@user = user
|
||||
mail(to: @user.email, subject: "Sorry to lose you.")
|
||||
end
|
||||
end
|
||||
|
|
@ -18,11 +18,6 @@ class Role < ApplicationRecord
|
|||
trusted
|
||||
banned
|
||||
warned
|
||||
triple_unicorn_member
|
||||
level_4_member
|
||||
level_3_member
|
||||
level_2_member
|
||||
level_1_member
|
||||
workshop_pass
|
||||
chatroom_beta_tester
|
||||
comment_banned
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def workshop_eligible?
|
||||
has_any_role?(:workshop_pass, :level_3_member, :level_4_member, :triple_unicorn_member)
|
||||
has_any_role?(:workshop_pass)
|
||||
end
|
||||
|
||||
def admin_organizations
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
class MembershipService
|
||||
attr_reader :customer, :user, :monthly_dues, :subscription, :plan
|
||||
|
||||
def initialize(customer, user, monthly_dues)
|
||||
@customer = customer
|
||||
@user = user
|
||||
@monthly_dues = monthly_dues || @user.monthly_dues
|
||||
@plan = find_or_create_plan
|
||||
@subscription = find_subscription
|
||||
end
|
||||
|
||||
def subscribe_customer
|
||||
true if create_subscription &&
|
||||
assign_membership_role &&
|
||||
user.update(monthly_dues: monthly_dues,
|
||||
membership_started_at: Time.current,
|
||||
email_membership_newsletter: true,
|
||||
stripe_id_code: customer.id) &&
|
||||
send_welcome_email
|
||||
end
|
||||
|
||||
def update_subscription
|
||||
true if update_stripe_plan_for_subscription &&
|
||||
assign_membership_role &&
|
||||
user.update(monthly_dues: monthly_dues) &&
|
||||
send_update_email
|
||||
end
|
||||
|
||||
def unsubscribe_customer
|
||||
true if cancel_subscription &&
|
||||
remove_all_membership_roles &&
|
||||
user.update(monthly_dues: 0, email_membership_newsletter: false) &&
|
||||
send_cancellation_email
|
||||
end
|
||||
|
||||
def find_subscription
|
||||
customer.subscriptions.first || nil
|
||||
end
|
||||
|
||||
def create_subscription
|
||||
customer.subscriptions.create(plan: plan.id)
|
||||
end
|
||||
|
||||
def cancel_subscription
|
||||
return true if customer.subscriptions.none?
|
||||
|
||||
subscription.delete
|
||||
end
|
||||
|
||||
def update_stripe_plan_for_subscription
|
||||
subscription.items = [{
|
||||
id: subscription.items.data[0].id,
|
||||
plan: plan.id
|
||||
}]
|
||||
subscription.save
|
||||
end
|
||||
|
||||
def find_or_create_plan
|
||||
Stripe::Plan.retrieve("membership-#{monthly_dues}")
|
||||
# Using rescue because not finding a plan errors out instead returning of nil
|
||||
rescue Stripe::InvalidRequestError
|
||||
Stripe::Plan.create(
|
||||
id: "membership-#{monthly_dues}",
|
||||
currency: "usd",
|
||||
interval: "month",
|
||||
name: "Monthly DEV Membership",
|
||||
amount: monthly_dues,
|
||||
statement_descriptor: "DEV membership",
|
||||
)
|
||||
end
|
||||
|
||||
def assign_membership_role
|
||||
# change role names here, in role.rb, users_controller#handle_settings_tab => @membership_names
|
||||
remove_all_membership_roles
|
||||
if monthly_dues >= 100_000
|
||||
user.add_role :triple_unicorn_member
|
||||
elsif monthly_dues > 2500
|
||||
user.add_role :level_4_member
|
||||
elsif monthly_dues == 2500
|
||||
user.add_role :level_3_member
|
||||
elsif monthly_dues.between?(1000, 2499)
|
||||
user.add_role :level_2_member
|
||||
else
|
||||
user.add_role :level_1_member
|
||||
end
|
||||
end
|
||||
|
||||
def remove_all_membership_roles
|
||||
tiers = %i[triple_unicorn_member level_4_member level_3_member level_2_member level_1_member]
|
||||
tiers.each { |t| user.remove_role(t) }
|
||||
end
|
||||
|
||||
def send_welcome_email
|
||||
MembershipMailer.delay.new_membership_subscription_email(user, user.roles.last.name)
|
||||
end
|
||||
|
||||
def send_update_email
|
||||
MembershipMailer.delay.subscription_update_confirm_email(user)
|
||||
end
|
||||
|
||||
def send_cancellation_email
|
||||
MembershipMailer.delay.subscription_cancellation_email(user)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
<img src="https://thepracticaldev.s3.amazonaws.com/i/186bp9xbue90w504wn97.png" style="height:200px; display: block; margin-left: auto; margin-right: auto;" alt="DEV membership logo">
|
||||
<% if @subscription_type == "triple_unicorn_member" %>
|
||||
<p>
|
||||
Whoa! You’re the best, and so generous. We tip our hats to you.
|
||||
</p>
|
||||
<p>
|
||||
As a triple-unicorn, you have full access to all dev.to workshops! We’ll be releasing our workshop schedule Early February.
|
||||
</p>
|
||||
<p>
|
||||
You’ll see your name at the featured position on our ‘Wall of Patrons and Scholars’ within the next few days, and you can claim your swag pack now by visiting your
|
||||
<a href="https://dev.to/settings/membership">settings page</a>.
|
||||
</p>
|
||||
<p>
|
||||
We’ll be in touch to schedule a time for all of us to chat together, and we’ll also be putting together some additional goodies.
|
||||
</p>
|
||||
<p>
|
||||
Thank you again for supporting The DEV Community. Your membership means a lot to us, and all the recipients of our scholarship fund. You went above and beyond on this one.
|
||||
</p>
|
||||
<% elsif @subscription_type == "level_4_member" %>
|
||||
<p>
|
||||
Thank you for becoming a DEV sustaining member. Your support means the world to us.
|
||||
</p>
|
||||
<p>
|
||||
As part of your membership, you’ll have early access to beta features on the site. For instance, post analytics have now been added to your
|
||||
<a href="https://dev.to/dashboard/">dashboard</a>.
|
||||
</p>
|
||||
<p>
|
||||
On your
|
||||
<a href="https://dev.to/settings/membership">membership settings page</a>, you’ll find the coupon that you’ll use to request your exclusive sticker pack and t-shirt combo.
|
||||
</p>
|
||||
<p>
|
||||
Your name will appear on our “Wall of Patrons and Scholars” soon, and you’ll also be receiving full access to all dev.to workshops! We’ll be releasing our first workshop schedule in early February.
|
||||
</p>
|
||||
<p>
|
||||
Above all, thank you for supporting The DEV Community. Your additional contribution means so much to us, and to all the recipients of our scholarship fund. You really went above and beyond on this one.
|
||||
</p>
|
||||
<p>
|
||||
With sincere gratitude...
|
||||
</p>
|
||||
<p>
|
||||
❤️
|
||||
<br />
|
||||
PBJ
|
||||
</p>
|
||||
<p>
|
||||
PS — feel free to reply to this email with any questions.
|
||||
</p>
|
||||
<% elsif @subscription_type == "level_3_member" %>
|
||||
<p>
|
||||
Thank you for becoming a DEV sustaining member. Your support means the world to us.
|
||||
</p>
|
||||
<p>
|
||||
As part of your membership, you’ll have early access to beta features on the site. For instance, post analytics have now been added to your
|
||||
<a href="https://dev.to/dashboard/">dashboard</a>.
|
||||
</p>
|
||||
<p>
|
||||
On your membership
|
||||
<a href="https://dev.to/settings/membership">settings page</a>, you’ll find the coupon that you’ll use to request your exclusive sticker pack and t-shirt combo.
|
||||
</p>
|
||||
<p>
|
||||
Your name will appear on our “Wall of Patrons and Scholars” soon, and you’ll also be receiving full access to all dev.to workshops! We’ll be releasing our first workshop schedule in early February.
|
||||
</p>
|
||||
<p>
|
||||
Feel free to reply to this email with any questions :)
|
||||
</p>
|
||||
<p>
|
||||
Thanks again! ❤️
|
||||
<br />
|
||||
PBJ
|
||||
</p>
|
||||
<% elsif @subscription_type == "level_2_member" %>
|
||||
<p>
|
||||
Thank you for becoming a DEV sustaining member. Your support means the world to us.
|
||||
</p>
|
||||
<p>
|
||||
As part of your membership, you’ll have early access to beta features on the site. For instance, post analytics have now been added to your
|
||||
<a href="https://dev.to/dashboard/">dashboard</a>.
|
||||
</p>
|
||||
<p>
|
||||
On your
|
||||
<a href="https://dev.to/settings/membership">membership settings</a> page, you’ll find the coupon that you’ll use to request your exclusive sticker pack. Within the next few days, you’ll be appearing on our ‘Wall of Patrons and Scholars.’
|
||||
</p>
|
||||
<p>
|
||||
Feel free to reply to this email with any questions :)
|
||||
</p>
|
||||
<p>
|
||||
Thanks again! ❤️
|
||||
<br />
|
||||
PBJ
|
||||
</p>
|
||||
<% elsif @subscription_type == "level_1_member" %>
|
||||
<p>
|
||||
Thank you for becoming a DEV sustaining member. Your support means the world to us.
|
||||
</p>
|
||||
<p>
|
||||
As part of your membership, you’ll have early access to beta features on the site. For instance, post analytics have now been added to your
|
||||
<a href="https://dev.to/dashboard/">dashboard</a>.
|
||||
</p>
|
||||
<p>
|
||||
Within the next few days, you’ll also appear on our ‘Wall of Patrons and Scholars.’
|
||||
</p>
|
||||
<p>
|
||||
Feel free to reply to this email with any questions :)
|
||||
</p>
|
||||
<p>
|
||||
Thanks again! ❤️
|
||||
<br />
|
||||
PBJ
|
||||
</p>
|
||||
<% end %>
|
||||
<h2 style="font-size:25px;">Thank you so much for your support.</h2>
|
||||
<p>
|
||||
Visit <a href="https://dev.to/settings/membership">Your membership settings page</a> for all details.
|
||||
</p>
|
||||
|
|
@ -1 +0,0 @@
|
|||
Visit https://dev.to/settings/membership for full details
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<p>
|
||||
Your DEV sustaining membership has been cancelled. Thank you so much for your support to date.
|
||||
</p>
|
||||
<p>
|
||||
If you have any feedback that can help us improve the membership experience, please feel free to reply to this email.
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
Thanks again,
|
||||
<br />
|
||||
PBJ
|
||||
</p>
|
||||
|
|
@ -1 +0,0 @@
|
|||
If you could send feedback to yo@dev.to to help us improve it would be much appreciated.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<img src="<%= asset_path "sustaining-membership.svg" %>" style="height:200px; display: block; margin-left: auto; margin-right: auto;" alt="DEV membership logo">
|
||||
<p>
|
||||
Your DEV sustaining membership monthly contribution amount has been updated. Be sure to check your
|
||||
<a href="https://dev.to/settings/membership">membership settings</a> page to see the most up-to-date information.
|
||||
</p>
|
||||
<p>
|
||||
Thank you so much for the support, and please email members@dev.to with any questions.
|
||||
</p>
|
||||
|
|
@ -1 +0,0 @@
|
|||
Visit https://dev.to/settings/membership for updated details
|
||||
|
|
@ -134,7 +134,6 @@ Rails.application.routes.draw do
|
|||
resources :notifications, only: [:index]
|
||||
resources :tags, only: [:index]
|
||||
resources :stripe_active_cards, only: %i[create update destroy]
|
||||
resources :stripe_cancellations, only: [:create]
|
||||
resources :live_articles, only: [:index]
|
||||
resources :github_repos, only: %i[create update]
|
||||
resources :buffered_articles, only: [:index]
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ end
|
|||
|
||||
Rails.logger.info "2. Creating Users"
|
||||
|
||||
roles = %i[level_1_member level_2_member level_3_member level_4_member
|
||||
workshop_pass]
|
||||
roles = %i[trusted chatroom_beta_tester workshop_pass]
|
||||
User.clear_index!
|
||||
10.times do |i|
|
||||
user = User.create!(
|
||||
|
|
@ -36,7 +35,7 @@ User.clear_index!
|
|||
password: "password",
|
||||
)
|
||||
|
||||
user.add_role(roles[rand(0..5)]) # includes chance of having no role
|
||||
user.add_role(roles[rand(0..3)]) # includes chance of having no role
|
||||
|
||||
Identity.create!(
|
||||
provider: "twitter",
|
||||
|
|
|
|||
|
|
@ -129,35 +129,6 @@ RSpec.describe MailchimpBot do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#upsert_to_membership_newsletter" do
|
||||
it "returns false if user isn't a sustaining member" do
|
||||
expect(described_class.new(user).upsert_to_membership_newsletter).to be(false)
|
||||
end
|
||||
|
||||
context "when user is a sustaining member" do
|
||||
it "send proper information" do
|
||||
user.update(monthly_dues: 2500, email_membership_newsletter: true)
|
||||
user.add_role(:level_2_member)
|
||||
described_class.new(user).upsert_to_membership_newsletter
|
||||
expect(my_gibbon_client).to have_received(:upsert).
|
||||
with(hash_including(
|
||||
body: hash_including(
|
||||
status: "subscribed",
|
||||
merge_fields: hash_including(MEMBERSHIP: "level_2_member"),
|
||||
),
|
||||
))
|
||||
end
|
||||
|
||||
it "unsubscribes if monthly due become 0" do
|
||||
user.update(monthly_dues: 2500)
|
||||
user.update(monthly_dues: 0)
|
||||
described_class.new(user).upsert_to_membership_newsletter
|
||||
expect(my_gibbon_client).to have_received(:upsert).
|
||||
with(hash_including(body: hash_including(status: "unsubscribed")))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#unsubscribe_all_newsletters" do
|
||||
context "when called" do
|
||||
before { allow(my_gibbon_client).to receive(:update).and_return(true) }
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe MembershipMailer, type: :mailer do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
describe "#new_membership_subscription_email" do
|
||||
it "renders proper subject" do
|
||||
email = described_class.new_membership_subscription_email(user, "level_1_member")
|
||||
expect(email.subject).to include("Thanks for subscribing")
|
||||
end
|
||||
|
||||
it "renders proper receiver" do
|
||||
email = described_class.new_membership_subscription_email(user, "level_1_member")
|
||||
expect(email.to).to eq([user.email])
|
||||
end
|
||||
|
||||
it "includes the tracking pixel" do
|
||||
email = described_class.new_membership_subscription_email(user, "level_1_member")
|
||||
expect(email.html_part.body).to include("open.gif")
|
||||
end
|
||||
|
||||
it "includes UTM params" do
|
||||
email = described_class.new_membership_subscription_email(user, "level_1_member")
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_medium=email"))
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_source=membership_mailer"))
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_campaign=new_membership_subscription_email"))
|
||||
end
|
||||
end
|
||||
|
||||
describe "#subscription_update_confirm_email" do
|
||||
it "renders proper subject" do
|
||||
email = described_class.subscription_update_confirm_email(user)
|
||||
expect(email.subject).to include("Your subscription has been updated.")
|
||||
end
|
||||
|
||||
it "renders proper receiver" do
|
||||
email = described_class.subscription_update_confirm_email(user)
|
||||
expect(email.to).to eq([user.email])
|
||||
end
|
||||
|
||||
it "includes the tracking pixel" do
|
||||
email = described_class.subscription_update_confirm_email(user)
|
||||
expect(email.html_part.body).to include("open.gif")
|
||||
end
|
||||
|
||||
it "includes UTM params" do
|
||||
email = described_class.subscription_update_confirm_email(user)
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_medium=email"))
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_source=membership_mailer"))
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_campaign=subscription_update_confirm_email"))
|
||||
end
|
||||
end
|
||||
|
||||
describe "#subscription_cancellation_email" do
|
||||
it "renders proper subject" do
|
||||
email = described_class.subscription_cancellation_email(user)
|
||||
expect(email.subject).to include("Sorry to lose you")
|
||||
end
|
||||
|
||||
it "renders proper receiver" do
|
||||
email = described_class.subscription_cancellation_email(user)
|
||||
expect(email.to).to eq([user.email])
|
||||
end
|
||||
|
||||
it "includes the tracking pixel" do
|
||||
email = described_class.subscription_cancellation_email(user)
|
||||
expect(email.html_part.body).to include("open.gif")
|
||||
end
|
||||
|
||||
it "includes UTM params" do
|
||||
email = described_class.subscription_cancellation_email(user)
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_medium=email"))
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_source=membership_mailer"))
|
||||
expect(email.html_part.body).to include(CGI.escape("utm_campaign=subscription_cancellation_email"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
class MembershipMailerPreview < ActionMailer::Preview
|
||||
def new_membership_subscription_email
|
||||
MembershipMailer.new_membership_subscription_email(User.last, "level_2_member")
|
||||
end
|
||||
|
||||
def subscription_update_confirm_email
|
||||
MembershipMailer.subscription_update_confirm_email(User.last)
|
||||
end
|
||||
|
||||
def subscription_cancellation_email
|
||||
MembershipMailer.subscription_cancellation_email(User.last)
|
||||
end
|
||||
end
|
||||
|
|
@ -12,13 +12,12 @@ RSpec.describe "StripeSubscriptions", type: :request do
|
|||
|
||||
after { StripeMock.stop }
|
||||
|
||||
def valid_instance(user = user_one, amount = 1200)
|
||||
def valid_instance(user)
|
||||
customer = Stripe::Customer.create(
|
||||
email: "stripe_tester@dev.to",
|
||||
source: stripe_helper.generate_card_token,
|
||||
)
|
||||
user.update(stripe_id_code: customer.id)
|
||||
MembershipService.new(Stripe::Customer.retrieve(user.stripe_id_code), user, amount)
|
||||
end
|
||||
|
||||
describe "POST StripeActiveCards#create" do
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "StripeCancellations", type: :request do
|
||||
let(:user) { create(:user) }
|
||||
let(:stripe_helper) { StripeMock.create_test_helper }
|
||||
|
||||
before do
|
||||
StripeMock.start
|
||||
allow_any_instance_of(StripeCancellationsController).to receive(:verify_stripe_signature).and_return(true)
|
||||
end
|
||||
|
||||
after { StripeMock.stop }
|
||||
|
||||
# rubocop:disable RSpec/ExampleLength
|
||||
it "mocks a stripe cancellation webhook" do
|
||||
customer = Stripe::Customer.create(
|
||||
email: user.email,
|
||||
source: stripe_helper.generate_card_token,
|
||||
)
|
||||
MembershipService.new(customer, user, 12).subscribe_customer
|
||||
user.reload
|
||||
expect(user.monthly_dues).not_to eq(0)
|
||||
|
||||
event = StripeMock.mock_webhook_event(
|
||||
"customer.subscription.deleted",
|
||||
customer: user.stripe_id_code, total_count: 1,
|
||||
)
|
||||
post "/stripe_cancellations", params: event.as_json
|
||||
user.reload
|
||||
expect(user.monthly_dues).to eq(0)
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
# rubocop:enable RSpec/ExampleLength
|
||||
end
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe MembershipService do
|
||||
let(:user_one) { create(:user, :super_admin) }
|
||||
let(:user_two) { create(:user, :super_admin) }
|
||||
let(:stripe_helper) { StripeMock.create_test_helper }
|
||||
let(:stripe_source_token) { stripe_helper.generate_card_token }
|
||||
|
||||
before { StripeMock.start }
|
||||
|
||||
after { StripeMock.stop }
|
||||
|
||||
def valid_instance(user = user_one, amount = 1200)
|
||||
customer = Stripe::Customer.create(
|
||||
email: "stripe_tester@dev.to",
|
||||
source: stripe_helper.generate_card_token,
|
||||
)
|
||||
user.update(stripe_id_code: customer.id)
|
||||
described_class.new(Stripe::Customer.retrieve(user.stripe_id_code), user, amount)
|
||||
end
|
||||
|
||||
describe "#find_or_create_plan" do
|
||||
it "creates a new plan if there is no previous plan" do
|
||||
expect(valid_instance.plan).to eq(Stripe::Plan.all.first)
|
||||
end
|
||||
|
||||
# it "uses an existing plan if the amount has been previously used" do
|
||||
# plan = stripe_helper.create_plan(id: "membership-1200", amount: 1200)
|
||||
# expect(valid_instance.plan).to eq(plan)
|
||||
# end
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
context "when evoked on a user that already has subscription" do
|
||||
# rubocop:disable RSpec/ExampleLength
|
||||
it "returns an object with subscription" do
|
||||
customer = Stripe::Customer.create(
|
||||
email: "stripe_tester@dev.to",
|
||||
source: stripe_source_token,
|
||||
)
|
||||
user_one.update(stripe_id_code: customer.id)
|
||||
plan = Stripe::Plan.create(
|
||||
id: "membership-1200",
|
||||
currency: "usd",
|
||||
interval: "month",
|
||||
name: "Monthly DEV Membership",
|
||||
amount: 1200,
|
||||
statement_descriptor: "DEV membership",
|
||||
)
|
||||
Stripe::Subscription.create(customer: customer.id, plan: plan.id)
|
||||
test = described_class.new(
|
||||
Stripe::Customer.retrieve(user_one.stripe_id_code), user_one, 1200
|
||||
)
|
||||
expect(test.subscription).not_to be(nil)
|
||||
end
|
||||
# rubocop:enable RSpec/ExampleLength
|
||||
end
|
||||
end
|
||||
|
||||
describe "#assign_membership_role" do
|
||||
context "when amount is 25 dollars" do
|
||||
it "adds level_3_member role" do
|
||||
valid_instance(user_one, 2500).subscribe_customer
|
||||
expect(user_one.has_role?(:level_3_member)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when amount is 10 dollars" do
|
||||
it "adds level_2_member role" do
|
||||
valid_instance(user_one, 1000).subscribe_customer
|
||||
expect(user_one.has_role?(:level_2_member)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when amount is 1 dollar" do
|
||||
it "adds level_1_member role" do
|
||||
valid_instance(user_one, 100).subscribe_customer
|
||||
expect(user_one.has_role?(:level_1_member)).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#find_subscription" do
|
||||
it "returns user's subscription" do
|
||||
new_membership = valid_instance
|
||||
new_membership.subscribe_customer
|
||||
test = described_class.new(Stripe::Customer.retrieve(user_one.stripe_id_code), user_one, 1200)
|
||||
expect(test.subscription).not_to eq(nil)
|
||||
end
|
||||
|
||||
it "returns nil if there's no subscription" do
|
||||
expect(valid_instance.subscription).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create_subscription" do
|
||||
it "creates a subscription for a user" do
|
||||
membership = valid_instance
|
||||
membership.subscribe_customer
|
||||
test = described_class.new(Stripe::Customer.retrieve(user_one.stripe_id_code), user_one, 1200)
|
||||
expect(test.subscription).not_to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue