diff --git a/app.rb b/app.rb new file mode 100644 index 00000000..f3c03b53 --- /dev/null +++ b/app.rb @@ -0,0 +1,114 @@ +require_relative 'lib/database_connection' +require_relative 'lib/shop_item_repository' +require_relative 'lib/order_repository' + +class Application + def initialize(database_name, io, shop_item_repository, order_repository) + DatabaseConnection.connect(database_name) + @io = io + @shop_item_repository = shop_item_repository + @order_repository = order_repository + end + + def run + @io.puts "Welcome to the shop management program!" + @io.puts "\n" + print_menu + @io.puts "\n" + choice = @io.gets.chomp + @io.puts "\n" + + run_selected_task(choice) + end + + private + + def print_menu + @io.puts "What do you want to do?" + @io.puts " 1 = list all shop items" + @io.puts " 2 = create a new item" + @io.puts " 3 = list all orders" + @io.puts " 4 = create a new order" + end + + def run_selected_task(choice) + case choice + when "1" then list_shop_items + when "2" then add_new_shop_item + when "3" then list_orders + when "4" then add_new_order + else @io.puts "Sorry I didn't understand that." + end + end + + def list_shop_items + @io.puts "Here's a list of all shop items:" + @io.puts "\n" + @shop_item_repository.all.each do |i| + @io.puts "##{i.id} #{i.name} - Unit price: #{i.unit_price} - Quantity: #{i.quantity}" + end + end + + def add_new_shop_item + @io.puts "Please enter the details of the item you want to create" + @io.print "Name: " + name = @io.gets.chomp + @io.print "Unit price: " + unit_price = @io.gets.chomp.to_f + @io.print "Quantity: " + quantity = @io.gets.chomp.to_i + create_shop_item(name, unit_price, quantity) + end + + def create_shop_item(name, unit_price, quantity) + item = ShopItem.new + item.name = name + item.unit_price = unit_price + item.quantity = quantity + + @shop_item_repository.create(item) + @io.puts "Item created" + end + + def list_orders + @io.puts "Here's a list of all orders:" + @io.puts "\n" + @order_repository.all.each do |order| + format_date = DateTime.parse(order.date_placed).strftime '%d/%m/%Y' + item_name = @shop_item_repository.find(order.shop_item_id).name + @io.puts "* Order id: #{order.id} - Customer name: #{order.customer_name}" + @io.puts " Order for: #{item_name} - Date placed: #{format_date}" + end + end + + def add_new_order + @io.puts "Please enter the order details" + @io.print "Customer name: " + customer_name = @io.gets.chomp + @io.print "Date placed (YYYY-MM-DD HH:MM:SS): " + date_placed = @io.gets.chomp + @io.print "Shop Item Id: " + shop_item_id = @io.gets.chomp + create_order(customer_name, date_placed, shop_item_id) + end + + def create_order(customer_name, date_placed, shop_item_id) + order = Order.new + order.customer_name = customer_name + order.date_placed = date_placed + order.shop_item_id = shop_item_id + + @order_repository.create(order) + @io.puts "Order added" + end +end + +if __FILE__ == $0 + app = Application.new( + 'shop_manager', + Kernel, + ShopItemRepository.new, + OrderRepository.new + ) + app.run +end diff --git a/design-recipe.md b/design-recipe.md new file mode 100644 index 00000000..7ca35280 --- /dev/null +++ b/design-recipe.md @@ -0,0 +1,316 @@ +# Design Recipe for Shop Manager Challenge + +## 1. Extract nouns from the user stories or specification + +```plain +As a shop manager +So I can know which items I have in stock +I want to keep a list of my shop items with their name and unit price. + +As a shop manager +So I can know which items I have in stock +I want to know which quantity (a number) I have for each item. + +As a shop manager +So I can manage items +I want to be able to create a new item. + +As a shop manager +So I can know which orders were made +I want to keep a list of orders with their customer name. + +As a shop manager +So I can know which orders were made +I want to assign each order to their corresponding item. + +As a shop manager +So I can know which orders were made +I want to know on which date an order was placed. + +As a shop manager +So I can manage orders +I want to be able to create a new order. +``` + +```plain +Nouns/key elements: + +list of shop items - name, unit price, quantity +list of orders - customer name, item_id, date placed + +items - list all, create new item +orders - list all, create new item +Assign order to corresponding item - item_id will be fk +``` + +## 2. Infer the Table Name and Columns + +| Record | Properties | +| --------- | ----------------------------------- | +| shop_item | name, unit_price, quantity | +| order | customer_name, item_id, date_placed | + +1. Name of the first table (always plural): `shop_items` + + Column names: `name`, `unit_price`, `quantity` + +2. Name of the second table (always plural): `orders` + + Column names: `customer_name`, `shop_item_id`, `date_placed` + +## 3. Decide the column types + +```plain +Table: shop_items +id: SERIAL +name: text +unit_price: money +quantity: int + +Table: orders +id: SERIAL +customer_name: text +date_placed: timestamp +shop_item_id: int +``` + +## 4. Decide on The Tables Relationship + +```plain +1. Can one shop item have many orders? YES +2. Can one order have many shop items? NO + +**NOTE** +One order could have many shop items. I have taken from the user story +'I want to assign each order to their corresponding item' and the menu +options that this is singular for the purposes of this challenge. + +-> Therefore, +-> A shop item HAS MANY orders +-> An order BELONGS TO a shop item + +-> Therefore, the foreign key is on the orders table. +``` + +## 5. Write the SQL + +```sql +-- file: shop_manager_tables.sql + +-- Create the table without the foreign key first. +CREATE TABLE shop_items ( + id SERIAL PRIMARY KEY, + name text, + unit_price money, + quantity int +); + +-- Then the table with the foreign key first. +CREATE TABLE orders ( + id SERIAL PRIMARY KEY, + customer_name text, + date_placed timestamp, +-- The foreign key name is always {other_table_singular}_id + shop_item_id int, + constraint fk_shop_item foreign key(shop_item_id) + references shop_items(id) + on delete cascade +); +``` + +## 6. Create the databases and tables + +```bash +createdb shop_manager +createdb shop_manager_test +psql -h 127.0.0.1 shop_manager < shop_manager_tables.sql +psql -h 127.0.0.1 shop_manager_test < shop_manager_tables.sql +``` + +## 7. Create Test SQL seeds + +```sql +-- (file: spec/seeds_shop_manager_test.sql) + +-- **NOTE** I am creating the test seeds in one file so I can truncate both +-- tables and resolve the error where it cannot truncate a table referenced +-- in a foreign key constraint. + +TRUNCATE TABLE shop_items, orders RESTART IDENTITY; + +-- Below this line there should only be `INSERT` statements. +-- Replace these statements with your own seed data. + +INSERT INTO shop_items (name, unit_price, quantity) VALUES ('Super Shark Vacuum Cleaner', 99.99, 30); +INSERT INTO shop_items (name, unit_price, quantity) VALUES ('Makerspresso', 69.00, 15); + +-- timestamp format - YYYY-MM-DD HH:MI:SS +INSERT INTO orders (customer_name, date_placed, shop_item_id) VALUES ('Sarah', '2023-04-06 12:57:03', 1) +INSERT INTO orders (customer_name, date_placed, shop_item_id) VALUES ('Fred', '2023-03-12 15:12:42', 2) +``` + +## 8. Define and implement the Model classes + +```ruby +# Table name: shop_items + +# Model class +# (in lib/shop_item.rb) +class ShopItem + attr_accessor :id, :name, :unit_price, :quantity +end + +# Table name: orders + +# Model class +# (in lib/order.rb) +class Order + attr_accessor :id, :customer_name, :date_placed, :shop_item_id +end +``` + +## 9. Define the Repository Class interface + +```ruby +# Table name: shop_items +# Repository class +# (in lib/shop_item_repository.rb) +class ShopItemRepository + + # Selecting all shop_items records + # No arguments + def all + # Executes the SQL query: + # SELECT id, name, unit_price, quantity FROM shop_items; + + # Returns an array of ShopItem objects + end + + # Create a new item + # Takes a ShopItem object as an argument + def create(shop_item) + # Executes the SQL query: + # INSERT INTO shop_items (name, unit_price, quantity) + # VALUES ($1, $2, $3); + + # Returns nil, inserts shop_item into db + end +end + +# Repository class +# (in lib/shop_item_repository.rb) +class OrderRepository + + # Selecting all order records + # No arguments + def all + # Executes the SQL query: + # SELECT id, customer_name, date_placed, shop_item_id FROM orders; + + # Returns an array of Order objects + end + + # Create a new item + # Takes an Order object as an argument + def create(order) + # Executes the SQL query: + # INSERT INTO orders (customer_name, date_placed, shop_item_id) + # VALUES ($1, $2, $3); + + # Returns nil, inserts order into db + end +end +``` + +## 10. Write Test Examples + +```ruby +# As a shop manager +# So I can know which items I have in stock +# I want to keep a list of my shop items with their name and unit price. + +# As a shop manager +# So I can know which items I have in stock +# I want to know which quantity (a number) I have for each item. + +# 1 +# Get all shop items +repo = ShopItemRepository.new + +shop_items = repo.all + +expect(shop_items.length).to eq 2 +expect(shop_items.first.name).to eq 'Super Shark Vacuum Cleaner' +expect(shop_items.first.unit_price).to eq '$99.99' +expect(shop_items.first.quantity).to eq '30' + +# As a shop manager +# So I can manage items +# I want to be able to create a new item. + +# 2 +# Create a new shop item +repo = ShopItemRepository.new +shop_item = ShopItem.new +shop_item.name = 'Dyson Airwrap' +shop_item.unit_price = 300 +shop_item.quantity = 5 +repo.create(shop_item) + +expect(repo.all.length).to eq 3 +expect(repo.all.last.id).to eq '3' +expect(repo.all.last.name).to eq 'Dyson Airwrap' +expect(repo.all.last.unit_price).to eq '$300.00' +expect(repo.all.last.quantity).to eq '5' + +# As a shop manager +# So I can know which orders were made +# I want to keep a list of orders with their customer name. + +# As a shop manager +# So I can know which orders were made +# I want to assign each order to their corresponding item. + +# As a shop manager +# So I can know which orders were made +# I want to know on which date an order was placed. + +# 3 +# Get all orders +repo = OrderRepository.new + +orders = repo.all + +expect(orders.length).to eq 2 +expect(orders.first.customer_name).to eq 'Sarah' +expect(orders.first.date_placed).to eq '2023-04-06 12:57:03' +expect(orders.first.shop_item_id).to eq '1' + +# As a shop manager +# So I can manage orders +# I want to be able to create a new order. + +# 4 +# Create a new order + +repo = OrderRepository.new +order = Order.new +order.customer_name = 'Bob' +order.date_placed = '30-04-2023 18:32:02' +order.shop_item_id = 2 +repo.create(order) + +expect(repo.all.length).to eq 3 +expect(repo.all.last.id).to eq '3' +expect(repo.all.last.customer_name).to eq 'Bob' +expect(repo.all.last.date_placed).to eq '30-04-2023 18:32:02' +expect(repo.all.last.shop_item_id).to eq '2' +``` + +## 11. Integration tests + +I wasn't sure whether we should test the application class. I have decided to create some integration tests. + +## 12. Questions + +Is it possible to test lines 106 and 112 in app.rb? diff --git a/lib/database_connection.rb b/lib/database_connection.rb new file mode 100644 index 00000000..f4bde0ff --- /dev/null +++ b/lib/database_connection.rb @@ -0,0 +1,28 @@ +# file: lib/database_connection.rb + +require 'pg' + +# This class is a thin "wrapper" around the +# PG library. We'll use it in our project to interact +# with the database using SQL. + +class DatabaseConnection + # This method connects to PostgreSQL using the + # PG gem. We connect to 127.0.0.1, and select + # the database name given in argument. + def self.connect(database_name) + @connection = PG.connect({ host: '127.0.0.1', dbname: database_name }) + end + + # This method executes an SQL query + # on the database, providing some optional parameters + # (you will learn a bit later about when to provide these parameters). + def self.exec_params(query, params) + if @connection.nil? + raise 'DatabaseConnection.exec_params: Cannot run a SQL query as the connection to'\ + 'the database was never opened. Did you make sure to call first the method '\ + '`DatabaseConnection.connect` in your app.rb file (or in your tests spec_helper.rb)?' + end + @connection.exec_params(query, params) + end +end diff --git a/lib/order.rb b/lib/order.rb new file mode 100644 index 00000000..680e29cc --- /dev/null +++ b/lib/order.rb @@ -0,0 +1,3 @@ +class Order + attr_accessor :id, :customer_name, :date_placed, :shop_item_id +end diff --git a/lib/order_repository.rb b/lib/order_repository.rb new file mode 100644 index 00000000..7d45b8bc --- /dev/null +++ b/lib/order_repository.rb @@ -0,0 +1,34 @@ +require_relative './order' + +class OrderRepository + def all + sql = 'SELECT id, customer_name, date_placed, shop_item_id FROM orders;' + + result_set = DatabaseConnection.exec_params(sql, []) + + orders = [] + result_set.each do |record| + orders << create_order(record) + end + return orders + end + + def create(order) + sql = 'INSERT INTO orders (customer_name, date_placed, shop_item_id) + VALUES ($1, $2, $3);' + params = [order.customer_name, order.date_placed, order.shop_item_id] + + DatabaseConnection.exec_params(sql, params) + end + + private + + def create_order(record) + order = Order.new + order.id = record['id'] + order.customer_name = record['customer_name'] + order.date_placed = record['date_placed'] + order.shop_item_id = record['shop_item_id'] + return order + end +end diff --git a/lib/shop_item.rb b/lib/shop_item.rb new file mode 100644 index 00000000..ef277d5b --- /dev/null +++ b/lib/shop_item.rb @@ -0,0 +1,3 @@ +class ShopItem + attr_accessor :id, :name, :unit_price, :quantity +end diff --git a/lib/shop_item_repository.rb b/lib/shop_item_repository.rb new file mode 100644 index 00000000..f75dd0b5 --- /dev/null +++ b/lib/shop_item_repository.rb @@ -0,0 +1,43 @@ +require_relative './shop_item' + +class ShopItemRepository + def all + sql = 'SELECT id, name, unit_price, quantity FROM shop_items;' + + result_set = DatabaseConnection.exec_params(sql, []) + + shop_items = [] + result_set.each do |record| + shop_items << create_shop_item(record) + end + return shop_items + end + + def create(shop_item) + sql = 'INSERT INTO shop_items (name, unit_price, quantity) + VALUES ($1, $2, $3);' + params = [shop_item.name, shop_item.unit_price, shop_item.quantity] + + DatabaseConnection.exec_params(sql, params) + end + + def find(id) + sql = 'SELECT id, name, unit_price, quantity FROM shop_items WHERE id = $1;' + params = [id] + + result_set = DatabaseConnection.exec_params(sql, params) + result = result_set[0] + create_shop_item(result) + end + + private + + def create_shop_item(record) + shop_item = ShopItem.new + shop_item.id = record['id'] + shop_item.name = record['name'] + shop_item.unit_price = record['unit_price'] + shop_item.quantity = record['quantity'] + return shop_item + end +end diff --git a/shop_manager_tables.sql b/shop_manager_tables.sql new file mode 100644 index 00000000..f0a4fe01 --- /dev/null +++ b/shop_manager_tables.sql @@ -0,0 +1,21 @@ +-- file: shop_manager_tables.sql + +-- Create the table without the foreign key first. +CREATE TABLE shop_items ( + id SERIAL PRIMARY KEY, + name text, + unit_price money, + quantity int +); + +-- Then the table with the foreign key first. +CREATE TABLE orders ( + id SERIAL PRIMARY KEY, + customer_name text, + date_placed timestamp, +-- The foreign key name is always {other_table_singular}_id + shop_item_id int, + constraint fk_shop_item foreign key(shop_item_id) + references shop_items(id) + on delete cascade +); \ No newline at end of file diff --git a/spec/order_repository_spec.rb b/spec/order_repository_spec.rb new file mode 100644 index 00000000..eef936a2 --- /dev/null +++ b/spec/order_repository_spec.rb @@ -0,0 +1,39 @@ +require 'order_repository' + +describe OrderRepository do + def reset_orders_table + seed_sql = File.read('spec/seeds_shop_manager_test.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'shop_manager_test' }) + connection.exec(seed_sql) + end + + before(:each) do + reset_orders_table + end + + it "returns a list of all orders" do + repo = OrderRepository.new + + orders = repo.all + + expect(orders.length).to eq 2 + expect(orders.first.customer_name).to eq 'Sarah' + expect(orders.first.date_placed).to eq '2023-04-06 12:57:03' + expect(orders.first.shop_item_id).to eq '1' + end + + it "creates a new order" do + repo = OrderRepository.new + order = Order.new + order.customer_name = 'Bob' + order.date_placed = '2023-04-30 18:32:02' + order.shop_item_id = 2 + repo.create(order) + + expect(repo.all.length).to eq 3 + expect(repo.all.last.id).to eq '3' + expect(repo.all.last.customer_name).to eq 'Bob' + expect(repo.all.last.date_placed).to eq '2023-04-30 18:32:02' + expect(repo.all.last.shop_item_id).to eq '2' + end +end diff --git a/spec/seeds_shop_manager_test.sql b/spec/seeds_shop_manager_test.sql new file mode 100644 index 00000000..510a1a35 --- /dev/null +++ b/spec/seeds_shop_manager_test.sql @@ -0,0 +1,11 @@ +TRUNCATE TABLE shop_items, orders RESTART IDENTITY; + +-- Below this line there should only be `INSERT` statements. +-- Replace these statements with your own seed data. + +INSERT INTO shop_items (name, unit_price, quantity) VALUES ('Super Shark Vacuum Cleaner', 99.99, 30); +INSERT INTO shop_items (name, unit_price, quantity) VALUES ('Makerspresso', 69, 15); + +-- timestamp format - YYYY-MM-DD HH:MI:SS +INSERT INTO orders (customer_name, date_placed, shop_item_id) VALUES ('Sarah', '2023-04-06 12:57:03', 1); +INSERT INTO orders (customer_name, date_placed, shop_item_id) VALUES ('Fred', '2023-03-12 15:12:42', 2); \ No newline at end of file diff --git a/spec/shop_item_repository_spec.rb b/spec/shop_item_repository_spec.rb new file mode 100644 index 00000000..3803a917 --- /dev/null +++ b/spec/shop_item_repository_spec.rb @@ -0,0 +1,48 @@ +require 'shop_item_repository' + +describe ShopItemRepository do + def reset_shop_items_table + seed_sql = File.read('spec/seeds_shop_manager_test.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'shop_manager_test' }) + connection.exec(seed_sql) + end + + before(:each) do + reset_shop_items_table + end + + it "returns a list of all shop items" do + repo = ShopItemRepository.new + + shop_items = repo.all + + expect(shop_items.length).to eq 2 + expect(shop_items.first.name).to eq 'Super Shark Vacuum Cleaner' + expect(shop_items.first.unit_price).to eq '$99.99' + expect(shop_items.first.quantity).to eq '30' + end + + it "creates a new shop item" do + repo = ShopItemRepository.new + shop_item = ShopItem.new + shop_item.name = 'Dyson Airwrap' + shop_item.unit_price = 300 + shop_item.quantity = 5 + repo.create(shop_item) + + expect(repo.all.length).to eq 3 + expect(repo.all.last.id).to eq '3' + expect(repo.all.last.name).to eq 'Dyson Airwrap' + expect(repo.all.last.unit_price).to eq '$300.00' + expect(repo.all.last.quantity).to eq '5' + end + + it "finds a shop item name by id" do + repo = ShopItemRepository.new + + shop_item = repo.find(1) + expect(shop_item.name).to eq "Super Shark Vacuum Cleaner" + expect(shop_item.unit_price).to eq "$99.99" + expect(shop_item.quantity).to eq "30" + end +end diff --git a/spec/shop_manager_integration_spec.rb b/spec/shop_manager_integration_spec.rb new file mode 100644 index 00000000..5e487129 --- /dev/null +++ b/spec/shop_manager_integration_spec.rb @@ -0,0 +1,135 @@ +require_relative '../app' + +describe "shop manager" do + def reset_shop_manager_table + seed_sql = File.read('spec/seeds_shop_manager_test.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'shop_manager_test' }) + connection.exec(seed_sql) + end + + before(:each) do + reset_shop_manager_table + end + + it "returns a list of all shop items when user selects 1" do + io = double :io + expect(io).to receive(:puts).with("Welcome to the shop management program!").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("What do you want to do?").ordered + expect(io).to receive(:puts).with(" 1 = list all shop items").ordered + expect(io).to receive(:puts).with(" 2 = create a new item").ordered + expect(io).to receive(:puts).with(" 3 = list all orders").ordered + expect(io).to receive(:puts).with(" 4 = create a new order").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:gets).and_return("1").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("Here's a list of all shop items:").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("#1 Super Shark Vacuum Cleaner - Unit price: $99.99 - Quantity: 30").ordered + expect(io).to receive(:puts).with("#2 Makerspresso - Unit price: $69.00 - Quantity: 15").ordered + + app = Application.new('shop_manager_test', io, ShopItemRepository.new, OrderRepository.new) + app.run + end + + it "creates a new item when user selects 2" do + io = double :io + shop_items = ShopItemRepository.new + expect(io).to receive(:puts).with("Welcome to the shop management program!").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("What do you want to do?").ordered + expect(io).to receive(:puts).with(" 1 = list all shop items").ordered + expect(io).to receive(:puts).with(" 2 = create a new item").ordered + expect(io).to receive(:puts).with(" 3 = list all orders").ordered + expect(io).to receive(:puts).with(" 4 = create a new order").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:gets).and_return("2").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("Please enter the details of the item you want to create").ordered + expect(io).to receive(:print).with("Name: ").ordered + expect(io).to receive(:gets).and_return("Dyson Airwrap").ordered + expect(io).to receive(:print).with("Unit price: ").ordered + expect(io).to receive(:gets).and_return("300").ordered + expect(io).to receive(:print).with("Quantity: ").ordered + expect(io).to receive(:gets).and_return("5").ordered + expect(io).to receive(:puts).with("Item created").ordered + + app = Application.new('shop_manager_test', io, shop_items, OrderRepository.new) + app.run + + expect(shop_items.all.last.name).to eq "Dyson Airwrap" + expect(shop_items.all.last.unit_price).to eq "$300.00" + expect(shop_items.all.last.quantity).to eq "5" + end + + it "returns a list of all order items when user selects 3" do + io = double :io + expect(io).to receive(:puts).with("Welcome to the shop management program!").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("What do you want to do?").ordered + expect(io).to receive(:puts).with(" 1 = list all shop items").ordered + expect(io).to receive(:puts).with(" 2 = create a new item").ordered + expect(io).to receive(:puts).with(" 3 = list all orders").ordered + expect(io).to receive(:puts).with(" 4 = create a new order").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:gets).and_return("3").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("Here's a list of all orders:").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("* Order id: 1 - Customer name: Sarah").ordered + expect(io).to receive(:puts).with(" Order for: Super Shark Vacuum Cleaner - Date placed: 06/04/2023").ordered + expect(io).to receive(:puts).with("* Order id: 2 - Customer name: Fred").ordered + expect(io).to receive(:puts).with(" Order for: Makerspresso - Date placed: 12/03/2023").ordered + + app = Application.new('shop_manager_test', io, ShopItemRepository.new, OrderRepository.new) + app.run + end + + it "creates a new order when user selects 4" do + io = double :io + orders = OrderRepository.new + expect(io).to receive(:puts).with("Welcome to the shop management program!").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("What do you want to do?").ordered + expect(io).to receive(:puts).with(" 1 = list all shop items").ordered + expect(io).to receive(:puts).with(" 2 = create a new item").ordered + expect(io).to receive(:puts).with(" 3 = list all orders").ordered + expect(io).to receive(:puts).with(" 4 = create a new order").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:gets).and_return("4").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("Please enter the order details").ordered + expect(io).to receive(:print).with("Customer name: ").ordered + expect(io).to receive(:gets).and_return("Bob").ordered + expect(io).to receive(:print).with("Date placed (YYYY-MM-DD HH:MM:SS): ").ordered + expect(io).to receive(:gets).and_return("2023-04-30 18:32:02").ordered + expect(io).to receive(:print).with("Shop Item Id: ").ordered + expect(io).to receive(:gets).and_return("2").ordered + expect(io).to receive(:puts).with("Order added").ordered + + app = Application.new('shop_manager_test', io, ShopItemRepository, orders) + app.run + + expect(orders.all.last.customer_name).to eq "Bob" + expect(orders.all.last.date_placed).to eq "2023-04-30 18:32:02" + expect(orders.all.last.shop_item_id).to eq "2" + end + + it "returns an error message if choice is not on menu" do + io = double :io + expect(io).to receive(:puts).with("Welcome to the shop management program!").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("What do you want to do?").ordered + expect(io).to receive(:puts).with(" 1 = list all shop items").ordered + expect(io).to receive(:puts).with(" 2 = create a new item").ordered + expect(io).to receive(:puts).with(" 3 = list all orders").ordered + expect(io).to receive(:puts).with(" 4 = create a new order").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:gets).and_return("5").ordered + expect(io).to receive(:puts).with("\n").ordered + expect(io).to receive(:puts).with("Sorry I didn't understand that.").ordered + + app = Application.new('shop_manager_test', io, ShopItemRepository, OrderRepository.new) + app.run + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 252747d8..361dadfc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ require 'simplecov' require 'simplecov-console' +require 'database_connection' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::Console, @@ -8,6 +9,8 @@ ]) SimpleCov.start +DatabaseConnection.connect('shop_manager_test') + RSpec.configure do |config| config.after(:suite) do puts