This commit is contained in:
Seth Call 2015-03-20 16:15:13 -05:00
parent 3cb706495e
commit f29a9d7465
7 changed files with 270 additions and 56 deletions

View File

@ -8,7 +8,7 @@ module JamRuby
validates :cart_id, presence: true
validates :cart_type, presence: true
validates :cart_class_name, presence: true
validates :marked_for_redeem, :inclusion => {:in => [true, false]}
validates :marked_for_redeem, numericality: {only_integer: true}
default_scope order('created_at DESC')

View File

@ -38,6 +38,8 @@ module JamRuby
def get_account(current_user)
current_user && current_user.recurly_code ? Recurly::Account.find(current_user.recurly_code) : nil
rescue Recurly::Error => x
raise RecurlyClientError, x.to_s
end
def update_account(current_user, billing_info=nil)

View File

@ -221,7 +221,7 @@
else {
$("#order_error").text(xhr.responseText).removeClass("hidden")
}
$orderContent.find(".place-order").on('click', placeOrder)
$screen.find(".place-order").on('click', placeOrder).removeClass('disabled')
}
function moveToThanks(purchaseResponse) {

View File

@ -61,13 +61,22 @@
if(user) {
user.done(populateAccountInfo).error(app.ajaxError);
}
else {
$reuseExistingCardChk.iCheck('uncheck').attr('checked', false)
if(gon.global.one_free_jamtrack_per_user) {
$freeJamTrackPrompt.removeClass('hidden')
}
else {
$noFreeJamTrackPrompt.removeClass('hidden')
}
}
})
}
function populateAccountInfo(user) {
userDetail = user;
$reuseExistingCardChk.iCheck(userDetail.reuse_card ? 'check' : 'uncheck').attr('checked', userDetail.reuse_card)
$reuseExistingCardChk.iCheck(userDetail.reuse_card && userDetail.has_recurly_account ? 'check' : 'uncheck').attr('checked', userDetail.reuse_card)
// show appropriate prompt text based on whether user has a free jamtrack
if(user.free_jamtrack) {
@ -151,7 +160,6 @@
var reuse_card_this_time = $reuseExistingCardChk.is(':checked');
var reuse_card_next_time = $paymentMethod.find('#save-card').is(':checked');
// validation
var billing_first_name = $billingInfo.find("#billing-first-name").val();
var billing_last_name = $billingInfo.find("#billing-last-name").val();
@ -162,13 +170,14 @@
var billing_zip = $billingInfo.find("#billing-zip").val();
var billing_country = $billingInfo.find("#billing-country").val();
var billingInfoValid = true;
if (!billing_first_name) {
$billingInfo.find('#divBillingFirstName .error-text').remove();
$billingInfo.find('#divBillingFirstName').addClass("error");
$billingInfo.find('#divBillingFirstName').addClass("error").addClass("transparent");
$billingInfo.find('#billing-first-name').after("<ul class='error-text'><li>First Name is required</li></ul>");
logger.info("no billing first name");
return false;
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingFirstName').removeClass("error");
@ -176,11 +185,11 @@
if (!billing_last_name) {
$billingInfo.find('#divBillingLastName .error-text').remove();
$billingInfo.find('#divBillingLastName').addClass("error");
$billingInfo.find('#divBillingLastName').addClass("error").addClass("transparent");
$billingInfo.find('#billing-last-name').after("<ul class='error-text'><li>Last Name is required</li></ul>");
logger.info("no billing last name");
return false;
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingLastName').removeClass("error");
@ -188,11 +197,11 @@
if (!billing_address1) {
$billingInfo.find('#divBillingAddress1 .error-text').remove();
$billingInfo.find('#divBillingAddress1').addClass("error");
$billingInfo.find('#divBillingAddress1').addClass("error").addClass("transparent");
$billingInfo.find('#billing-address1').after("<ul class='error-text'><li>Address is required</li></ul>");
logger.info("no billing address line 1");
return false;
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingAddress1').removeClass("error");
@ -200,11 +209,11 @@
if (!billing_zip) {
$billingInfo.find('#divBillingZip .error-text').remove();
$billingInfo.find('#divBillingZip').addClass("error");
$billingInfo.find('#billing-zip').after("<ul class='error-text'><li>Zip code is required</li></ul>");
$billingInfo.find('#divBillingZip').addClass("error").addClass("transparent");
$billingInfo.find('#billing-zip').after("<ul class='error-text'><li>Zip Code is required</li></ul>");
logger.info("no billing address line 2");
return false;
logger.info("no billing zip");
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingZip').removeClass("error");
@ -212,11 +221,11 @@
if (!billing_state) {
$billingInfo.find('#divBillingState .error-text').remove();
$billingInfo.find('#divBillingState').addClass("error");
$billingInfo.find('#billing-zip').after("<ul class='error-text'><li>State is required</li></ul>");
$billingInfo.find('#divBillingState').addClass("error").addClass("transparent");
$billingInfo.find('#billing-state').after("<ul class='error-text'><li>State is required</li></ul>");
logger.info("no billing zip");
return false;
logger.info("no billing state");
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingState').removeClass("error");
@ -224,11 +233,11 @@
if (!billing_city) {
$billingInfo.find('#divBillingCity .error-text').remove();
$billingInfo.find('#divBillingCity').addClass("error");
$billingInfo.find('#divBillingCity').addClass("error").addClass("transparent");
$billingInfo.find('#billing-city').after("<ul class='error-text'><li>City is required</li></ul>");
logger.info("no billing city");
return false;
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingCity').removeClass("error");
@ -236,11 +245,11 @@
if (!billing_country) {
$billingInfo.find('#divBillingCountry .error-text').remove();
$billingInfo.find('#divBillingCountry').addClass("error");
$billingInfo.find('#divBillingCountry').addClass("error").addClass("transparent");
$billingInfo.find('#billing-country').after("<ul class='error-text'><li>Country is required</li></ul>");
logger.info("no billing country");
return false;
billingInfoValid = false;
}
else {
$billingInfo.find('#divBillingCountry').removeClass("error");
@ -263,7 +272,7 @@
if (!shipping_first_name) {
$shippingAddress.find('#divShippingFirstName .error-text').remove();
$shippingAddress.find('#divShippingFirstName').addClass("error");
$shippingAddress.find('#divShippingFirstName').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-first-name').after("<ul class='error-text'><li>First Name is required</li></ul>");
logger.info("no address first name");
@ -275,7 +284,7 @@
if (!shipping_last_name) {
$shippingAddress.find('#divShippingLastName .error-text').remove();
$shippingAddress.find('#divShippingLastName').addClass("error");
$shippingAddress.find('#divShippingLastName').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-last-name').after("<ul class='error-text'><li>Last Name is required</li></ul>");
logger.info("no last name");
@ -287,7 +296,7 @@
if (!shipping_address1) {
$shippingAddress.find('#divShippingAddress1 .error-text').remove();
$shippingAddress.find('#divShippingAddress1').addClass("error");
$shippingAddress.find('#divShippingAddress1').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-address1').after("<ul class='error-text'><li>Address is required</li></ul>");
logger.info("no shipping address 1");
@ -299,7 +308,7 @@
if (!shipping_zip) {
$shippingAddress.find('#divShippingZip .error-text').remove();
$shippingAddress.find('#divShippingZip').addClass("error");
$shippingAddress.find('#divShippingZip').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-zip').after("<ul class='error-text'><li>Zip code is required</li></ul>");
logger.info("no shipping address 2");
@ -311,7 +320,7 @@
if (!shipping_state) {
$shippingAddress.find('#divShippingState .error-text').remove();
$shippingAddress.find('#divShippingState').addClass("error");
$shippingAddress.find('#divShippingState').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-zip').after("<ul class='error-text'><li>State is required</li></ul>");
logger.info("no shipping state");
@ -323,7 +332,7 @@
if (!shipping_city) {
$shippingAddress.find('#divShippingCity .error-text').remove();
$shippingAddress.find('#divShippingCity').addClass("error");
$shippingAddress.find('#divShippingCity').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-city').after("<ul class='error-text'><li>City is required</li></ul>");
logger.info("no shipping city");
@ -335,7 +344,7 @@
if (!shipping_country) {
$shippingAddress.find('#divShippingCountry .error-text').remove();
$shippingAddress.find('#divShippingCountry').addClass("error");
$shippingAddress.find('#divShippingCountry').addClass("error").addClass("transparent");
$shippingAddress.find('#shipping-country').after("<ul class='error-text'><li>Country is required</li></ul>");
logger.info("no shipping country");
@ -356,7 +365,7 @@
/**
if (!card_name) {
$paymentMethod.find('#divCardName .error-text').remove();
$paymentMethod.find('#divCardName').addClass("error");
$paymentMethod.find('#divCardName').addClass("error").addClass("transparent");
$paymentMethod.find('#card-name').after("<ul class='error-text'><li>Card Name is required</li></ul>");
return false;
} else {
@ -367,48 +376,54 @@
if(!reuse_card_this_time) {
if (!card_number) {
$paymentMethod.find('#divCardNumber .error-text').remove();
$paymentMethod.find('#divCardNumber').addClass("error");
$paymentMethod.find('#divCardNumber').addClass("error").addClass("transparent");
$paymentMethod.find('#card-number').after("<ul class='error-text'><li>Card Number is required</li></ul>");
logger.info("no card number");
return false;
billingInfoValid = false;
} else if (!$.payment.validateCardNumber(card_number)) {
$paymentMethod.find('#divCardNumber .error-text').remove();
$paymentMethod.find('#divCardNumber').addClass("error");
$paymentMethod.find('#divCardNumber').addClass("error").addClass("transparent");
$paymentMethod.find('#card-number').after("<ul class='error-text'><li>Card Number is not valid</li></ul>");
logger.info("invalid card number");
return false;
billingInfoValid = false;
} else {
$paymentMethod.find('#divCardNumber').removeClass("error");
}
if (!$.payment.validateCardExpiry(card_month, card_year)) {
$paymentMethod.find('#divCardExpiry .error-text').remove();
$paymentMethod.find('#divCardExpiry').addClass("error");
$paymentMethod.find('#divCardExpiry').addClass("error").addClass("transparent");
$paymentMethod.find('#card-expiry').after("<ul class='error-text'><li>Card Number is not valid</li></ul>");
logger.info("invalid card expiry");
return false;
billingInfoValid = false;
} else {
$paymentMethod.find('#divCardExpiry').removeClass("error");
}
if (!card_verify) {
$paymentMethod.find('#divCardVerify .error-text').remove();
$paymentMethod.find('#divCardVerify').addClass("error");
$paymentMethod.find('#divCardVerify').addClass("error").addClass("transparent");
$paymentMethod.find('#card-verify').after("<ul class='error-text'><li>Card Verification Value is required</li></ul>");
logger.info("no card verify");
return false;
billingInfoValid = false;
} else if (!$.payment.validateCardCVC(card_verify)) {
$paymentMethod.find('#divCardVerify .error-text').remove();
$paymentMethod.find('#divCardVerify').addClass("error");
$paymentMethod.find('#divCardVerify').addClass("error").addClass("transparent");
$paymentMethod.find('#card-verify').after("<ul class='error-text'><li>Card Verification Value is not valid.</li></ul>");
logger.info("bad card CVC");
return false;
billingInfoValid = false;
} else {
$paymentMethod.find('#divCardVerify').removeClass("error");
}
}
if(!billingInfoValid) {
logger.debug("billing info is invalid. returning");
return false;
}
billing_info = {};
shipping_info = {};
billing_info.first_name = billing_first_name;
@ -480,34 +495,34 @@
$.each(xhr.responseJSON.errors, function(key, error) {
if (key == 'number') {
$paymentMethod.find('#divCardNumber .error-text').remove();
$paymentMethod.find('#divCardNumber').addClass("error");
$paymentMethod.find('#divCardNumber').addClass("error").addClass("transparent");
$paymentMethod.find('#card-number').after("<ul class='error-text'><li>" + error + "</li></ul>");
}
else if (key == 'verification_value') {
$paymentMethod.find('#divCardVerify .error-text').remove();
$paymentMethod.find('#divCardVerify').addClass("error");
$paymentMethod.find('#divCardVerify').addClass("error").addClass("transparent");
$paymentMethod.find('#card-verify').after("<ul class='error-text'><li>" + error + "</li></ul>");
}
else if(key == 'email') {
var $email = $accountSignup.find('input[name="email"]')
var $field = $email.closest('.field')
$field.find('.error-text').remove()
$field.addClass("error");
$field.append("<ul class='error-text'><li>" + error + "</li></ul>");
$field.addClass("error").addClass("transparent");
$email.after("<ul class='error-text'><li>" + error + "</li></ul>");
}
else if(key == 'password') {
var $password = $accountSignup.find('input[name="password"]')
var $field = $password.closest('.field')
$field.find('.error-text').remove()
$field.addClass("error");
$field.append("<ul class='error-text'><li>" + error + "</li></ul>");
$field.addClass("error").addClass("transparent");
$password.after("<ul class='error-text'><li>" + error + "</li></ul>");
}
else if(key == 'terms_of_service') {
var $terms = $accountSignup.find('input[name="terms-of-service"]')
var $field = $terms.closest('.field')
$field.find('.error-text').remove()
$field.addClass("error");
$field.append("<ul class='error-text'><li>" + error + "</li></ul>");
$field.addClass("error").addClass("transparent");
$accountSignup.find('.terms-of-service-label-holder').append("<ul class='error-text'><li>" + error + "</li></ul>");
}
});
}

View File

@ -16,6 +16,16 @@
line-height:125%;
}
.field.error {
background-color: transparent !important;
padding: 0 !important;
border-width:0 !important;
li {
list-style:none;
}
}
h2 {
color:white;
background-color:#4d4d4d;

View File

@ -392,6 +392,24 @@ textarea {
padding:5px;
border: solid 1px #900;
.error-text {
display:block;
font-size:11px;
color:#F00;
margin:10px 0 0;
}
&.transparent {
background-color:transparent;
padding:0;
border-width:0px;
.error-text {
margin:5px 0 0;
font-size:14px;
font-weight:bold;
}
}
}
.error input {
@ -403,12 +421,6 @@ textarea {
display:none;
}
.error .error-text {
display:block;
font-size:11px;
color:#F00;
margin:10px 0 0;
}
.grey {
color:#999;
}

View File

@ -17,33 +17,63 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
JamTrack.delete_all
JamTrackTrack.delete_all
JamTrackLicensor.delete_all
User.delete_all
stub_const("APP_CONFIG", web_config)
end
def verify_nav(selected)
3.times do |i|
badge = i + 1
if i == selected
find('.badge-number', text:badge)
else
find('.badge-number.disabled', text:badge)
end
end
end
describe "Checkout Signin" do
it "allows user to log in" do
it "allows user to log in on the signin page" do
visit '/client#/checkoutSignin'
find('h3', text: 'ALREADY A MEMBER OF THE JAMKAZAM COMMUNITY?')
verify_nav(1)
# try a bogus user/pass first
fill_in "email", with: user.email
fill_in "password", with: 'wrong'
find('.signin-submit').trigger(:click)
find('.login-error-msg', text: 'Invalid login')
# try successfully
fill_in "email", with: user.email
fill_in "password", with: user.password
find('.signin-submit').trigger(:click)
# this should take us to the payment screen
find('p.payment-prompt')
end
it "allows user to skip login and go to payment screen" do
visit '/client#/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')
end
it "indicates already logged in" do
@ -51,6 +81,9 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
# verify that the signin page shows, but indicates to the user that they are already signed in
find('h3', text: 'YOU ARE ALREADY LOGGED IN')
verify_nav(1)
find('p.carry-on-prompt', text: 'You can move on to the next step of checkout.')
# let them move on to the next step
@ -59,4 +92,146 @@ describe "Checkout", :js => true, :type => :feature, :capybara_feature => true d
end
end
describe "Checkout Payment" do
it "allows anonymous to visit" do
visit '/client#/checkoutPayment'
find('p.payment-prompt.free-jamtrack')
find('.jamkazam-account-signup')
# try to submit, and see slew of errors
find('#payment-info-next').trigger(:click)
find('#divBillingFirstName.error .error-text', text: 'First Name is required')
find('#divBillingLastName.error .error-text', text: 'Last Name is required')
find('#divBillingAddress1.error .error-text', text: 'Address is required')
find('#divBillingCity.error .error-text', text: 'City is required')
find('#divBillingState.error .error-text', text: 'State is required')
find('#divBillingZip.error .error-text', text: 'Zip Code is required')
find('#divCardNumber.error .error-text', text: 'Card Number is required')
find('#divCardVerify.error .error-text', text: 'Card Verification Value is required')
# 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: '4111111111111111'
fill_in 'card-verify', with: '012'
# try to submit, and see new account errors
find('#payment-info-next').trigger(:click)
find('#divJamKazamEmail.error .error-text', text: "can't be blank,is invalid")
find('#divJamKazamPassword.error .error-text', text: "is too short (minimum is 6 characters)")
find('#divJamKazamTos.error .error-text', text: "must be accepted")
# verify that all filled out fields have had errors removed
find('#divBillingFirstName').has_no_css?('.error')
find('#divBillingLastName').has_no_css?('.error')
find('#divBillingAddress1').has_no_css?('.error')
find('#divBillingCity').has_no_css?('.error')
find('#divBillingState').has_no_css?('.error')
find('#divBillingZip').has_no_css?('.error')
find('#divCardNumber').has_no_css?('.error')
find('#divCardVerify').has_no_css?('.error')
# fill in user/email/tos
fill_in 'email', with: 'seth@jamkazam.com'
fill_in '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)
# find empty shopping cart prompt notice
find('p.empty-cart-prompt')
user.reload
user.reuse_card.should be_true
end
it "allows billing info submit for existing user" do
fast_signin(user, '/client#/checkoutPayment')
find('p.payment-prompt.free-jamtrack')
expect(page).to_not have_selector('.jamkazam-account-signup')
# try to submit, and see slew of errors
find('#payment-info-next').trigger(:click)
find('#divBillingAddress1.error .error-text', text: 'Address is required')
find('#divBillingZip.error .error-text', text: 'Zip Code is required')
find('#divCardNumber.error .error-text', text: 'Card Number is required')
find('#divCardVerify.error .error-text', text: 'Card Verification Value is required')
# 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: '4111111111111111'
fill_in 'card-verify', with: '012'
# try to submit, and see order page
find('#payment-info-next').trigger(:click)
# find empty shopping cart prompt notice
find('p.empty-cart-prompt')
user.reload
user.reuse_card.should be_true
end
it "allows user to specify don't save card" 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: '4111111111111111'
fill_in 'card-verify', with: '012'
find('.save-card-checkbox ins.iCheck-helper').trigger(:click) # don't accept re-use card default
# try to submit, and see order page
find('#payment-info-next').trigger(:click)
# find empty shopping cart prompt notice
find('p.empty-cart-prompt')
user.reload
user.reuse_card.should be_false
end
it "payment shows saved card info correctly if user has billing info and reuse_card set to true" do
user.reuse_card = true
user.recurly_code = user.id
user.has_redeemable_jamtrack = false
user.save!
fast_signin(user, '/client#/checkoutPayment')
find('p.payment-prompt.no-free-jamtrack')
end
end
end