bookingsync-api 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile +2 -1
  4. data/Guardfile +3 -6
  5. data/README.md +11 -3
  6. data/bookingsync-api.gemspec +2 -2
  7. data/lib/bookingsync/api.rb +0 -2
  8. data/lib/bookingsync/api/client.rb +151 -54
  9. data/lib/bookingsync/api/client/amenities.rb +22 -0
  10. data/lib/bookingsync/api/client/billing_addresses.rb +22 -0
  11. data/lib/bookingsync/api/client/bookings.rb +7 -9
  12. data/lib/bookingsync/api/client/bookings_payments.rb +22 -0
  13. data/lib/bookingsync/api/client/clients.rb +43 -0
  14. data/lib/bookingsync/api/client/destinations.rb +22 -0
  15. data/lib/bookingsync/api/client/inquiries.rb +2 -2
  16. data/lib/bookingsync/api/client/payments.rb +53 -0
  17. data/lib/bookingsync/api/client/periods.rb +54 -0
  18. data/lib/bookingsync/api/client/photos.rb +22 -0
  19. data/lib/bookingsync/api/client/rates.rb +23 -0
  20. data/lib/bookingsync/api/client/rates_rules.rb +22 -0
  21. data/lib/bookingsync/api/client/rates_tables.rb +53 -0
  22. data/lib/bookingsync/api/client/rental_agreements.rb +50 -0
  23. data/lib/bookingsync/api/client/rentals.rb +39 -1
  24. data/lib/bookingsync/api/client/reviews.rb +31 -0
  25. data/lib/bookingsync/api/client/seasons.rb +53 -0
  26. data/lib/bookingsync/api/client/special_offers.rb +54 -0
  27. data/lib/bookingsync/api/relation.rb +87 -0
  28. data/lib/bookingsync/api/resource.rb +58 -0
  29. data/lib/bookingsync/api/response.rb +79 -0
  30. data/lib/bookingsync/api/serializer.rb +100 -0
  31. data/lib/bookingsync/api/version.rb +1 -1
  32. data/spec/bookingsync/api/client/amenities_spec.rb +12 -0
  33. data/spec/bookingsync/api/client/billing_addresses_spec.rb +12 -0
  34. data/spec/bookingsync/api/client/billings_payments_spec.rb +12 -0
  35. data/spec/bookingsync/api/client/bookings_spec.rb +10 -8
  36. data/spec/bookingsync/api/client/clients_spec.rb +55 -0
  37. data/spec/bookingsync/api/client/destinations_spec.rb +12 -0
  38. data/spec/bookingsync/api/client/inquiries_spec.rb +1 -1
  39. data/spec/bookingsync/api/client/payments_spec.rb +56 -0
  40. data/spec/bookingsync/api/client/periods_spec.rb +61 -0
  41. data/spec/bookingsync/api/client/photos_spec.rb +12 -0
  42. data/spec/bookingsync/api/client/rates_rules_spec.rb +13 -0
  43. data/spec/bookingsync/api/client/rates_spec.rb +12 -0
  44. data/spec/bookingsync/api/client/rates_tables_spec.rb +59 -0
  45. data/spec/bookingsync/api/client/rental_agreements_spec.rb +64 -0
  46. data/spec/bookingsync/api/client/rentals_spec.rb +56 -6
  47. data/spec/bookingsync/api/client/reviews_spec.rb +33 -0
  48. data/spec/bookingsync/api/client/seasons_spec.rb +61 -0
  49. data/spec/bookingsync/api/client/special_offers_spec.rb +63 -0
  50. data/spec/bookingsync/api/client_spec.rb +31 -10
  51. data/spec/bookingsync/api/relation_spec.rb +72 -0
  52. data/spec/bookingsync/api/resource_spec.rb +79 -0
  53. data/spec/bookingsync/api/response_spec.rb +66 -0
  54. data/spec/cassettes/BookingSync_API_Client_Amenities/_amenities/returns_amenities.yml +72 -0
  55. data/spec/cassettes/BookingSync_API_Client_BillingAddresses/_billing_addresses/returns_billing_addresses.yml +65 -0
  56. data/spec/cassettes/BookingSync_API_Client_Bookings/_bookings/pagination/with_a_block/yields_block_with_batch_of_bookings.yml +12 -12
  57. data/spec/cassettes/BookingSync_API_Client_Bookings/_bookings/pagination/with_auto_paginate_true/returns_all_bookings_joined_from_many_requests.yml +12 -12
  58. data/spec/cassettes/BookingSync_API_Client_Bookings/_bookings/pagination/with_per_page_setting/returns_limited_number_of_bookings.yml +3 -3
  59. data/spec/cassettes/BookingSync_API_Client_Bookings/_clients/returns_clients.yml +66 -0
  60. data/spec/cassettes/BookingSync_API_Client_Bookings/_create_booking/creates_a_booking.yml +1 -1
  61. data/spec/cassettes/BookingSync_API_Client_Bookings/_create_client/creates_a_new_client.yml +64 -0
  62. data/spec/cassettes/BookingSync_API_Client_Bookings/_edit_booking/updates_given_booking_by_ID.yml +18 -14
  63. data/spec/cassettes/BookingSync_API_Client_Bookings/_edit_client/updates_given_client_by_ID.yml +62 -0
  64. data/spec/cassettes/BookingSync_API_Client_BookingsPayments/_bookings_payments/returns_bookings_payments.yml +65 -0
  65. data/spec/cassettes/BookingSync_API_Client_Destinations/_destinations/returns_destinations.yml +64 -0
  66. data/spec/cassettes/BookingSync_API_Client_Inquiries/_create_inquiry/creates_a_new_inquiry.yml +1 -1
  67. data/spec/cassettes/BookingSync_API_Client_Inquiries/_inquiries/returns_inquiries.yml +1 -1
  68. data/spec/cassettes/BookingSync_API_Client_Payments/_cancel_payment/cancels_given_payment.yml +57 -0
  69. data/spec/cassettes/BookingSync_API_Client_Payments/_create_payment/creates_a_new_payment.yml +63 -0
  70. data/spec/cassettes/BookingSync_API_Client_Payments/_edit_payment/updates_given_payment_by_ID.yml +61 -0
  71. data/spec/cassettes/BookingSync_API_Client_Payments/_payments/returns_payments.yml +64 -0
  72. data/spec/cassettes/BookingSync_API_Client_Periods/_create_period/creates_a_new_period.yml +63 -0
  73. data/spec/cassettes/BookingSync_API_Client_Periods/_delete_period/deletes_given_period.yml +70 -0
  74. data/spec/cassettes/BookingSync_API_Client_Periods/_edit_period/updates_given_period_by_ID.yml +61 -0
  75. data/spec/cassettes/BookingSync_API_Client_Periods/_periods/returns_periods.yml +64 -0
  76. data/spec/cassettes/BookingSync_API_Client_Photos/_photos/returns_photos.yml +72 -0
  77. data/spec/cassettes/BookingSync_API_Client_Rates/_rates/returns_rates.yml +64 -0
  78. data/spec/cassettes/BookingSync_API_Client_RatesRules/_rates_rules/returns_rates_rules.yml +64 -0
  79. data/spec/cassettes/BookingSync_API_Client_RatesTables/_create_rates_table/creates_a_new_rates_table.yml +64 -0
  80. data/spec/cassettes/BookingSync_API_Client_RatesTables/_delete_rates_table/deletes_given_rates_table.yml +57 -0
  81. data/spec/cassettes/BookingSync_API_Client_RatesTables/_edit_rates_table/updates_given_rates_table_by_ID.yml +62 -0
  82. data/spec/cassettes/BookingSync_API_Client_RatesTables/_rates_tables/returns_rates_tables.yml +74 -0
  83. data/spec/cassettes/BookingSync_API_Client_RentalAgreements/_create_rental_agreement/creates_a_new_rental_agreement.yml +63 -0
  84. data/spec/cassettes/BookingSync_API_Client_RentalAgreements/_create_rental_agreement_for_booking/creates_a_new_rental_agreement.yml +63 -0
  85. data/spec/cassettes/BookingSync_API_Client_RentalAgreements/_create_rental_agreement_for_rental/creates_a_new_rental_agreement.yml +63 -0
  86. data/spec/cassettes/BookingSync_API_Client_RentalAgreements/_rental_agreements/returns_rental_agreements.yml +64 -0
  87. data/spec/cassettes/BookingSync_API_Client_Rentals/_cancel_rental/cancels_given_rental.yml +57 -0
  88. data/spec/cassettes/BookingSync_API_Client_Rentals/_create_rental/creates_a_new_rental.yml +64 -0
  89. data/spec/cassettes/BookingSync_API_Client_Rentals/_edit_rental/updates_given_rental_by_ID.yml +64 -0
  90. data/spec/cassettes/BookingSync_API_Client_Rentals/_rental/returns_a_single_rental.yml +67 -0
  91. data/spec/cassettes/BookingSync_API_Client_Rentals/_rentals/links/returns_associated_photos.yml +152 -0
  92. data/spec/cassettes/BookingSync_API_Client_Rentals/_rentals/links/returns_links_to_associated_resources.yml +91 -0
  93. data/spec/cassettes/BookingSync_API_Client_Rentals/_rentals/returns_rentals.yml +45 -20
  94. data/spec/cassettes/BookingSync_API_Client_Reviews/_create_review/creates_a_new_review.yml +64 -0
  95. data/spec/cassettes/BookingSync_API_Client_Reviews/_reviews/returns_reviews.yml +83 -0
  96. data/spec/cassettes/BookingSync_API_Client_Seasons/_create_season/creates_a_new_season.yml +64 -0
  97. data/spec/cassettes/BookingSync_API_Client_Seasons/_delete_season/deletes_given_season.yml +57 -0
  98. data/spec/cassettes/BookingSync_API_Client_Seasons/_edit_season/updates_given_season_by_ID.yml +62 -0
  99. data/spec/cassettes/BookingSync_API_Client_Seasons/_seasons/returns_seasons.yml +74 -0
  100. data/spec/cassettes/BookingSync_API_Client_SpecialOffers/_create_special_offer/creates_a_new_special_offer.yml +63 -0
  101. data/spec/cassettes/BookingSync_API_Client_SpecialOffers/_delete_special_offer/deletes_given_special_offer.yml +57 -0
  102. data/spec/cassettes/BookingSync_API_Client_SpecialOffers/_edit_special_offer/updates_given_special_offer_by_ID.yml +61 -0
  103. data/spec/cassettes/{BookingSync_API_Client_Rentals/_rentals/with_specified_fields_in_options/returns_rentals_with_filtered_fields.yml → BookingSync_API_Client_SpecialOffers/_special_offers/returns_special_offers.yml} +17 -10
  104. data/spec/spec_helper.rb +1 -0
  105. metadata +143 -7
  106. data/lib/bookingsync/ext/resource.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49357703554dfb72c24e523586bde4e44de11470
4
- data.tar.gz: 50f648b33c091403d8ca8561122c64cdd1ba2f42
3
+ metadata.gz: a2cb84342589240cfa192b7d61350efb89297de9
4
+ data.tar.gz: 17549658e975c21ff097e3bcbe7b92ce3aec0db8
5
5
  SHA512:
6
- metadata.gz: 3c365736c033b2da829f778465f2faaf40019593ce40ceb6de61eccdd7c1bf5dd2dbd027caa453772b0064de050f161a866b7412f23089222bfc046a5e09d97d
7
- data.tar.gz: 2f6e36a3ddda23970adc5921512e85256de13ab90e88150b347ba5fd94fa7e313a0c7046c9f1964bca7bc58d1da990544cf53463e6ace77c2b57b1c060c6a835
6
+ metadata.gz: 00db8c9b72935df38730f0288252cddcd85c343e6847b9983e7fe9c410a900cbff84ff2c401e9a88d66245b2dd4686152a7820892fd1cb54f20538f3c0de7b06
7
+ data.tar.gz: ad647464027c54595e3703d813447366845487d7031397b4d27f39f8cba15486228edc7097e1b49962bfd0995ff83a2339e229e295a466241dfd797f29d68ae6
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.0
3
+ - 2.1.1
4
4
  - 2.0.0
5
5
  - 1.9.3
data/Gemfile CHANGED
@@ -9,7 +9,8 @@ group 'test' do
9
9
  gem 'guard'
10
10
  gem 'guard-rspec'
11
11
  gem 'yard'
12
- gem 'guard-yard'
12
+ gem 'ruby_gntp'
13
+ gem 'pry'
13
14
  end
14
15
 
15
16
  gemspec
data/Guardfile CHANGED
@@ -1,10 +1,7 @@
1
- guard :rspec do
1
+ guard :rspec, cmd: "bundle exec rspec --format p" do
2
+ watch(%r{^spec/(.+)_spec\.rb$})
2
3
  watch(%r{^lib/bookingsync/(.+)\.rb$}) { |m| "spec/bookingsync/#{m[1]}_spec.rb" }
3
4
  watch(%r{^lib/bookingsync/api/client/(.+)\.rb$}) { |m| "spec/bookingsync/api/client/#{m[1]}_spec.rb" }
4
- watch(%r{^lib/bookingsync/api/(.+)\.rb$}) { |m| "spec/bookingsync/api/#{m[1]}_spec.rb" }
5
+ watch(%r{^lib/bookingsync/api/(.+)\.rb$}) { |m| "spec" }
5
6
  watch('spec/spec_helper.rb') { "spec" }
6
7
  end
7
-
8
- guard 'yard' do
9
- watch(%r{lib/.+\.rb})
10
- end
data/README.md CHANGED
@@ -24,7 +24,7 @@ Or install it yourself as:
24
24
  Gem assumes that you already have OAuth token for an account.
25
25
 
26
26
  api = BookingSync::API.new("OAUTH_TOKEN")
27
- rentals = api.rentals # => [Sawyer::Resource, Sawyer::Resource]
27
+ rentals = api.rentals # => [BookingSync::API::Resource, BookingSync::API::Resource]
28
28
  rentals.first.name # => "Small apartment"
29
29
 
30
30
  ### Pagination
@@ -33,7 +33,7 @@ All endpoints returning a collection of resources can be paginated. There are th
33
33
 
34
34
  Specify `:per_page` and `:page` params. It's useful when implementing pagination on your site.
35
35
 
36
- api.bookings(per_page: 10, page: 1) => [Sawyer::Resource, Sawyer::Resource, ...]
36
+ api.bookings(per_page: 10, page: 1) => [BookingSync::API::Resource, BookingSync::API::Resource, ...]
37
37
 
38
38
  Use pagination with a block.
39
39
 
@@ -43,7 +43,7 @@ Use pagination with a block.
43
43
 
44
44
  Fetch all resources (with multiple requests under the hood) and return one big array.
45
45
 
46
- api.bookings(auto_paginate: true) => [Sawyer::Resource, Sawyer::Resource, ...]
46
+ api.bookings(auto_paginate: true) => [BookingSync::API::Resource, BookingSync::API::Resource, ...]
47
47
 
48
48
  ## Gem documentation
49
49
 
@@ -61,6 +61,14 @@ OR
61
61
 
62
62
  bundle exec guard
63
63
 
64
+ ### Recording VCR cassettes
65
+
66
+ For developing bookingsync-api gem you need OAuth access token. In order to record a cassette,
67
+ you need to run spec with below environment variables.
68
+
69
+ ACCESS_TOKEN=abc bundle exec rspec
70
+
71
+ If you want to change a cassette, you need to delete it first.
64
72
 
65
73
  ## Contributing
66
74
 
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "faraday", "~> 0.9"
22
- spec.add_dependency "sawyer"
23
- spec.add_dependency "json"
22
+ spec.add_dependency "addressable"
23
+ spec.add_dependency "hashie"
24
24
  spec.add_development_dependency "bundler", "~> 1.5"
25
25
  spec.add_development_dependency "rake"
26
26
  end
@@ -1,7 +1,5 @@
1
1
  require "faraday"
2
- require "sawyer"
3
2
 
4
- require "bookingsync/ext/resource"
5
3
  require "bookingsync/api/version"
6
4
  require "bookingsync/api/client"
7
5
 
@@ -1,14 +1,48 @@
1
1
  require "bookingsync/api/middleware/authentication"
2
+ require "bookingsync/api/client/amenities"
3
+ require "bookingsync/api/client/billing_addresses"
2
4
  require "bookingsync/api/client/bookings"
5
+ require "bookingsync/api/client/bookings_payments"
6
+ require "bookingsync/api/client/clients"
7
+ require "bookingsync/api/client/destinations"
3
8
  require "bookingsync/api/client/inquiries"
9
+ require "bookingsync/api/client/periods"
10
+ require "bookingsync/api/client/payments"
11
+ require "bookingsync/api/client/photos"
12
+ require "bookingsync/api/client/rates"
13
+ require "bookingsync/api/client/rates_rules"
14
+ require "bookingsync/api/client/rates_tables"
4
15
  require "bookingsync/api/client/rentals"
16
+ require "bookingsync/api/client/rental_agreements"
17
+ require "bookingsync/api/client/reviews"
18
+ require "bookingsync/api/client/seasons"
19
+ require "bookingsync/api/client/special_offers"
5
20
  require "bookingsync/api/error"
21
+ require "bookingsync/api/relation"
22
+ require "bookingsync/api/response"
23
+ require "bookingsync/api/resource"
24
+ require "bookingsync/api/serializer"
6
25
 
7
26
  module BookingSync::API
8
27
  class Client
28
+ include BookingSync::API::Client::Amenities
29
+ include BookingSync::API::Client::BillingAddresses
9
30
  include BookingSync::API::Client::Bookings
31
+ include BookingSync::API::Client::BookingsPayments
32
+ include BookingSync::API::Client::Clients
33
+ include BookingSync::API::Client::Destinations
10
34
  include BookingSync::API::Client::Inquiries
35
+ include BookingSync::API::Client::Periods
36
+ include BookingSync::API::Client::Payments
37
+ include BookingSync::API::Client::Photos
38
+ include BookingSync::API::Client::Rates
39
+ include BookingSync::API::Client::RatesRules
40
+ include BookingSync::API::Client::RatesTables
11
41
  include BookingSync::API::Client::Rentals
42
+ include BookingSync::API::Client::RentalAgreements
43
+ include BookingSync::API::Client::Reviews
44
+ include BookingSync::API::Client::Seasons
45
+ include BookingSync::API::Client::SpecialOffers
12
46
 
13
47
  MEDIA_TYPE = "application/vnd.api+json"
14
48
 
@@ -17,16 +51,25 @@ module BookingSync::API
17
51
  # Initialize new Client
18
52
  #
19
53
  # @param token [String] OAuth token
54
+ # @param options [Hash]
55
+ # @option options [String] base_url: Base URL to BookingSync site
20
56
  # @return [BookingSync::API::Client] New BookingSync API client
21
- def initialize(token)
57
+ def initialize(token, options = {})
22
58
  @token = token
59
+ @base_url = options[:base_url]
60
+ @serializer = Serializer.new
61
+ @conn = Faraday.new(faraday_options)
62
+ @conn.headers[:accept] = MEDIA_TYPE
63
+ @conn.headers[:content_type] = MEDIA_TYPE
64
+ @conn.url_prefix = api_endpoint
65
+ yield @conn if block_given?
23
66
  end
24
67
 
25
68
  # Make a HTTP GET request
26
69
  #
27
70
  # @param path [String] The path, relative to {#api_endpoint}
28
71
  # @param options [Hash] Query params for the request
29
- # @return [Array<Sawyer::Resource>] Array of resources.
72
+ # @return [Array<BookingSync::API::Resource>] Array of resources.
30
73
  def get(path, options = {})
31
74
  request :get, path, query: options
32
75
  end
@@ -35,7 +78,7 @@ module BookingSync::API
35
78
  #
36
79
  # @param path [String] The path, relative to {#api_endpoint}
37
80
  # @param options [Hash] Body params for the request
38
- # @return [Array<Sawyer::Resource>]
81
+ # @return [Array<BookingSync::API::Resource>]
39
82
  def post(path, options = {})
40
83
  request :post, path, options
41
84
  end
@@ -44,7 +87,7 @@ module BookingSync::API
44
87
  #
45
88
  # @param path [String] The path, relative to {#api_endpoint}
46
89
  # @param options [Hash] Body params for the request
47
- # @return [Array<Sawyer::Resource>]
90
+ # @return [Array<BookingSync::API::Resource>]
48
91
  def put(path, options = {})
49
92
  request :put, path, options
50
93
  end
@@ -53,7 +96,7 @@ module BookingSync::API
53
96
  #
54
97
  # @param path [String] The path, relative to {#api_endpoint}
55
98
  # @param options [Hash] Body params for the request
56
- # @return [Array<Sawyer::Resource>]
99
+ # @return [Array<BookingSync::API::Resource>]
57
100
  def delete(path, options = {})
58
101
  request :delete, path, options
59
102
  end
@@ -62,80 +105,110 @@ module BookingSync::API
62
105
  #
63
106
  # @return [String] URL to API endpoint
64
107
  def api_endpoint
65
- "#{base_url}/api/v3"
108
+ URI.join(base_url, "api/v3").to_s
66
109
  end
67
110
 
68
- protected
111
+ # Encode an object to a string for the API request.
112
+ #
113
+ # @param data [Object] The Hash or Resource that is being sent.
114
+ # @return [String] Object encoded into JSON string
115
+ def encode_body(data)
116
+ @serializer.encode(data)
117
+ end
69
118
 
70
- # Make a HTTP request to given path
119
+ # Decode a String response body to a Resource.
120
+ #
121
+ # @param str [String] The String body from the response.
122
+ # @return [Object] Object resource
123
+ def decode_body(str)
124
+ @serializer.decode(str)
125
+ end
126
+
127
+ # Make a HTTP request to a path and returns an Array of Resources
71
128
  #
72
129
  # @param method [Symbol] HTTP verb to use.
73
130
  # @param path [String] The path, relative to {#api_endpoint}.
74
131
  # @param data [Hash] Data to be send in the request's body
75
132
  # it can include query: key with requests params for GET requests
76
133
  # @param options [Hash] A customizable set of request options.
77
- # @return [Array<Sawyer::Resource>] Array of resources.
78
- def request(method, path, data, options = {})
79
- if data.is_a?(Hash)
80
- options[:query] = data.delete(:query) || {}
81
- options[:query].keys.each do |key|
82
- if options[:query][key].is_a?(Array)
83
- options[:query][key] = options[:query][key].join(",")
84
- end
85
- end
86
- end
87
-
88
- @last_response = response = agent.call(method, path, data.to_json, options)
89
- case response.status
90
- when 204; [] # update/destroy response
91
- when 200..299; json_api_to_array(response.data)
92
- when 401; raise Unauthorized.new
93
- when 422; raise UnprocessableEntity.new
94
- end
134
+ # @return [Array<BookingSync::API::Resource>] Array of resources.
135
+ def request(method, path, data = nil, options = nil)
136
+ response = call(method, path, data, options)
137
+ response.respond_to?(:resources) ? response.resources : response
95
138
  end
96
139
 
140
+ # Make a HTTP GET request to a path with pagination support.
141
+ #
142
+ # @param options [Hash]
143
+ # @option options [Integer] per_page: Number of resources per page
144
+ # @option options [Integer] page: Number of page to return
145
+ # @option options [Boolean] auto_paginate: If true, all resources will
146
+ # be returned. It makes multiple requestes underneath and joins the results.
147
+ #
148
+ # @yieldreturn [Array<BookingSync::API::Resource>] Batch of resources
149
+ # @return [Array<BookingSync::API::Resource>] Batch of resources
97
150
  def paginate(path, options = {}, &block)
98
151
  auto_paginate = options.delete(:auto_paginate)
152
+ response = call(:get, path, query: options)
153
+ data = response.resources.dup
99
154
 
100
- data = request(:get, path, query: options)
101
-
102
- if (block_given? or auto_paginate) && @last_response.rels[:next]
155
+ if (block_given? or auto_paginate) && response.rels[:next]
103
156
  first_request = true
104
157
  loop do
105
158
  if block_given?
106
- yield(json_api_to_array(@last_response.data))
159
+ yield(response.resources)
107
160
  elsif auto_paginate
108
- data.concat(json_api_to_array(@last_response.data)) unless first_request
161
+ data.concat(response.resources) unless first_request
109
162
  first_request = false
110
163
  end
111
- break unless @last_response.rels[:next]
112
- @last_response = @last_response.rels[:next].get
164
+ break unless response.rels[:next]
165
+ response = response.rels[:next].get
113
166
  end
114
167
  end
115
168
 
116
169
  data
117
170
  end
118
171
 
119
- private
120
-
121
- # Return collection of resources
172
+ # Make a HTTP request to given path and returns Response object.
122
173
  #
123
- # In jsonapi spec every response has format
124
- # {resources => [{resource}, {resource}]. This method returns the inner Array
125
- # @param data [Sawyer::Resource] Sawyer resource from response.data
126
- # @return [<Sawyer::Resource>] An Array of resources
127
- # FIXME: This could have better name
128
- def json_api_to_array(data)
129
- data.to_hash.values.flatten
130
- end
174
+ # @param method [Symbol] HTTP verb to use.
175
+ # @param path [String] The path, relative to {#api_endpoint}.
176
+ # @param data [Hash] Data to be send in the request's body
177
+ # it can include query: key with requests params for GET requests
178
+ # @param options [Hash] A customizable set of request options.
179
+ # @return [BookingSync::API::Response] A Response object.
180
+ def call(method, path, data = nil, options = nil)
181
+ if [:get, :head].include?(method)
182
+ options = data
183
+ data = nil
184
+ end
185
+ options ||= {}
131
186
 
132
- def agent
133
- @agent ||= Sawyer::Agent.new(api_endpoint, sawyer_options) do |http|
134
- http.headers[:accept] = MEDIA_TYPE
135
- http.headers[:content_type] = MEDIA_TYPE
187
+ if options.has_key?(:query)
188
+ options[:query].keys.each do |key|
189
+ if options[:query][key].is_a?(Array)
190
+ options[:query][key] = options[:query][key].join(",")
191
+ end
192
+ end
136
193
  end
194
+
195
+ url = expand_url(path, options[:uri])
196
+ res = @conn.send(method, url) do |req|
197
+ if data
198
+ req.body = data.is_a?(String) ? data : encode_body(data)
199
+ end
200
+ if params = options[:query]
201
+ req.params.update params
202
+ end
203
+ if headers = options[:headers]
204
+ req.headers.update headers
205
+ end
206
+ end
207
+ handle_response(res)
137
208
  end
138
209
 
210
+ private
211
+
139
212
  def middleware
140
213
  Faraday::RackBuilder.new do |builder|
141
214
  builder.use :authentication, token
@@ -143,21 +216,18 @@ module BookingSync::API
143
216
  end
144
217
  end
145
218
 
146
- def sawyer_options
147
- {faraday: Faraday.new(faraday_options)}
148
- end
149
-
150
219
  def faraday_options
151
220
  {builder: middleware, ssl: {verify: verify_ssl?}}
152
221
  end
153
222
 
154
223
  # Return BookingSync base URL. Default is https://www.bookingsync.com
155
224
  # it can be altered via ENV variable BOOKINGSYNC_URL which
156
- # is useful in specs when recording vcr cassettes
225
+ # is useful in specs when recording vcr cassettes. In also can be passed
226
+ # as :base_url option when initializing the Client object
157
227
  #
158
228
  # @return [String] Base URL to BookingSync
159
229
  def base_url
160
- ENV.fetch "BOOKINGSYNC_URL", "https://www.bookingsync.com"
230
+ @base_url || ENV.fetch("BOOKINGSYNC_URL", "https://www.bookingsync.com")
161
231
  end
162
232
 
163
233
  # Return true if SSL cert should be verified
@@ -169,5 +239,32 @@ module BookingSync::API
169
239
  def verify_ssl?
170
240
  ENV["BOOKINGSYNC_VERIFY_SSL"] == "false" ? false : true
171
241
  end
242
+
243
+ # Expand an URL template into a full URL
244
+ #
245
+ # @param url [String|Addressable::Template] - An URL to be expanded
246
+ # @param options [Hash] - Variables which will be used to expand
247
+ # @return [String] - Expanded URL
248
+ def expand_url(url, options = nil)
249
+ tpl = url.respond_to?(:expand) ? url : Addressable::Template.new(url.to_s)
250
+ tpl.expand(options || {}).to_s
251
+ end
252
+
253
+ # Process faraday response.
254
+ #
255
+ # @param faraday_response [Faraday::Response] - A response to process
256
+ # @raise [BookingSync::API::Unauthorized] - On unauthorized user
257
+ # @raise [BookingSync::API::UnprocessableEntity] - On validations error
258
+ # @return [BookingSync::API::Response|NilClass]
259
+ def handle_response(faraday_response)
260
+ response = Response.new(self, faraday_response)
261
+ case response.status
262
+ when 204; nil # destroy/cancel
263
+ when 200..299; response
264
+ when 401; raise Unauthorized.new
265
+ when 422; raise UnprocessableEntity.new
266
+ else nil
267
+ end
268
+ end
172
269
  end
173
270
  end
@@ -0,0 +1,22 @@
1
+ module BookingSync::API
2
+ class Client
3
+ module Amenities
4
+ # List amenities
5
+ #
6
+ # Returns amenities for the account user is authenticated with.
7
+ # @param options [Hash] A customizable set of options.
8
+ # @option options [Array] fields: List of fields to be fetched.
9
+ # @return [Array<BookingSync::API::Resource>] Array of amenities.
10
+ #
11
+ # @example Get the list of amenities for the current account
12
+ # amenities = @api.amenities
13
+ # amenities.first.title # => "Internet"
14
+ # @example Get the list of amenities only with title and rental_id for smaller response
15
+ # @api.amenities(fields: [:title, :rental_id])
16
+ # @see http://docs.api.bookingsync.com/reference/endpoints/amenities/#list-amenities
17
+ def amenities(options = {}, &block)
18
+ paginate :amenities, options, &block
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module BookingSync::API
2
+ class Client
3
+ module BillingAddresses
4
+ # List billing addresses
5
+ #
6
+ # Returns billing addresses for the account user is authenticated with.
7
+ # @param options [Hash] A customizable set of options.
8
+ # @option options [Array] fields: List of fields to be fetched.
9
+ # @return [Array<BookingSync::API::Resource>] Array of billing addresses.
10
+ #
11
+ # @example Get the list of billing addresses for the current account
12
+ # billing_addresses = @api.billing_addresses
13
+ # billing_addresses.first.city # => "Paris"
14
+ # @example Get the list of billing addresses only with city and address1 for smaller response
15
+ # @api.billing_addresses(fields: [:city, :address1])
16
+ # @see http://docs.api.bookingsync.com/reference/endpoints/billing addresss/#list-billing-addresses
17
+ def billing_addresses(options = {}, &block)
18
+ paginate :billing_addresses, options, &block
19
+ end
20
+ end
21
+ end
22
+ end