ytlabs_api_client 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +10 -0
- data/README.md +203 -0
- data/lib/ytlabs_api.rb +35 -0
- data/lib/ytlabs_api/availability.rb +34 -0
- data/lib/ytlabs_api/booking.rb +107 -0
- data/lib/ytlabs_api/cancellation.rb +55 -0
- data/lib/ytlabs_api/client.rb +129 -0
- data/lib/ytlabs_api/end_points.yml +26 -0
- data/lib/ytlabs_api/property.rb +61 -0
- data/lib/ytlabs_api/room_type.rb +59 -0
- data/lib/ytlabs_api/supplementary_information.rb +63 -0
- data/lib/ytlabs_api/version.rb +3 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/ytlabs_api/client_spec.rb +163 -0
- data/spec/ytlabs_api_spec.rb +9 -0
- metadata +72 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f30bcad7ecac2a4ebf8c127f56f8d6da4cfa1437
|
4
|
+
data.tar.gz: a3fb99eb663787a7eb06ff638265766a5e613ead
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c679f3ecd6b371a0eefdf26e877679b4c28a645ca35f072045dd6efcfe678e272d5b2d579646b650b2105ab09664458ff3da8b2c456d42c3b81468a863d2a5ca
|
7
|
+
data.tar.gz: 2e6d1c071b7d1012c333ae2d3d70ee5e752dfbcb99cf86433a9a96787da8f5998ce5e1103865aebbdee90d7d1bd118696681d8eff79484457e0b5703f29eb982
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
YTLabs API Client
|
2
|
+
===================
|
3
|
+
|
4
|
+
A Ruby wrapper packaged as a Gem enabling Ruby calls to the Yello Travel Labs API which provides endpoints to search & book their inventory of Korea based rental properties. Visit Yello Travel Labs at [http://www.ytlabs.co.kr/](http://www.ytlabs.co.kr/). You will need an access token.
|
5
|
+
|
6
|
+
The YTLabs API uses camelCase params, however as this is a Ruby wrapper I have followed the Ruby convention of using underscore_case parameter naming, with the exception of `client.post_reservation_confirmation`. The belows README (and also the comments above the definition of each method) documents all required and optional parameter formats.
|
7
|
+
|
8
|
+
A work in progress as of July 2016, hence currently calling staging url.
|
9
|
+
|
10
|
+
### Requirements:
|
11
|
+
|
12
|
+
httparty [github.com/jnunemaker/httparty](http://www.github.com/jnunemaker/httparty)
|
13
|
+
|
14
|
+
===================
|
15
|
+
|
16
|
+
### Install:
|
17
|
+
|
18
|
+
```
|
19
|
+
gem install 'ytlabs_api_client'
|
20
|
+
```
|
21
|
+
|
22
|
+
===================
|
23
|
+
|
24
|
+
### Usage:
|
25
|
+
|
26
|
+
```
|
27
|
+
client = YTLabsApi::Client.new(token, :json)
|
28
|
+
```
|
29
|
+
|
30
|
+
===================
|
31
|
+
|
32
|
+
### Endpoints covered:
|
33
|
+
|
34
|
+
#### GET Requests
|
35
|
+
|
36
|
+
#### get_properties: "GET /properties/"
|
37
|
+
```
|
38
|
+
Use this resource to get a response a list of properties in the YTLabs API.
|
39
|
+
|
40
|
+
- Required => updated_at Date at which data starts being returned. (YYYY-MM-
|
41
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN,
|
42
|
+
- Optional => offset default: 0 Data offset (default 0)
|
43
|
+
- Optional => limit default: 30 Amount of requested properties (default 30)
|
44
|
+
- Optional => active default: 1 To filter by only active properties. 0 returns all. 1 returns Active o
|
45
|
+
|
46
|
+
When parameter 'limit=0&updatedAt=1970-01-01' is specified in request, all of the properties' information is
|
47
|
+
returned. It is recommended only for the first ever call made to retrieve all information.
|
48
|
+
|
49
|
+
Usage: get_property(params)
|
50
|
+
Example usage: client.get_properties(:updated_at => "1970-01-01", :limit => 3)
|
51
|
+
```
|
52
|
+
===================
|
53
|
+
|
54
|
+
#### get_property: "GET /properties/{propertyID}/"
|
55
|
+
```
|
56
|
+
Use this resource with a property_identifier (e.g. "w_w0307279") to get the property's information.
|
57
|
+
|
58
|
+
- Required => property_identifier The unique property identifier/hash (e.g. w_w0307279)
|
59
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
60
|
+
|
61
|
+
Usage: get_property(property_identifier, params=nil)
|
62
|
+
Example usage: client.get_property("w_w0307279", :i18n => "en-US")
|
63
|
+
```
|
64
|
+
===================
|
65
|
+
|
66
|
+
#### get_availability: "GET /available/{propertyID}"
|
67
|
+
```
|
68
|
+
Use this resource with a property_identifier (e.g. "w_w0307279") & a stay start_date to obtain rates & availability.
|
69
|
+
|
70
|
+
Required => property_identifier The unique property identifier/hash (e.g. w_w0307279)
|
71
|
+
Required => start_date YYYY-MM-DD (ex: 2016-02-01). Stay start date.
|
72
|
+
Optional => end_date default: (start_date + 1 day) YYYY-MM-DD (ex: 2016-02-05). Stay end date. If empty, defaults to start_date + 1 day.
|
73
|
+
|
74
|
+
Usage: get_availability(property_identifier, start_date, end_date=nil)
|
75
|
+
Example usage: client.get_availability("w_w0307279_R01", "2016-07-01", "2016-07-10")
|
76
|
+
```
|
77
|
+
===================
|
78
|
+
|
79
|
+
#### get_provinces: "GET /provincecode/"
|
80
|
+
```
|
81
|
+
Returns a list with code or name of province.
|
82
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
83
|
+
|
84
|
+
Example usage: client.get_provinces
|
85
|
+
```
|
86
|
+
===================
|
87
|
+
|
88
|
+
#### get_cities: "GET /citycode/"
|
89
|
+
```
|
90
|
+
Returns a list with code or name of cities.
|
91
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
92
|
+
|
93
|
+
Example usage: client.get_cities
|
94
|
+
```
|
95
|
+
===================
|
96
|
+
|
97
|
+
#### get_extra_service_codes: "GET /extraservicecode/"
|
98
|
+
```
|
99
|
+
Returns a list mapping the codes and names of extra services.
|
100
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
101
|
+
|
102
|
+
Example usage: client.get_extra_service_codes
|
103
|
+
```
|
104
|
+
===================
|
105
|
+
|
106
|
+
#### get_theme_codes: "GET /themecode/"
|
107
|
+
```
|
108
|
+
Returns a list mapping the code and name of themes.
|
109
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
110
|
+
|
111
|
+
Example usage: client.get_theme_codes
|
112
|
+
```
|
113
|
+
===================
|
114
|
+
|
115
|
+
#### get_reservations: "GET /reservation/information"
|
116
|
+
```
|
117
|
+
1. Use this resource with a set of dates to retrieve a collection of reservations between the given dates
|
118
|
+
2. Use this resource with a reservation identifier(hash) + the start date to retrieve a collection of one reservation.
|
119
|
+
|
120
|
+
- Required => start_date YYYY-MM-DD (ex: 2016-02-01). Search by start date.
|
121
|
+
- Required => end_date YYYY-MM-DD (ex: 2016-02-05). Search by end date.
|
122
|
+
- Optional => reservation_identifier The unique property identifier/hash (e.g. w_w03072)
|
123
|
+
|
124
|
+
Example usage: client.get_reservations("2016-07-01", "2016-07-10", "w_w0307279_R01")
|
125
|
+
```
|
126
|
+
===================
|
127
|
+
|
128
|
+
#### get_room_types: "GET /roomtypes/"
|
129
|
+
```
|
130
|
+
Use this resource to obtain a list of all room types.
|
131
|
+
- Required => updated_at Date at which data starts being returned. (YYYY-MM-
|
132
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-
|
133
|
+
- Optional => offset default: 0 Data offset (default 0)
|
134
|
+
- Optional => limit default: 30 Amount of requested room type (default 30)
|
135
|
+
- Optional => active default: 1 To filter by only active room type. 0 returns all. 1 returns Active o
|
136
|
+
|
137
|
+
Example usage: client.get_room_types(:updated_at => "1970-01-01", :limit => 1)
|
138
|
+
```
|
139
|
+
===================
|
140
|
+
|
141
|
+
#### get_property_room_types: "GET /properties/{propertyID}/roomtypes/"
|
142
|
+
```
|
143
|
+
Using a specific propertyID, get all roomtypes' information of the property.
|
144
|
+
|
145
|
+
- Required => property_identifier Date at which data starts being returned. (YYYY-MM-
|
146
|
+
- Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja
|
147
|
+
|
148
|
+
Example usage: client.get_property_room_types("w_w0307279", :i81n => "en-US")
|
149
|
+
```
|
150
|
+
===================
|
151
|
+
|
152
|
+
#### get_cancellation_charge: "GET /reservation/cancelcharge/"
|
153
|
+
```
|
154
|
+
Using a reservation number get the cancellation fee payable. If a reservation is cancelled within 7 days of the check in day, a cancellation fee will be charged.
|
155
|
+
|
156
|
+
- Required => reservation_number Unique reservation number
|
157
|
+
|
158
|
+
Example usage: client.get_cancellation_charge("w_WP20160705145532ECD5")
|
159
|
+
```
|
160
|
+
|
161
|
+
#### POST Requests
|
162
|
+
|
163
|
+
#### post_reservation_request(property_identifier, start_date, end_date): "POST /reservation/holding/"
|
164
|
+
```
|
165
|
+
Before making a reservation, the room must be held - to prevent double booking.
|
166
|
+
|
167
|
+
Example usage: client.post_reservation_request("w_w0814002_R01", "2016-07-01", "2016-07-10")
|
168
|
+
```
|
169
|
+
===================
|
170
|
+
|
171
|
+
|
172
|
+
#### post_reservation_confirmation: "POST /reservation/confirm"
|
173
|
+
```
|
174
|
+
Confirm a booking.
|
175
|
+
|
176
|
+
Format expected (Ruby Hash):
|
177
|
+
|
178
|
+
request_body = {
|
179
|
+
"reservationNo" => "w_WP20160718164753DE39",
|
180
|
+
"roomtypeCode" => "w_w0814002_R01",
|
181
|
+
"checkInDate" => "2016-07-01",
|
182
|
+
"checkOutDate" => "2016-07-10",
|
183
|
+
"guestName" => "Bob",
|
184
|
+
"guestCount" => 4,
|
185
|
+
"adultCount" => 2,
|
186
|
+
"childrenCount" => 2,
|
187
|
+
"paidPrice" => 2000.0,
|
188
|
+
"sellingPrice" => 2000.0,
|
189
|
+
"commissionPrice" => 200.0,
|
190
|
+
"currency" => "KRW"
|
191
|
+
}
|
192
|
+
|
193
|
+
Example usage: client.post_reservation_confirmation(request_body)
|
194
|
+
```
|
195
|
+
===================
|
196
|
+
|
197
|
+
#### post_cancellation_request(reservation_number, paid_price, commission_price, currency) "POST /reservation/cancel"
|
198
|
+
|
199
|
+
```
|
200
|
+
Cancel a booking.
|
201
|
+
|
202
|
+
Example usage: client.post_cancellation_request("w_WP20160718164753DE39", 2000.0, 200.0, "KRW")
|
203
|
+
```
|
data/lib/ytlabs_api.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'httparty'
|
4
|
+
require 'active_support/inflector'
|
5
|
+
|
6
|
+
require_relative 'ytlabs_api/client'
|
7
|
+
|
8
|
+
## Exceptions
|
9
|
+
module YTLabsApi
|
10
|
+
|
11
|
+
#To be implemented in the Client.
|
12
|
+
class NetworkError < StandardError
|
13
|
+
def initialize(status, body)
|
14
|
+
super("Error. HTTP status: #{status}. Response body: #{body}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class InvalidAccessToken < StandardError
|
19
|
+
def initialize
|
20
|
+
super("Your access token is not valid. It must be 36 characters long.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class InvalidContentType < StandardError
|
25
|
+
def initialize
|
26
|
+
super("Your content type is invalid. 'json' or 'xml' are the 2 valid options")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class EndPointNotSupported < StandardError
|
31
|
+
def initialize
|
32
|
+
super("This endpoint is not supported: Try one of these: #{Client::END_POINTS.keys}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module YTLabsApi
|
2
|
+
module Availability
|
3
|
+
|
4
|
+
# GET /available/
|
5
|
+
# Use this resource with a property_identifier (e.g. "w_w0307279") & a stay start_date to obtain rates & availability.
|
6
|
+
#
|
7
|
+
# Parameters:
|
8
|
+
#
|
9
|
+
# Required => property_identifier The unique property identifier/hash (e.g. w_w0307279)
|
10
|
+
# Required => start_date YYYY-MM-DD (ex: 2016-02-01). Stay start date.
|
11
|
+
#
|
12
|
+
# Optional => end_date default: start_date + 1 day YYYY-MM-DD (ex: 2016-02-05). Stay end date. If empty, defaults to start_date + 1 day.
|
13
|
+
#
|
14
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/available?roomCode=w_w0307279_R01&searchStartDate=2016-07-01&searchEndDate=2016-07-10
|
15
|
+
#
|
16
|
+
# Example usage: client.get_availability("w_w0307279_R01", "2016-12-01", "2016-12-10")
|
17
|
+
|
18
|
+
def get_availability(property_identifier, start_date, end_date=nil)
|
19
|
+
params = {
|
20
|
+
:roomCode => "#{property_identifier}",
|
21
|
+
:searchStartDate => "#{start_date}"
|
22
|
+
}
|
23
|
+
|
24
|
+
params.merge!(:searchEndDate => "#{end_date}") if end_date
|
25
|
+
|
26
|
+
response = HTTParty.get(
|
27
|
+
"#{build_url(__method__.to_s)}?#{transform_params!(params)}",
|
28
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
29
|
+
)
|
30
|
+
|
31
|
+
prepare_response(response)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module YTLabsApi
|
2
|
+
module Booking
|
3
|
+
|
4
|
+
# POST /reservation/holding/
|
5
|
+
# Before making a reservation, the room must be held - to prevent double booking.
|
6
|
+
# Other customers cannot make a reservation until the holding status has ended.
|
7
|
+
# If 'pending' is returned in the response, the user can request Reservation Confirm.
|
8
|
+
|
9
|
+
# Format expected (JSON content type):
|
10
|
+
#
|
11
|
+
# {
|
12
|
+
# "roomCode" : "w_w0814002_R01",
|
13
|
+
# "checkInDate" : "2016-09-15",
|
14
|
+
# "checkOutDate" : "2016-09-16"
|
15
|
+
# }
|
16
|
+
|
17
|
+
def post_reservation_request(property_identifier, start_date, end_date)
|
18
|
+
request_body = {
|
19
|
+
:roomCode => "#{property_identifier}",
|
20
|
+
:checkInDate => "#{start_date}",
|
21
|
+
:checkOutDate => "#{end_date}"
|
22
|
+
}.to_json
|
23
|
+
|
24
|
+
response = HTTParty.post(
|
25
|
+
"#{build_url(__method__.to_s)}",
|
26
|
+
body: request_body,
|
27
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
28
|
+
)
|
29
|
+
|
30
|
+
prepare_response(response)
|
31
|
+
end
|
32
|
+
|
33
|
+
# _________________________________________________________________________________________ #
|
34
|
+
|
35
|
+
# POST /reservation/confirm/
|
36
|
+
# The user must have a valid reservation number that will have been returned by making a successful 'reservation request'.
|
37
|
+
#
|
38
|
+
# Note that this method accepts a body with keys specified in camelcase.
|
39
|
+
|
40
|
+
# Format expected (JSON content type):
|
41
|
+
#
|
42
|
+
# {
|
43
|
+
# *** Required ***
|
44
|
+
# "reservationNo" : "w_WP000000000000000",
|
45
|
+
# "roomtypeCode" : "w_w0814002_R01",
|
46
|
+
# "checkInDate" : "2016-09-15",
|
47
|
+
# "checkOutDate" : "2016-09-16",
|
48
|
+
# "guestName" : "Lucy",
|
49
|
+
# "guestCount" : 3,
|
50
|
+
# "adultCount" : 2,
|
51
|
+
# "childrenCount" : 1,
|
52
|
+
# "paidPrice" : 2000.0,
|
53
|
+
# "sellingPrice" : 2000.0,
|
54
|
+
# "commissionPrice" : 200.0,
|
55
|
+
# "currency" : "KRW",
|
56
|
+
#
|
57
|
+
# *** Optional ***
|
58
|
+
# "guestPhone" : "010-0000-0000",
|
59
|
+
# "guestEmail" : "aaa@mail.com",
|
60
|
+
# "guestNationality" : "Korea"
|
61
|
+
# }
|
62
|
+
|
63
|
+
def post_reservation_confirmation(request_body={})
|
64
|
+
response = HTTParty.post(
|
65
|
+
"#{build_url(__method__.to_s)}",
|
66
|
+
body: request_body.to_json,
|
67
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
68
|
+
)
|
69
|
+
|
70
|
+
prepare_response(response)
|
71
|
+
end
|
72
|
+
|
73
|
+
# _________________________________________________________________________________________ #
|
74
|
+
|
75
|
+
# GET /reservation/information
|
76
|
+
|
77
|
+
# Use this resource with a set of dates to retrieve a collection of reservations between the given dates
|
78
|
+
# OR
|
79
|
+
# Use this resource with a reservation identifier(hash) + the start date to retrieve a collection of one reservation.
|
80
|
+
#
|
81
|
+
# Parameters:
|
82
|
+
#
|
83
|
+
# Required => start_date YYYY-MM-DD (ex: 2016-02-01). Search by start date.
|
84
|
+
# Required => end_date YYYY-MM-DD (ex: 2016-02-05). Search by end date.
|
85
|
+
# Optional => reservation_identifier The unique property identifier/hash (e.g. w_w0307279)
|
86
|
+
#
|
87
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/reservation/information?searchStartDate=2016-07-01&searchEndDate=2016-07-10&reservationNo=
|
88
|
+
#
|
89
|
+
# Example usage: client.get_reservations("2016-07-01", "2016-07-10", "w_w0307279_R01")
|
90
|
+
|
91
|
+
def get_reservations(start_date, end_date, reservation_identifier=nil)
|
92
|
+
params = {
|
93
|
+
:searchStartDate => "#{start_date}",
|
94
|
+
:searchEndDate => "#{end_date}"
|
95
|
+
}
|
96
|
+
|
97
|
+
params.merge!( :reservationNo => "#{reservation_identifier}" ) if reservation_identifier
|
98
|
+
|
99
|
+
response = HTTParty.get(
|
100
|
+
"#{build_url(__method__.to_s)}?#{transform_params!(params)}",
|
101
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
102
|
+
)
|
103
|
+
|
104
|
+
prepare_response(response)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module YTLabsApi
|
2
|
+
module Cancellation
|
3
|
+
|
4
|
+
# POST /reservation/cancel/
|
5
|
+
#
|
6
|
+
# If a reservation is canceled by the guest, the partner should request /reservation/cancel/
|
7
|
+
# If a real reservation is not completed within 10 minutes after ReservationHolding, Partner should also request /reservation/cancel/
|
8
|
+
#
|
9
|
+
# {
|
10
|
+
# "reservationNo" : "w_WP0000000000000000",
|
11
|
+
# "refundPaidPrice" : 2000.0,
|
12
|
+
# "refundCommissionPrice" : 200.0,
|
13
|
+
# "currency" : "KRW"
|
14
|
+
# }
|
15
|
+
|
16
|
+
def post_cancellation_request(reservation_number, paid_price, commission_price, currency)
|
17
|
+
request_body = {
|
18
|
+
:reservationNo => "#{reservation_number}",
|
19
|
+
:refundPaidPrice => "#{paid_price}",
|
20
|
+
:refundCommissionPrice => "#{commission_price}",
|
21
|
+
:currency => "#{currency}"
|
22
|
+
}.to_json
|
23
|
+
|
24
|
+
response = HTTParty.post(
|
25
|
+
"#{build_url(__method__.to_s)}",
|
26
|
+
body: request_body,
|
27
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
28
|
+
)
|
29
|
+
|
30
|
+
prepare_response(response)
|
31
|
+
end
|
32
|
+
|
33
|
+
# GET /reservation/cancelcharge/
|
34
|
+
# Using a reservation number get the cancellation fee payable.
|
35
|
+
#
|
36
|
+
# If a reservation is cancelled within 7 days of the check in day, a cancellation fee will be charged.
|
37
|
+
|
38
|
+
# Parameters:
|
39
|
+
#
|
40
|
+
# Required => reseveration_number Unique reservation number - provided when booking was made.
|
41
|
+
#
|
42
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/reservation/cancelcharge?reservationNo=w_WP20160705145532ECD5
|
43
|
+
#
|
44
|
+
# Example usage: client.get_cancellation_charge("w_WP20160705145532ECD5")
|
45
|
+
def get_cancellation_charge(reservation_number)
|
46
|
+
response = HTTParty.get(
|
47
|
+
"#{build_url(__method__.to_s)}?reservationNo=#{reservation_number}",
|
48
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
49
|
+
)
|
50
|
+
|
51
|
+
prepare_response(response)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# +YTLabsApi::Client+ - entry class to the API client.
|
2
|
+
#
|
3
|
+
# Proposed usage:
|
4
|
+
# => client = YTLabsApi::Client.new("your_token", :json)
|
5
|
+
# => client.get_properties(params_hash)
|
6
|
+
|
7
|
+
require_relative 'availability'
|
8
|
+
require_relative 'booking'
|
9
|
+
require_relative 'property'
|
10
|
+
require_relative 'supplementary_information'
|
11
|
+
require_relative 'cancellation'
|
12
|
+
require_relative 'room_type'
|
13
|
+
|
14
|
+
|
15
|
+
module YTLabsApi
|
16
|
+
class Client
|
17
|
+
include HTTParty
|
18
|
+
|
19
|
+
include YTLabsApi::Availability
|
20
|
+
include YTLabsApi::Booking
|
21
|
+
include YTLabsApi::Cancellation
|
22
|
+
include YTLabsApi::Property
|
23
|
+
include YTLabsApi::RoomType
|
24
|
+
include YTLabsApi::SupplementaryInformation
|
25
|
+
|
26
|
+
END_POINTS = YAML::load(File.open(File.join('lib', 'ytlabs_api', 'end_points.yml')))
|
27
|
+
URL = "https://api.ytlabs.co.kr/stage/v1"
|
28
|
+
VALID_CONTENT_TYPES = [:json, :xml].freeze
|
29
|
+
|
30
|
+
format :json
|
31
|
+
default_timeout 1 #Hard timeout after 1 second.
|
32
|
+
|
33
|
+
attr_reader :token, :content_type, :base_url, :errors
|
34
|
+
|
35
|
+
def initialize(token, content_type=nil)
|
36
|
+
@token = token
|
37
|
+
@content_type = "application/#{content_type.to_s}" || "application/json"
|
38
|
+
@base_url = URL
|
39
|
+
@errors = []
|
40
|
+
|
41
|
+
raise InvalidAccessToken unless valid_token?(token)
|
42
|
+
raise InvalidContentType unless valid_content_type?(content_type)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# HTTParty will raise Net::OpenTimeout if it can't connect to the server.
|
47
|
+
# It will raise Net::ReadTimeout if reading the response from the server times out.
|
48
|
+
# Handle these exceptions to return a empty hash, and set the timeout to 1 second.
|
49
|
+
# Wrap any calls made using HTTParty in a handle_timeouts block
|
50
|
+
|
51
|
+
# handle_timeouts do
|
52
|
+
# your HTTParty call.
|
53
|
+
# end
|
54
|
+
|
55
|
+
# TODO
|
56
|
+
# def handle_timeouts
|
57
|
+
# begin
|
58
|
+
# yield
|
59
|
+
# rescue Net::OpenTimeout, Net::ReadTimeout
|
60
|
+
# {}
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
|
64
|
+
# Since the only public methods this client supports are calls to the specified endpoints,
|
65
|
+
# which are implemented - we will raise a more specific error here.
|
66
|
+
def method_missing(method, *args, &block)
|
67
|
+
raise EndPointNotSupported
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
## Transforms {:a => 2, :b => 2} to "a=2&b=2"
|
73
|
+
def transform_params!(params)
|
74
|
+
URI.encode_www_form(params) if params
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
## Accepts underscored variables/params & converts them to camelCase as required by the YTLabs API.
|
79
|
+
## The intention is to 'Rubify' the wrapper allowing underscore_style_variable_naming.
|
80
|
+
## Example:
|
81
|
+
## camelize_params_keys!({:room_code=>"123", :search_start_date=>"456"})
|
82
|
+
## => {"roomCode"=>"123", "searchStartDate"=>"456"}
|
83
|
+
def camelize_params_keys!(params_hash)
|
84
|
+
return unless params_hash
|
85
|
+
|
86
|
+
params_hash.keys.each do |key|
|
87
|
+
value = params_hash.delete(key)
|
88
|
+
new_key = key.to_s.camelize(:lower)
|
89
|
+
params_hash[new_key] = value
|
90
|
+
end
|
91
|
+
params_hash
|
92
|
+
end
|
93
|
+
|
94
|
+
## Builds endpoint URL dynamically.
|
95
|
+
def build_url(action, identifier=nil)
|
96
|
+
end_point = END_POINTS[action]
|
97
|
+
|
98
|
+
if identifier
|
99
|
+
url = "#{base_url}/#{end_point}/#{identifier}"
|
100
|
+
else
|
101
|
+
url = "#{base_url}/#{end_point}"
|
102
|
+
end
|
103
|
+
url
|
104
|
+
end
|
105
|
+
|
106
|
+
# The responses from the API are somewhat misleading. Calls that one might expect to 404 seem to return 403 Forbidden
|
107
|
+
# with "message"=>"Authorization header requires 'Credential' parameter. Consider how to provide more helpful messages.
|
108
|
+
def prepare_response(response)
|
109
|
+
if response.parsed_response["status"] == (200..206)
|
110
|
+
parse_successful_response(response)
|
111
|
+
else
|
112
|
+
# Temporary
|
113
|
+
JSON.parse(response.body)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def parse_successful_response(response)
|
118
|
+
JSON.parse(response.body)
|
119
|
+
end
|
120
|
+
|
121
|
+
def valid_token?(token)
|
122
|
+
token.size == 36
|
123
|
+
end
|
124
|
+
|
125
|
+
def valid_content_type?(content_type)
|
126
|
+
VALID_CONTENT_TYPES.include?(content_type)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Define each endpoint here +end_points.yml+ to map a method name to
|
2
|
+
# an endpoint that it will call on the API.
|
3
|
+
|
4
|
+
# GET Requests
|
5
|
+
get_properties: "properties"
|
6
|
+
get_property: "properties"
|
7
|
+
get_availability: "available"
|
8
|
+
|
9
|
+
get_provinces: "provincecode"
|
10
|
+
get_cities: "citycode"
|
11
|
+
get_extra_service_codes: "extraservicecode"
|
12
|
+
get_theme_codes: "themecode"
|
13
|
+
|
14
|
+
get_reservations: "reservation/information"
|
15
|
+
|
16
|
+
get_room_types: "roomtypes"
|
17
|
+
get_property_room_types: "properties"
|
18
|
+
|
19
|
+
get_cancellation_charge: "reservation/cancelcharge"
|
20
|
+
|
21
|
+
|
22
|
+
# POST Requests
|
23
|
+
post_reservation_request: "reservation/holding"
|
24
|
+
post_reservation_confirmation: "reservation/confirm"
|
25
|
+
|
26
|
+
post_cancellation_request: "reservation/cancel"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module YTLabsApi
|
2
|
+
module Property
|
3
|
+
|
4
|
+
# GET /properties/
|
5
|
+
# Use this resource to get a response a list of properties in the YTLabs API.
|
6
|
+
#
|
7
|
+
# Parameters:
|
8
|
+
#
|
9
|
+
# Required => updated_at Date at which data starts being returned. (YYYY-MM-DD).
|
10
|
+
#
|
11
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
12
|
+
# Optional => offset default: 0 Data offset (default 0)
|
13
|
+
# Optional => limit default: 30 Amount of requested properties (default 30)
|
14
|
+
# Optional => active default: 1 To filter by only active properties. 0 returns all. 1 returns Active only.
|
15
|
+
#
|
16
|
+
# When parameter 'limit=0&updatedAt=1970-01-01' is specified in request, all of the properties' information is
|
17
|
+
# returned. It is recommended only for the first time
|
18
|
+
#
|
19
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/properties?i18n=en-US&offset=0&limit=30&active=1&updatedAt=2016-05-24
|
20
|
+
#
|
21
|
+
# Example usage: client.get_properties(:updated_at => "1970-01-01", :limit => 3)
|
22
|
+
|
23
|
+
def get_properties(params)
|
24
|
+
camelize_params_keys!(params)
|
25
|
+
|
26
|
+
response = HTTParty.get(
|
27
|
+
"#{build_url(__method__.to_s)}?#{transform_params!(params)}",
|
28
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
29
|
+
)
|
30
|
+
|
31
|
+
prepare_response(response)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# _________________________________________________________________________________________ #
|
36
|
+
|
37
|
+
# GET /properties/{propertyID}/
|
38
|
+
# Use this resource with a property_identifier (e.g. "w_w0307279") to get the property's information.
|
39
|
+
#
|
40
|
+
# Parameters:
|
41
|
+
#
|
42
|
+
# Required => property_identifier The unique property identifier/hash (e.g. w_w0307279)
|
43
|
+
#
|
44
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
45
|
+
#
|
46
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/properties/w_w0307279?i18n=en-US
|
47
|
+
#
|
48
|
+
# Example usage: client.get_property("w_w0307279", :i18n => "en-US")
|
49
|
+
|
50
|
+
def get_property(property_identifier, params=nil)
|
51
|
+
camelize_params_keys!(params)
|
52
|
+
|
53
|
+
response = HTTParty.get(
|
54
|
+
"#{build_url(__method__.to_s, property_identifier)}?#{transform_params!(params)}",
|
55
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
56
|
+
)
|
57
|
+
|
58
|
+
prepare_response(response)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module YTLabsApi
|
2
|
+
module RoomType
|
3
|
+
|
4
|
+
# GET /roomtypes/
|
5
|
+
# Obtain a list of all room types.
|
6
|
+
|
7
|
+
# Parameters:
|
8
|
+
#
|
9
|
+
# Required => updated_at Date at which data starts being returned. (YYYY-MM-DD).
|
10
|
+
#
|
11
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
12
|
+
# Optional => offset default: 0 Data offset (default 0)
|
13
|
+
# Optional => limit default: 30 Amount of requested room type (default 30)
|
14
|
+
# Optional => active default: 1 To filter by only active room type. 0 returns all. 1 returns Active only.
|
15
|
+
#
|
16
|
+
# When parameter 'updatedAt' is specified in request, only updated information is returned.
|
17
|
+
#
|
18
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/roomtypes?i18n=en-US&offset=0&limit=30&active=1&updatedAt=2016-05-24
|
19
|
+
#
|
20
|
+
# Example usage: client.get_room_types(:updated_at => "1970-01-01", :limit => 1)
|
21
|
+
|
22
|
+
def get_room_types(params=nil)
|
23
|
+
camelize_params_keys!(params)
|
24
|
+
|
25
|
+
response = HTTParty.get(
|
26
|
+
"#{build_url(__method__.to_s)}?#{transform_params!(params)}",
|
27
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
28
|
+
)
|
29
|
+
|
30
|
+
prepare_response(response)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# GET /properties/{propertyID}/roomtypes/
|
35
|
+
# Using a specific propertyID, get all roomtypes' information of the property.
|
36
|
+
|
37
|
+
# Parameters:
|
38
|
+
#
|
39
|
+
# Required => property_identifier Date at which data starts being returned. (YYYY-MM-DD).
|
40
|
+
#
|
41
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
42
|
+
#
|
43
|
+
# Example Request: https://api.ytlabs.co.kr/stage/v1/properties/w_w0307279/roomtypes?i18n=en-US
|
44
|
+
#
|
45
|
+
# Example usage: client.get_property_room_types("w_w0307279", :i81n => "en-US")
|
46
|
+
|
47
|
+
def get_property_room_types(property_identifier, params=nil)
|
48
|
+
camelize_params_keys!(params)
|
49
|
+
|
50
|
+
response = HTTParty.get(
|
51
|
+
"#{build_url(__method__.to_s, property_identifier)}/roomtypes?#{transform_params!(params)}",
|
52
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
53
|
+
)
|
54
|
+
|
55
|
+
prepare_response(response)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module YTLabsApi
|
2
|
+
module SupplementaryInformation
|
3
|
+
|
4
|
+
# GET /provincecode/
|
5
|
+
# Returns a list with code or name of province.
|
6
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
7
|
+
|
8
|
+
def get_provinces(i18n="ko-KR")
|
9
|
+
response = HTTParty.get(
|
10
|
+
"#{build_url(__method__.to_s)}?i18n=#{i18n}",
|
11
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
12
|
+
)
|
13
|
+
|
14
|
+
prepare_response(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
# _________________________________________________________________________________________ #
|
18
|
+
|
19
|
+
# GET /citycode/
|
20
|
+
# Returns a list with code or name of cities.
|
21
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
22
|
+
|
23
|
+
def get_cities(i18n="ko-KR")
|
24
|
+
response = HTTParty.get(
|
25
|
+
"#{build_url(__method__.to_s)}?i18n=#{i18n}",
|
26
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
27
|
+
)
|
28
|
+
|
29
|
+
prepare_response(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
# _________________________________________________________________________________________ #
|
33
|
+
|
34
|
+
# GET /extraservicecode/
|
35
|
+
# Returns a list mapping the codes and names of extra services.
|
36
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
37
|
+
|
38
|
+
def get_extra_service_codes(i18n="ko-KR")
|
39
|
+
response = HTTParty.get(
|
40
|
+
"#{build_url(__method__.to_s)}?i18n=#{i18n}",
|
41
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
42
|
+
)
|
43
|
+
|
44
|
+
prepare_response(response)
|
45
|
+
end
|
46
|
+
|
47
|
+
# _________________________________________________________________________________________ #
|
48
|
+
|
49
|
+
# GET /themecode/
|
50
|
+
# Returns a list mapping the code and name of themes.
|
51
|
+
# Optional => i18n default: "ko-KR" Return text in other lanaguages(ko-KR, en-US, zh-CN, ja-JP)
|
52
|
+
|
53
|
+
def get_theme_codes(i18n="ko-KR")
|
54
|
+
response = HTTParty.get(
|
55
|
+
"#{build_url(__method__.to_s)}?i18n=#{i18n}",
|
56
|
+
headers: { "Authorization" => token.to_s, "Content-Type" => "#{content_type}" }
|
57
|
+
)
|
58
|
+
|
59
|
+
prepare_response(response)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe YTLabsApi::Client do
|
4
|
+
## Generates a 36 char length token.
|
5
|
+
let(:token) { SecureRandom.hex(18) }
|
6
|
+
let(:content_type) { :json }
|
7
|
+
let(:client) { described_class.new(token, content_type) }
|
8
|
+
|
9
|
+
describe "Client" do
|
10
|
+
it "instantiates a new client object" do
|
11
|
+
expect(client).to be_a (YTLabsApi::Client)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "token" do
|
15
|
+
it "raises an error if a token is not valid" do
|
16
|
+
error_message = "Your access token is not valid. It must be 36 characters long."
|
17
|
+
bad_token = "123"
|
18
|
+
expect { described_class.new(bad_token) }.to raise_error (error_message)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "content_type" do
|
23
|
+
it "accepts json" do
|
24
|
+
client = described_class.new(token, :json)
|
25
|
+
expect(client.content_type).to eq "application/json"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "accepts xml" do
|
29
|
+
client = described_class.new(token, :xml)
|
30
|
+
expect(client.content_type).to eq "application/xml"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "does not content types other than json or xml" do
|
34
|
+
error_message = "Your content type is invalid. 'json' or 'xml' are the 2 valid options"
|
35
|
+
expect { described_class.new(token, :html) }.to raise_error (error_message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "invalid/not implemented method/endpoint called" do
|
40
|
+
it "raises when invalid endpoint is called" do
|
41
|
+
error_message = 'This endpoint is not supported: Try one of these: ["get_properties", "get_property", "get_availability", "get_provinces", "get_cities", "get_extra_service_codes", "get_theme_codes", "get_reservations", "get_room_types", "get_property_room_types", "get_cancellation_charge", "post_reservation_request", "post_reservation_confirmation", "post_cancellation_request"]'
|
42
|
+
expect { client.bob }.to raise_error.with_message (error_message)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "base_url" do
|
48
|
+
it "responds with the base url" do
|
49
|
+
expect(client).to respond_to (:base_url)
|
50
|
+
expect(client.base_url).to eq ("https://api.ytlabs.co.kr/stage/v1")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "properties" do
|
55
|
+
describe "#get_property" do
|
56
|
+
context "with an invalid access token" do
|
57
|
+
it "returns an Unauthorized response" do
|
58
|
+
WebMock.allow_net_connect!
|
59
|
+
expect(client.get_property("w_w0307360")).to include ( {"message"=>"Unauthorized"} )
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with a valid access token" do
|
64
|
+
before do
|
65
|
+
response = '[{ "property": "a property for you" }]'
|
66
|
+
stub_request(:any, "https://api.ytlabs.co.kr/stage/v1/properties").to_return(:body => response, :status => 200, :headers => {})
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns a property within a parsed response" do
|
70
|
+
client = YTLabsApi::Client.new(token, :json)
|
71
|
+
response = client.get_property("w_w0307360")
|
72
|
+
expect(response).to eq response
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#get_properties" do
|
78
|
+
context "with an invalid access token" do
|
79
|
+
it "returns an Unauthorized response" do
|
80
|
+
WebMock.allow_net_connect!
|
81
|
+
expect(client.get_properties(:updated_at => "1970-01-01", :limit => 3)).to include ( {"message"=>"Unauthorized"} )
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with a valid access token" do
|
86
|
+
before do
|
87
|
+
response = '[{ "property": "a property for you" }, { "property_2": "another property for you" }]'
|
88
|
+
url = "https://api.ytlabs.co.kr/stage/v1/properties?i18n=en-US&offset=0&limit=2&active=1&updatedAt=2016-05-24"
|
89
|
+
stub_request(:any, url).to_return(:body => response, :status => 200, :headers => {})
|
90
|
+
end
|
91
|
+
|
92
|
+
it "returns 2 properties within a parsed response" do
|
93
|
+
client = YTLabsApi::Client.new(token, :json)
|
94
|
+
response = client.get_properties(updated_at: Date.today)
|
95
|
+
expect(response).to eq response
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#get_room_types" do
|
101
|
+
before do
|
102
|
+
response = '[{ "room_type": "a room_type for you" }, { "room_type_2": "another room_type for you" }]'
|
103
|
+
url = "https://api.ytlabs.co.kr/stage/v1/roomtypes?i18n=en-US&offset=0&limit=30&active=1&updatedAt=2016-05-24"
|
104
|
+
stub_request(:any, url).to_return(:body => response, :status => 200, :headers => {})
|
105
|
+
end
|
106
|
+
|
107
|
+
it "returns 2 room_types within a parsed response" do
|
108
|
+
client = YTLabsApi::Client.new(token, :json)
|
109
|
+
response = client.get_room_types
|
110
|
+
expect(response).to eq response
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "supplementary_information" do
|
116
|
+
describe "#get_provinces" do
|
117
|
+
before do
|
118
|
+
response = '[{ "province_one": "great place", "province_two": "an ever better place" }]'
|
119
|
+
stub_request(:any, "https://api.ytlabs.co.kr/stage/v1/provincecode").to_return(:body => response, :status => 200, :headers => {})
|
120
|
+
end
|
121
|
+
|
122
|
+
it "returns a property within a parsed response" do
|
123
|
+
client = YTLabsApi::Client.new(token, :json)
|
124
|
+
response = client.get_provinces
|
125
|
+
expect(response).to eq response
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
describe "#build_url" do
|
133
|
+
context "without identifier (i.e. a room hash/id)" do
|
134
|
+
it "builds the endpoint URL correctly" do
|
135
|
+
stub_const("YTLabs::CLient::END_POINTS", { get_properties: "properties" } )
|
136
|
+
action = "get_properties"
|
137
|
+
expect(client.send(:build_url, action)).to eq "https://api.ytlabs.co.kr/stage/v1/properties"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "with an identifier (i.e. a room hash/id)" do
|
142
|
+
it "builds the endpoint URL correctly" do
|
143
|
+
stub_const("YTLabsApi::CLient::END_POINTS", { get_properties: "properties" } )
|
144
|
+
action = "get_properties"
|
145
|
+
identifier = "123"
|
146
|
+
expect(client.send(:build_url, action, identifier)).to eq "https://api.ytlabs.co.kr/stage/v1/properties/123"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#camelize_params_keys!(params_hash)" do
|
152
|
+
it "modifies a Rubified set of params keys correctly" do
|
153
|
+
params_hash = { :room_code => "123", :search_start_date => "456" }
|
154
|
+
expect(client.send(:camelize_params_keys!, params_hash)).to eq ({"roomCode"=> "123", "searchStartDate"=> "456"})
|
155
|
+
end
|
156
|
+
|
157
|
+
it "it does not modify keys that are already camelized" do
|
158
|
+
params_hash = { :roomCode => "123", :searchStartDate => "456" }
|
159
|
+
expect(client.send(:camelize_params_keys!, params_hash)).to eq ({"roomCode"=> "123", "searchStartDate"=> "456"})
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ytlabs_api_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Hawker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Ruby wrapper enabling authenticated calls to the YT Labs API
|
28
|
+
email: ben.c.hawker@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- Gemfile
|
34
|
+
- README.md
|
35
|
+
- lib/ytlabs_api.rb
|
36
|
+
- lib/ytlabs_api/availability.rb
|
37
|
+
- lib/ytlabs_api/booking.rb
|
38
|
+
- lib/ytlabs_api/cancellation.rb
|
39
|
+
- lib/ytlabs_api/client.rb
|
40
|
+
- lib/ytlabs_api/end_points.yml
|
41
|
+
- lib/ytlabs_api/property.rb
|
42
|
+
- lib/ytlabs_api/room_type.rb
|
43
|
+
- lib/ytlabs_api/supplementary_information.rb
|
44
|
+
- lib/ytlabs_api/version.rb
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
- spec/ytlabs_api/client_spec.rb
|
47
|
+
- spec/ytlabs_api_spec.rb
|
48
|
+
homepage:
|
49
|
+
licenses:
|
50
|
+
- MIT
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.4.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: YT Labs API Ruby Client
|
72
|
+
test_files: []
|