bookingsync-api 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -1
- data/lib/bookingsync/api.rb +1 -0
- data/lib/bookingsync/api/client.rb +80 -10
- data/lib/bookingsync/api/client/bookings.rb +42 -2
- data/lib/bookingsync/api/client/inquiries.rb +23 -0
- data/lib/bookingsync/api/client/rentals.rb +3 -2
- data/lib/bookingsync/api/error.rb +1 -0
- data/lib/bookingsync/api/version.rb +1 -1
- data/lib/bookingsync/ext/resource.rb +9 -0
- data/spec/bookingsync/api/client/bookings_spec.rb +78 -0
- data/spec/bookingsync/api/client/inquiries_spec.rb +37 -0
- data/spec/bookingsync/api/client_spec.rb +65 -3
- data/spec/cassettes/BookingSync_API_Client_Bookings/_bookings/pagination/with_a_block/yields_block_with_batch_of_bookings.yml +190 -0
- data/spec/cassettes/BookingSync_API_Client_Bookings/_bookings/pagination/with_auto_paginate_true/returns_all_bookings_joined_from_many_requests.yml +190 -0
- data/spec/cassettes/BookingSync_API_Client_Bookings/_bookings/pagination/with_per_page_setting/returns_limited_number_of_bookings.yml +65 -0
- data/spec/cassettes/BookingSync_API_Client_Bookings/_cancel_booking/cancels_given_booking.yml +57 -0
- data/spec/cassettes/BookingSync_API_Client_Bookings/_create_booking/creates_a_booking.yml +63 -0
- data/spec/cassettes/BookingSync_API_Client_Bookings/_edit_booking/updates_given_booking_by_ID.yml +57 -0
- data/spec/cassettes/BookingSync_API_Client_Inquiries/_create_inquiry/creates_a_new_inquiry.yml +64 -0
- data/spec/cassettes/BookingSync_API_Client_Inquiries/_inquiries/returns_inquiries.yml +64 -0
- data/spec/cassettes/spec/cassettes/BookingSync_API_Client_Bookings/_create_booking/creates_a_booking_yml.yml +62 -0
- data/spec/spec_helper.rb +24 -0
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43eb6b12130e0e8f634f516be82b68aa771aee94
|
4
|
+
data.tar.gz: cb1438eb9863b01ba062f7d695e7f724bb8b5ec1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0236f9a753191bb68adc74a0074acd258901ad0f37fd1e5ea78ffa2ce658fe1056482480e1b53abd1cb7dbd0aa6014ed586c45ee4c67114afaae3af1a4411c3
|
7
|
+
data.tar.gz: 65eaa193e9b8f89a24a0192486554313f16462494327602966b32efc649eba4e720acb06126d70c175b13e9cf0146a1ba9b82c2455f23885dd4ac3b50b286136
|
data/README.md
CHANGED
@@ -27,7 +27,31 @@ Gem assumes that you already have OAuth token for an account.
|
|
27
27
|
rentals = api.rentals # => [Sawyer::Resource, Sawyer::Resource]
|
28
28
|
rentals.first.name # => "Small apartment"
|
29
29
|
|
30
|
-
|
30
|
+
### Pagination
|
31
|
+
|
32
|
+
All endpoints returning a collection of resources can be paginated. There are three ways to do it.
|
33
|
+
|
34
|
+
Specify `:per_page` and `:page` params. It's useful when implementing pagination on your site.
|
35
|
+
|
36
|
+
api.bookings(per_page: 10, page: 1) => [Sawyer::Resource, Sawyer::Resource, ...]
|
37
|
+
|
38
|
+
Use pagination with a block.
|
39
|
+
|
40
|
+
api.bookings(per_page: 10) do |batch|
|
41
|
+
# display 10 bookings, will make one HTTP request for each batch
|
42
|
+
end
|
43
|
+
|
44
|
+
Fetch all resources (with multiple requests under the hood) and return one big array.
|
45
|
+
|
46
|
+
api.bookings(auto_paginate: true) => [Sawyer::Resource, Sawyer::Resource, ...]
|
47
|
+
|
48
|
+
## Gem documentation
|
49
|
+
|
50
|
+
See [gem documentation](http://rdoc.info/github/BookingSync/bookingsync-api/master/frames) for more info.
|
51
|
+
|
52
|
+
## API documentation
|
53
|
+
|
54
|
+
See [API documentation](http://docs.api.bookingsync.com).
|
31
55
|
|
32
56
|
## Running specs
|
33
57
|
|
data/lib/bookingsync/api.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require "bookingsync/api/middleware/authentication"
|
2
2
|
require "bookingsync/api/client/bookings"
|
3
|
+
require "bookingsync/api/client/inquiries"
|
3
4
|
require "bookingsync/api/client/rentals"
|
4
5
|
require "bookingsync/api/error"
|
5
6
|
|
6
7
|
module BookingSync::API
|
7
8
|
class Client
|
8
9
|
include BookingSync::API::Client::Bookings
|
10
|
+
include BookingSync::API::Client::Inquiries
|
9
11
|
include BookingSync::API::Client::Rentals
|
10
12
|
|
11
13
|
MEDIA_TYPE = "application/vnd.api+json"
|
@@ -23,9 +25,37 @@ module BookingSync::API
|
|
23
25
|
# Make a HTTP GET request
|
24
26
|
#
|
25
27
|
# @param path [String] The path, relative to {#api_endpoint}
|
28
|
+
# @param options [Hash] Query params for the request
|
26
29
|
# @return [Array<Sawyer::Resource>] Array of resources.
|
27
30
|
def get(path, options = {})
|
28
|
-
request :get, path, options
|
31
|
+
request :get, path, query: options
|
32
|
+
end
|
33
|
+
|
34
|
+
# Make a HTTP POST request
|
35
|
+
#
|
36
|
+
# @param path [String] The path, relative to {#api_endpoint}
|
37
|
+
# @param options [Hash] Body params for the request
|
38
|
+
# @return [Array<Sawyer::Resource>]
|
39
|
+
def post(path, options = {})
|
40
|
+
request :post, path, options
|
41
|
+
end
|
42
|
+
|
43
|
+
# Make a HTTP PUT request
|
44
|
+
#
|
45
|
+
# @param path [String] The path, relative to {#api_endpoint}
|
46
|
+
# @param options [Hash] Body params for the request
|
47
|
+
# @return [Array<Sawyer::Resource>]
|
48
|
+
def put(path, options = {})
|
49
|
+
request :put, path, options
|
50
|
+
end
|
51
|
+
|
52
|
+
# Make a HTTP DELETE request
|
53
|
+
#
|
54
|
+
# @param path [String] The path, relative to {#api_endpoint}
|
55
|
+
# @param options [Hash] Body params for the request
|
56
|
+
# @return [Array<Sawyer::Resource>]
|
57
|
+
def delete(path, options = {})
|
58
|
+
request :delete, path, options
|
29
59
|
end
|
30
60
|
|
31
61
|
# Return API endpoint
|
@@ -41,28 +71,68 @@ module BookingSync::API
|
|
41
71
|
#
|
42
72
|
# @param method [Symbol] HTTP verb to use.
|
43
73
|
# @param path [String] The path, relative to {#api_endpoint}.
|
44
|
-
# @param
|
74
|
+
# @param data [Hash] Data to be send in the request's body
|
75
|
+
# it can include query: key with requests params for GET requests
|
76
|
+
# @param options [Hash] A customizable set of request options.
|
45
77
|
# @return [Array<Sawyer::Resource>] Array of resources.
|
46
|
-
def request(method, path,
|
47
|
-
|
48
|
-
query
|
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
|
49
86
|
end
|
50
87
|
|
51
|
-
response = agent.call(method, path,
|
88
|
+
@last_response = response = agent.call(method, path, data.to_json, options)
|
52
89
|
case response.status
|
53
|
-
|
54
|
-
|
55
|
-
# will return [{rental}, {rental}]
|
56
|
-
when 200..299; response.data.to_hash.values.flatten
|
90
|
+
when 204; [] # update/destroy response
|
91
|
+
when 200..299; json_api_to_array(response.data)
|
57
92
|
when 401; raise Unauthorized.new
|
93
|
+
when 422; raise UnprocessableEntity.new
|
58
94
|
end
|
59
95
|
end
|
60
96
|
|
97
|
+
def paginate(path, options = {}, &block)
|
98
|
+
auto_paginate = options.delete(:auto_paginate)
|
99
|
+
|
100
|
+
data = request(:get, path, query: options)
|
101
|
+
|
102
|
+
if (block_given? or auto_paginate) && @last_response.rels[:next]
|
103
|
+
first_request = true
|
104
|
+
loop do
|
105
|
+
if block_given?
|
106
|
+
yield(json_api_to_array(@last_response.data))
|
107
|
+
elsif auto_paginate
|
108
|
+
data.concat(json_api_to_array(@last_response.data)) unless first_request
|
109
|
+
first_request = false
|
110
|
+
end
|
111
|
+
break unless @last_response.rels[:next]
|
112
|
+
@last_response = @last_response.rels[:next].get
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
data
|
117
|
+
end
|
118
|
+
|
61
119
|
private
|
62
120
|
|
121
|
+
# Return collection of resources
|
122
|
+
#
|
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
|
131
|
+
|
63
132
|
def agent
|
64
133
|
@agent ||= Sawyer::Agent.new(api_endpoint, sawyer_options) do |http|
|
65
134
|
http.headers[:accept] = MEDIA_TYPE
|
135
|
+
http.headers[:content_type] = MEDIA_TYPE
|
66
136
|
end
|
67
137
|
end
|
68
138
|
|
@@ -15,11 +15,51 @@ module BookingSync::API
|
|
15
15
|
# are shown, otherwise they are hidden.
|
16
16
|
# @option options [Array] status: Array of booking states.
|
17
17
|
# If specyfied bookings with given states are shown.
|
18
|
+
# Possible statuses: `:booked`, `:unavailable` and `:tentative`
|
18
19
|
# @return [Array<Sawyer::Resource>] Array of bookings.
|
19
20
|
# @example
|
20
21
|
# @api.bookings(months: 12, states: [:booked, :unavailable], include_canceled: true)
|
21
|
-
|
22
|
-
|
22
|
+
#
|
23
|
+
# @example Pagination
|
24
|
+
# @api.bookings(per_page: 10) do |batch|
|
25
|
+
# # do something with ten bookings
|
26
|
+
# end
|
27
|
+
# @see http://docs.api.bookingsync.com/reference/endpoints/bookings/#list-bookings
|
28
|
+
# @see http://docs.api.bookingsync.com/reference/endpoints/bookings/#search-bookings
|
29
|
+
def bookings(options = {}, &block)
|
30
|
+
paginate :bookings, options, &block
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Create a booking
|
35
|
+
#
|
36
|
+
# @param options [Hash] Booking attributes
|
37
|
+
# @return <Sawyer::Resource> Newly create booking
|
38
|
+
def create_booking(options = {})
|
39
|
+
post(:bookings, bookings: [options]).pop
|
40
|
+
end
|
41
|
+
|
42
|
+
# Edit a booking
|
43
|
+
#
|
44
|
+
# @param booking [Sawyer::Resource|Integer] Booking or ID of the booking
|
45
|
+
# to be updated
|
46
|
+
# @param options [Hash] Booking attributes to be updated
|
47
|
+
# FIXME: should be changed resource
|
48
|
+
# @return [Array] An empty Array on success, exception is raised otherwise
|
49
|
+
# @example
|
50
|
+
# booking = @api.bookings.first
|
51
|
+
# @api.edit_booking(booking, {adults: 1}) => []
|
52
|
+
def edit_booking(booking, options = {})
|
53
|
+
put "bookings/#{booking}", bookings: [options]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Cancel a booking
|
57
|
+
#
|
58
|
+
# @param booking [Sawyer::Resource|Integer] Booking or ID of the booking
|
59
|
+
# to be canceled
|
60
|
+
# @return [Array] An empty Array on success, exception is raised otherwise
|
61
|
+
def cancel_booking(booking, options = {})
|
62
|
+
delete "bookings/#{booking}"
|
23
63
|
end
|
24
64
|
end
|
25
65
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module BookingSync::API
|
2
|
+
class Client
|
3
|
+
module Inquiries
|
4
|
+
# List inquiries
|
5
|
+
#
|
6
|
+
# Return list of inquiries for current account.
|
7
|
+
# @param options [Hash] A customizable set of query options.
|
8
|
+
# @return [Array<Sawyer::Resource>] Array of inquiries.
|
9
|
+
# @see http://docs.api.bookingsync.com/reference/endpoints/inquiries/#list-inquiries
|
10
|
+
def inquiries(options = {}, &block)
|
11
|
+
paginate :inquiries, options, &block
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create a new inquiry
|
15
|
+
#
|
16
|
+
# @param options [Hash] Inquiry attributes
|
17
|
+
# @return <Sawyer::Resource> Newly create inquiry
|
18
|
+
def create_inquiry(options = {})
|
19
|
+
post(:inquiries, inquiries: [options]).pop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -13,8 +13,9 @@ module BookingSync::API
|
|
13
13
|
# rentals.first.name # => "Small apartment"
|
14
14
|
# @example Get the list of rentals only with name and description for smaller response
|
15
15
|
# @api.rentals(fields: [:name, :description])
|
16
|
-
|
17
|
-
|
16
|
+
# @see http://docs.api.bookingsync.com/reference/endpoints/rentals/#list-rentals
|
17
|
+
def rentals(options = {}, &block)
|
18
|
+
paginate :rentals, options, &block
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -8,5 +8,83 @@ describe BookingSync::API::Client::Bookings do
|
|
8
8
|
expect(client.bookings).not_to be_nil
|
9
9
|
assert_requested :get, bs_url("bookings")
|
10
10
|
end
|
11
|
+
|
12
|
+
describe "pagination" do
|
13
|
+
context "with per_page setting" do
|
14
|
+
it "returns limited number of bookings" do
|
15
|
+
bookings = client.bookings(per_page: 2)
|
16
|
+
expect(bookings.size).to eql(2)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with a block" do
|
21
|
+
it "yields block with batch of bookings" do
|
22
|
+
sizes = [2, 2, 1]
|
23
|
+
index = 0
|
24
|
+
client.bookings(per_page: 2) do |bookings|
|
25
|
+
expect(bookings.size).to eql(sizes[index])
|
26
|
+
index += 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with auto_paginate: true" do
|
32
|
+
it "returns all bookings joined from many requests" do
|
33
|
+
bookings = client.bookings(per_page: 2, auto_paginate: true)
|
34
|
+
expect(bookings.size).to eql(5)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".create_booking", :vcr do
|
41
|
+
let(:attributes) {
|
42
|
+
{start_at: '2014-01-03', end_at: '2014-01-04', rental_id: 20,
|
43
|
+
booked: true}
|
44
|
+
}
|
45
|
+
|
46
|
+
it "creates a booking" do
|
47
|
+
client.create_booking(attributes)
|
48
|
+
assert_requested :post, bs_url("bookings"),
|
49
|
+
body: {bookings: [attributes]}.to_json
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns newly created booking" do
|
53
|
+
VCR.use_cassette('BookingSync_API_Client_Bookings/_create_booking/creates_a_booking') do
|
54
|
+
booking = client.create_booking(attributes)
|
55
|
+
expect(booking.account_id).to eql(1)
|
56
|
+
expect(booking.rental_id).to eql(20)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe ".edit_booking", :vcr do
|
62
|
+
it "updates given booking by ID" do
|
63
|
+
client.edit_booking(50, {adults: 1})
|
64
|
+
assert_requested :put, bs_url("bookings/50"),
|
65
|
+
body: {bookings: [{adults: 1}]}.to_json
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns an empty array" do
|
69
|
+
VCR.use_cassette('BookingSync_API_Client_Bookings/_edit_booking/updates_given_booking_by_ID') do
|
70
|
+
expect(client.edit_booking(50, {adults: 1})).to eql([])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "updates given booking by Resource object" do
|
75
|
+
VCR.use_cassette('BookingSync_API_Client_Bookings/_edit_booking/updates_given_booking_by_ID') do
|
76
|
+
resource = double(to_s: "50")
|
77
|
+
client.edit_booking(resource, {adults: 1})
|
78
|
+
assert_requested :put, bs_url("bookings/50"),
|
79
|
+
body: {bookings: [{adults: 1}]}.to_json
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".cancel_booking", :vcr do
|
85
|
+
it "cancels given booking" do
|
86
|
+
client.cancel_booking(50)
|
87
|
+
assert_requested :delete, bs_url("bookings/50")
|
88
|
+
end
|
11
89
|
end
|
12
90
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BookingSync::API::Client::Inquiries do
|
4
|
+
let(:client) { BookingSync::API::Client.new(test_access_token) }
|
5
|
+
|
6
|
+
describe ".inquiries", :vcr do
|
7
|
+
it "returns inquiries" do
|
8
|
+
expect(client.inquiries).not_to be_nil
|
9
|
+
assert_requested :get, bs_url("inquiries")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".create_inquiry", :vcr do
|
14
|
+
let(:attributes) { {
|
15
|
+
rental_id: 7,
|
16
|
+
start_at: Time.now,
|
17
|
+
end_at: Time.now + 86400, # one day
|
18
|
+
firstname: "John",
|
19
|
+
lastname: "Smith",
|
20
|
+
email: "john@example.com"
|
21
|
+
} }
|
22
|
+
|
23
|
+
it "creates a new inquiry" do
|
24
|
+
client.create_inquiry(attributes)
|
25
|
+
assert_requested :post, bs_url("inquiries"),
|
26
|
+
body: {inquiries: [attributes]}.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns newly created inquiry" do
|
30
|
+
VCR.use_cassette('BookingSync_API_Client_Inquiries/_create_inquiry/creates_a_new_inquiry') do
|
31
|
+
inquiry = client.create_inquiry(attributes)
|
32
|
+
expect(inquiry.rental_id).to eql(7)
|
33
|
+
expect(inquiry.firstname).to eql("John")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -17,6 +17,48 @@ describe BookingSync::API::Client do
|
|
17
17
|
client.get("resource")
|
18
18
|
assert_requested :get, bs_url("resource")
|
19
19
|
end
|
20
|
+
|
21
|
+
it "adds query options to the URL" do
|
22
|
+
stub_get("resource?abc=123")
|
23
|
+
client.get("resource", abc: 123)
|
24
|
+
assert_requested :get, bs_url("resource?abc=123")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#post" do
|
29
|
+
before { VCR.turn_off! }
|
30
|
+
it "makes a HTTP POST request with body" do
|
31
|
+
stub_post("resource")
|
32
|
+
client.post("resource", {key: :value})
|
33
|
+
assert_requested :post, bs_url("resource"), body: '{"key":"value"}'
|
34
|
+
end
|
35
|
+
|
36
|
+
context "on 422 response" do
|
37
|
+
it "raises UnprocessableEntity exception" do
|
38
|
+
stub_post("resource", status: 422)
|
39
|
+
expect {
|
40
|
+
client.post("resource", {key: :value})
|
41
|
+
}.to raise_error(BookingSync::API::UnprocessableEntity)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#put" do
|
47
|
+
before { VCR.turn_off! }
|
48
|
+
it "makes a HTTP PUT request with body" do
|
49
|
+
stub_put("resource")
|
50
|
+
client.put("resource", {key: :value})
|
51
|
+
assert_requested :put, bs_url("resource"), body: '{"key":"value"}'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#delete" do
|
56
|
+
before { VCR.turn_off! }
|
57
|
+
it "makes a HTTP DELETE request" do
|
58
|
+
stub_delete("resource")
|
59
|
+
client.delete("resource")
|
60
|
+
assert_requested :delete, bs_url("resource")
|
61
|
+
end
|
20
62
|
end
|
21
63
|
|
22
64
|
describe "#request" do
|
@@ -29,13 +71,20 @@ describe BookingSync::API::Client do
|
|
29
71
|
headers: {"Authorization" => "Bearer fake-access-token"}
|
30
72
|
end
|
31
73
|
|
32
|
-
it "requests proper
|
74
|
+
it "requests proper accept header for JSON API" do
|
33
75
|
stub_get("resource")
|
34
76
|
client.get("resource")
|
35
77
|
assert_requested :get, bs_url("resource"),
|
36
78
|
headers: {"Accept" => "application/vnd.api+json"}
|
37
79
|
end
|
38
80
|
|
81
|
+
it "requests sends data with JSON API content type" do
|
82
|
+
stub_post("resource")
|
83
|
+
client.post("resource")
|
84
|
+
assert_requested :post, bs_url("resource"),
|
85
|
+
headers: {"Content-Type" => "application/vnd.api+json"}
|
86
|
+
end
|
87
|
+
|
39
88
|
it "returns Array of resources" do
|
40
89
|
stub_get("resource", body: {resources: [{name: "Megan"}]}.to_json)
|
41
90
|
resources = client.get("resource")
|
@@ -43,7 +92,7 @@ describe BookingSync::API::Client do
|
|
43
92
|
expect(resources.first.name).to eq("Megan")
|
44
93
|
end
|
45
94
|
|
46
|
-
context "
|
95
|
+
context "API returns 401" do
|
47
96
|
it "raises Unauthorized exception" do
|
48
97
|
stub_get("resource", status: 401)
|
49
98
|
expect {
|
@@ -52,19 +101,32 @@ describe BookingSync::API::Client do
|
|
52
101
|
end
|
53
102
|
end
|
54
103
|
|
55
|
-
context "status code
|
104
|
+
context "API returns status code outside 200..299 range" do
|
56
105
|
it "returns nil" do
|
57
106
|
stub_get("resource", status: 404)
|
58
107
|
expect(client.get("resource")).to be_nil
|
59
108
|
end
|
60
109
|
end
|
61
110
|
|
111
|
+
context "API returns 204 No Content" do
|
112
|
+
it "returns an empty array" do
|
113
|
+
stub_get("resource", status: 204)
|
114
|
+
expect(client.get("resource")).to eql([])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
62
118
|
context "user wants to fetch only specific fields" do
|
63
119
|
it "constructs url for filtered fields" do
|
64
120
|
stub_get("resource?fields=name,description")
|
65
121
|
client.get("resource", fields: [:name, :description])
|
66
122
|
assert_requested :get, bs_url("resource?fields=name,description")
|
67
123
|
end
|
124
|
+
|
125
|
+
it "should support single field" do
|
126
|
+
stub_get("resource?fields=name")
|
127
|
+
client.get("resource", fields: :name)
|
128
|
+
assert_requested :get, bs_url("resource?fields=name")
|
129
|
+
end
|
68
130
|
end
|
69
131
|
|
70
132
|
context "user passes additional query options" do
|