hotel_beds 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -44
  3. data/lib/hotel_beds/basket_remove/envelope.rb +16 -0
  4. data/lib/hotel_beds/basket_remove/operation.rb +36 -0
  5. data/lib/hotel_beds/basket_remove/request.rb +19 -0
  6. data/lib/hotel_beds/basket_remove/response.rb +31 -0
  7. data/lib/hotel_beds/client.rb +21 -0
  8. data/lib/hotel_beds/hotel_basket_add/request.rb +1 -1
  9. data/lib/hotel_beds/hotel_basket_add/response.rb +4 -35
  10. data/lib/hotel_beds/hotel_search/envelope.rb +10 -9
  11. data/lib/hotel_beds/hotel_search/request.rb +6 -4
  12. data/lib/hotel_beds/hotel_search/response.rb +4 -9
  13. data/lib/hotel_beds/model/available_room.rb +22 -1
  14. data/lib/hotel_beds/model/cancellation_policy.rb +0 -1
  15. data/lib/hotel_beds/model/comment.rb +13 -0
  16. data/lib/hotel_beds/model/contract.rb +15 -0
  17. data/lib/hotel_beds/model/customer.rb +21 -0
  18. data/lib/hotel_beds/model/destination.rb +13 -0
  19. data/lib/hotel_beds/model/hotel.rb +12 -7
  20. data/lib/hotel_beds/model/price.rb +18 -0
  21. data/lib/hotel_beds/model/purchase.rb +7 -2
  22. data/lib/hotel_beds/model/room.rb +0 -1
  23. data/lib/hotel_beds/model/service.rb +6 -4
  24. data/lib/hotel_beds/parser.rb +94 -0
  25. data/lib/hotel_beds/parser/available_room.rb +37 -0
  26. data/lib/hotel_beds/parser/cancellation_policy.rb +13 -0
  27. data/lib/hotel_beds/parser/comment.rb +13 -0
  28. data/lib/hotel_beds/parser/contract.rb +17 -0
  29. data/lib/hotel_beds/parser/customer.rb +18 -0
  30. data/lib/hotel_beds/parser/destination.rb +13 -0
  31. data/lib/hotel_beds/parser/errors.rb +39 -0
  32. data/lib/hotel_beds/parser/hotel.rb +27 -0
  33. data/lib/hotel_beds/parser/price.rb +14 -0
  34. data/lib/hotel_beds/parser/purchase.rb +24 -0
  35. data/lib/hotel_beds/parser/room_grouper.rb +104 -0
  36. data/lib/hotel_beds/parser/service.rb +21 -0
  37. data/lib/hotel_beds/purchase_confirm/envelope.rb +42 -0
  38. data/lib/hotel_beds/purchase_confirm/operation.rb +36 -0
  39. data/lib/hotel_beds/purchase_confirm/request.rb +72 -0
  40. data/lib/hotel_beds/purchase_confirm/response.rb +31 -0
  41. data/lib/hotel_beds/purchase_flush/envelope.rb +15 -0
  42. data/lib/hotel_beds/purchase_flush/operation.rb +36 -0
  43. data/lib/hotel_beds/purchase_flush/request.rb +17 -0
  44. data/lib/hotel_beds/purchase_flush/response.rb +26 -0
  45. data/lib/hotel_beds/version.rb +1 -1
  46. data/spec/features/flushing_the_basket_spec.rb +63 -0
  47. data/spec/features/ordering_a_hotel_room_spec.rb +96 -0
  48. data/spec/features/removing_a_basket_item_spec.rb +74 -0
  49. data/spec/lib/hotel_beds/hotel_search/request_spec.rb +4 -4
  50. data/spec/lib/hotel_beds/{hotel_search/parser → parser}/room_grouper_spec.rb +3 -3
  51. data/spec/lib/hotel_beds/parser/service_spec.rb +44 -0
  52. metadata +42 -15
  53. data/lib/hotel_beds/hotel_search/parser/errors.rb +0 -49
  54. data/lib/hotel_beds/hotel_search/parser/hotel.rb +0 -71
  55. data/lib/hotel_beds/hotel_search/parser/price.rb +0 -38
  56. data/lib/hotel_beds/hotel_search/parser/room.rb +0 -61
  57. data/lib/hotel_beds/hotel_search/parser/room_grouper.rb +0 -101
  58. data/spec/features/adding_a_hotel_to_basket_spec.rb +0 -58
  59. data/spec/features/grouped_hotel_search_spec.rb +0 -67
  60. data/spec/features/hotel_search_spec.rb +0 -113
@@ -1,3 +1,3 @@
1
1
  module HotelBeds
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -0,0 +1,63 @@
1
+ require "hotel_beds"
2
+ require "securerandom"
3
+
4
+ RSpec.describe "ordering a hotel room" do
5
+ describe "#response" do
6
+ before(:all) do
7
+ @client = HotelBeds::Client.new({
8
+ endpoint: :test,
9
+ username: ENV.fetch("HOTEL_BEDS_USERNAME"),
10
+ password: ENV.fetch("HOTEL_BEDS_PASSWORD"),
11
+ proxy: ENV.fetch("HOTEL_BEDS_PROXY", nil)
12
+ })
13
+ @check_in_date = Date.today + 28 + rand(10)
14
+ @check_out_date = @check_in_date + rand(3) + rand(2) + 1
15
+ @search_operation = @client.perform_hotel_search({
16
+ check_in_date: @check_in_date,
17
+ check_out_date: @check_out_date,
18
+ rooms: [{ adult_count: 2 }],
19
+ destination_code: "SYD"
20
+ })
21
+ if @search_operation.errors.any?
22
+ raise StandardError, @search_operation.errors.full_messages.join("\n")
23
+ end
24
+ @search_response = @search_operation.response
25
+
26
+ hotel = @search_response.hotels.first
27
+ rooms = hotel.available_rooms.first
28
+
29
+ @basket_operation = @client.add_hotel_room_to_basket({
30
+ service: {
31
+ check_in_date: @check_in_date,
32
+ check_out_date: @check_out_date,
33
+ availability_token: hotel.availability_token,
34
+ hotel_code: hotel.code,
35
+ destination_code: hotel.destination.code,
36
+ contract_name: hotel.contract.name,
37
+ contract_incoming_office_code: hotel.contract.incoming_office_code,
38
+ rooms: rooms
39
+ }
40
+ })
41
+ if @basket_operation.errors.any?
42
+ raise StandardError, @basket_operation.errors.full_messages.join("\n")
43
+ end
44
+ @basket_response = @basket_operation.response
45
+
46
+ @flush_operation = @client.flush_purchase({
47
+ purchase_token: @basket_response.purchase.token
48
+ })
49
+ if @flush_operation.errors.any?
50
+ raise StandardError, @flush_operation.errors.full_messages.join("\n")
51
+ end
52
+ @flush_operation = @flush_operation.response
53
+ end
54
+
55
+ let(:response) { @flush_operation }
56
+
57
+ subject { response }
58
+
59
+ it "should be a success" do
60
+ expect(subject).to be_success
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,96 @@
1
+ require "hotel_beds"
2
+ require "securerandom"
3
+
4
+ RSpec.describe "ordering a hotel room" do
5
+ describe "#response" do
6
+ before(:all) do
7
+ @client = HotelBeds::Client.new({
8
+ endpoint: :test,
9
+ username: ENV.fetch("HOTEL_BEDS_USERNAME"),
10
+ password: ENV.fetch("HOTEL_BEDS_PASSWORD"),
11
+ proxy: ENV.fetch("HOTEL_BEDS_PROXY", nil)
12
+ })
13
+ @check_in_date = Date.today + 28 + rand(10)
14
+ @check_out_date = @check_in_date + rand(3) + rand(2) + 1
15
+ @search_operation = @client.perform_hotel_search({
16
+ check_in_date: @check_in_date,
17
+ check_out_date: @check_out_date,
18
+ rooms: [{ adult_count: 2 }],
19
+ destination_code: "SYD"
20
+ })
21
+ if @search_operation.errors.any?
22
+ raise StandardError, @search_operation.errors.full_messages.join("\n")
23
+ end
24
+ @search_response = @search_operation.response
25
+
26
+ hotel = @search_response.hotels.first
27
+ rooms = hotel.available_rooms.first
28
+
29
+ @basket_operation = @client.add_hotel_room_to_basket({
30
+ service: {
31
+ check_in_date: @check_in_date,
32
+ check_out_date: @check_out_date,
33
+ availability_token: hotel.availability_token,
34
+ hotel_code: hotel.code,
35
+ destination_code: hotel.destination.code,
36
+ contract_name: hotel.contract.name,
37
+ contract_incoming_office_code: hotel.contract.incoming_office_code,
38
+ rooms: rooms
39
+ }
40
+ })
41
+ if @basket_operation.errors.any?
42
+ raise StandardError, @basket_operation.errors.full_messages.join("\n")
43
+ end
44
+ @basket_response = @basket_operation.response
45
+
46
+ @agency_reference = SecureRandom.hex[0..15].upcase
47
+ @checkout_operation = @client.confirm_purchase({
48
+ purchase: {
49
+ agency_reference: @agency_reference,
50
+ token: @basket_response.purchase.token,
51
+ holder: {
52
+ id: "1",
53
+ type: :adult,
54
+ name: "David",
55
+ last_name: "Smith",
56
+ age: "43"
57
+ },
58
+ services: @basket_response.purchase.services.map { |service|
59
+ {
60
+ id: service.id,
61
+ type: service.type,
62
+ customers: [
63
+ { id: "1", type: :adult, name: "David", last_name: "Smith", age: "43" },
64
+ { id: "2", type: :adult, name: "Jane", last_name: "Smith", age: "40" }
65
+ ]
66
+ }
67
+ }
68
+ }
69
+ })
70
+ if @checkout_operation.errors.any?
71
+ raise StandardError, @checkout_operation.errors.full_messages.join("\n")
72
+ end
73
+ @checkout_response = @checkout_operation.response
74
+ end
75
+
76
+ let(:response) { @checkout_response }
77
+
78
+ subject { response }
79
+
80
+ it "should be a success" do
81
+ expect(subject).to be_success
82
+ end
83
+
84
+ describe "#purchase" do
85
+ subject { response.purchase }
86
+
87
+ it "should have a service" do
88
+ expect(subject.services).to_not be_empty
89
+ end
90
+
91
+ it "should have a agency reference" do
92
+ expect(subject.agency_reference).to eq(@agency_reference)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,74 @@
1
+ require "hotel_beds"
2
+ require "securerandom"
3
+
4
+ RSpec.describe "ordering a hotel room" do
5
+ describe "#response" do
6
+ before(:all) do
7
+ @client = HotelBeds::Client.new({
8
+ endpoint: :test,
9
+ username: ENV.fetch("HOTEL_BEDS_USERNAME"),
10
+ password: ENV.fetch("HOTEL_BEDS_PASSWORD"),
11
+ proxy: ENV.fetch("HOTEL_BEDS_PROXY", nil)
12
+ })
13
+ @check_in_date = Date.today + 28 + rand(10)
14
+ @check_out_date = @check_in_date + rand(3) + rand(2) + 1
15
+ @search_operation = @client.perform_hotel_search({
16
+ check_in_date: @check_in_date,
17
+ check_out_date: @check_out_date,
18
+ rooms: [{ adult_count: 2 }],
19
+ destination_code: "SYD"
20
+ })
21
+ if @search_operation.errors.any?
22
+ raise StandardError, @search_operation.errors.full_messages.join("\n")
23
+ end
24
+ @search_response = @search_operation.response
25
+
26
+ hotel = @search_response.hotels.first
27
+ rooms = hotel.available_rooms.first
28
+
29
+ @basket_operation = @client.add_hotel_room_to_basket({
30
+ service: {
31
+ check_in_date: @check_in_date,
32
+ check_out_date: @check_out_date,
33
+ availability_token: hotel.availability_token,
34
+ hotel_code: hotel.code,
35
+ destination_code: hotel.destination.code,
36
+ contract_name: hotel.contract.name,
37
+ contract_incoming_office_code: hotel.contract.incoming_office_code,
38
+ rooms: rooms
39
+ }
40
+ })
41
+ if @basket_operation.errors.any?
42
+ raise StandardError, @basket_operation.errors.full_messages.join("\n")
43
+ end
44
+ @basket_response = @basket_operation.response
45
+
46
+ @service_id = @basket_response.purchase.services.first.id
47
+ @remove_operation = @client.remove_service_from_basket({
48
+ purchase_token: @basket_response.purchase.token,
49
+ service_id: @service_id
50
+ })
51
+ if @remove_operation.errors.any?
52
+ raise StandardError, @remove_operation.errors.full_messages.join("\n")
53
+ end
54
+ @remove_operation = @remove_operation.response
55
+ end
56
+
57
+ let(:response) { @remove_operation }
58
+ let(:service_id) { @service_id }
59
+
60
+ subject { response }
61
+
62
+ it "should be a success" do
63
+ expect(subject).to be_success
64
+ end
65
+
66
+ describe "#purchase" do
67
+ subject { response.purchase }
68
+
69
+ it "should not have the service that was removed" do
70
+ expect(subject.services.map(&:id)).to_not include(service_id)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -8,7 +8,7 @@ RSpec.describe HotelBeds::HotelSearch::Request do
8
8
  language: "FRA",
9
9
  check_in_date: Date.today,
10
10
  check_out_date: Date.today + 2,
11
- destination: "SYD",
11
+ destination_code: "SYD",
12
12
  rooms: [{
13
13
  adult_count: 2,
14
14
  child_count: 1,
@@ -19,15 +19,15 @@ RSpec.describe HotelBeds::HotelSearch::Request do
19
19
 
20
20
  describe "a valid instance" do
21
21
  subject { described_class.new(valid_attributes) }
22
-
22
+
23
23
  it "should be valid" do
24
24
  expect(subject).to be_valid
25
25
  end
26
26
  end
27
-
27
+
28
28
  describe "an instance missing rooms" do
29
29
  subject { described_class.new(valid_attributes.merge(rooms: [])) }
30
-
30
+
31
31
  it "should not be valid" do
32
32
  expect(subject).to_not be_valid
33
33
  end
@@ -1,8 +1,8 @@
1
- require "hotel_beds/hotel_search/parser/room_grouper"
1
+ require "hotel_beds/parser/room_grouper"
2
2
  require "hotel_beds/model/available_room"
3
3
 
4
- RSpec.describe HotelBeds::HotelSearch::Parser::RoomGrouper do
5
- subject { described_class.new(requested_rooms, response_rooms).results }
4
+ RSpec.describe HotelBeds::Parser::RoomGrouper do
5
+ subject { described_class.new(requested_rooms, response_rooms).groups }
6
6
 
7
7
  context "when asking for 3 rooms (2 x 2 adults & 1 x 1 adult, 1 child)" do
8
8
  let(:requested_rooms) do
@@ -0,0 +1,44 @@
1
+ require "nokogiri"
2
+ require "ostruct"
3
+ require "hotel_beds/parser/service"
4
+
5
+ RSpec.describe HotelBeds::Parser::Service do
6
+ let(:source) do
7
+ %Q(<HotelService SPUI="#{attrs[:id]}">
8
+ <Contract>
9
+ <Name>#{attrs[:contract_name]}</Name>
10
+ <IncomingOffice code="#{attrs[:contract_incoming_office_code]}" />
11
+ </Contract>
12
+
13
+ <DateFrom date="#{attrs[:check_in_date]}" />
14
+ <DateTo date="#{attrs[:check_out_date]}" />
15
+ <Currency code="#{attrs[:currency]}">Great British Pounds</Currency>
16
+ <TotalAmount>#{attrs[:amount]}</TotalAmount>
17
+ </HotelService>)
18
+ end
19
+
20
+ let(:attrs) do
21
+ {
22
+ id: "123",
23
+ contract_name: "Test",
24
+ contract_incoming_office_code: "Big Corp",
25
+ check_in_date: "20140505",
26
+ check_out_date: "20140506",
27
+ currency: "GBP",
28
+ amount: "123.45"
29
+ }
30
+ end
31
+
32
+ let(:parser) do
33
+ described_class.new(Nokogiri::XML(source).at_css("HotelService"))
34
+ end
35
+
36
+ describe "#to_model" do
37
+ subject { parser.to_model(model_class) }
38
+ let(:model_class) { OpenStruct }
39
+
40
+ it "should insert the data into the given class" do
41
+ expect(subject).to be_kind_of(model_class)
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hotel_beds
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Townsend
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-30 00:00:00.000000000 Z
11
+ date: 2014-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon
@@ -171,6 +171,10 @@ files:
171
171
  - Rakefile
172
172
  - hotel_beds.gemspec
173
173
  - lib/hotel_beds.rb
174
+ - lib/hotel_beds/basket_remove/envelope.rb
175
+ - lib/hotel_beds/basket_remove/operation.rb
176
+ - lib/hotel_beds/basket_remove/request.rb
177
+ - lib/hotel_beds/basket_remove/response.rb
174
178
  - lib/hotel_beds/client.rb
175
179
  - lib/hotel_beds/configuration.rb
176
180
  - lib/hotel_beds/connection.rb
@@ -180,31 +184,53 @@ files:
180
184
  - lib/hotel_beds/hotel_basket_add/response.rb
181
185
  - lib/hotel_beds/hotel_search/envelope.rb
182
186
  - lib/hotel_beds/hotel_search/operation.rb
183
- - lib/hotel_beds/hotel_search/parser/errors.rb
184
- - lib/hotel_beds/hotel_search/parser/hotel.rb
185
- - lib/hotel_beds/hotel_search/parser/price.rb
186
- - lib/hotel_beds/hotel_search/parser/room.rb
187
- - lib/hotel_beds/hotel_search/parser/room_grouper.rb
188
187
  - lib/hotel_beds/hotel_search/request.rb
189
188
  - lib/hotel_beds/hotel_search/response.rb
190
189
  - lib/hotel_beds/model.rb
191
190
  - lib/hotel_beds/model/available_room.rb
192
191
  - lib/hotel_beds/model/cancellation_policy.rb
192
+ - lib/hotel_beds/model/comment.rb
193
+ - lib/hotel_beds/model/contract.rb
194
+ - lib/hotel_beds/model/customer.rb
195
+ - lib/hotel_beds/model/destination.rb
193
196
  - lib/hotel_beds/model/hotel.rb
197
+ - lib/hotel_beds/model/price.rb
194
198
  - lib/hotel_beds/model/purchase.rb
195
199
  - lib/hotel_beds/model/requested_room.rb
196
200
  - lib/hotel_beds/model/room.rb
197
201
  - lib/hotel_beds/model/search_result.rb
198
202
  - lib/hotel_beds/model/service.rb
203
+ - lib/hotel_beds/parser.rb
204
+ - lib/hotel_beds/parser/available_room.rb
205
+ - lib/hotel_beds/parser/cancellation_policy.rb
206
+ - lib/hotel_beds/parser/comment.rb
207
+ - lib/hotel_beds/parser/contract.rb
208
+ - lib/hotel_beds/parser/customer.rb
209
+ - lib/hotel_beds/parser/destination.rb
210
+ - lib/hotel_beds/parser/errors.rb
211
+ - lib/hotel_beds/parser/hotel.rb
212
+ - lib/hotel_beds/parser/price.rb
213
+ - lib/hotel_beds/parser/purchase.rb
214
+ - lib/hotel_beds/parser/room_grouper.rb
215
+ - lib/hotel_beds/parser/service.rb
216
+ - lib/hotel_beds/purchase_confirm/envelope.rb
217
+ - lib/hotel_beds/purchase_confirm/operation.rb
218
+ - lib/hotel_beds/purchase_confirm/request.rb
219
+ - lib/hotel_beds/purchase_confirm/response.rb
220
+ - lib/hotel_beds/purchase_flush/envelope.rb
221
+ - lib/hotel_beds/purchase_flush/operation.rb
222
+ - lib/hotel_beds/purchase_flush/request.rb
223
+ - lib/hotel_beds/purchase_flush/response.rb
199
224
  - lib/hotel_beds/version.rb
200
- - spec/features/adding_a_hotel_to_basket_spec.rb
201
- - spec/features/grouped_hotel_search_spec.rb
202
- - spec/features/hotel_search_spec.rb
225
+ - spec/features/flushing_the_basket_spec.rb
226
+ - spec/features/ordering_a_hotel_room_spec.rb
227
+ - spec/features/removing_a_basket_item_spec.rb
203
228
  - spec/lib/hotel_beds/client_spec.rb
204
229
  - spec/lib/hotel_beds/configuration_spec.rb
205
230
  - spec/lib/hotel_beds/connection_spec.rb
206
- - spec/lib/hotel_beds/hotel_search/parser/room_grouper_spec.rb
207
231
  - spec/lib/hotel_beds/hotel_search/request_spec.rb
232
+ - spec/lib/hotel_beds/parser/room_grouper_spec.rb
233
+ - spec/lib/hotel_beds/parser/service_spec.rb
208
234
  - spec/lib/hotel_beds/version_spec.rb
209
235
  - spec/spec_helper.rb
210
236
  homepage: https://www.hotelsindex.com/open-source
@@ -232,13 +258,14 @@ signing_key:
232
258
  specification_version: 4
233
259
  summary: Interfaces with the HotelBeds SOAP API to book hotel rooms
234
260
  test_files:
235
- - spec/features/adding_a_hotel_to_basket_spec.rb
236
- - spec/features/grouped_hotel_search_spec.rb
237
- - spec/features/hotel_search_spec.rb
261
+ - spec/features/flushing_the_basket_spec.rb
262
+ - spec/features/ordering_a_hotel_room_spec.rb
263
+ - spec/features/removing_a_basket_item_spec.rb
238
264
  - spec/lib/hotel_beds/client_spec.rb
239
265
  - spec/lib/hotel_beds/configuration_spec.rb
240
266
  - spec/lib/hotel_beds/connection_spec.rb
241
- - spec/lib/hotel_beds/hotel_search/parser/room_grouper_spec.rb
242
267
  - spec/lib/hotel_beds/hotel_search/request_spec.rb
268
+ - spec/lib/hotel_beds/parser/room_grouper_spec.rb
269
+ - spec/lib/hotel_beds/parser/service_spec.rb
243
270
  - spec/lib/hotel_beds/version_spec.rb
244
271
  - spec/spec_helper.rb
@@ -1,49 +0,0 @@
1
- require "active_model/errors"
2
-
3
- module HotelBeds
4
- module HotelSearch
5
- module Parser
6
- class Errors
7
- def self.call(*args, &block)
8
- new(*args, &block).call
9
- end
10
-
11
- attr_accessor :response, :body
12
- private :response, :body
13
-
14
- def initialize(response, body)
15
- self.response = response
16
- self.body = body
17
- freeze
18
- end
19
-
20
- def call
21
- ActiveModel::Errors.new(self).tap do |errors|
22
- apply_response_errors(errors)
23
- apply_body_errors(errors)
24
- end.freeze
25
- end
26
-
27
- private
28
- def apply_response_errors(errors)
29
- if response.http_error?
30
- errors.add(:base, "HTTP error")
31
- elsif response.soap_fault?
32
- errors.add(:base, "SOAP error")
33
- elsif !response.success?
34
- errors.add(:base, "Request failed")
35
- end
36
- end
37
-
38
- def apply_body_errors(errors)
39
- body.css("ErrorList Error").each do |error|
40
- errors.add(:base, [
41
- (sm = error.at_css("Message")) && sm.content,
42
- (dm = error.at_css("DetailedMessage")) && dm.content
43
- ].compact.join("\n"))
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end