Skip to content

Commit

Permalink
Merge d1aba4a into a3ff8bc
Browse files Browse the repository at this point in the history
  • Loading branch information
nazwhale committed Mar 27, 2017
2 parents a3ff8bc + d1aba4a commit 4de04ae
Show file tree
Hide file tree
Showing 14 changed files with 399 additions and 44 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ gem 'rake'
gem 'rspec'
gem 'coveralls', require: false
gem 'capybara'
gem 'twilio-ruby'
gem 'smarter_csv'
12 changes: 11 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
builder (3.2.3)
capybara (2.4.4)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
Expand All @@ -20,8 +21,10 @@ GEM
http-cookie (1.0.2)
domain_name (~> 0.5)
json (1.8.3)
jwt (1.5.6)
mime-types (2.6.1)
mini_portile (0.6.2)
multi_json (1.12.1)
netrc (0.10.3)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
Expand Down Expand Up @@ -51,10 +54,15 @@ GEM
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
smarter_csv (1.1.4)
term-ansicolor (1.3.2)
tins (~> 1.0)
thor (0.19.1)
tins (1.6.0)
twilio-ruby (4.13.0)
builder (>= 2.1.2)
jwt (~> 1.0)
multi_json (>= 1.3.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
Expand All @@ -69,9 +77,11 @@ DEPENDENCIES
coveralls
rake
rspec
smarter_csv
twilio-ruby

RUBY VERSION
ruby 2.3.1p112

BUNDLED WITH
1.12.0
1.14.6
104 changes: 61 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,12 @@ Takeaway Challenge
:' // ': \ \ ''..'--:'-.. ':
'. '' .' \:.....:--'.-'' .'
':..:' ':..:'
```
Instructions
-------

* Challenge time: rest of the day and weekend, until Monday 9am
* Feel free to use google, your notes, books, etc. but work on your own
* If you refer to the solution of another coach or student, please put a link to that in your README
* If you have a partial solution, **still check in a partial solution**
* You must submit a pull request to this repo with your code by 9am Monday morning
```

Task
-----
### Task

* Fork this repo
* Run the command 'bundle' in the project directory to ensure you have all the gems
* Write a Takeaway program with the following user stories:
I aimed to write a program to satisfy the following user stories:

```
As a customer
Expand All @@ -47,45 +35,75 @@ As a customer
So that I am reassured that my order will be delivered on time
I would like to receive a text such as "Thank you! Your order was placed and will be delivered before 18:52" after I have ordered
```
I first broke down the user stories using domain modelling. My resulting models were then converted into failing feature tests, then translated into RSpec as failing unit tests. Following that, I wrote my code.

* Hints on functionality to implement:
* Ensure you have a list of dishes with prices
* Place the order by giving the list of dishes, their quantities and a number that should be the exact total. If the sum is not correct the method should raise an error, otherwise the customer is sent a text saying that the order was placed successfully and that it will be delivered 1 hour from now, e.g. "Thank you! Your order was placed and will be delivered before 18:52".
* The text sending functionality should be implemented using Twilio API. You'll need to register for it. It’s free.
* Use the twilio-ruby gem to access the API
* Use the Gemfile to manage your gems
* Make sure that your Takeaway is thoroughly tested and that you use mocks and/or stubs, as necessary to not to send texts when your tests are run
* However, if your Takeaway is loaded into IRB and the order is placed, the text should actually be sent
* Note that you can only send texts in the same country as you have your account. I.e. if you have a UK account you can only send to UK numbers.
I aimed to complete this challenge by using a test-driven approach, using manual feature tests within PRY and automated unit tests using RSpec.

* Advanced! (have a go if you're feeling adventurous):
* Implement the ability to place orders via text message.
Care has been taken to ensure encapsulation was done as much as possible, so that the user (Customer) can only interact with an instance of the Interface class.

* A free account on Twilio will only allow you to send texts to "verified" numbers. Use your mobile phone number, don't worry about the customer's mobile phone.
* Finally submit a pull request before Monday at 9am with your solution or partial solution. However much or little amount of code you wrote please please please submit a pull request before Monday at 9am
I used the [Twillo API](https://www.twilio.com/docs/api/rest) to enable my program to send confirmation texts to mobile phones.

### Installation

In code review we'll be hoping to see:

* All tests passing
* High [Test coverage](https://github.com/makersacademy/course/blob/master/pills/test_coverage.md) (>95% is good)
* The code is elegant: every class has a clear responsibility, methods are short etc.
Clone repository:
```
$ git clone git@github.com:nazwhale/takeaway-challenge.git
$ cd takeaway-challenge
```

Reviewers will potentially be using this [code review rubric](docs/review.md). Referring to this rubric in advance will make the challenge somewhat easier. You should be the judge of how much challenge you want this weekend.
Install dependencies with bundle:
```
$ gem install bundler
$ bundle install
```

Notes on Test Coverage
------------------
### Example of use

You can see your [test coverage](https://github.com/makersacademy/course/blob/master/pills/test_coverage.md) when you submit a pull request, and you can also get a summary locally by running:
To create an order in a REPL:

```
$ coveralls report
$ pry
$ require './lib/takeaway'
=> true
$ i_need_sushi = Takeaway.new
Greetings, Welcome to Ruby Sushi!
--------------
Todays's Menu:
--------------
Edamame: £2
Kaiso: £4
Maki: £4
Nigiri: £3
--------------
What would you like to order? Enter 'done' when you are happy with your selection
Dish: kaiso
Quantity: 2
Dish: maki
Quantity: 1
Dish: nigiri
Quantity: 4
Dish: done
--------------
Your order:
--------------
2x kaiso @ £4
1x maki @ £4
4x nigiri @ £3
Total: £24
Is this correct? (y/n)
y
```

This repo works with [Coveralls](https://coveralls.io/) to calculate test coverage statistics on each pull request.
### Domain model

Build Badge Example
------------------
Functional representation:

[![Build Status](https://travis-ci.org/makersacademy/takeaway-challenge.svg?branch=master)](https://travis-ci.org/makersacademy/takeaway-challenge)
[![Coverage Status](https://coveralls.io/repos/makersacademy/takeaway-challenge/badge.png)](https://coveralls.io/r/makersacademy/takeaway-challenge)
| Objects | Messages |
| ------------------------ | ------------------------ |
| Menu | display |
| Interface | welcome |
| Interface | total_correct? |
| Order | take_order |
| Calculator | total_order |
| Text | send_text |
2 changes: 2 additions & 0 deletions lib/feature_tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require './lib/takeaway'
ta = Takeaway.new
30 changes: 30 additions & 0 deletions lib/menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#displays a list of dishes with prices
require 'smarter_csv'
require 'words'

class Menu

attr_reader :dishes

def initialize
@dishes = parse
end

def display
Words.menu_header
dishes.each do |plate,price|
puts "#{plate.capitalize}: £#{price}"
end
Words.line
end

private

def parse
data = SmarterCSV.process('./rubysushi.csv')
dishes = {}
data.each {|dish| dishes[dish[:plate]] = dish[:price]}
dishes
end

end
46 changes: 46 additions & 0 deletions lib/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#takes selection of dishes
#looks up in menu to ensure dish is valid
require_relative 'takeaway'
require_relative 'menu'
require_relative 'words'

class Order

attr_reader :items, :total, :menu

def initialize(menu = Menu.new)
@items = {}
@total = 0
@menu = menu
end

def take_order
Words.order_prompt
loop do
Words.dish_selection_prompt
dish = gets.chomp.downcase
until menu.dishes.key?(dish) || dish == "done"
Words.not_a_dish
dish = gets.chomp.downcase
end
break if dish == "done"
Words.quantity_selection_prompt
quantity = gets.chomp.to_i
add_to_order(dish, quantity)
calculate(dish, quantity)
end
end

private

attr_writer :total

def calculate(dish, quantity)
self.total += menu.dishes[dish] * quantity
end

def add_to_order(dish, quantity)
items[dish] = quantity
end

end
15 changes: 15 additions & 0 deletions lib/sms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'twilio-ruby'

class Sms
attr_reader :confirmation_sms
TWILIO_ACCOUNT_SID = "ACf5913cffd02b007aa9462769e71beb1d"
TWILIO_AUTH_TOKEN = "[AUTH TOKEN]"
def confirmation_sms
client = Twilio::REST::Client.new(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)

client.messages.create(
from: "+441872672068",
to: "[PHONE NUMBER]",
body: "Thank you! Your order was placed and will be delivered before #{(Time.now + 60*60).strftime("%H:%M")} 🍣")
end
end
67 changes: 67 additions & 0 deletions lib/takeaway.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#prints messages to user, calls methods in correct order

require_relative 'menu'
require_relative 'order'
require_relative 'sms'
require_relative 'words'

class Takeaway

attr_reader :menu, :order

def initialize(menu = Menu.new)
@menu = menu
welcome
total_correct?
end

def total_correct?
breakdown
answer = gets.chomp.downcase
if answer == "y"
correct
elsif answer == "n"
incorrect
else
Words.invalid_input
total_correct?
end
end

private

def correct
sms = Sms.new
sms.confirmation_sms
Words.thankyou_message
end

def incorrect
Words.incorrect_order_options
answer = gets.chomp.downcase
until answer == "n" || answer == "q"
Words.invalid_yesno_input
answer = gets.chomp.downcase
end
answer == "n" ? start_over : abort(Words.exit_message)
end

def start_over
Takeaway.new
end

def welcome(order = Order.new)
Words.greeting
menu.display
@order = order
order.take_order
end

def breakdown
Words.breakdown_header
order.items.each {|plate,price| puts "#{price}x #{plate.capitalize} @ £#{menu.dishes[plate]}"}
puts "Total: £#{order.total}"
Words.breakdown_correct?
end

end
Loading

0 comments on commit 4de04ae

Please sign in to comment.