Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sam Button Takeaway Challenge #2231

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/SMS.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'twilio-ruby'

class SMS

ETA = (Time.now + 3600).strftime("%H:%M")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number could be defined elsewhere


attr_reader :sent, :phone_number

def initialize
@sent = false
end

def sms

@client = Twilio::REST::Client.new ENV['account Sid'], ENV['Auth token']
message = @client.messages.create(
body: "Thank you! Your order has been logged and will be with before #{ETA}",
to: "+my number",
from: ENV['+magic number'])

puts message.sid
end

def send_sms(phone_number)
@phone_number = phone_number
sms
@sent = true
sms_confirmation
end

def sent?
@sent
end

def sms_confirmation

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea to have the confirmation message, but again could be in private

"Confirmation message has been sent"
end
end
19 changes: 19 additions & 0 deletions docs/menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require './docs/order'

class Menu

attr_reader :menu

def initialize
@menu = {
"Guinness" => 6.00,
"Espresso Martini" => 12.50,
"Ruddles" => 1.99,
"Huel" => 3.00 }
end

def show_menu
@menu
end

end
35 changes: 35 additions & 0 deletions docs/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require './docs/menu'
require './docs/SMS'
require 'rubygems'

class Order

attr_reader :current_order

def initialize
@current_order = []
@new_menu = Menu.new
@order_price = 0
end

def add_to_basket(dish, quantity)
raise "Item not on the menu" unless @new_menu.menu.has_key?(dish)
quantity.times { @current_order << dish }
end

def calculate_price

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think some of these methods could be encapsulated into private as the the user doesn't need to calculate the price, the program just needs to do it and the user sees the output

price = 0

@current_order.each do |dish|
if @new_menu.menu.has_key?(dish)
price += @new_menu.menu.fetch(dish)
end
end
@order_price + price
end

def complete_order(phone_number)
SMS.new.send_sms(phone_number)
end

end
28 changes: 28 additions & 0 deletions spec/SMS_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require './docs/SMS'

describe SMS do

subject(:sms) { described_class.new }

before do
allow(sms).to receive(:sms)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much prefer this was of stubbing the SMS method directly rather than trying to stub the client like I did

end

it 'sends a payment confirmation text message' do
sms.send_sms(ENV['my number'])
end

it 'confirms a message has been sent' do
expect(subject.sms_confirmation).to eq('Confirmation message has been sent')
end

it 'changes sent? to true after a message is sent' do
expect { subject.send_sms(ENV['my number']) }.to change(subject, :sent?).to true
end

describe '#send_sms' do
it "takes a phone number as an argument" do
expect(subject).to respond_to(:send_sms).with(1).argument
end
end
end
13 changes: 13 additions & 0 deletions spec/menu_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require './docs/menu'

describe Menu do
it 'responds to Menu class' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think this test is needed. Rspec always initialises the subject to be a new instance of the described class

expect(subject).to be_an_instance_of Menu
end

describe '#see menu' do
it 'returns the menu' do
expect(subject.show_menu).to eq({ "Espresso Martini" => 12.5, "Guinness" => 6.0, "Huel" => 3.0, "Ruddles" => 1.99 })
end
end
end
51 changes: 51 additions & 0 deletions spec/order_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require './docs/order'

describe Order do
let(:menu) { Menu.create }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting why .create and not .new ?

let(:order) { Order.create }

it 'is an instance of Order class' do
expect(subject).to be_an_instance_of Order
end

it 'responds to add_to_basket' do
expect(subject).to respond_to :add_to_basket

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think this is being tested below so could probably be refactored out as well

end

describe '#add_to_order' do
context 'item is on the menu' do
it 'can add dishes to current order' do
subject.add_to_basket("Guinness", 1)
expect(subject.current_order).to eq(["Guinness"])
end

it 'can add multiple dishes at once' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever I hadn't thought about implementing quantity

subject.add_to_basket("Guinness", 4)
expect(subject.current_order).to eq(["Guinness", "Guinness", "Guinness", "Guinness"])
end
end

context 'item is not on the menu' do
it 'returns "Item not on the menu"' do
expect { subject.add_to_basket("Chips", 1) }.to raise_error ("Item not on the menu")
end
end
end

describe '#calculate_price' do
it 'adds up the current order price' do
menu = Menu.new
subject.add_to_basket("Guinness", 2)
subject.add_to_basket("Huel", 1)
expect(subject.calculate_price).to eq(15)
end
end

describe '#complete_order' do
it 'completes the order' do
text = SMS.new
text.send_sms("my number")
expect(text).to respond_to(:complete_order)
end
end
end