hotel_beds 0.1.3 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: def94cec45be31dc8a52150ee27a4d4ed43715c0
4
- data.tar.gz: 9c608ab58056fc0906845519db57a6f48aec545f
3
+ metadata.gz: f4e1d67927848975b80e7a3dc3cd80654105e485
4
+ data.tar.gz: 65aadd0fb3f316987e34d5aa83dbe4c3d50319a6
5
5
  SHA512:
6
- metadata.gz: 13fdfea5ec248841401c034cf574b0f349780b482a4ebbb1a70ce355e197c783a40b8cf2befe163a2e751bdd6c533767920454ac5200ba54abfe09f80e2ffad1
7
- data.tar.gz: f49794c9d02dce57bc3d7c88b1e4ecd3468423e0bf20aa1687d2657ac2ecc3e112fda4efc1e84874b4b70f4e5f6ecfdb4dbb3bcfd63bd977ac9acf846a075b48
6
+ metadata.gz: 7a795daa686af484ce5bede7955a7133dddeece24b065f4da8c0d372c03671c9e3f3d311ed52b872bccda910524b5d4a8295d9320fcb5e14619ea2d6c45c5a6c
7
+ data.tar.gz: 5ba1daeadd74a320a985378997bd8f0cc9f670fd5f78051404dc0adf4fee4b8a29af12293d6e3ce66af91f6e9c56a68a21f66850fdd98f7d72e9354630d503fa
data/.tm_properties ADDED
@@ -0,0 +1,5 @@
1
+ exclude = '{$exclude,tmp,pkg,Gemfile.lock,*.gem}'
2
+ TM_STRIP_WHITESPACE_ON_SAVE = true
3
+
4
+ tabSize = 2
5
+ softTabs = true
data/INTERNALS.md ADDED
@@ -0,0 +1,9 @@
1
+ # Grouping results
2
+
3
+ The process we use to group results is as follows:
4
+
5
+ 1) Group the available rooms (AR) by occupants (OK)
6
+ 2) Expand the rooms (AR) in the array to illustrate the availability of each room (limit to a max of 5, as we don't support searches of more than 5 rooms)
7
+ 3) Group the count of each requested room (RC) by occupants (OK)
8
+ 4) For each group, determine all combinations of the available rooms (AR) for the given count (RC), this gives us the search results per room group (RSRG)
9
+ 5) Find all combinations of the search results per room group, giving us unique search results (SR)
data/README.md CHANGED
@@ -18,7 +18,7 @@ Manually, via command line:
18
18
 
19
19
  # create the connection to HotelBeds
20
20
  client = HotelBeds::Client.new(endpoint: :test, username: "user", password: "pass")
21
-
21
+
22
22
  # perform the search
23
23
  search = client.perform_hotel_search({
24
24
  check_in_date: Date.today,
@@ -26,7 +26,7 @@ Manually, via command line:
26
26
  rooms: [{ adult_count: 2 }],
27
27
  destination: "SYD"
28
28
  })
29
-
29
+
30
30
  # inspect the response
31
31
  puts search.response.hotels
32
32
  # => [<HotelBeds::Model::Hotel>, <HotelBeds::Model::Hotel>]
@@ -35,6 +35,24 @@ Manually, via command line:
35
35
  puts search.response.current_page
36
36
  # => 1
37
37
 
38
+ ### Options
39
+
40
+ The HotelBeds API will return individual rooms, rather than being grouped by what you searched for (e.g. 2 rooms, 1 with 2 adults, 1 with 1 adult and 1 child). To fix this issue, you can enable result grouping by adding `group_results: true` to the `perform_hotel_search` call.
41
+
42
+ Example:
43
+
44
+ # perform the search
45
+ search = client.perform_hotel_search({
46
+ check_in_date: Date.today,
47
+ check_out_date: Date.today + 1,
48
+ rooms: [
49
+ { adult_count: 2 },
50
+ { adult_count: 1, child_count: 1, child_ages: [7] }
51
+ ],
52
+ destination: "SYD",
53
+ group_results: true
54
+ })
55
+
38
56
  ## Contributing
39
57
 
40
58
  1. [Fork it](https://github.com/platformq/hotel_beds/fork)
@@ -12,7 +12,7 @@ module HotelBeds
12
12
  OccupancyList: occupancy_list
13
13
  }.merge(Hash(destination)).merge(Hash(hotels)).merge(Hash(extra_params))
14
14
  end
15
-
15
+
16
16
  private
17
17
  def extra_params
18
18
  { ExtraParamList: {
@@ -27,7 +27,7 @@ module HotelBeds
27
27
  }]
28
28
  } }
29
29
  end
30
-
30
+
31
31
  def pagination_data
32
32
  { :@pageNumber => Integer(page_number) }
33
33
  end
@@ -52,7 +52,7 @@ module HotelBeds
52
52
  } }
53
53
  end
54
54
  end
55
-
55
+
56
56
  def hotels
57
57
  if Array(__getobj__.hotels).any?
58
58
  { HotelCodeList: {
@@ -61,20 +61,22 @@ module HotelBeds
61
61
  } }
62
62
  end
63
63
  end
64
-
64
+
65
65
  def occupancy_list
66
- Array(rooms).map do |room|
67
- { HotelOccupancy: {
68
- RoomCount: Integer(room.adult_count) + Integer(room.child_count),
69
- Occupancy: {
66
+ { HotelOccupancy: Array(rooms).map { |room|
67
+ guest_list = if room.child_count > 0
68
+ { GuestList: { Customer: Array(room.child_ages).map { |age|
69
+ { :@type => "CH", :Age => Integer(age) }
70
+ } } }
71
+ end
72
+ {
73
+ RoomCount: 1,
74
+ Occupancy: (guest_list || Hash.new).merge({
70
75
  AdultCount: Integer(room.adult_count),
71
76
  ChildCount: Integer(room.child_count)
72
- },
73
- GuestList: Array(room.child_ages).each { |age|
74
- { Customer: { :@type => "CH", :Age => Integer(age) } }
75
- }
76
- } }
77
- end
77
+ })
78
+ }
79
+ } }
78
80
  end
79
81
  end
80
82
  end
@@ -7,14 +7,14 @@ module HotelBeds
7
7
  class Operation
8
8
  attr_accessor :request, :response, :errors
9
9
  private :request=, :response=, :errors=
10
-
10
+
11
11
  def initialize(*args)
12
12
  self.request = Request.new(*args)
13
13
  end
14
-
14
+
15
15
  def perform(connection:)
16
16
  if request.valid?
17
- self.response = Response.new(retrieve(connection))
17
+ self.response = Response.new(request, retrieve(connection))
18
18
  self.errors = response.errors
19
19
  else
20
20
  self.errors = request.errors
@@ -22,11 +22,11 @@ module HotelBeds
22
22
  freeze
23
23
  self
24
24
  end
25
-
25
+
26
26
  private
27
27
  def retrieve(connection)
28
28
  connection.call({
29
- method: :getHotelValuedAvail,
29
+ method: :getHotelValuedAvail,
30
30
  namespace: :HotelValuedAvailRQ,
31
31
  data: Envelope.new(request).attributes
32
32
  })
@@ -3,14 +3,14 @@ require "hotel_beds/model"
3
3
  module HotelBeds
4
4
  module HotelSearch
5
5
  class Request
6
- class Room
6
+ class Room
7
7
  include HotelBeds::Model
8
-
8
+
9
9
  # attributes
10
10
  attribute :adult_count, Integer, default: 0
11
11
  attribute :child_count, Integer, default: 0
12
12
  attribute :child_ages, Array[Integer], default: Array.new
13
-
13
+
14
14
  # validation
15
15
  validates :adult_count, :child_count, numericality: {
16
16
  greater_than_or_equal_to: 0,
@@ -23,7 +23,7 @@ module HotelBeds
23
23
  end
24
24
  end
25
25
  end
26
-
26
+
27
27
  include HotelBeds::Model
28
28
 
29
29
  # attributes
@@ -34,7 +34,8 @@ module HotelBeds
34
34
  attribute :destination, String
35
35
  attribute :hotels, Array[Integer]
36
36
  attribute :rooms, Array[Room]
37
-
37
+ attribute :group_results, Virtus::Attribute::Boolean, default: false
38
+
38
39
  # validation
39
40
  validates :language, :destination, length: { is: 3 }
40
41
  validates :check_in_date, :check_out_date, presence: true
@@ -1,13 +1,16 @@
1
1
  require "active_model/errors"
2
2
  require "hotel_beds/model/hotel"
3
+ require "hotel_beds/model/available_room"
4
+ require_relative "room_grouper"
3
5
 
4
6
  module HotelBeds
5
7
  module HotelSearch
6
8
  class Response
7
- attr_accessor :headers, :body, :errors
8
- private :headers=, :body=, :errors=
9
-
10
- def initialize(response)
9
+ attr_accessor :request, :headers, :body, :errors
10
+ private :request=, :headers=, :body=, :errors=
11
+
12
+ def initialize(request, response)
13
+ self.request = request
11
14
  self.headers = response.header
12
15
  self.body = Nokogiri::XML(response.body.fetch(:get_hotel_valued_avail))
13
16
  self.errors = ActiveModel::Errors.new(self).tap do |errors|
@@ -28,11 +31,11 @@ module HotelBeds
28
31
  end
29
32
  freeze
30
33
  end
31
-
34
+
32
35
  def inspect
33
36
  "<#{self.class.name} errors=#{errors.inspect} headers=#{headers.inspect} body=#{body.to_s}>"
34
37
  end
35
-
38
+
36
39
  def current_page
37
40
  if data = pagination_data
38
41
  Integer(data.attr("currentPage"))
@@ -40,7 +43,7 @@ module HotelBeds
40
43
  0
41
44
  end
42
45
  end
43
-
46
+
44
47
  def total_pages
45
48
  if data = pagination_data
46
49
  Integer(data.attr("totalPages"))
@@ -48,7 +51,7 @@ module HotelBeds
48
51
  0
49
52
  end
50
53
  end
51
-
54
+
52
55
  def hotels
53
56
  body.css("ServiceHotel").lazy.map do |hotel|
54
57
  HotelBeds::Model::Hotel.new({
@@ -57,37 +60,39 @@ module HotelBeds
57
60
  images: hotel.css("HotelInfo ImageList Image Url").map(&:content),
58
61
  latitude: hotel.at_css("HotelInfo Position").attr("latitude"),
59
62
  longitude: hotel.at_css("HotelInfo Position").attr("longitude"),
60
- results: parse_available_rooms(hotel.css("AvailableRoom"))
63
+ results: generate_results(hotel.css("AvailableRoom"))
61
64
  })
62
65
  end
63
66
  end
64
-
67
+
65
68
  private
66
69
  def pagination_data
67
70
  body.at_css("PaginationData")
68
71
  end
69
-
70
- def parse_available_rooms(rooms)
71
- Array(rooms).map do |room|
72
- {
73
- adult_count: room.at_css("HotelOccupancy AdultCount").content,
74
- child_count: room.at_css("HotelOccupancy ChildCount").content,
75
- rooms: parse_hotel_rooms(room.css("HotelRoom"))
76
- }
72
+
73
+ def generate_results(rooms)
74
+ parsed_rooms = parse_available_rooms(rooms)
75
+ if request.group_results?
76
+ parsed_rooms = RoomGrouper.new(request.rooms, parsed_rooms).results
77
+ end
78
+ parsed_rooms.map do |rooms|
79
+ HotelBeds::Model::SearchResult.new(rooms: Array(rooms))
77
80
  end
78
81
  end
79
82
 
80
- def parse_hotel_rooms(rooms)
83
+ def parse_available_rooms(rooms)
81
84
  Array(rooms).map do |room|
82
- {
83
- number_available: room.attr("availCount"),
84
- id: room.attr("SHRUI"),
85
- description: room.at_css("RoomType").content,
86
- board: room.at_css("Board").content,
87
- price: ((room > "Price") > "Amount").first.content,
85
+ HotelBeds::Model::AvailableRoom.new({
86
+ id: room.at_css("HotelRoom").attr("SHRUI"),
87
+ adult_count: room.at_css("HotelOccupancy AdultCount").content,
88
+ child_count: room.at_css("HotelOccupancy ChildCount").content,
89
+ number_available: room.at_css("HotelRoom").attr("availCount"),
90
+ description: room.at_css("HotelRoom RoomType").content,
91
+ board: room.at_css("HotelRoom Board").content,
88
92
  currency: body.at_css("Currency").attr("code"),
93
+ price: ((room.at_css("HotelRoom") > "Price") > "Amount").first.content,
89
94
  rates: parse_price_list(room.css("Price PriceList Price"))
90
- }
95
+ })
91
96
  end
92
97
  end
93
98
 
@@ -0,0 +1,64 @@
1
+ require "hotel_beds/model/search_result"
2
+
3
+ # see INTERNALS.md for comment symbols
4
+ module HotelBeds
5
+ module HotelSearch
6
+ class RoomGrouper < Struct.new(:requested_rooms, :response_rooms)
7
+ def results
8
+ if requested_rooms.size == 1
9
+ response_rooms.map { |room| [room] }
10
+ else
11
+ combined_available_rooms
12
+ end
13
+ end
14
+
15
+ private
16
+ # returns an array of room combinations for all rooms
17
+ def combined_available_rooms
18
+ room_groups = combine_available_rooms_by_occupants.values
19
+ head, *rest = room_groups
20
+ head.product(*rest).map { |rooms| rooms.flatten.sort_by(&:id) }.uniq
21
+ end
22
+
23
+ # returns a hash of OK => RSRG
24
+ def combine_available_rooms_by_occupants
25
+ group_requested_room_count_by_occupants.to_a.inject(Hash.new) do |result, (key, count)|
26
+ result[key] = group_rooms_by_occupants.fetch(key).combination(count).to_a
27
+ result
28
+ end
29
+ rescue KeyError => e
30
+ Hash.new
31
+ end
32
+
33
+ # returns a hash of OK => RC
34
+ def group_requested_room_count_by_occupants
35
+ requested_rooms.inject(Hash.new) do |result, room|
36
+ key = occupant_key(room)
37
+ result[key] ||= 0
38
+ result[key] += 1
39
+ result
40
+ end
41
+ end
42
+
43
+ # returns a hash of OK => AR
44
+ def group_rooms_by_occupants
45
+ @frozen_rooms ||= response_rooms.inject(Hash.new) do |result, room|
46
+ key = occupant_key(room)
47
+ result[key] ||= Array.new
48
+ 1.upto([room.number_available, 5].min) do |i|
49
+ result[key].push(room)
50
+ end
51
+ result
52
+ end.freeze
53
+ end
54
+
55
+ # returns an OK for a given room
56
+ def occupant_key(room)
57
+ {
58
+ adult_count: room.adult_count,
59
+ child_count: room.child_count
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -5,6 +5,7 @@ module HotelBeds
5
5
  module Model
6
6
  def self.included(base)
7
7
  base.class_eval do
8
+ include Comparable
8
9
  include Virtus.model
9
10
  include ActiveModel::Validations
10
11
  end
@@ -1,15 +1,25 @@
1
1
  require "hotel_beds/model"
2
- require_relative "hotel_room"
3
2
 
4
3
  module HotelBeds
5
4
  module Model
6
5
  class AvailableRoom
7
6
  include HotelBeds::Model
8
-
7
+
9
8
  # attributes
10
- attribute :rooms, Array[HotelRoom]
9
+ attribute :id, Integer
11
10
  attribute :adult_count, Integer
12
11
  attribute :child_count, Integer
12
+ attribute :description, String
13
+ attribute :board, String
14
+ attribute :price, BigDecimal
15
+ attribute :currency, String
16
+ attribute :number_available, Integer
17
+ attribute :rates, Hash[Date => BigDecimal]
18
+
19
+ # compare based on id
20
+ def <=>(other)
21
+ id == other.id && !id.nil?
22
+ end
13
23
  end
14
24
  end
15
25
  end
@@ -1,5 +1,5 @@
1
1
  require "hotel_beds/model"
2
- require_relative "available_room"
2
+ require_relative "search_result"
3
3
 
4
4
  module HotelBeds
5
5
  module Model
@@ -13,7 +13,7 @@ module HotelBeds
13
13
  attribute :stars, Integer
14
14
  attribute :longitude, BigDecimal
15
15
  attribute :latitude, BigDecimal
16
- attribute :results, Array[AvailableRoom]
16
+ attribute :results, Array[SearchResult]
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -0,0 +1,19 @@
1
+ require "hotel_beds/model"
2
+ require_relative "available_room"
3
+
4
+ module HotelBeds
5
+ module Model
6
+ class SearchResult
7
+ include HotelBeds::Model
8
+
9
+ # attributes
10
+ attribute :rooms, Array[AvailableRoom]
11
+ attribute :currency, String
12
+
13
+ # results are purely based upon their combination of rooms
14
+ def <=>(other)
15
+ rooms.map(&:id).sort == other.rooms.map(&:id).sort
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module HotelBeds
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,67 @@
1
+ require "hotel_beds"
2
+
3
+ RSpec.describe "performing a grouped hotel search" do
4
+ describe "#response" do
5
+ before(:all) do
6
+ @client = HotelBeds::Client.new({
7
+ endpoint: :test,
8
+ username: ENV.fetch("HOTEL_BEDS_USERNAME"),
9
+ password: ENV.fetch("HOTEL_BEDS_PASSWORD"),
10
+ proxy: ENV.fetch("HOTEL_BEDS_PROXY", nil)
11
+ })
12
+ @check_in_date = Date.today + 28 + rand(10)
13
+ @check_out_date = @check_in_date + rand(3) + rand(2) + 1
14
+ @operation = @client.perform_hotel_search({
15
+ check_in_date: @check_in_date,
16
+ check_out_date: @check_out_date,
17
+ rooms: [
18
+ { adult_count: 2 },
19
+ { adult_count: 1, child_count: 1, child_ages: [rand(17)] }
20
+ ],
21
+ destination: "SYD",
22
+ group_results: true
23
+ })
24
+ if @operation.errors.any?
25
+ raise StandardError, @operation.errors.full_messages.join("\n")
26
+ end
27
+ @response = @operation.response
28
+ end
29
+
30
+ let(:check_in_date) { @check_in_date }
31
+ let(:check_out_date) { @check_out_date }
32
+ let(:response) { @response }
33
+
34
+ describe "#errors" do
35
+ subject { response.errors }
36
+
37
+ it "should be empty" do
38
+ expect(subject).to be_empty
39
+ end
40
+ end
41
+
42
+ describe "#hotels" do
43
+ subject { response.hotels }
44
+
45
+ it "should have room counts to match the searched room count" do
46
+ room_counts = subject.map { |h| h.results.map { |r| r.rooms.size } }
47
+ expect(room_counts.to_a.flatten.uniq).to eq([response.request.rooms.size])
48
+ end
49
+ end
50
+
51
+ describe "#current_page" do
52
+ subject { response.current_page }
53
+
54
+ it "should return '1'" do
55
+ expect(subject).to eq(1)
56
+ end
57
+ end
58
+
59
+ describe "#total_pages" do
60
+ subject { response.total_pages }
61
+
62
+ it "should be greater or equal to current page" do
63
+ expect(subject).to be >= response.current_page
64
+ end
65
+ end
66
+ end
67
+ end
@@ -25,12 +25,12 @@ RSpec.describe "performing a hotel search" do
25
25
 
26
26
  describe "#errors" do
27
27
  subject { response.errors }
28
-
28
+
29
29
  it "should be empty" do
30
30
  expect(subject).to be_empty
31
31
  end
32
32
  end
33
-
33
+
34
34
  describe "#hotels" do
35
35
  subject { response.hotels }
36
36
 
@@ -39,18 +39,23 @@ RSpec.describe "performing a hotel search" do
39
39
  expect(subject.to_a).to_not be_empty
40
40
  expect(subject.first).to be_kind_of(HotelBeds::Model::Hotel)
41
41
  end
42
-
42
+
43
43
  it "should parse the rates correctly" do
44
44
  room = subject.first.results.first.rooms.first
45
45
  expect(room.price).to eq(room.rates.values.inject(:+))
46
46
  end
47
-
47
+
48
48
  it "should have the same number of rates as nights requested" do
49
49
  room = subject.first.results.first.rooms.first
50
50
  expect(room.rates.size).to eq(check_out_date - check_in_date)
51
51
  end
52
+
53
+ it "should only have one room per result" do
54
+ room_counts = subject.map { |h| h.results.map { |r| r.rooms.size } }
55
+ expect(room_counts.to_a.flatten.uniq).to eq([1])
56
+ end
52
57
  end
53
-
58
+
54
59
  describe "#current_page" do
55
60
  subject { response.current_page }
56
61
 
@@ -58,7 +63,7 @@ RSpec.describe "performing a hotel search" do
58
63
  expect(subject).to eq(1)
59
64
  end
60
65
  end
61
-
66
+
62
67
  describe "#total_pages" do
63
68
  subject { response.total_pages }
64
69
 
@@ -0,0 +1,45 @@
1
+ require "hotel_beds/hotel_search/room_grouper"
2
+
3
+ RSpec.describe HotelBeds::HotelSearch::RoomGrouper do
4
+ subject { described_class.new(requested_rooms, response_rooms).results }
5
+
6
+ context "when asking for 2 rooms (2 adults & 1 adult, 1 child)" do
7
+ let(:requested_rooms) do
8
+ [
9
+ double(:requested_room, adult_count: 2, child_count: 0),
10
+ double(:requested_room, adult_count: 1, child_count: 1)
11
+ ]
12
+ end
13
+
14
+ let(:response_rooms) do
15
+ [
16
+ double(:response_room_1, id: "room_1", adult_count: 2, child_count: 0, number_available: 1),
17
+ double(:response_room_2, id: "room_2", adult_count: 2, child_count: 0, number_available: 1),
18
+ double(:response_room_3, id: "room_3", adult_count: 1, child_count: 1, number_available: 2),
19
+ double(:response_room_4, id: "room_4", adult_count: 1, child_count: 1, number_available: 1),
20
+ double(:response_room_5, id: "room_5", adult_count: 2, child_count: 0, number_available: 2)
21
+ ]
22
+ end
23
+
24
+ it "should return 6 results" do
25
+ expect(subject.size).to eq(6)
26
+ end
27
+ end
28
+
29
+ context "when asking for 1 rooms (1 adult, 1 child)" do
30
+ let(:requested_rooms) do
31
+ [double(:requested_room, adult_count: 1, child_count: 1)]
32
+ end
33
+
34
+ let(:response_rooms) do
35
+ [
36
+ double(:response_room_1, id: "room_1", adult_count: 1, child_count: 1, number_available: 2),
37
+ double(:response_room_2, id: "room_2", adult_count: 1, child_count: 1, number_available: 1)
38
+ ]
39
+ end
40
+
41
+ it "should return 2 results" do
42
+ expect(subject.size).to eq(2)
43
+ end
44
+ end
45
+ 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.1.3
4
+ version: 0.2.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-18 00:00:00.000000000 Z
11
+ date: 2014-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon
@@ -162,8 +162,10 @@ files:
162
162
  - ".rspec"
163
163
  - ".ruby-gemset"
164
164
  - ".ruby-version"
165
+ - ".tm_properties"
165
166
  - Gemfile
166
167
  - Guardfile
168
+ - INTERNALS.md
167
169
  - LICENSE.txt
168
170
  - README.md
169
171
  - Rakefile
@@ -176,16 +178,19 @@ files:
176
178
  - lib/hotel_beds/hotel_search/operation.rb
177
179
  - lib/hotel_beds/hotel_search/request.rb
178
180
  - lib/hotel_beds/hotel_search/response.rb
181
+ - lib/hotel_beds/hotel_search/room_grouper.rb
179
182
  - lib/hotel_beds/model.rb
180
183
  - lib/hotel_beds/model/available_room.rb
181
184
  - lib/hotel_beds/model/hotel.rb
182
- - lib/hotel_beds/model/hotel_room.rb
185
+ - lib/hotel_beds/model/search_result.rb
183
186
  - lib/hotel_beds/version.rb
187
+ - spec/features/grouped_hotel_search_spec.rb
184
188
  - spec/features/hotel_search_spec.rb
185
189
  - spec/lib/hotel_beds/client_spec.rb
186
190
  - spec/lib/hotel_beds/configuration_spec.rb
187
191
  - spec/lib/hotel_beds/connection_spec.rb
188
192
  - spec/lib/hotel_beds/hotel_search/request_spec.rb
193
+ - spec/lib/hotel_beds/hotel_search/room_grouper_spec.rb
189
194
  - spec/lib/hotel_beds/version_spec.rb
190
195
  - spec/spec_helper.rb
191
196
  homepage: https://www.hotelsindex.com/open-source
@@ -213,10 +218,12 @@ signing_key:
213
218
  specification_version: 4
214
219
  summary: Interfaces with the HotelBeds SOAP API to book hotel rooms
215
220
  test_files:
221
+ - spec/features/grouped_hotel_search_spec.rb
216
222
  - spec/features/hotel_search_spec.rb
217
223
  - spec/lib/hotel_beds/client_spec.rb
218
224
  - spec/lib/hotel_beds/configuration_spec.rb
219
225
  - spec/lib/hotel_beds/connection_spec.rb
220
226
  - spec/lib/hotel_beds/hotel_search/request_spec.rb
227
+ - spec/lib/hotel_beds/hotel_search/room_grouper_spec.rb
221
228
  - spec/lib/hotel_beds/version_spec.rb
222
229
  - spec/spec_helper.rb
@@ -1,18 +0,0 @@
1
- require "hotel_beds/model"
2
-
3
- module HotelBeds
4
- module Model
5
- class HotelRoom
6
- include HotelBeds::Model
7
-
8
- # attributes
9
- attribute :id, Integer
10
- attribute :description, String
11
- attribute :board, String
12
- attribute :price, BigDecimal
13
- attribute :currency, String
14
- attribute :number_available, Integer
15
- attribute :rates, Hash[Date => BigDecimal]
16
- end
17
- end
18
- end