Skip to content
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
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ group :test do
gem 'rspec'
gem 'simplecov', require: false, group: :test
gem 'simplecov-console', require: false, group: :test
gem 'timecop'
gem 'twilio_mock'
end

group :development, :test do
gem 'rubocop', '1.20'
end

gem 'twilio-ruby', '~> 5.66.2'
gem 'rack'
gem 'dotenv'
54 changes: 54 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
ansi (1.5.0)
ast (2.4.2)
crack (0.4.5)
rexml
diff-lcs (1.4.4)
docile (1.4.0)
dotenv (2.7.6)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.3)
multipart-post (>= 1.2, < 3)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
hashdiff (1.0.1)
jwt (2.3.0)
multipart-post (2.1.1)
nokogiri (1.13.4-x86_64-darwin)
racc (~> 1.4)
parallel (1.20.1)
parser (3.0.2.0)
ast (~> 2.4.1)
public_suffix (4.0.7)
racc (1.5.1)
rack (2.2.3)
rainbow (3.0.0)
regexp_parser (2.1.1)
rexml (3.2.5)
Expand Down Expand Up @@ -36,6 +72,7 @@ GEM
rubocop-ast (1.11.0)
parser (>= 3.0.1.1)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.5)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand All @@ -48,16 +85,33 @@ GEM
simplecov_json_formatter (0.1.3)
terminal-table (3.0.1)
unicode-display_width (>= 1.1.1, < 3)
timecop (0.9.5)
twilio-ruby (5.66.2)
faraday (>= 0.9, < 2.0)
jwt (>= 1.5, <= 2.5)
nokogiri (>= 1.6, < 2.0)
twilio_mock (0.4.6)
twilio-ruby (~> 5.3, >= 5.3.1)
webmock (~> 3.0, >= 2)
unicode-display_width (2.0.0)
webmock (3.14.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)

PLATFORMS
ruby

DEPENDENCIES
dotenv
rack
rspec
rubocop (= 1.20)
simplecov
simplecov-console
timecop
twilio-ruby (~> 5.66.2)
twilio_mock

RUBY VERSION
ruby 3.0.2p107
Expand Down
104 changes: 39 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,43 @@
Takeaway Challenge
==================
# Takeaway Challenge

- This program is designed to order dishes from takeaway shop.
- This program can show menu and suggest if dish is available.
- This program creates basket for the user, where you they can put or delete selected dishes.
- This program can check the total of order.
- This program can send sms when order confirmed with suggested delivered time.
- This program uses Twilio.

---

## How to install the program

```
_________
r== | |
_ // | M.A. | ))))
|_)//(''''': | |
// \_____:_____.-------D )))))
// | === | / \
.:'//. \ \=| \ / .:'':./ )))))
:' // ': \ \ ''..'--:'-.. ':
'. '' .' \:.....:--'.-'' .'
':..:' ':..:'

```

Instructions
-------

* 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
-----

* 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:
- Fork this repository

- Use "git clone" + your fork URL
```

---

## How to run the program

```shell

irb -r "./lib/order.rb"
```

---

## How to run the test

```shell
rspec

irb
```


## User story
```
As a customer
So that I can check if I want to order something
Expand All @@ -45,39 +54,4 @@ I would like to check that the total I have been given matches the sum of the va
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
```

* Hints on functionality to implement:
* Ensure you have a list of dishes with prices
* The text should state 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.

* Advanced! (have a go if you're feeling adventurous):
* Implement the ability to place orders via text message.

* 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.

> :warning: **WARNING:** think twice before you push your **mobile number** or **Twilio API Key** to a public space like GitHub :eyes:
>
> :key: Now is a great time to think about security and how you can keep your private information secret. You might want to explore environment variables.

* 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


In code review we'll be hoping to see:

* All tests passing
* High [Test coverage](https://github.com/makersacademy/course/blob/main/pills/test_coverage.md) (>95% is good)
* The code is elegant: every class has a clear responsibility, methods are short etc.

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 at this moment.

Notes on Test Coverage
------------------

You can see your [test coverage](https://github.com/makersacademy/course/blob/main/pills/test_coverage.md) when you run your tests.
```
22 changes: 22 additions & 0 deletions lib/dishes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Dishes
attr_reader :menu

def initialize
@menu = [
{ name: "Diet (not really) Pizza", price: 5.99 },
{ name: "Make me fat Pizza", price: 6.99 },
{ name: "Easy-Peasy Pizza", price: 7.99 },
{ name: "Hold my beer Pizza", price: 8.99 },
{ name: "Once in a lifetime Pizza", price: 9.99 }
]
end

def show_dishes
@menu.each_with_index { |meal, index| puts "#{index + 1}. #{meal[:name]} £#{meal[:price]}" }
@menu
end

def dish_available?(index)
@menu[index] != nil
end
end
10 changes: 10 additions & 0 deletions lib/main.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require_relative 'text'
require 'twilio-ruby'
require 'dotenv'

account_sid = ENV['ACCOUNT_SID']
auth_token = ENV['AUTH_TOKEN']
client = Twilio::REST::Client.new(account_sid, auth_token)

text = Text.new(client)
text.send_message
40 changes: 40 additions & 0 deletions lib/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require_relative 'dishes'
require_relative 'text'

class Order
attr_reader :basket, :menu, :dishes, :complete, :text
Copy link

Choose a reason for hiding this comment

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

I don't think all of these attribute readers are needed. Extra available state from inside our objects can cause problems sometimes - especially if someone else is going to use our code as an API (like a gem) - if we allow them to use more parts of our code, they are likely to rely upon them, and we have to work to maintain that too.


def initialize
@basket = Array.new(0)
dishes = Dishes.new
@menu = dishes.menu
@dishes = dishes
@complete = false
@text = Text.new
end

def select_dishes(index)
raise "Order already confirmed and can't be changed." if @complete
raise "Dish is not available. Please choose a different dish." if !dishes.dish_available?(index - 1)
@basket << @menu[index - 1]
end

def delete_dishes(index)
raise "Order already confirmed and can't be changed." if @complete
@basket.delete(@menu[index - 1])
@basket
end

def check_total
total = 0
@basket.each { |meal| total += meal[:price] }
return "£#{total}"
end

def confirm_order
@complete = true
puts "Order complete."
text.send_message
return check_total
end
end
32 changes: 32 additions & 0 deletions lib/text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'twilio-ruby'
require 'dotenv'

class Text
TIME_FORMAT = "%k:%M"

attr_reader :mobile

def initialize
@mobile = ENV['CUST_NUMBER']
end

def send_message
account_sid = ENV['ACCOUNT_SID']
auth_token = ENV['AUTH_TOKEN']
client = Twilio::REST::Client.new(account_sid, auth_token)

begin
client.messages.create(
body: "Thank you! Your order was placed and will be delivered before #{delivery_time}",
to: @mobile,
from: ENV['TWILIO_NUMBER']
)
puts message.sid
rescue
Copy link

Choose a reason for hiding this comment

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

This empty rescue block just swallows any errors, without telling you / the user about them.

I'd encourage you to look into whether you can rescue a more specific error, and at least puts to share that an error occurred.

end
end

def delivery_time
time = (Time.now + 60 * 60).strftime(TIME_FORMAT)
end
end
31 changes: 31 additions & 0 deletions spec/dishes_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'dishes'

describe Dishes do
it "creates an instance of the class" do
expect(subject).to be_instance_of(Dishes)
end

describe "#show_dishes" do
it "prints a list of dishes with prices" do
expect { subject.show_dishes }.to output(<<~output
1. Diet (not really) Pizza £5.99
2. Make me fat Pizza £6.99
3. Easy-Peasy Pizza £7.99
4. Hold my beer Pizza £8.99
5. Once in a lifetime Pizza £9.99
output
).to_stdout
end
end

describe "#dishes_available?" do
it "returns true when dishes available" do
expect(subject.dish_available?(1)).to eq(true)
end

it "returns true when dishes available" do
expect(subject.dish_available?(10)).to eq false
end
end
end

Loading