diff --git a/lib/online_order.rb b/lib/online_order.rb new file mode 100644 index 00000000..6bd7aad7 --- /dev/null +++ b/lib/online_order.rb @@ -0,0 +1,73 @@ +# online order +require 'awesome_print' +require 'csv' +require_relative "order.rb" +require 'pry' + +#example + +module Grocery + + class OnlineOrder < Order + + attr_reader :id, :products, :customer_id, :fulfillment_status + + def initialize(id, products, customer_id, fulfillment_status) + @id = id + @products = products + @customer_id = customer_id + @fulfillment_status = fulfillment_status.to_sym + + # tip from Katie: 16 and 22 are the customer id's that exsit but do not have orders + end + + def self.all + array_of_orders = [] + CSV.open("support/online_orders.csv", 'r').each do |line| + customer_id = line[2] + fulfillment_status = line[3].to_sym + product_list = line[1].split(';') + product_hash = {} + product_list.each do |item| + product = item.split(':') + product_hash[product[0]] = product[1] + end + array_of_orders << Grocery::OnlineOrder.new(line[0].to_i, product_hash, customer_id, fulfillment_status) + end + array_of_orders + end + + # (shouldn't need to rewrite out a new self.find method since it inherits from Order class and should work the same.) + + def self.find_by_customer(customer_id) + + OnlineOrder.all.each do |single_order| + order_list = [] + if single_order[2] == customer_id + order_list << single_order + end + return order_list + end + end + + def total + shipping_fee = 10.0 + return super + shipping_fee + end + + def add_product(product_name, product_price) + if @status == :pending || @status == :paid + return false if @products.has_key?(product_name) + @products[product_name] = product_price + return true + else + raise ArgumentError.new("Status is neither pending nor paid") + end + end + + end # end of OnlineOrder Class + + + + +end # end of Module Class diff --git a/lib/order.rb b/lib/order.rb index c567a484..17751392 100644 --- a/lib/order.rb +++ b/lib/order.rb @@ -1,18 +1,90 @@ +require 'awesome_print' +require 'csv' + + + +# manually choose the data from the first line of the CSV file and ensure you can create a new instance of your Order using that data + module Grocery + + class Order attr_reader :id, :products + # id: Integer, represents unique identifier + # input_products: hash that represents products with keys of product name and values of price (Float) def initialize(id, products) @id = id @products = products end + # "../support/orders.csv " #change path back to this when opening this file in ruby instead of through rake + + + def self.all + array_of_orders = [] + CSV.open("support/orders.csv", 'r').each do |line| + # for each line I need to take the index[0] and make it a key of a hash and the value of that hash is then another hash (which is index[1] of the array) with key: product name , value: product price + # first step is turning two elements of an array into a hash. second step is taking the value of that hash and turning it into another hash + + product_list = line[1].split(';') + product_hash = {} + product_list.each do |item| + product = item.split(':') + product_hash[product[0]] = product[1] + end + array_of_orders << Grocery::Order.new(line[0].to_i, product_hash) + end + array_of_orders + end + + def self.find(id) + # returns an instance of Order where the value of the id field in the CSV matches the passed parameter. + #to call this Class method: Grocery::Order.find(id) + + all_orders = Grocery::Order.all + + order = nil + + all_orders.each do |single_order| + + if single_order.id == id + order = single_order + end + end + return order + end + + + def total - # TODO: implement total + subtotal = @products.values.sum + sum = subtotal + (subtotal * 0.075).round(2) + return sum end def add_product(product_name, product_price) - # TODO: implement add_product + + return false if @products.has_key?(product_name) + @products[product_name] = product_price + return true + end #end of add_product method + + + # • Add a remove_product method to the Order class which will take in one parameter, a product name, and remove the product from the collection + # It should return true if the item was successfully remove and false if it was not + + def remove_product(product_name) + #p @products + if @products.key?(product_name) + @products.delete(product_name) + return true + else + return false + end end - end -end + + end #end of Order class + + +end #end of module diff --git a/specs/online_order_spec.rb b/specs/online_order_spec.rb index 41683558..7aa57fec 100644 --- a/specs/online_order_spec.rb +++ b/specs/online_order_spec.rb @@ -3,7 +3,7 @@ require 'minitest/skip_dsl' # TODO: uncomment the next line once you start wave 3 -# require_relative '../lib/online_order' +require_relative '../lib/online_order' # You may also need to require other classes here # Because an OnlineOrder is a kind of Order, and we've @@ -11,80 +11,106 @@ # we effectively get all that testing for free! Here we'll # only test things that are different. -xdescribe "OnlineOrder" do +describe "OnlineOrder" do describe "#initialize" do it "Is a kind of Order" do - # Check that an OnlineOrder is in fact a kind of Order + all_orders = Grocery::OnlineOrder.all - # Instatiate your OnlineOrder here - # online_order = - # online_order.must_be_kind_of Grocery::Order - end + all_orders.class.must_equal Array - it "Can access Customer object" do - # TODO: Your test code here! - end + all_orders.each do |order| + order.must_be_instance_of Grocery::OnlineOrder + end - it "Can access the online order status" do - # TODO: Your test code here! + all_orders.count.must_equal 100 end end - describe "#total" do - it "Adds a shipping fee" do - # TODO: Your test code here! - end + xit "Can access Customer object" do + # TODO: I did not create a Customer class. + end + + it "Can access the online order status" do + + all_orders = Grocery::OnlineOrder.all + + all_orders[0][3].must_be_kind_of Symbol - it "Doesn't add a shipping fee if there are no products" do - # TODO: Your test code here! - end end +end - describe "#add_product" do - it "Does not permit action for processing, shipped or completed statuses" do - # TODO: Your test code here! - end +xdescribe "#total" do + xit "Adds a shipping fee" do + # TODO: Your test code here! + end - it "Permits action for pending and paid satuses" do - # TODO: Your test code here! - end + xit "Doesn't add a shipping fee if there are no products" do + # TODO: Your test code here! end +end - describe "OnlineOrder.all" do - it "Returns an array of all online orders" do - # TODO: Your test code here! - end +xdescribe "#add_product" do + xit "Does not permit action for processing, shipped or completed statuses" do + # TODO: Your test code here! + end - it "Returns accurate information about the first online order" do - # TODO: Your test code here! - end + xit "Permits action for pending and paid satuses" do + # TODO: Your test code here! + end +end - it "Returns accurate information about the last online order" do - # TODO: Your test code here! +xdescribe "OnlineOrder.all" do + it "Returns an array of all online orders" do + all_orders = Grocery::OnlineOrder.all + # all_orders.must_be_kind_of Array + all_orders.class.must_equal Array + + all_orders.each do |order| + order.must_be_instance_of Grocery::OnlineOrder end + + all_orders.count.must_equal 100 end - describe "OnlineOrder.find" do - it "Will find an online order from the CSV" do - # TODO: Your test code here! - end - it "Raises an error for an online order that doesn't exist" do - # TODO: Your test code here! - end +it "Returns accurate information about the first online order" do + all_orders = Grocery::OnlineOrder.all + + all_orders[0].id.must_equal 1 + + all_orders[0].products.must_be_kind_of Hash +end + +it "Returns accurate information about the last online order" do + all_orders = Grocery::OnlineOrder.all + + all_orders[-1].id.must_equal 100 + all_orders[-1].products.must_be_kind_of Hash + +end + +end + +xdescribe "OnlineOrder.find" do + xit "Will find an online order from the CSV" do + # TODO: Your test code here! end - describe "OnlineOrder.find_by_customer" do - it "Returns an array of online orders for a specific customer ID" do - # TODO: Your test code here! - end + xit "Raises an error for an online order that doesn't exist" do + # TODO: Your test code here! + end +end - it "Raises an error if the customer does not exist" do - # TODO: Your test code here! - end +xdescribe "OnlineOrder.find_by_customer" do + xit "Returns an array of online orders for a specific customer ID" do + Grocery::OnlineOrder.find(1).must_be_instance_of Grocery::OnlineOrder + end - it "Returns an empty array if the customer has no orders" do - # TODO: Your test code here! - end + xit "Raises an error if the customer does not exist" do + # TODO: Your test code here! + end + + xit "Returns an empty array if the customer has no orders" do + Grocery::OnlineOrder.find_by_customer(22).must_be_empty end end diff --git a/specs/order_spec.rb b/specs/order_spec.rb index 86077dcf..73b9ae3e 100644 --- a/specs/order_spec.rb +++ b/specs/order_spec.rb @@ -1,8 +1,11 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require 'pry' require_relative '../lib/order' +Minitest::Reporters.use! + describe "Order Wave 1" do describe "#initialize" do it "Takes an ID and collection of products" do @@ -38,12 +41,17 @@ describe "#add_product" do it "Increases the number of products" do + # Arrange products = { "banana" => 1.99, "cracker" => 3.00 } before_count = products.count order = Grocery::Order.new(1337, products) + # Act order.add_product("salad", 4.25) + + # Assert expected_count = before_count + 1 + order.products.count.must_equal expected_count end @@ -76,35 +84,119 @@ result.must_equal true end end + + #Basically the opposite of #add_product + describe "#remove_product" do + it "Decreases the number of products" do + products = { "banana" => 1.99, "cracker" => 3.00 } + before_count = products.count + order = Grocery::Order.new(1337, products) + + # based only on the first argument or name of product + order.remove_product("banana") + # remove instead of add + expected_count = before_count - 1 + order.products.count.must_equal expected_count + end + + it "Is removed to the collection of products" do + products = { "banana" => 1.99, "cracker" => 3.00 } + order = Grocery::Order.new(1337, products) + + order.remove_product("sandwich") + order.products.include?("sandwich").wont_equal true + end + + it "Returns true if the product is removed" do + products = { "banana" => 1.99, "cracker" => 3.00 } + + order = Grocery::Order.new(1337, products) + before_total = order.total + + result = order.remove_product("banana") + after_total = order.total + + # Returns true if the before total != after total when item is removed + result.must_equal true + before_total.wont_equal after_total + end + + it "Returns false if the product is new" do + products = { "banana" => 1.99, "cracker" => 3.00 } + order = Grocery::Order.new(1337, products) + + result = order.remove_product("salad") + result.must_equal false + end + + end end # TODO: change 'xdescribe' to 'describe' to run these tests -xdescribe "Order Wave 2" do +describe "Order Wave 2" do describe "Order.all" do + it "Returns an array of all orders" do - # TODO: Your test code here! + # wait don't I need to put an "arrange" statement here?? + + all_orders = Grocery::Order.all + # all_orders.must_be_kind_of Array + all_orders.class.must_equal Array + + all_orders.each do |order| + order.must_be_instance_of Grocery::Order + end + + all_orders.count.must_equal 100 end it "Returns accurate information about the first order" do - # TODO: Your test code here! + + all_orders = Grocery::Order.all + # binding.pry + + + all_orders[0].id.must_equal 1 + + all_orders[0].products.must_be_kind_of Hash + + end it "Returns accurate information about the last order" do - # TODO: Your test code here! + all_orders = Grocery::Order.all + + all_orders[-1].id.must_equal 100 + all_orders[-1].products.must_be_kind_of Hash + + end end describe "Order.find" do + + before do + @order_class = Grocery::Order + end + + it "Can find the first order from the CSV" do - # TODO: Your test code here! + + @order_class.find(1).must_be_instance_of Grocery::Order + end it "Can find the last order from the CSV" do - # TODO: Your test code here! + + @order_class.find(100).must_be_instance_of Grocery::Order + end - it "Raises an error for an order that doesn't exist" do - # TODO: Your test code here! + it "Returns nil for an order that doesn't exist" do + + @order_class.find(500).must_be_nil + + end end end