This commit is contained in:
Seth Call 2015-03-24 10:19:21 -05:00
parent 04aa1a9b3c
commit 1c0407cca4
12 changed files with 364 additions and 25 deletions

View File

@ -23,7 +23,7 @@ module JamRuby
end
def has_redeemable_jamtrack
false
true
end
end
end

View File

@ -23,7 +23,7 @@ module JamRuby
end
def cart_product
self.cart_class_name.classify.constantize.find_by_id self.cart_id unless self.cart_class_name.blank?
self.cart_class_name.classify.constantize.find_by_id(self.cart_id) unless self.cart_class_name.blank?
end
def redeem(mark_redeem)
@ -60,7 +60,7 @@ module JamRuby
mark_redeem = true # start out assuming we can redeem...
any_user.shopping_carts.each do |shopping_cart|
# but if we find any shopping cart item already marked for redeem, then back out of mark_redeem=true
if shopping_cart.cart_type == product.class::PRODUCT_TYPE && shopping_cart.marked_for_redeem > 0
if shopping_cart.cart_type == JamTrack::PRODUCT_TYPE && shopping_cart.marked_for_redeem > 0
mark_redeem = false
break
end
@ -71,10 +71,24 @@ module JamRuby
# adds a jam_track to cart, checking for promotions
def self.add_jam_track_to_cart(any_user, jam_track)
cart = nil
ShoppingCart.transaction do
mark_redeem = ShoppingCart.user_has_redeemable_jam_track?(any_user)
@cart = ShoppingCart.create(any_user, jam_track, 1, mark_redeem)
# does this user already have this JamTrack in their cart? If so, don't add it.
duplicate_found = false
any_user.shopping_carts.each do |shopping_cart|
if shopping_cart.cart_type == JamTrack::PRODUCT_TYPE && shopping_cart.cart_id.to_i == jam_track.id
duplicate_found = true
return
end
end
unless duplicate_found
mark_redeem = ShoppingCart.user_has_redeemable_jam_track?(any_user)
cart = ShoppingCart.create(any_user, jam_track, 1, mark_redeem)
end
end
cart
end
# deletes a jam track from the shopping cart, updating redeem flag as necessary

View File

@ -12,7 +12,7 @@ module JamRuby
account = Recurly::Account.create(options)
raise RecurlyClientError.new(account.errors) if account.errors.any?
rescue Recurly::Error, NoMethodError => x
puts "Error: #{x} : #{Kernel.caller}"
#puts "Error: #{x} : #{Kernel.caller}"
raise RecurlyClientError, x.to_s
else
if account
@ -162,6 +162,8 @@ module JamRuby
end
end
free = false
# this means we already have a subscription, so don't try to create a new one for the same plan (Recurly would fail this anyway)
unless recurly_subscription_uuid
@ -189,11 +191,19 @@ module JamRuby
raise RecurlyClientError, "Plan code '#{paid_subscription.plan_code}' doesn't match jam track: '#{jam_track.plan_code}'" unless recurly_subscription_uuid
jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id)
jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id) do |jam_track_right|
jam_track_right.redeemed = free
end
User.where(id: current_user.id).update_all(has_redeemable_jamtrack: false) if free
# also if the purchase was a free one, then update the user record to no longer allow redeemed jamtracks
# this can't go in the block above, as it's here to fix bad subscription UUIDs in an update path
if jam_track_right.recurly_subscription_uuid != recurly_subscription_uuid
jam_track_right.recurly_subscription_uuid = recurly_subscription_uuid
jam_track_right.save
end
raise RecurlyClientError.new("Error creating jam_track_right for jam_track: #{jam_track.id}") if jam_track_right.nil?
raise RecurlyClientError.new(jam_track_right.errors) if jam_track_right.errors.any?
rescue Recurly::Error, NoMethodError => x

View File

@ -4,6 +4,7 @@ describe ShoppingCart do
let(:user) { FactoryGirl.create(:user) }
let(:jam_track) {FactoryGirl.create(:jam_track) }
let(:jam_track2) {FactoryGirl.create(:jam_track) }
before(:each) do
ShoppingCart.delete_all
@ -20,4 +21,48 @@ describe ShoppingCart do
user.shopping_carts[0].quantity.should == 1
end
it "should not add duplicate JamTrack to ShoppingCart" do
cart1 = ShoppingCart.add_jam_track_to_cart(user, jam_track)
cart1.should_not be_nil
user.reload
cart2 = ShoppingCart.add_jam_track_to_cart(user, jam_track)
cart2.should be_nil
end
describe "redeemable behavior" do
it "adds redeemable item to shopping cart" do
user.has_redeemable_jamtrack.should be_true
# first item added to shopping cart should be marked for redemption
cart = ShoppingCart.add_jam_track_to_cart(user, jam_track)
cart.marked_for_redeem.should eq(1)
# but the second item should not
user.reload
cart = ShoppingCart.add_jam_track_to_cart(user, jam_track2)
cart.marked_for_redeem.should eq(0)
end
it "removes redeemable item to shopping cart" do
user.has_redeemable_jamtrack.should be_true
cart1 = ShoppingCart.add_jam_track_to_cart(user, jam_track)
cart1.should_not be_nil
user.reload
cart2 = ShoppingCart.add_jam_track_to_cart(user, jam_track2)
cart2.should_not be_nil
cart1.marked_for_redeem.should eq(1)
cart2.marked_for_redeem.should eq(0)
ShoppingCart.remove_jam_track_from_cart(user, jam_track)
user.shopping_carts.length.should eq(1)
cart2.reload
cart1.marked_for_redeem.should eq(1)
end
end
end

View File

@ -61,6 +61,7 @@
$orderPanel.removeClass("hidden")
$thanksPanel.addClass("hidden")
$screen.find(".place-order").addClass('disabled').off('click', placeOrder)
$("#order_error").text('').addClass("hidden")
step = 3;
renderNavigation();
populateOrderPage();
@ -219,6 +220,7 @@
function placeOrder(e) {
e.preventDefault();
$screen.find(".place-order").off('click').addClass('disabled')
$("#order_error").text('').addClass("hidden")
rest.placeOrder()
.done(moveToThanks)
.fail(orderErrorHandling);

View File

@ -40,7 +40,6 @@
step = 2;
renderNavigation();
renderAccountInfo();
}
@ -49,6 +48,7 @@
$newCardInfo.removeClass('hidden');
$freeJamTrackPrompt.addClass('hidden');
$noFreeJamTrackPrompt.addClass('hidden');
$("#payment_error").addClass('hidden').text('')
var selectCountryReady = selectCountry.ready();
if(!selectCountryReady) {
@ -155,7 +155,7 @@
$paymentInfoPanel.find('.error-text').remove();
$paymentInfoPanel.find('.error').removeClass('error');
e.preventDefault();
$("#payment_error").addClass("hidden")
$("#payment_error").addClass("hidden").text('')
var reuse_card_this_time = $reuseExistingCardChk.is(':checked');
var reuse_card_next_time = $paymentMethod.find('#save-card').is(':checked');
@ -524,10 +524,13 @@
$field.addClass("error").addClass("transparent");
$accountSignup.find('.terms-of-service-label-holder').append("<ul class='error-text'><li>" + error + "</li></ul>");
}
else if(key == 'message') {
$("#payment_error").text(error).removeClass('hidden')
}
});
}
else {
$("#payment_error").text(xhr.responseText)
$("#payment_error").text(xhr.responseText).removeClass('hidden')
}

View File

@ -204,8 +204,10 @@
var user = app.user()
if(user) {
user.done(function(userProfile) {
console.log("app.layout.getCurrentScreen() != 'checkoutOrderScreen'", app.layout.getCurrentScreen())
if (userProfile.show_whats_next &&
window.location.pathname.indexOf(gon.client_path) == 0 &&
window.location.pathname.indexOf('/checkout') == -1 &&
!app.layout.isDialogShowing('getting-started'))
{
app.layout.showDialog('getting-started');

View File

@ -43,6 +43,13 @@
margin-bottom:5px;
}
#payment_error {
@include border_box_sizing;
background-color: #300;
padding: 5px;
border: solid 1px #900;
}
form.payment-info {
width: 100%;
display:block;

View File

@ -5,7 +5,6 @@ div layout="screen" layout-id="checkoutOrder" id="checkoutOrderScreen" class="sc
h1 check out
= render "screen_navigation"
.content-body
#order_error.error.hidden
.content-body-scroller
.content-wrapper
.checkout-navigation-bar
@ -23,7 +22,7 @@ div layout="screen" layout-id="checkoutOrder" id="checkoutOrderScreen" class="sc
| &nbsp;page to enter your billing info.
.order-content
#order_error.error.hidden
.clearall
.action-bar

View File

@ -5,7 +5,6 @@ div layout="screen" layout-id="checkoutPayment" id="checkoutPaymentScreen" class
h1 check out
= render "screen_navigation"
.content-body
#payment_error.error.hidden
.content-body-scroller
.content-wrapper
.checkout-navigation-bar
@ -186,13 +185,13 @@ div layout="screen" layout-id="checkoutPayment" id="checkoutPaymentScreen" class
.account-label
label for="email" Email Address:
.account-value
input name="email" type="text"
input name="email" id="checkout-signup-email" type="text"
.clearall
#divJamKazamPassword.field
.account-label
label for="email" Password:
label for="password" Password:
.account-value
input name="password" type="password"
input name="password" id="checkout-signup-password" type="password"
.clearall
#divJamKazamTos.field
.terms-of-service.ichecbuttons
@ -203,6 +202,7 @@ div layout="screen" layout-id="checkoutPayment" id="checkoutPaymentScreen" class
a rel="external" href=corp_terms_path terms of service
.clearall
.clearall
.row.third.hidden#payment_error
.clearall

View File

@ -30,7 +30,7 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
before(:all) do
Capybara.javascript_driver = :poltergeist
Capybara.current_driver = Capybara.javascript_driver
Capybara.default_wait_time = 60 # these tests are SLOOOOOW
Capybara.default_wait_time = 20 # these tests are SLOOOOOW
@recurlyClient = RecurlyClient.new
@created_accounts = []
@ -47,9 +47,6 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
before(:each) do
ShoppingCart.delete_all
JamTrack.delete_all
JamTrackTrack.delete_all
JamTrackLicensor.delete_all
User.delete_all
stub_const("APP_CONFIG", web_config)
@ -203,6 +200,29 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
user.reuse_card.should be_true
end
it "shows card error correctly" do
fast_signin(user, '/client#/checkoutPayment')
find('p.payment-prompt.free-jamtrack')
expect(page).to_not have_selector('.jamkazam-account-signup')
# fill out all billing info, but not account info
fill_in 'billing-first-name', with: 'Seth'
fill_in 'billing-last-name', with: 'Call'
fill_in 'billing-address1', with: '10704 Buckthorn Drive'
fill_in 'billing-city', with: 'Austin'
fill_in 'billing-state', with: 'Texas'
fill_in 'billing-zip', with: '78759'
fill_in 'card-number', with: '4000-0000-0000-0002'
fill_in 'card-verify', with: '012'
# try to submit, and see slew of errors
find('#payment-info-next').trigger(:click)
find('#payment_error', text:'Your transaction was declined. Please use a different card or contact your bank.')
end
it "allows billing info submit for existing user" do
fast_signin(user, '/client#/checkoutPayment')
@ -270,7 +290,6 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
it "payment shows saved card info correctly if user has billing info and reuse_card set to true" do
puts "jamtrack_acdc_backinblack #{jamtrack_acdc_backinblack}"
ShoppingCart.add_jam_track_to_cart(user, jamtrack_acdc_backinblack)
user.reuse_card = true
@ -405,8 +424,17 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
end
describe "Checkout Order" do
it "shows no billing info notice" do
fast_signin(user, '/client#/checkoutOrder')
# the user should be toldy they have a empty cart
find('p.no-account-info-prompt')
end
it "shows empty cart notice" do
@recurlyClient.create_account(user, billing_info)
fast_signin(user, '/client#/checkoutOrder')
@ -419,7 +447,7 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
# verify that both Place Your Orders are disabled
find('.order-content .place-order.disabled')
find('.order-panel .place-order.disabled')
find('.order-panel .action-bar .place-order.disabled')
end
it "shows one free item correctly" do
@ -443,26 +471,256 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
end
it "shows one free, one not free item correctly" do
ShoppingCart.add_jam_track_to_cart(user, jamtrack_acdc_backinblack)
user.reload
ShoppingCart.add_jam_track_to_cart(user, jamtrack_pearljam_evenflow)
@recurlyClient.create_account(user, billing_info)
user.reuse_card = true
user.has_redeemable_jamtrack = true
user.save!
fast_signin(user, '/client#/checkoutOrder')
find('p.order-prompt')
find('.order-items-value.order-total', text:'$1.99')
find('.order-items-value.shipping-handling', text:'$0.00')
find('.order-items-value.sub-total', text:'$1.99')
find('.order-items-value.taxes', text:'$0.00')
find('.order-items-value.grand-total', text:'$1.99')
end
it "shows one non-free item correctly" do
user.has_redeemable_jamtrack = false
user.save!
ShoppingCart.add_jam_track_to_cart(user, jamtrack_acdc_backinblack)
@recurlyClient.create_account(user, billing_info)
user.reuse_card = true
user.has_redeemable_jamtrack = true
user.save!
fast_signin(user, '/client#/checkoutOrder')
find('p.order-prompt')
find('.order-items-value.order-total', text:'$1.99')
find('.order-items-value.shipping-handling', text:'$0.00')
find('.order-items-value.sub-total', text:'$1.99')
find('.order-items-value.taxes', text:'$0.00')
find('.order-items-value.grand-total', text:'$1.99')
end
it "shows two non-free items correctly" do
user.has_redeemable_jamtrack = false
user.save!
ShoppingCart.add_jam_track_to_cart(user, jamtrack_acdc_backinblack)
user.reload
ShoppingCart.add_jam_track_to_cart(user, jamtrack_pearljam_evenflow)
@recurlyClient.create_account(user, billing_info)
user.reuse_card = true
user.has_redeemable_jamtrack = true
user.save!
fast_signin(user, '/client#/checkoutOrder')
find('p.order-prompt')
find('.order-items-value.order-total', text:'$3.98')
find('.order-items-value.shipping-handling', text:'$0.00')
find('.order-items-value.sub-total', text:'$3.98')
find('.order-items-value.taxes', text:'$0.00')
find('.order-items-value.grand-total', text:'$3.98')
find('.place-order-center a.button-orange.place-order').trigger(:click)
# and now we should see confirmation, and a notice that we are in a normal browser
find('.thanks-detail.jam-tracks-in-browser')
acdc = jamtrack_acdc_backinblack.right_for_user(user)
acdc.redeemed.should be_false
pearljam = jamtrack_pearljam_evenflow.right_for_user(user)
pearljam.redeemed.should be_false
end
it "shows purchase error correctly" do
ShoppingCart.add_jam_track_to_cart(user, jamtrack_acdc_backinblack)
@recurlyClient.create_account(user, billing_info)
user.reuse_card = true
user.save!
fast_signin(user, '/client#/checkoutOrder')
find('p.order-prompt')
# fiddle with the user's recurly-code so that the checkout fails
user.recurly_code = 'bleh'
user.save!
find('.place-order-center a.button-orange.place-order').trigger(:click)
find('#order_error', text: "Error submitting payment: message: Couldn't find Account with account_code = bleh")
end
end
describe "Complete Checkout Flow" do
it "for anonyous user" do
it "for anonymous user" do
visit "/client#/jamtrack"
find('h1', text: 'jamtracks')
find('a', text: 'What is a JamTrack?')
find("a.jamtrack-add-cart[data-jamtrack-id=\"#{jamtrack_acdc_backinblack.id}\"]").trigger(:click)
find('h1', text: 'shopping cart')
find('.cart-item-caption', text: "JamTrack: #{jamtrack_acdc_backinblack.name}")
find('.cart-item-price', text: "$ #{jamtrack_acdc_backinblack.price}")
# attempt to checkout
find('a.button-orange', text: 'PROCEED TO CHECKOUT').trigger(:click)
# we should now be on checkoutSignin
find('h3', text: 'ALREADY A MEMBER OF THE JAMKAZAM COMMUNITY?')
verify_nav(1)
# skip to payment without signing in
find('a.btnNext').trigger(:click)
# this should take us to the payment screen
find('p.payment-prompt')
find('.jamkazam-account-signup')
# fill out all billing info and account info
fill_in 'billing-first-name', with: 'Seth'
fill_in 'billing-last-name', with: 'Call'
fill_in 'billing-address1', with: '10704 Buckthorn Drive'
fill_in 'billing-city', with: 'Austin'
fill_in 'billing-state', with: 'Texas'
fill_in 'billing-zip', with: '78759'
fill_in 'card-number', with: '4111111111111111'
fill_in 'card-verify', with: '012'
fill_in 'checkout-signup-email', with: 'guy@jamkazam.com'
fill_in 'checkout-signup-password', with: 'jam123'
find('#divJamKazamTos ins.iCheck-helper').trigger(:click) # accept TOS
# try to submit, and see order page
find('#payment-info-next').trigger(:click)
# now see order page, and everything should appear free
find('p.order-prompt')
find('.order-items-value.order-total', text:'$0.00')
find('.order-items-value.shipping-handling', text:'$0.00')
find('.order-items-value.sub-total', text:'$0.00')
find('.order-items-value.taxes', text:'$0.00')
find('.order-items-value.grand-total', text:'$0.00')
# click the ORDER button
find('.place-order-center a.button-orange.place-order').trigger(:click)
# and now we should see confirmation, and a notice that we are in a normal browser
find('.thanks-detail.jam-tracks-in-browser')
guy = User.find_by_email('guy@jamkazam.com')
jam_track_right = jamtrack_acdc_backinblack.right_for_user(guy)
# make sure it appears the user actually bought the jamtrack!
jam_track_right.should_not be_nil
jam_track_right.redeemed.should be_true
guy.has_redeemable_jamtrack.should be_false
# now, go back to checkout flow again, and make sure we are told there are no free jam tracks
visit "/client#/jamtrack"
find("a.jamtrack-add-cart[data-jamtrack-id=\"#{jamtrack_pearljam_evenflow.id}\"]").trigger(:click)
find('h1', text: 'shopping cart')
find('.cart-item-caption', text: "JamTrack: #{jamtrack_pearljam_evenflow.name}")
find('.cart-item-price', text: "$ #{jamtrack_pearljam_evenflow.price}")
# attempt to checkout
find('a.button-orange', text: 'PROCEED TO CHECKOUT').trigger(:click)
# should be taken straight to order page
# now see order page, and everything should appear free
find('p.order-prompt')
find('.order-items-value.order-total', text:'$1.99')
find('.order-items-value.shipping-handling', text:'$0.00')
find('.order-items-value.sub-total', text:'$1.99')
find('.order-items-value.taxes', text:'$0.00')
find('.order-items-value.grand-total', text:'$1.99')
# click the ORDER button
find('.place-order-center a.button-orange.place-order').trigger(:click)
# and now we should see confirmation, and a notice that we are in a normal browser
find('.thanks-detail.jam-tracks-in-browser')
jam_track_right = jamtrack_pearljam_evenflow.right_for_user(guy)
# make sure it appears the user actually bought the jamtrack!
jam_track_right.should_not be_nil
jam_track_right.redeemed.should be_false
guy.has_redeemable_jamtrack.should be_false
end
it "for existing user" do
fast_signin(user, "/client#/jamtrack")
find('h1', text: 'jamtracks')
find('a', text: 'What is a JamTrack?')
find("a.jamtrack-add-cart[data-jamtrack-id=\"#{jamtrack_acdc_backinblack.id}\"]").trigger(:click)
find('h1', text: 'shopping cart')
find('.cart-item-caption', text: "JamTrack: #{jamtrack_acdc_backinblack.name}")
find('.cart-item-price', text: "$ #{jamtrack_acdc_backinblack.price}")
# attempt to checkout
find('a.button-orange', text: 'PROCEED TO CHECKOUT').trigger(:click)
# we should be skipping the signin screen, and be taken directly to payment
# this should take us to the payment screen
find('p.payment-prompt')
# fill out all billing info and account info
fill_in 'billing-first-name', with: 'Seth'
fill_in 'billing-last-name', with: 'Call'
fill_in 'billing-address1', with: '10704 Buckthorn Drive'
fill_in 'billing-city', with: 'Austin'
fill_in 'billing-state', with: 'Texas'
fill_in 'billing-zip', with: '78759'
fill_in 'card-number', with: '4111111111111111'
fill_in 'card-verify', with: '012'
# try to submit, and see order page
find('#payment-info-next').trigger(:click)
# now see order page, and everything should appear free
find('p.order-prompt')
find('.order-items-value.order-total', text:'$0.00')
find('.order-items-value.shipping-handling', text:'$0.00')
find('.order-items-value.sub-total', text:'$0.00')
find('.order-items-value.taxes', text:'$0.00')
find('.order-items-value.grand-total', text:'$0.00')
# click the ORDER button
find('.place-order-center a.button-orange.place-order').trigger(:click)
# and now we should see confirmation, and a notice that we are in a normal browser
find('.thanks-detail.jam-tracks-in-browser')
user.reload
jam_track_right = jamtrack_acdc_backinblack.right_for_user(user)
# make sure it appears the user actually bought the jamtrack!
jam_track_right.should_not be_nil
jam_track_right.redeemed.should be_true
user.has_redeemable_jamtrack.should be_false
end
end
end

View File

@ -138,6 +138,5 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
find('.shopping-sub-total', text: "Subtotal: $ #{jt_us.price + jt_ww.price}")
end
end
end