Skip to content

Commit

Permalink
discount manager specs
Browse files Browse the repository at this point in the history
  • Loading branch information
goodviber committed Jun 11, 2018
1 parent 2237187 commit 3802c36
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 10 deletions.
6 changes: 3 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ task :run do
item1 = Product.new('001', 'Very Cheap Chair', 9.25)
item2 = Product.new('002', 'Little Table', 45.00)
item3 = Product.new('003', 'Funky Light', 19.95)
item4 = Product.new('001', 'Very Cheap Chair', 9.25)

puts "first run"

puts "first basket"

co = Checkout.new(promo_rules)
puts "scanning"
co.scan(item1)
co.scan(item2)
co.scan(item3)
co.scan(item4)


puts co.total
end
12 changes: 5 additions & 7 deletions lib/checkout.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
class Checkout
attr_reader :promo_rules
attr_reader :discount_manager
attr_accessor :basket

def initialize(promo_rules = [])
@dicount_manager = DiscountManager.new(promo_rules)
@promo_rules = promo_rules
@basket = []
end
Expand All @@ -12,16 +14,12 @@ def scan(item)
end

def total
multi_discount_price = 0
price = 0
puts basket
basket.each do |product|
promo_rules.each do |promo_rule|
if promo_rule.type == PromoRule::TYPE[:multi_discount]
multi_discount_price = promo_rule.apply(product.code, quantity_in_basket(product.code))
end
end
price += product.price
end
multi_discount_price
price.round(2)
end

def quantity_in_basket(code)
Expand Down
28 changes: 28 additions & 0 deletions lib/discount_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class DiscountManager

attr_reader :promo_rules

def initialize(promo_rules = [])
@promo_rules = promo_rules
end

def discount_price_for(product, quantity)
discount_price = 0

promo_rules.each do |promo_rule|
if promo_rule.type == PromoRule::TYPE[:multibuy_discount] #multi_discount
discount_price = promo_rule.apply(product.code, quantity)
end
end
discount_price == 0 ? product.price : discount_price
end

def discount_total(total)
promo_rules.each do |promo_rule|
if promo_rule.type == PromoRule::TYPE[:discount] # discount
total = promo_rule.apply(total)
end
end
total
end
end
40 changes: 40 additions & 0 deletions spec/checkout_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'spec_helper'

describe Checkout do
ProductStub = Struct.new(:code, :name, :price)
subject { Checkout.new }

describe "on setup" do
it 'should start with an empty basket' do
expect(subject.basket.count).to eq(0)
end
it 'should start with zero price' do
expect(subject.total).to eq(0)
end
end

context 'with no promo_rules' do
describe 'scan items' do
let(:product1) { ProductStub.new('001', 'name', 10) }
let(:product2) { ProductStub.new('002', 'here', 10) }

it 'should calculate total as the product price' do
subject.scan(product1)
subject.scan(product2)
expect(subject.total).to eq(20)
end

it 'should round total to two decimal places' do
product = ProductStub.new('001', 'name', 25.4552)
subject.scan(product)
expect(subject.total).to eq(25.46)
end
end
end

context 'with promo_rules' do
let(:product1) { ProductStub.new('001', 'name', 10) }
let(:product2) { ProductStub.new('002', 'here', 10) }
end

end
61 changes: 61 additions & 0 deletions spec/discount_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'spec_helper'

describe DiscountManager do
let(:promo_rule) {double('promo_rule')}
let(:product) { Struct.new(:code, :name, :price).new('001', 'foobar', 10.97) }
subject { DiscountManager.new([promo_rule]) }

describe '#discount_price_for' do
before do
allow(promo_rule).to receive(:type) { PromoRule::TYPE[:multibuy_discount] }
allow(promo_rule).to receive(:apply) { 60 }
end

it 'should pass the calculation to the promo_rule with params' do
expect(promo_rule).to receive(:type) { PromoRule::TYPE[:multibuy_discount] }
expect(promo_rule).to receive(:apply).with(product.code, 2)

subject.discount_price_for(product, 2)
end

it 'should return the discounted price when rule applied' do
price = subject.discount_price_for(product, 1)
expect(price).to eq(60)
end

it 'should return the original price if no rule applied' do
discount_manager = DiscountManager.new

price = discount_manager.discount_price_for(product, 1)
expect(price).to eq(product.price)
end

end

describe '#discount_total' do
before do
allow(promo_rule).to receive(:type) { PromoRule::TYPE[:discount] }
allow(promo_rule).to receive(:apply) { 100 }
end

it 'should pass the calculation to the rule with subtotal' do
expect(promo_rule).to receive(:type) { PromoRule::TYPE[:discount] }
expect(promo_rule).to receive(:apply).with(10)

subject.discount_total(10)
end

it 'should return the calculated total when rule applied' do
total = subject.discount_total(10)
expect(total).to eq(100)
end

it 'should return original subtotal if no rule match' do
discount_manager = DiscountManager.new

total = discount_manager.discount_total(10)
expect(total).to eq(10)
end

end
end

0 comments on commit 3802c36

Please sign in to comment.