require "spec_helper"

describe Supermarket::PromotionalRules::PriceDiscountForBulkBuy do
  let(:item)        { Supermarket::Item.new(sku: :item_a, name: "Item A", price: 10) }
  let(:constraints) { {threshold: 3, discount: 2, sku: :item_a} }
  let(:subject)     { described_class.new(type: :item, constraints: constraints) }

  it "returns the original total if no items are passed" do
    expect(subject.call({total: 10})).to eq(10)
  end

  it "raises an error if threshold is invalid" do
    params = {total: 10, items: {item.sku => {}}}

    instance = described_class.new(type: :total, constraints: {})
    expect { instance.call(params) }.to raise_error(ArgumentError)

    instance = described_class.new(type: :total, constraints: {threshold: :foo})
    expect { instance.call(params) }.to raise_error(ArgumentError)
  end

  it "raises an error if discount is invalid" do
    params = {total: 10, items: {item.sku => {}}}

    instance = described_class.new(type: :total, constraints: {threshold: 10})
    expect { instance.call(params) }.to raise_error(ArgumentError)

    instance = described_class.new(type: :total, constraints: {threshold: 10, discount: :foo})
    expect { instance.call(params) }.to raise_error(ArgumentError)
  end

  it "raises an error if sku is invalid" do
    params = {total: 10, items: {item.sku => {}}}

    instance = described_class.new(type: :total, constraints: {threshold: 10, discount: 10})
    expect { instance.call(params) }.to raise_error(ArgumentError)
  end

  it "returns the original total if items list is empty" do
    items = {}
    expect(subject.call({total: 10, items: items})).to eq(10)
  end

  it "returns the original total if item with sku is not in the list" do
    items = {item_b: {}}
    expect(subject.call({total: 10, items: items})).to eq(10)
  end

  it "returns the original total if constraints are not met" do
    items = {item_a: {item: item, quantity: 2}} 
    expect(subject.call({total: 10, items: items})).to eq(10)
  end

  it "returns a new value with the discount applied" do
    items = {item_a: {item: item, quantity: 10}} 
    expect(subject.call({total: 100, items: items})).to eq(80)
  end
end
