Skip to content

Instantly share code, notes, and snippets.

@ktusznio
Created January 15, 2013 21:22
Show Gist options
  • Save ktusznio/4542195 to your computer and use it in GitHub Desktop.
Save ktusznio/4542195 to your computer and use it in GitHub Desktop.
describe Purchase do
let(:have_1) { FactoryGirl.build_stubbed(:have, asking_price: 15) }
let(:have_2) { FactoryGirl.build_stubbed(:have, asking_price: 20) }
describe "#amount_for_haves" do
let(:amount_for_haves) { purchase.amount_for_haves([have_1, have_2], credit, promo) }
let(:credit) { 0 }
let(:expected_amount_for_haves) do
# Order haves by asking_price, high to low.
have_2_expected_amount_hash.merge(have_1_expected_amount_hash)
end
let(:have_1) { create(:have, asking_price: 15) }
let(:have_1_expected_amount_hash) { expected_amount_hash(have_1) }
let(:have_2) { create(:have, asking_price: 20) }
let(:have_2_expected_amount_hash) { expected_amount_hash(have_2) }
let(:promo) do
if promo_type && promo_value
create(:promo_code, code: "CAT", promo_type: promo_type, value: promo_value)
end
end
let(:promo_type) { nil }
let(:promo_value) { nil }
let(:purchase) { create(:purchase) }
def expected_amount_hash have
{
have.id => {
flip: {
amount: have.current_price_in_cents,
buyer_shipping_cents: have.buyer_shipping.in_cents,
credit_cents: 0,
discount_cents: 0,
promo_code_id: nil,
seller_id: have.user.id,
seller_shipping_cents: have.seller_shipping.in_cents
},
payment: {
amount: have.current_price_in_cents + have.buyer_shipping.in_cents
}
}
}
end
shared_examples_for "any amount_for_haves" do
it "calculates the amount correctly" do
amount_for_haves.should == expected_amount_for_haves
end
end
context "with no discount and no credit" do
let(:promo) { nil }
it_behaves_like "any amount_for_haves"
end
context "with a flat promo" do
let(:promo_type) { :discount }
context "of value less than any have" do
let(:promo_value) { 100 }
# Expect the promo to be applied to have_2's flip since it has the greater asking price.
let(:have_2_expected_amount_hash) do
hash = expected_amount_hash(have_2)
hash[have_2.id][:flip].merge!({
discount_cents: promo.value,
promo_code_id: promo.id
})
hash[have_2.id][:payment].merge!({
amount: have_2.current_price_in_cents + have_2.buyer_shipping.in_cents - promo.value
})
hash
end
it_behaves_like "any amount_for_haves"
end
context "of value greater than a have" do
let(:promo_value) { 100 + have_2.total_price.in_cents }
# Expect the promo to fully cover have_2's total price, and part of have_1's total price.
let(:have_1_expected_amount_hash) do
hash = expected_amount_hash(have_1)
hash[have_1.id][:flip].merge!({
discount_cents: promo.value - have_2.total_price.in_cents,
promo_code_id: promo.id
})
hash[have_1.id][:payment].merge!({
amount: have_1.total_price.in_cents - (promo.value - have_2.total_price.in_cents)
})
hash
end
let(:have_2_expected_amount_hash) do
hash = expected_amount_hash(have_2)
hash[have_2.id][:flip].merge!({
discount_cents: have_2.total_price.in_cents,
promo_code_id: promo.id
})
hash[have_2.id][:payment].merge!(amount: 0)
hash
end
it_behaves_like "any amount_for_haves"
end
end
context "with a percent off promo" do
let(:promo_type) { :percent_off }
let(:promo_value) { 20 }
# Expect the promo to be applied to both flips.
let(:have_1_expected_amount_hash) do
discount = (have_1.current_price_in_cents + have_1.buyer_shipping.in_cents) * 0.2
hash = expected_amount_hash(have_1)
hash[have_1.id][:flip].merge!({
discount_cents: discount,
promo_code_id: promo.id
})
hash[have_1.id][:payment].merge!({
amount: have_1.current_price_in_cents + have_1.buyer_shipping.in_cents - discount
})
hash
end
let(:have_2_expected_amount_hash) do
discount = (have_2.current_price_in_cents + have_2.buyer_shipping.in_cents) * 0.2
hash = expected_amount_hash(have_2)
hash[have_2.id][:flip].merge!({
discount_cents: discount,
promo_code_id: promo.id
})
hash[have_2.id][:payment].merge!({
amount: have_2.current_price_in_cents + have_2.buyer_shipping.in_cents - discount
})
hash
end
it_behaves_like "any amount_for_haves"
end
context "with a credit" do
let(:credit) { 100 }
# Expect the credit to be applied to have_2's flip since it has the greater asking price.
let(:have_2_expected_amount_hash) do
hash = expected_amount_hash(have_2)
hash[have_2.id][:flip].merge!({
credit_cents: credit
})
hash[have_2.id][:payment].merge!({
amount: have_2.current_price_in_cents + have_2.buyer_shipping.in_cents - credit
})
hash
end
it_behaves_like "any amount_for_haves"
end
context "with a credit and flat discount" do
let(:promo_type) { :discount }
context "where credit and discount aren't enough to cover the most expensive have" do
let(:credit) { 100 }
let(:promo_value) { 100 }
let(:have_2_expected_amount_hash) do
hash = expected_amount_hash(have_2)
hash[have_2.id][:flip].merge!({
credit_cents: credit,
discount_cents: promo.value,
promo_code_id: promo.id
})
hash[have_2.id][:payment].merge!({
amount: have_2.current_price_in_cents + have_2.buyer_shipping.in_cents - promo.value - credit
})
hash
end
it_behaves_like "any amount_for_haves"
end
context "where credit and discount are enough to cover both haves" do
let(:credit) { 6000 }
let(:promo_value) { 1000 }
# Expect the promo to be applied to both flips.
let(:have_1_expected_amount_hash) do
hash = expected_amount_hash(have_1)
hash[have_1.id][:flip].merge!({
credit_cents: have_1.total_price.in_cents
})
hash[have_1.id][:payment].merge!(amount: 0)
hash
end
let(:have_2_expected_amount_hash) do
discount = (have_2.current_price_in_cents + have_2.buyer_shipping.in_cents) * 0.2
hash = expected_amount_hash(have_2)
hash[have_2.id][:flip].merge!({
credit_cents: have_2.total_price.in_cents - promo.value,
discount_cents: promo.value,
promo_code_id: promo.id
})
hash[have_2.id][:payment].merge!(amount: 0)
hash
end
it_behaves_like "any amount_for_haves"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment