hungrytable 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Guardfile +16 -0
- data/README.md +16 -0
- data/hungrytable.gemspec +8 -7
- data/lib/hungrytable/config.rb +26 -0
- data/lib/hungrytable/get_request.rb +15 -0
- data/lib/hungrytable/post_request.rb +15 -0
- data/lib/hungrytable/request.rb +17 -0
- data/lib/hungrytable/request_extensions.rb +21 -0
- data/lib/hungrytable/request_header.rb +109 -0
- data/lib/hungrytable/reservation_cancel.rb +30 -0
- data/lib/hungrytable/reservation_make.rb +51 -0
- data/lib/hungrytable/reservation_status.rb +0 -0
- data/lib/hungrytable/restaurant.rb +50 -27
- data/lib/hungrytable/restaurant_search.rb +76 -0
- data/lib/hungrytable/restaurant_slotlock.rb +45 -0
- data/lib/hungrytable/version.rb +1 -1
- data/lib/hungrytable.rb +21 -6
- data/test/restaurant_get_details_result.json +6 -0
- data/test/restaurant_search_result.json +7 -0
- data/test/test_helper.rb +4 -6
- data/test/unit/config_test.rb +43 -0
- data/test/unit/get_request_test.rb +0 -0
- data/test/unit/hungrytable/restaurant_test.rb +11 -3
- data/test/unit/hungrytable/user_test.rb +28 -0
- data/test/unit/post_request_test.rb +0 -0
- data/test/unit/request_test.rb +0 -0
- data/test/unit/reservation_cancel_test.rb +0 -0
- data/test/unit/reservation_make_test.rb +0 -0
- data/test/unit/restaurant_search_test.rb +0 -0
- data/test/unit/restaurant_slotlock_test.rb +0 -0
- data/test/unit/restaurant_test.rb +39 -0
- data/test/user_login_result.json +6 -0
- metadata +127 -43
- data/lib/hungrytable/base.rb +0 -26
- data/lib/hungrytable/oauth_patch.rb +0 -19
- data/test/hungrytable_test.rb +0 -8
- data/test/support/minitest_junit.rb +0 -81
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
notification :libnotify
|
5
|
+
|
6
|
+
guard 'minitest' do
|
7
|
+
# with Minitest::Unit
|
8
|
+
watch(%r|^test/(.*)_test\.rb|)
|
9
|
+
watch(%r|^lib/(.*)/([^/]+)\.rb|) { |m| "test/unit/#{m[1]}/#{m[2]}_test.rb" }
|
10
|
+
watch(%r|^test/test_helper\.rb|) { "test" }
|
11
|
+
|
12
|
+
# with Minitest::Spec
|
13
|
+
# watch(%r|^spec/(.*)_spec\.rb|)
|
14
|
+
# watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
|
15
|
+
# watch(%r|^spec/spec_helper\.rb|) { "spec" }
|
16
|
+
end
|
data/README.md
CHANGED
@@ -28,6 +28,22 @@ Observe:
|
|
28
28
|
export OT_OAUTH_KEY=<YOUR OPENTABLE OAUTH KEY>
|
29
29
|
export OT_OAUTH_SECRET=<YOUR OPENTABLE OAUTH SECRET KEY>
|
30
30
|
|
31
|
+
## Example Run
|
32
|
+
|
33
|
+
$ restaurant = Hungrytable::Restaurant.new(82591)
|
34
|
+
|
35
|
+
> #<Hungrytable::Restaurant:0x0000000032e4098 ... >
|
36
|
+
|
37
|
+
$ search = Hungrytable::RestaurantSearch.new(restaurant, {date_time: 5.days.from_now, party_size: 3})
|
38
|
+
|
39
|
+
> #<Hungrytable::RestaurantSearch:0x00000003143388 ... >
|
40
|
+
|
41
|
+
$ slotlock = Hungrytable::RestaurantSlotlock.new(search)
|
42
|
+
|
43
|
+
> #<Hungrytable::RestaurantSlotlock:0x00000002973a68 ... >
|
44
|
+
|
45
|
+
$ reservation = Hungrytable::ReservationMake.new(slotlock, {email_address: 'foo@bar.com', firstname: 'Mike', lastname: 'Jones', phone: '2813308004'})
|
46
|
+
|
31
47
|
|
32
48
|
## Contributing
|
33
49
|
|
data/hungrytable.gemspec
CHANGED
@@ -22,15 +22,16 @@ Gem::Specification.new do |s|
|
|
22
22
|
# s.add_development_dependency "rspec"
|
23
23
|
# s.add_runtime_dependency "rest-client"
|
24
24
|
|
25
|
-
s.add_runtime_dependency 'oauth', '~> 0.4.5'
|
26
25
|
s.add_runtime_dependency 'json', '~> 1.7.1'
|
26
|
+
s.add_runtime_dependency 'activesupport'
|
27
|
+
s.add_runtime_dependency 'i18n'
|
28
|
+
s.add_runtime_dependency 'curb'
|
27
29
|
|
28
|
-
s.add_development_dependency
|
29
|
-
s.add_development_dependency
|
30
|
-
s.add_development_dependency
|
31
|
-
s.add_development_dependency
|
32
|
-
s.add_development_dependency 'simplecov-rcov'
|
33
|
-
s.add_development_dependency 'rcov', '0.9.11'
|
30
|
+
s.add_development_dependency 'rake'
|
31
|
+
s.add_development_dependency 'minitest'
|
32
|
+
s.add_development_dependency 'minitest-reporters'
|
33
|
+
s.add_development_dependency 'mocha'
|
34
34
|
s.add_development_dependency 'pry'
|
35
|
+
s.add_development_dependency 'webmock'
|
35
36
|
end
|
36
37
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
module Config
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def partner_id
|
6
|
+
ENV['OT_PARTNER_ID'] || config_error('OT_PARTNER_ID')
|
7
|
+
end
|
8
|
+
|
9
|
+
def oauth_key
|
10
|
+
ENV['OT_OAUTH_KEY'] || config_error('OT_OAUTH_KEY')
|
11
|
+
end
|
12
|
+
|
13
|
+
def oauth_secret
|
14
|
+
ENV['OT_OAUTH_SECRET'] || config_error('OT_OAUTH_SECRET')
|
15
|
+
end
|
16
|
+
|
17
|
+
def base_url
|
18
|
+
'https://secure.opentable.com/api/otapi_v2.ashx'
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def config_error var
|
23
|
+
raise HungrytableError, "ENV variable #{var} must be set."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class GetRequest < Request
|
3
|
+
private
|
4
|
+
def auth_header
|
5
|
+
Hungrytable::RequestHeader.new(:get, @uri, {}, {})
|
6
|
+
end
|
7
|
+
|
8
|
+
def make_request
|
9
|
+
Curl::Easy.perform(@uri) do |curl|
|
10
|
+
curl.headers['Authorization'] = auth_header
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class PostRequest < Request
|
3
|
+
private
|
4
|
+
def auth_header
|
5
|
+
Hungrytable::RequestHeader.new(:post, @uri, {}, {})
|
6
|
+
end
|
7
|
+
|
8
|
+
def make_request
|
9
|
+
Curl::Easy.http_post(@uri, @params.to_query) do |curl|
|
10
|
+
curl.headers['Authorization'] = auth_header
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class Request
|
3
|
+
def initialize uri, params={}
|
4
|
+
@uri = Hungrytable::Config.base_url << uri
|
5
|
+
@params = params
|
6
|
+
end
|
7
|
+
|
8
|
+
def parsed_response
|
9
|
+
JSON.parse(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def response
|
14
|
+
@response ||= make_request.body_str
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
module RequestExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
private
|
6
|
+
def request
|
7
|
+
@request ||= @requester.new(request_uri, params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def ensure_required_opts
|
11
|
+
required_opts.each do |key|
|
12
|
+
raise ArgumentError, "options must include a value for #{key}" unless opts.has_key?(key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Will be overwritten in objects that send post requests
|
17
|
+
def params
|
18
|
+
{}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# Modified from simple_oauth (https://github.com/laserlemon/simple_oauth)
|
2
|
+
module Hungrytable
|
3
|
+
class RequestHeader
|
4
|
+
|
5
|
+
ATTRIBUTE_KEYS = %w(consumer_key nonce signature_method timestamp token version).map(&:to_sym)
|
6
|
+
|
7
|
+
def self.default_options
|
8
|
+
{
|
9
|
+
:nonce => OpenSSL::Random.random_bytes(16).unpack('H*')[0],
|
10
|
+
:signature_method => 'HMAC-SHA1',
|
11
|
+
:timestamp => Time.now.to_i.to_s,
|
12
|
+
:version => '1.0',
|
13
|
+
:consumer_key => Hungrytable::Config.oauth_key,
|
14
|
+
:consumer_secret => Hungrytable::Config.oauth_secret,
|
15
|
+
:token => ''
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.encode(value)
|
20
|
+
URI.encode(value.to_s, /[^a-z0-9\-\.\_\~]/i)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.decode(value)
|
24
|
+
URI.decode(value.to_s)
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :method, :params, :options
|
28
|
+
|
29
|
+
def initialize(method, url, params, oauth = {})
|
30
|
+
@method = method.to_s.upcase
|
31
|
+
@uri = URI.parse(url.to_s)
|
32
|
+
@uri.scheme = @uri.scheme.downcase
|
33
|
+
@uri.normalize!
|
34
|
+
@uri.fragment = nil
|
35
|
+
@params = params
|
36
|
+
@options = self.class.default_options.merge(oauth)
|
37
|
+
end
|
38
|
+
|
39
|
+
def url
|
40
|
+
uri = @uri.dup
|
41
|
+
uri.query = nil
|
42
|
+
uri.to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
%Q(OAuth realm="http://www.opentable.com/", #{normalized_attributes})
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid?(secrets = {})
|
50
|
+
original_options = options.dup
|
51
|
+
options.merge!(secrets)
|
52
|
+
valid = options[:signature] == signature
|
53
|
+
options.replace(original_options)
|
54
|
+
valid
|
55
|
+
end
|
56
|
+
|
57
|
+
def signed_attributes
|
58
|
+
attributes.merge(:oauth_signature => signature)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def normalized_attributes
|
64
|
+
signed_attributes.sort_by{|k,v| k.to_s }.map{|k,v| %(#{k}="#{self.class.encode(v)}") }.join(', ')
|
65
|
+
end
|
66
|
+
|
67
|
+
def attributes
|
68
|
+
ATTRIBUTE_KEYS.inject({}){|a,k| options.key?(k) ? a.merge(:"oauth_#{k}" => options[k]) : a }
|
69
|
+
end
|
70
|
+
|
71
|
+
def signature
|
72
|
+
send(options[:signature_method].downcase.tr('-', '_') + '_signature')
|
73
|
+
end
|
74
|
+
|
75
|
+
def hmac_sha1_signature
|
76
|
+
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, secret, signature_base)).chomp.gsub(/\n/, '')
|
77
|
+
end
|
78
|
+
|
79
|
+
def secret
|
80
|
+
options.values_at(:consumer_secret, :token_secret).map{|v| self.class.encode(v) }.join('&')
|
81
|
+
end
|
82
|
+
alias_method :plaintext_signature, :secret
|
83
|
+
|
84
|
+
def signature_base
|
85
|
+
[method, url, normalized_params].map{|v| self.class.encode(v) }.join('&')
|
86
|
+
end
|
87
|
+
|
88
|
+
def normalized_params
|
89
|
+
signature_params.map{|p| p.map{|v| self.class.encode(v) } }.sort.map{|p| p.join('=') }.join('&')
|
90
|
+
end
|
91
|
+
|
92
|
+
def signature_params
|
93
|
+
attributes.to_a + params.to_a + url_params
|
94
|
+
end
|
95
|
+
|
96
|
+
def url_params
|
97
|
+
CGI.parse(@uri.query || '').inject([]){|p,(k,vs)| p + vs.sort.map{|v| [k, v] } }
|
98
|
+
end
|
99
|
+
|
100
|
+
def rsa_sha1_signature
|
101
|
+
Base64.encode64(private_key.sign(OpenSSL::Digest::SHA1.new, signature_base)).chomp.gsub(/\n/, '')
|
102
|
+
end
|
103
|
+
|
104
|
+
def private_key
|
105
|
+
OpenSSL::PKey::RSA.new(options[:consumer_secret])
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class ReservationCancel
|
3
|
+
include RequestExtensions
|
4
|
+
|
5
|
+
attr_reader :opts
|
6
|
+
|
7
|
+
def initialize opts={}
|
8
|
+
@opts = opts
|
9
|
+
ensure_required_opts
|
10
|
+
@requester = opts[:requester] || GetRequest
|
11
|
+
end
|
12
|
+
|
13
|
+
def successful?
|
14
|
+
details["ns:ErrorID"] == "0"
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def request_uri
|
19
|
+
"/reservation/?pid=#{Config.partner_id}&rid=#{opts[:restaurant_id]}&conf=#{opts[:confirmation_number]}&email=#{CGI.escape(opts[:email_address])}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def details
|
23
|
+
request.parsed_response["Results"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def required_opts
|
27
|
+
%w(email_address confirmation_number restaurant_id).map(&:to_sym)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class ReservationMake
|
3
|
+
include RequestExtensions
|
4
|
+
|
5
|
+
attr_reader :restaurant_slotlock, :opts
|
6
|
+
|
7
|
+
def initialize restaurant_slotlock, opts={}
|
8
|
+
@opts = opts
|
9
|
+
ensure_required_opts
|
10
|
+
@requester = opts[:requester] || PostRequest
|
11
|
+
@restaurant_slotlock = restaurant_slotlock
|
12
|
+
end
|
13
|
+
|
14
|
+
def successful?
|
15
|
+
details["ns:ErrorID"] == "0"
|
16
|
+
end
|
17
|
+
|
18
|
+
def confirmation_number
|
19
|
+
return nil unless successful?
|
20
|
+
details["ns:ConfirmationNumber"]
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def required_opts
|
25
|
+
%w(email_address firstname lastname phone).map(&:to_sym)
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_options
|
29
|
+
{
|
30
|
+
'OTannouncementOption' => '0',
|
31
|
+
'RestaurantEmailOption' => '0',
|
32
|
+
'firsttimediner' => '0',
|
33
|
+
'specialinstructions' => 'Have a great time',
|
34
|
+
'slotlockid' => restaurant_slotlock.slotlock_id
|
35
|
+
}.merge(restaurant_slotlock.params)
|
36
|
+
end
|
37
|
+
|
38
|
+
def params
|
39
|
+
default_options.merge(opts)
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_uri
|
43
|
+
"/reservation/?pid=#{Config.partner_id}&st=0"
|
44
|
+
end
|
45
|
+
|
46
|
+
def details
|
47
|
+
request.parsed_response["MakeResults"]
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
File without changes
|
@@ -1,35 +1,58 @@
|
|
1
1
|
module Hungrytable
|
2
|
-
class Restaurant
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
authorize_path: '',
|
13
|
-
access_token_path: '',
|
14
|
-
oauth_token: '',
|
15
|
-
oauth_version: '1.0',
|
16
|
-
http_method: :get
|
17
|
-
)
|
18
|
-
|
19
|
-
@access_token = OAuth::AccessToken.new(@consumer)
|
2
|
+
class Restaurant
|
3
|
+
include RequestExtensions
|
4
|
+
|
5
|
+
def initialize restaurant_id, opts={}
|
6
|
+
@requester = opts[:requester] || GetRequest
|
7
|
+
@restaurant_id = restaurant_id
|
8
|
+
end
|
9
|
+
|
10
|
+
def id
|
11
|
+
@restaurant_id
|
20
12
|
end
|
21
13
|
|
22
|
-
def
|
23
|
-
|
24
|
-
response = @access_token.get(uri)
|
25
|
-
parse_json(response.body)
|
14
|
+
def valid?
|
15
|
+
error_ID == "0"
|
26
16
|
end
|
27
17
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
18
|
+
def method_missing meth, *args, &blk
|
19
|
+
if %w(
|
20
|
+
address
|
21
|
+
city
|
22
|
+
error_ID
|
23
|
+
error_message
|
24
|
+
image_link
|
25
|
+
latitude
|
26
|
+
longitude
|
27
|
+
metro_name
|
28
|
+
neighborhood_name
|
29
|
+
parking
|
30
|
+
parking_details
|
31
|
+
phone
|
32
|
+
postal_code
|
33
|
+
price_range
|
34
|
+
primary_food_type
|
35
|
+
restaurant_description
|
36
|
+
restaurant_ID
|
37
|
+
restaurant_name
|
38
|
+
state
|
39
|
+
url
|
40
|
+
).map(&:to_sym).include?(meth)
|
41
|
+
return details["ns:#{meth.to_s.camelize}"]
|
42
|
+
end
|
43
|
+
super
|
33
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def request_uri
|
49
|
+
"/restaurant/?pid=#{Config.partner_id}&rid=#{id}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Hash]
|
53
|
+
def details
|
54
|
+
request.parsed_response["RestaurantDetailsResults"]
|
55
|
+
end
|
56
|
+
|
34
57
|
end
|
35
58
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class RestaurantSearch
|
3
|
+
include RequestExtensions
|
4
|
+
|
5
|
+
attr_reader :restaurant, :opts
|
6
|
+
|
7
|
+
def initialize restaurant, opts={}
|
8
|
+
@opts = opts
|
9
|
+
ensure_required_opts
|
10
|
+
@requester = opts[:requester] || GetRequest
|
11
|
+
@restaurant = restaurant
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
error_ID == "0"
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing meth, *args, &blk
|
19
|
+
if %w(
|
20
|
+
cuisine_type
|
21
|
+
early_security_ID
|
22
|
+
early_time
|
23
|
+
error_ID
|
24
|
+
error_message
|
25
|
+
exact_security_ID
|
26
|
+
exact_time
|
27
|
+
later_security_ID
|
28
|
+
later_time
|
29
|
+
latitude
|
30
|
+
longitude
|
31
|
+
neighborhood_name
|
32
|
+
restaurant_name
|
33
|
+
results_key
|
34
|
+
).map(&:to_sym).include?(meth)
|
35
|
+
return details["ns:#{meth.to_s.camelize}"]
|
36
|
+
end
|
37
|
+
super
|
38
|
+
end
|
39
|
+
|
40
|
+
def ideal_security_id
|
41
|
+
return exact_security_ID unless exact_security_ID.nil?
|
42
|
+
return early_security_ID unless early_security_ID.nil?
|
43
|
+
return later_security_ID unless later_security_ID.nil?
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def ideal_time
|
48
|
+
return exact_time unless exact_time.nil?
|
49
|
+
return early_time unless early_time.nil?
|
50
|
+
return later_time unless later_time.nil?
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def party_size
|
55
|
+
opts[:party_size]
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def required_opts
|
60
|
+
%w(date_time party_size).map(&:to_sym)
|
61
|
+
end
|
62
|
+
|
63
|
+
def encoded_date_time
|
64
|
+
URI.encode(opts[:date_time].strftime("%m/%d/%Y %I:%M %p"), /[^a-z0-9\-\.\_\~]/i)
|
65
|
+
end
|
66
|
+
|
67
|
+
def request_uri
|
68
|
+
"/table/?pid=#{Config.partner_id}&rid=#{restaurant.id}&dt=#{encoded_date_time}&ps=#{party_size}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def details
|
72
|
+
request.parsed_response["SearchResults"]
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Hungrytable
|
2
|
+
class RestaurantSlotlock
|
3
|
+
include RequestExtensions
|
4
|
+
|
5
|
+
attr_reader :restaurant_search
|
6
|
+
|
7
|
+
def initialize restaurant_search, requester=PostRequest
|
8
|
+
@restaurant_search = restaurant_search
|
9
|
+
@requester = requester
|
10
|
+
end
|
11
|
+
|
12
|
+
def successful?
|
13
|
+
details["ns:ErrorID"] == "0"
|
14
|
+
end
|
15
|
+
|
16
|
+
def slotlock_id
|
17
|
+
return nil unless successful?
|
18
|
+
details["ns:SlotLockID"]
|
19
|
+
end
|
20
|
+
|
21
|
+
def params
|
22
|
+
{
|
23
|
+
'RID' => restaurant.id,
|
24
|
+
'datetime' => restaurant_search.ideal_time,
|
25
|
+
'partysize' => restaurant_search.party_size,
|
26
|
+
'timesecurityID' => restaurant_search.ideal_security_id,
|
27
|
+
'resultskey' => restaurant_search.results_key
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def request_uri
|
33
|
+
"/slotlock/?pid=#{Config.partner_id}&st=0"
|
34
|
+
end
|
35
|
+
|
36
|
+
def restaurant
|
37
|
+
restaurant_search.restaurant
|
38
|
+
end
|
39
|
+
|
40
|
+
def details
|
41
|
+
request.parsed_response["SlotLockResults"]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
data/lib/hungrytable/version.rb
CHANGED
data/lib/hungrytable.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
require 'uri'
|
2
|
+
require 'json'
|
3
|
+
require 'openssl'
|
4
|
+
require 'base64'
|
5
|
+
require 'cgi'
|
6
|
+
require 'curb'
|
7
|
+
require 'active_support/core_ext'
|
8
|
+
require 'hungrytable/version'
|
9
|
+
require 'hungrytable/config'
|
10
|
+
require 'hungrytable/request_extensions'
|
11
|
+
require 'hungrytable/request_header'
|
12
|
+
require 'hungrytable/request'
|
13
|
+
require 'hungrytable/get_request'
|
14
|
+
require 'hungrytable/post_request'
|
15
|
+
require 'hungrytable/restaurant'
|
16
|
+
require 'hungrytable/restaurant_search'
|
17
|
+
require 'hungrytable/restaurant_slotlock'
|
18
|
+
require 'hungrytable/reservation_make'
|
19
|
+
require 'hungrytable/reservation_status'
|
20
|
+
require 'hungrytable/reservation_cancel'
|
7
21
|
|
8
22
|
module Hungrytable
|
23
|
+
class HungrytableError < StandardError;end
|
9
24
|
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Status: 200
|
3
|
+
Vary: Accept-Encoding
|
4
|
+
Content-Type: application/json
|
5
|
+
|
6
|
+
{ "RestaurantDetailsResults": {"ns:Address": null, "ns:City": "799 Market Street", "ns:ErrorID": "0", "ns:ErrorMessage": null, "ns:ImageLink": null, "ns:Latitude": null, "ns:Longitude": null, "ns:MenuURL": null, "ns:MetroID": "1", "ns:MetroName": "Demoland", "ns:NeighborhoodName": "Devland", "ns:Parking": "No", "ns:ParkingDetails": null, "ns:Phone": "4157897485", "ns:PostalCode": "94103", "ns:PriceRange": "$30 and under", "ns:PrimaryFoodType": "American", "ns:ReserveUrl": "1759B23C", "ns:RestaurantDescription": "Coming Soon!", "ns:RestaurantID": "82591", "ns:RestaurantName": "OTConnect-Partner-Rest1", "ns:State": "CA", "ns:Url": null, "xmlns:ns": "com.opentable.webservices.v2" }}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Status: 200
|
3
|
+
Vary: Accept-Encoding
|
4
|
+
Content-Type: application/json
|
5
|
+
|
6
|
+
{"SearchResults": {"ns:CuisineType": "American", "ns:EarlyPoints": "100", "ns:EarlySecurityID": "1113043844", "ns:EarlyTime": "5/16/2012 1:45:00 PM", "ns:ErrorID": "0", "ns:ErrorMessage": null, "ns:ExactPoints": "100", "ns:ExactSecurityID": "1113043836", "ns:ExactTime": "5/16/2012 2:00:00 PM", "ns:ImageExists": "0", "ns:Latitude": null, "ns:Longitude": null, "ns:NeighborhoodName": "Devland", "ns:Price": "$$", "ns:RestaurantID": "82591", "ns:RestaurantName": "OTConnect-Partner-Rest1", "ns:ResultsKey": "z0OlOTkH2NbY%2bq7bjf7Lxw%3d%3d", "xmlns:ns": "com.opentable.webservices.v2" }}
|
7
|
+
|
data/test/test_helper.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
|
-
# Set up simplecov
|
2
|
-
require 'simplecov'
|
3
|
-
require 'simplecov-rcov'
|
4
|
-
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
5
|
-
|
6
1
|
require 'minitest/autorun'
|
7
2
|
require 'minitest/reporters'
|
8
3
|
|
9
4
|
require 'ostruct'
|
10
5
|
require 'pry'
|
6
|
+
require 'webmock'
|
7
|
+
include WebMock::API
|
8
|
+
|
11
9
|
|
12
10
|
# Load support files
|
13
11
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
@@ -19,5 +17,5 @@ if ENV['JENKINS']
|
|
19
17
|
MiniTest::Unit.runner.reporters << MiniTest::Reporters::JUnitReporter.new
|
20
18
|
end
|
21
19
|
|
22
|
-
|
20
|
+
require 'mocha'
|
23
21
|
require File.expand_path("../../lib/hungrytable.rb", __FILE__)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Hungrytable::Config do
|
4
|
+
describe 'when the correct ENV vars are not set' do
|
5
|
+
before do
|
6
|
+
ENV['OT_PARTNER_ID'] = nil
|
7
|
+
ENV['OT_OAUTH_KEY'] = nil
|
8
|
+
ENV['OT_OAUTH_SECRET'] = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'raises a HungrytableError' do
|
12
|
+
[:partner_id, :oauth_key, :oauth_secret].each do |meth|
|
13
|
+
-> {Hungrytable::Config.send meth}.must_raise Hungrytable::HungrytableError
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'when the ENV vars are set' do
|
19
|
+
before do
|
20
|
+
ENV['OT_PARTNER_ID'] = 'foo'
|
21
|
+
ENV['OT_OAUTH_KEY'] = 'bar'
|
22
|
+
ENV['OT_OAUTH_SECRET'] = 'baz'
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '.partner_id' do
|
26
|
+
it 'returns the value for OT_PARTNER_ID' do
|
27
|
+
Hungrytable::Config.partner_id.must_equal 'foo'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.oauth_key' do
|
32
|
+
it 'returns the value for OT_OAUTH_KEY' do
|
33
|
+
Hungrytable::Config.oauth_key.must_equal 'bar'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '.oauth_secret' do
|
38
|
+
it 'returns the value for OT_OAUTH_SECRET' do
|
39
|
+
Hungrytable::Config.oauth_secret.must_equal 'baz'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
File without changes
|
@@ -13,21 +13,29 @@ describe Hungrytable::Restaurant do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
describe '
|
16
|
+
describe '#get_details' do
|
17
17
|
before do
|
18
18
|
@restaurant = subject.new
|
19
|
+
stub_request(:get, /.*secure.opentable.com\/api\/otapi_v2.ashx\/restaurant.*/).to_return(File.new('./test/restaurant_get_details_result.json'))
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
it 'should return relevant details about an individual restaurant' do
|
22
23
|
response = @restaurant.get_details(82591)
|
23
24
|
response.must_be_kind_of Hash
|
24
25
|
end
|
26
|
+
end
|
25
27
|
|
28
|
+
describe '#search' do
|
29
|
+
before do
|
30
|
+
@restaurant = subject.new
|
31
|
+
stub_request(:get, /.*secure.opentable.com\/api\/otapi_v2.ashx\/table.*/).to_return(File.new('./test/restaurant_search_result.json'), :status => 200)
|
32
|
+
end
|
33
|
+
|
26
34
|
it 'should look for availability at an inidividual restaurant' do
|
27
35
|
date_time = Time.now.strftime "%-m/#{Time.now.day + 1}/%Y %-l:%M %p"
|
28
36
|
response = @restaurant.search({ restaurant_id: 82591, date_time: date_time, party_size: 2 })
|
29
37
|
response.must_be_kind_of Hash
|
30
38
|
end
|
31
|
-
|
32
39
|
end
|
40
|
+
|
33
41
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
=begin
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
describe Hungrytable::User do
|
5
|
+
subject { Hungrytable::User }
|
6
|
+
|
7
|
+
it 'should be a class' do
|
8
|
+
subject.class.must_be_kind_of Class
|
9
|
+
end
|
10
|
+
|
11
|
+
%w{ login }.each do |meth|
|
12
|
+
it "should respond to #{meth}" do
|
13
|
+
assert subject.new.respond_to?(meth.to_sym), true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'users' do
|
18
|
+
before do
|
19
|
+
stub_request(:get, /.*secure.opentable.com\/api\/otapi_v2.ashx\/user.*/).to_return(File.new('./test/user_login_result.json'), :status => 200)
|
20
|
+
@user = subject.new
|
21
|
+
end
|
22
|
+
it 'should be able to login' do
|
23
|
+
response = @user.login({ email: 'bob@webservices.com', password: 'password' })
|
24
|
+
response.must_be_kind_of Hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
=end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
describe Hungrytable::Restaurant do
|
5
|
+
before do
|
6
|
+
@mock_requester = mock('GetRequest')
|
7
|
+
@mock_request = mock('get')
|
8
|
+
@mock_requester.expects(:new).returns(@mock_request)
|
9
|
+
@mock_request.stubs(:parsed_response).returns({"RestaurantDetailsResults" => {}})
|
10
|
+
ENV['OT_PARTNER_ID'] = 'foo'
|
11
|
+
@restaurant = Hungrytable::Restaurant.new(1, requester: @mock_requester)
|
12
|
+
end
|
13
|
+
%w(
|
14
|
+
address
|
15
|
+
city
|
16
|
+
error_ID
|
17
|
+
error_message
|
18
|
+
image_link
|
19
|
+
latitude
|
20
|
+
longitude
|
21
|
+
metro_name
|
22
|
+
neighborhood_name
|
23
|
+
parking
|
24
|
+
parking_details
|
25
|
+
phone
|
26
|
+
postal_code
|
27
|
+
price_range
|
28
|
+
primary_food_type
|
29
|
+
restaurant_description
|
30
|
+
restaurant_ID
|
31
|
+
restaurant_name
|
32
|
+
state
|
33
|
+
url
|
34
|
+
).map(&:to_sym).each do |meth|
|
35
|
+
it "responds to #{meth.to_s} via method_missing" do
|
36
|
+
@restaurant.send(meth).must_equal nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hungrytable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,55 +9,75 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 1.7.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: json
|
27
|
-
requirement: &6925700 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
25
|
none: false
|
29
26
|
requirements:
|
30
27
|
- - ~>
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: 1.7.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement:
|
47
|
+
name: i18n
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
42
52
|
- !ruby/object:Gem::Version
|
43
53
|
version: '0'
|
44
|
-
type: :
|
54
|
+
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
49
|
-
requirement:
|
63
|
+
name: curb
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
53
68
|
- !ruby/object:Gem::Version
|
54
69
|
version: '0'
|
55
|
-
type: :
|
70
|
+
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: rake
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
71
|
-
requirement:
|
95
|
+
name: minitest
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
82
|
-
requirement:
|
111
|
+
name: minitest-reporters
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,21 +117,31 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
|
-
name:
|
93
|
-
requirement:
|
127
|
+
name: mocha
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
|
-
- -
|
131
|
+
- - ! '>='
|
97
132
|
- !ruby/object:Gem::Version
|
98
|
-
version: 0
|
133
|
+
version: '0'
|
99
134
|
type: :development
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
102
142
|
- !ruby/object:Gem::Dependency
|
103
143
|
name: pry
|
104
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
105
145
|
none: false
|
106
146
|
requirements:
|
107
147
|
- - ! '>='
|
@@ -109,7 +149,28 @@ dependencies:
|
|
109
149
|
version: '0'
|
110
150
|
type: :development
|
111
151
|
prerelease: false
|
112
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: webmock
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
113
174
|
description: Gem to interact with OpenTable's REST API
|
114
175
|
email:
|
115
176
|
- david@isotope11.com
|
@@ -120,20 +181,41 @@ files:
|
|
120
181
|
- .gitignore
|
121
182
|
- .rvmrc
|
122
183
|
- Gemfile
|
184
|
+
- Guardfile
|
123
185
|
- LICENSE
|
124
186
|
- README.md
|
125
187
|
- RELEASE_NOTES.md
|
126
188
|
- Rakefile
|
127
189
|
- hungrytable.gemspec
|
128
190
|
- lib/hungrytable.rb
|
129
|
-
- lib/hungrytable/
|
130
|
-
- lib/hungrytable/
|
191
|
+
- lib/hungrytable/config.rb
|
192
|
+
- lib/hungrytable/get_request.rb
|
193
|
+
- lib/hungrytable/post_request.rb
|
194
|
+
- lib/hungrytable/request.rb
|
195
|
+
- lib/hungrytable/request_extensions.rb
|
196
|
+
- lib/hungrytable/request_header.rb
|
197
|
+
- lib/hungrytable/reservation_cancel.rb
|
198
|
+
- lib/hungrytable/reservation_make.rb
|
199
|
+
- lib/hungrytable/reservation_status.rb
|
131
200
|
- lib/hungrytable/restaurant.rb
|
201
|
+
- lib/hungrytable/restaurant_search.rb
|
202
|
+
- lib/hungrytable/restaurant_slotlock.rb
|
132
203
|
- lib/hungrytable/version.rb
|
133
|
-
- test/
|
134
|
-
- test/
|
204
|
+
- test/restaurant_get_details_result.json
|
205
|
+
- test/restaurant_search_result.json
|
135
206
|
- test/test_helper.rb
|
207
|
+
- test/unit/config_test.rb
|
208
|
+
- test/unit/get_request_test.rb
|
136
209
|
- test/unit/hungrytable/restaurant_test.rb
|
210
|
+
- test/unit/hungrytable/user_test.rb
|
211
|
+
- test/unit/post_request_test.rb
|
212
|
+
- test/unit/request_test.rb
|
213
|
+
- test/unit/reservation_cancel_test.rb
|
214
|
+
- test/unit/reservation_make_test.rb
|
215
|
+
- test/unit/restaurant_search_test.rb
|
216
|
+
- test/unit/restaurant_slotlock_test.rb
|
217
|
+
- test/unit/restaurant_test.rb
|
218
|
+
- test/user_login_result.json
|
137
219
|
homepage: http://www.isotope11.com/
|
138
220
|
licenses: []
|
139
221
|
post_install_message:
|
@@ -146,20 +228,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
228
|
- - ! '>='
|
147
229
|
- !ruby/object:Gem::Version
|
148
230
|
version: '0'
|
231
|
+
segments:
|
232
|
+
- 0
|
233
|
+
hash: -1516024462257141481
|
149
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
235
|
none: false
|
151
236
|
requirements:
|
152
237
|
- - ! '>='
|
153
238
|
- !ruby/object:Gem::Version
|
154
239
|
version: '0'
|
240
|
+
segments:
|
241
|
+
- 0
|
242
|
+
hash: -1516024462257141481
|
155
243
|
requirements: []
|
156
244
|
rubyforge_project: hungrytable
|
157
|
-
rubygems_version: 1.8.
|
245
|
+
rubygems_version: 1.8.24
|
158
246
|
signing_key:
|
159
247
|
specification_version: 3
|
160
248
|
summary: Gem to interact with OpenTable's REST API
|
161
|
-
test_files:
|
162
|
-
- test/hungrytable_test.rb
|
163
|
-
- test/support/minitest_junit.rb
|
164
|
-
- test/test_helper.rb
|
165
|
-
- test/unit/hungrytable/restaurant_test.rb
|
249
|
+
test_files: []
|
data/lib/hungrytable/base.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Hungrytable
|
2
|
-
class Base
|
3
|
-
def validate_environment_variables
|
4
|
-
raise "Please set the environment variable OT_OAUTH_KEY to your OpenTable OAuth Table." unless ENV['OT_OAUTH_KEY']
|
5
|
-
raise "Please set the environment variable OT_OAUTH_SECRET to your OpenTable OAuth Secret Key." unless ENV['OT_OAUTH_SECRET']
|
6
|
-
raise "Please set the environment variable OT_PARTNER_ID to your OpentTable Partner ID." unless ENV['OT_PARTNER_ID']
|
7
|
-
end
|
8
|
-
|
9
|
-
def parse_uri_option(option_name, options)
|
10
|
-
val = options[option_name.to_sym]
|
11
|
-
raise "Missing required option: #{option_name}" if val.nil?
|
12
|
-
if val.is_a?(String)
|
13
|
-
val = CGI.escape(val).gsub(/[+]/, '%20')
|
14
|
-
end
|
15
|
-
instance_variable_set("@#{option_name}", val)
|
16
|
-
end
|
17
|
-
|
18
|
-
def parse_uri_options(*option_names, options)
|
19
|
-
option_names.each { |option_name| parse_uri_option(option_name, options) }
|
20
|
-
end
|
21
|
-
|
22
|
-
def parse_json(string)
|
23
|
-
JSON.parse(string)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'oauth'
|
2
|
-
module OAuth::Client
|
3
|
-
class Helper
|
4
|
-
def oauth_parameters
|
5
|
-
{
|
6
|
-
'oauth_body_hash' => options[:body_hash],
|
7
|
-
'oauth_callback' => options[:oauth_callback],
|
8
|
-
'oauth_consumer_key' => options[:consumer].key,
|
9
|
-
'oauth_token' => options[:token] ? options[:token].token : '',
|
10
|
-
'oauth_signature_method' => options[:signature_method],
|
11
|
-
'oauth_timestamp' => timestamp,
|
12
|
-
'oauth_nonce' => nonce,
|
13
|
-
'oauth_verifier' => options[:oauth_verifier],
|
14
|
-
'oauth_version' => (options[:oauth_version] || '1.0'),
|
15
|
-
'oauth_session_handle' => options[:oauth_session_handle]
|
16
|
-
}.reject { |k,v| v.to_s == "" && k.to_s != 'oauth_token' }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/test/hungrytable_test.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'ansi'
|
2
|
-
|
3
|
-
module MiniTest
|
4
|
-
module Reporters
|
5
|
-
# A reporter identical to the standard MiniTest reporter.
|
6
|
-
#
|
7
|
-
# Based upon Ryan Davis of Seattle.rb's MiniTest (MIT License).
|
8
|
-
#
|
9
|
-
# @see https://github.com/seattlerb/minitest MiniTest
|
10
|
-
class JUnitReporter
|
11
|
-
include MiniTest::Reporter
|
12
|
-
|
13
|
-
def before_suites(suites, type)
|
14
|
-
end
|
15
|
-
|
16
|
-
def before_test(suite, test)
|
17
|
-
end
|
18
|
-
|
19
|
-
def pass(suite, test, test_runner)
|
20
|
-
end
|
21
|
-
|
22
|
-
def skip(suite, test, test_runner)
|
23
|
-
end
|
24
|
-
|
25
|
-
def failure(suite, test, test_runner)
|
26
|
-
end
|
27
|
-
|
28
|
-
def error(suite, test, test_runner)
|
29
|
-
end
|
30
|
-
|
31
|
-
def after_suites(suites, type)
|
32
|
-
time = Time.now - runner.start_time
|
33
|
-
i = 0
|
34
|
-
runner.report.each do |suite, tests|
|
35
|
-
File.open("#{suite.to_s.gsub(" ", '_').downcase}.xml", 'w') do |out|
|
36
|
-
out.puts '<?xml version="1.0" encoding="UTF-8" ?>'
|
37
|
-
out.puts "<testsuite errors=\"#{runner.errors}\" failures=\"#{runner.failures}\" tests=\"#{runner.test_count}\" time=\"#{time}\" timestamp=\"#{runner.start_time.strftime('%FT%R')}\">"
|
38
|
-
tests.each do |test, test_runner|
|
39
|
-
out.print "<testcase classname=\"#{suite}\" name=\"#{test}\" time=\"0\">"
|
40
|
-
message = message_for(test_runner)
|
41
|
-
out.puts "\n#{message}" if message
|
42
|
-
out.puts '</testcase>'
|
43
|
-
end
|
44
|
-
out.puts '</testsuite>'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
def location(exception)
|
51
|
-
last_before_assertion = ''
|
52
|
-
|
53
|
-
exception.backtrace.reverse_each do |s|
|
54
|
-
break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
|
55
|
-
last_before_assertion = s
|
56
|
-
end
|
57
|
-
|
58
|
-
last_before_assertion.sub(/:in .*$/, '')
|
59
|
-
end
|
60
|
-
|
61
|
-
def message_for(test_runner)
|
62
|
-
suite = test_runner.suite
|
63
|
-
test = test_runner.test
|
64
|
-
e = test_runner.exception
|
65
|
-
|
66
|
-
case test_runner.result
|
67
|
-
when :pass then nil
|
68
|
-
when :skip then "<skipped message=\"\"/>"
|
69
|
-
when :failure then "<failure message=\"#{e.message}\" type=\"failure\">#{location(e)}:\n#{e.message}\n</failure>"
|
70
|
-
when :error then "<error message=\"#{e.message}\" type=\"error\">#{location(e)}:\n#{e.message}\n</error>"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def status
|
75
|
-
'%d tests, %d assertions, %d failures, %d errors, %d skips' %
|
76
|
-
[runner.test_count, runner.assertion_count, runner.failures, runner.errors, runner.skips]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|