lelylan-rb 0.0.3 → 0.0.4
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.
- data/CHANGELOG.md +8 -0
- data/README.md +79 -79
- data/lelylan_rb.gemspec +1 -1
- data/lib/faraday/response/raise_http_error.rb +9 -2
- data/lib/lelylan/client/physical.rb +10 -2
- data/lib/lelylan/connection.rb +6 -5
- data/lib/lelylan/request.rb +1 -1
- data/lib/lelylan/version.rb +1 -1
- data/spec/fixtures/errors/401.json +9 -0
- data/spec/fixtures/errors/404.json +10 -0
- data/spec/fixtures/errors/422.json +10 -0
- data/spec/lelylan/client/physical_spec.rb +2 -2
- data/spec/lelylan/client/subscription_spec.rb +16 -15
- data/spec/lelylan/error_spec.rb +55 -0
- metadata +38 -38
- data/images/bg_hr.png +0 -0
- data/images/blacktocat.png +0 -0
- data/images/icon_download.png +0 -0
- data/images/sprite_download.png +0 -0
- data/index.html +0 -74
- data/javascripts/main.js +0 -1
- data/stylesheets/pygment_trac.css +0 -70
- data/stylesheets/stylesheet.css +0 -431
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.0.4 (January 26, 2013)
|
4
|
+
|
5
|
+
* Full support to error handling
|
6
|
+
* Fixed physical device request
|
7
|
+
* Fixed HTTP Basic Authentication system for subscription services
|
8
|
+
* Made some extra tests to check the fact that delete services are
|
9
|
+
correctly working
|
10
|
+
|
3
11
|
## v0.0.3 (January 25, 2013)
|
4
12
|
|
5
13
|
* Added content lenght 0 for all DELETE requests
|
data/README.md
CHANGED
@@ -53,8 +53,10 @@ related documentation in the [dev center](http://dev.lelylan.com/api/oauth#langu
|
|
53
53
|
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
54
54
|
|
55
55
|
# Redirect the application to the Lelylan authorization page
|
56
|
-
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
57
|
-
# => http://people.lelylan.com/oauth/authorize?
|
56
|
+
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri, scope: scope)
|
57
|
+
# => http://people.lelylan.com/oauth/authorize?
|
58
|
+
# redirect_uri=http://localhost:3000/callback&
|
59
|
+
# scope=<scope>&response_type=code&client_id=<client-id>
|
58
60
|
|
59
61
|
# Get the access token object (authorization code is given from the previous step)
|
60
62
|
token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
@@ -69,8 +71,12 @@ following example shows how to print in the console a list of owned devices.
|
|
69
71
|
# Initialize Lelylan client
|
70
72
|
lelylan = Lelylan::Client.new(token: token)
|
71
73
|
|
72
|
-
# Get the first device where the name matches with Dimmer
|
74
|
+
# Get the first device where the name matches with Dimmer.
|
73
75
|
device = lelylan.devices(name: 'Dimmer').first
|
76
|
+
|
77
|
+
# The client returns an Hashie (https://github.com/intridea/hashie)
|
78
|
+
puts device.uri # get the device uri
|
79
|
+
puts device.properties.first.value # get the first device property value
|
74
80
|
```
|
75
81
|
|
76
82
|
### Realtime services
|
@@ -83,106 +89,87 @@ lelylan = Lelylan::Client.new(client_id:'<client-id>', client_secret: '<client-s
|
|
83
89
|
subscriptions = lelylan.subscriptions
|
84
90
|
```
|
85
91
|
|
86
|
-
|
87
|
-
|
88
|
-
Lelylan support three OAuth2 authorization flows.
|
89
|
-
|
90
|
-
### Authorization code flows
|
91
|
-
|
92
|
-
```ruby
|
93
|
-
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
94
|
-
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
95
|
-
token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
96
|
-
```
|
97
|
-
|
98
|
-
### Implicit grant flow
|
99
|
-
|
100
|
-
```ruby
|
101
|
-
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
102
|
-
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
103
|
-
token = OAuth2::AccessToken.from_kvform(client, params)
|
104
|
-
```
|
92
|
+
### Implemented Services
|
105
93
|
|
106
|
-
|
107
|
-
|
108
|
-
```ruby
|
109
|
-
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
110
|
-
token = oauth.password.get_token('email', 'password')
|
111
|
-
```
|
112
|
-
|
113
|
-
Access tokens, when expired, are automatically refreshed.
|
114
|
-
|
115
|
-
|
116
|
-
## Lelylan Services
|
117
|
-
|
118
|
-
### Devices
|
119
|
-
|
120
|
-
The Device API defines a set of services to monitor and control every existing device.
|
121
|
-
Its final goal is to map every device to a unique URI which provides control over it.
|
94
|
+
**Devices** - The Device API defines a set of services to monitor and control every existing
|
95
|
+
device. Its final goal is to map every device to a unique URI which provides control over it.
|
122
96
|
[See examples](http://dev.lelylan.com/api/devices#ruby).
|
123
97
|
|
124
|
-
|
98
|
+
**Activations** - Easy way to move the device ownership between people.
|
99
|
+
[See examples](http://dev.lelylan.com/api/devices#ruby).
|
125
100
|
|
126
|
-
When a device updates its properties or executes a function a new history
|
127
|
-
a snapshot of all device properties is created by Lelylan, also the ones that
|
128
|
-
updated. This makes it easy to recreate previous device status and extract usage
|
129
|
-
to improve the way people live their house.
|
101
|
+
**Histories** - When a device updates its properties or executes a function a new history
|
102
|
+
resource with a snapshot of all device properties is created by Lelylan, also the ones that
|
103
|
+
has not been updated. This makes it easy to recreate previous device status and extract usage
|
104
|
+
patterns to improve the way people live their house.
|
130
105
|
[See examples](http://dev.lelylan.com/api/devices/histories#ruby).
|
131
106
|
|
132
|
-
|
133
|
-
|
134
|
-
A type describes the structure of a device. In its simplest form every type can be defined
|
135
|
-
as the combination of three key elements: properties (what vary during time), functions
|
107
|
+
**Types** - A type describes the structure of a device. In its simplest form every type can be
|
108
|
+
defined as the combination of three key elements: properties (what vary during time), functions
|
136
109
|
(what a device can do), statuses (what a device is in a specific time of its life).
|
137
110
|
[See examples](http://dev.lelylan.com/api/types#ruby).
|
138
111
|
|
139
|
-
|
140
|
-
|
141
|
-
A property is whatever vary in a device during time. It can be the intensity in a dimmer,
|
142
|
-
the temperature in a cooling system or the volume in a television.
|
112
|
+
**Properties** - A property is whatever vary in a device during time. It can be the intensity in
|
113
|
+
a dimmer, the temperature in a cooling system or the volume in a television.
|
143
114
|
[See examples](http://dev.lelylan.com/api/types/properties#ruby).
|
144
115
|
|
145
|
-
|
146
|
-
|
147
|
-
Functions defines the daily interactions you have with the devices in your house, for
|
148
|
-
example when you turn on a light, close a door or raise the temperature in a room.
|
116
|
+
**Functions** - Functions defines the daily interactions you have with the devices in your house,
|
117
|
+
for example when you turn on a light, close a door or raise the temperature in a room.
|
149
118
|
With functions you can control any device in the same way you do everyday of your life.
|
150
119
|
[See examples](http://dev.lelylan.com/api/types/functions#ruby).
|
151
120
|
|
152
|
-
|
153
|
-
|
154
|
-
Properties are not always enough to describe the status of a device. Think at a roller
|
121
|
+
**Statuses** - Properties are not always enough to describe the status of a device. Think at a roller
|
155
122
|
shutter for example. It has the property aperture that is 100 when open or 0 when closed.
|
156
123
|
But what if the roller shutter is opening? It is nether open or close. To have a complete
|
157
124
|
control over the device status in a specific moment of its life is to use the status API.
|
158
125
|
[See examples](http://dev.lelylan.com/api/types/statuses#ruby).
|
159
126
|
|
160
|
-
|
161
|
-
|
162
|
-
Locations are the places we live in and where physical devices are placed. Lelylan identifies
|
127
|
+
**Locations** - Locations are the places we live in and where physical devices are placed. Lelylan identifies
|
163
128
|
three types of locations usually organized in a hierarchical structure: houses, floors and
|
164
129
|
rooms.
|
165
130
|
[See examples](http://dev.lelylan.com/api/locations#ruby).
|
166
131
|
|
167
|
-
|
168
|
-
|
169
|
-
Physical devices are the real objects you physically interact with everyday of your life
|
132
|
+
**Physical Devices** - Physical devices are the real objects you physically interact with everyday of your life
|
170
133
|
like lights, appliances, alarms and more. To enable the communication between Lelylan and
|
171
134
|
physical devices they should provide a simple set of web services.
|
172
135
|
[See examples](http://dev.lelylan.com/api/physicals#ruby).
|
173
136
|
|
174
|
-
|
175
|
-
|
176
|
-
Get real-time updates by subscribing to a resource and its related event.
|
137
|
+
**Subscriptions** - Get realtime updates by subscribing to a resource and its related event.
|
177
138
|
[See examples](http://dev.lelylan.com/api/realtime#ruby).
|
178
139
|
|
179
|
-
|
180
|
-
|
181
|
-
Returns extended information for the authenticated user.
|
140
|
+
**User Profile** - Returns extended information for the authenticated user.
|
182
141
|
[See examples](http://dev.lelylan.com/api/core#get-a-user-ruby).
|
183
142
|
|
184
143
|
|
185
|
-
|
144
|
+
### Authorization flows
|
145
|
+
|
146
|
+
#### Authorization code flows
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
150
|
+
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
151
|
+
token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
152
|
+
```
|
153
|
+
|
154
|
+
#### Implicit grant flow
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
158
|
+
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
159
|
+
token = OAuth2::AccessToken.from_kvform(client, params)
|
160
|
+
```
|
161
|
+
|
162
|
+
#### Resource owner password credentials flow
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
166
|
+
token = oauth.password.get_token('email', 'password')
|
167
|
+
```
|
168
|
+
|
169
|
+
Access tokens, when expired, are automatically refreshed.
|
170
|
+
|
171
|
+
|
172
|
+
### Errors
|
186
173
|
|
187
174
|
Exceptions are raised when a 4xx or 5xx status code is returned.
|
188
175
|
|
@@ -199,18 +186,21 @@ Through the error message attribute you can access the error information.
|
|
199
186
|
|
200
187
|
```ruby
|
201
188
|
begin
|
202
|
-
|
189
|
+
device = lelylan.device('<id>')
|
203
190
|
rescue Lelylan::Error => e
|
204
|
-
puts
|
191
|
+
puts e.message
|
205
192
|
end
|
206
193
|
```
|
207
194
|
|
195
|
+
Unluckily the `#message` method can only be a string. For this reason we
|
196
|
+
can't return a JSON structure when lelylan offers it, but we return the
|
197
|
+
`error.description` value.
|
208
198
|
Learn more about the [error response structure](http://dev.lelylan.com/api/core#errors).
|
209
199
|
|
210
200
|
|
211
|
-
|
201
|
+
### Configurations
|
212
202
|
|
213
|
-
|
203
|
+
#### API endpoint
|
214
204
|
|
215
205
|
Configuration block.
|
216
206
|
|
@@ -242,24 +232,34 @@ provide specs to your contribution.
|
|
242
232
|
* Run `bundle install` for dependencies.
|
243
233
|
* Run `bundle exec guard` and press enter to execute all specs.
|
244
234
|
|
235
|
+
### Running locally
|
236
|
+
|
237
|
+
Whenever you want to use the source code from your IRB session simply import `lib/`.
|
238
|
+
|
239
|
+
```
|
240
|
+
$ git clone https://github.com/lelylan/lelylan-rb
|
241
|
+
$ cd lelylan-rb
|
242
|
+
$ irb -I lib/
|
243
|
+
$ > require 'lelylan'
|
244
|
+
```
|
245
245
|
|
246
|
-
|
246
|
+
### Spec guidelines
|
247
247
|
|
248
248
|
Follow [rspec best practices](http://betterspecs.org) guidelines.
|
249
249
|
|
250
250
|
|
251
|
-
|
251
|
+
### Coding guidelines
|
252
252
|
|
253
253
|
Follow [github](https://github.com/styleguide/) guidelines.
|
254
254
|
|
255
255
|
|
256
|
-
|
256
|
+
### Feedback
|
257
257
|
|
258
258
|
Use the [issue tracker](http://github.com/lelylan/lelylan-rb/issues) for bugs.
|
259
259
|
[Mail](mailto:touch@lelylan.com) or [Tweet](http://twitter.com/lelylan) us for any idea that can improve the project.
|
260
260
|
|
261
261
|
|
262
|
-
|
262
|
+
### Links
|
263
263
|
|
264
264
|
* [GIT Repository](http://github.com/lelylan/lelylan-rb)
|
265
265
|
* [Lelylan Ruby Website](http://lelylan.github.com/lelylan-rb).
|
data/lelylan_rb.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'faraday'
|
2
|
-
require '
|
2
|
+
require 'hashie'
|
3
3
|
|
4
4
|
module Faraday
|
5
5
|
class Response::RaiseHttpError < Response::Middleware
|
@@ -29,7 +29,14 @@ module Faraday
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def error_message(response)
|
32
|
-
response[:body]
|
32
|
+
body = response[:body] || ''
|
33
|
+
|
34
|
+
begin
|
35
|
+
body = Hashie::Mash.new(JSON.parse(response[:body]))
|
36
|
+
rescue
|
37
|
+
end
|
38
|
+
|
39
|
+
body.is_a?(::Hashie::Mash) ? body.error.description : body
|
33
40
|
end
|
34
41
|
end
|
35
42
|
end
|
@@ -23,10 +23,18 @@ module Lelylan
|
|
23
23
|
|
24
24
|
digest = OpenSSL::Digest::Digest.new('sha1')
|
25
25
|
signature = OpenSSL::HMAC.hexdigest(digest, secret, params.to_json.to_s)
|
26
|
-
headers = { 'X-Physical-Signature' => signature
|
26
|
+
headers = { 'X-Physical-Signature' => signature }
|
27
|
+
|
28
|
+
request = Faraday.new do |builder|
|
29
|
+
builder.request :json
|
30
|
+
builder.use Faraday::Response::RaiseHttpError
|
31
|
+
builder.use FaradayMiddleware::Mashify
|
32
|
+
builder.use FaradayMiddleware::ParseJson
|
33
|
+
builder.adapter(adapter)
|
34
|
+
end
|
27
35
|
|
28
|
-
request = Faraday.new
|
29
36
|
response = request.put(uri, params, headers)
|
37
|
+
|
30
38
|
response.body
|
31
39
|
end
|
32
40
|
end
|
data/lib/lelylan/connection.rb
CHANGED
@@ -6,7 +6,7 @@ module Lelylan
|
|
6
6
|
module Connection
|
7
7
|
private
|
8
8
|
|
9
|
-
def connection(authenticate=true, raw=false, version=0, force_urlencoded=false
|
9
|
+
def connection(method='get', path='', authenticate=true, raw=false, version=0, force_urlencoded=false)
|
10
10
|
|
11
11
|
options = {
|
12
12
|
:headers => {'Accept' => 'application/json', 'User-Agent' => user_agent, 'Content-Type' => 'application/json'},
|
@@ -22,17 +22,18 @@ module Lelylan
|
|
22
22
|
|
23
23
|
if path =~ /subscriptions/
|
24
24
|
raise Lelylan::Error, 'To make a request to the realtime services you need both client id and client secret' if (!client_id or !client_secret) and path =~ /subscriptions/
|
25
|
-
basic = Base64.encode64("#{self.client_id}:#{self.client_secret}")
|
26
|
-
options[:headers].merge!('Authorization' => "Bearer #{basic}")
|
27
25
|
end
|
28
26
|
|
29
|
-
|
27
|
+
if method == :delete
|
28
|
+
options[:headers].merge!('Content-Length' => '0')
|
29
|
+
end
|
30
30
|
|
31
31
|
connection = Faraday.new(options) do |builder|
|
32
32
|
builder.request :json
|
33
|
-
builder.use Faraday::
|
33
|
+
builder.use Faraday::Request::BasicAuthentication, self.client_id, self.client_secret if path =~ /subscriptions/
|
34
34
|
builder.use FaradayMiddleware::Mashify
|
35
35
|
builder.use FaradayMiddleware::ParseJson
|
36
|
+
builder.use Faraday::Response::RaiseHttpError
|
36
37
|
builder.adapter(adapter)
|
37
38
|
end
|
38
39
|
|
data/lib/lelylan/request.rb
CHANGED
@@ -40,7 +40,7 @@ module Lelylan
|
|
40
40
|
# raw - The Boolean value let return the complete response.
|
41
41
|
# force_urlencoded - The Boolean value that force the url encoding.
|
42
42
|
def request(method, path, options, authenticate, raw, version, force_urlencoded)
|
43
|
-
response = connection(authenticate, raw, version, force_urlencoded
|
43
|
+
response = connection(method, path, authenticate, raw, version, force_urlencoded).send(method) do |request|
|
44
44
|
case method
|
45
45
|
when :delete, :get
|
46
46
|
request.url(path, options)
|
data/lib/lelylan/version.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
{
|
2
|
+
"status": 404,
|
3
|
+
"method": "GET",
|
4
|
+
"request": "http://api.lelylan.com/devices/4f4ba959d033a95549000261",
|
5
|
+
"error": {
|
6
|
+
"code": "notifications.resource.not_found",
|
7
|
+
"description": "Resource not found",
|
8
|
+
"uri": "http://api.lelylan.com/devices/4f4ba959d033a95549000261"
|
9
|
+
}
|
10
|
+
}
|
@@ -9,7 +9,7 @@ describe Lelylan::Client::Type do
|
|
9
9
|
describe '#physical_properties' do
|
10
10
|
|
11
11
|
before do
|
12
|
-
stub_request(:put, 'http://mqtt.lelylan.com/devices/1').to_return(status: 202)
|
12
|
+
stub_request(:put, 'http://mqtt.lelylan.com/devices/1').to_return(status: 202, body: fixture('device.json'))
|
13
13
|
end
|
14
14
|
|
15
15
|
let!(:device) do
|
@@ -17,7 +17,7 @@ describe Lelylan::Client::Type do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'returns the type' do
|
20
|
-
device.
|
20
|
+
device.id.should_not be_nil
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'sends the request' do
|
@@ -13,7 +13,7 @@ describe Lelylan::Client::Subscription do
|
|
13
13
|
describe '#subscription' do
|
14
14
|
|
15
15
|
before do
|
16
|
-
|
16
|
+
stub_request(:get, 'http://id:secret@api.lelylan.com/subscriptions/1').to_return(body: fixture('subscription.json'))
|
17
17
|
end
|
18
18
|
|
19
19
|
let!(:subscription) do
|
@@ -25,7 +25,7 @@ describe Lelylan::Client::Subscription do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'sends the request' do
|
28
|
-
|
28
|
+
a_request(:get, 'http://id:secret@api.lelylan.com/subscriptions/1').should have_been_made
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -33,7 +33,7 @@ describe Lelylan::Client::Subscription do
|
|
33
33
|
describe '#subscriptions' do
|
34
34
|
|
35
35
|
before do
|
36
|
-
|
36
|
+
stub_request(:get, 'http://id:secret@api.lelylan.com/subscriptions').to_return(body: fixture('subscriptions.json'))
|
37
37
|
end
|
38
38
|
|
39
39
|
let!(:subscriptions) do
|
@@ -45,13 +45,13 @@ describe Lelylan::Client::Subscription do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'sends the request' do
|
48
|
-
|
48
|
+
a_request(:get, 'http://id:secret@api.lelylan.com/subscriptions').should have_been_made
|
49
49
|
end
|
50
50
|
|
51
51
|
context 'with params' do
|
52
52
|
|
53
53
|
before do
|
54
|
-
|
54
|
+
stub_request(:get, 'http://id:secret@api.lelylan.com/subscriptions').with(query: { per: '25' }).to_return(body: fixture('subscription.json'))
|
55
55
|
end
|
56
56
|
|
57
57
|
before do
|
@@ -59,7 +59,7 @@ describe Lelylan::Client::Subscription do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'sends the params' do
|
62
|
-
|
62
|
+
a_request(:get, 'http://id:secret@api.lelylan.com/subscriptions').with(query: { per: '25' }).should have_been_made
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -68,11 +68,11 @@ describe Lelylan::Client::Subscription do
|
|
68
68
|
describe '#create_subscription' do
|
69
69
|
|
70
70
|
before do
|
71
|
-
|
71
|
+
stub_request(:post, 'http://id:secret@api.lelylan.com/subscriptions').with(body: { event: 'property-update' }).to_return(body: fixture('subscription.json'))
|
72
72
|
end
|
73
73
|
|
74
74
|
let!(:subscription) do
|
75
|
-
lelylan.create_subscription(
|
75
|
+
lelylan.create_subscription(event: 'property-update')
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'returns the subscription' do
|
@@ -80,7 +80,7 @@ describe Lelylan::Client::Subscription do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'sends the request' do
|
83
|
-
|
83
|
+
a_request(:post, 'http://id:secret@api.lelylan.com/subscriptions').with(body: { event: 'property-update' }).should have_been_made
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -88,11 +88,11 @@ describe Lelylan::Client::Subscription do
|
|
88
88
|
describe '#update_subscription' do
|
89
89
|
|
90
90
|
before do
|
91
|
-
|
91
|
+
stub_request(:put, 'http://id:secret@api.lelylan.com/subscriptions/1').with(body: { event: 'delete' }).to_return(body: fixture('subscription.json'))
|
92
92
|
end
|
93
93
|
|
94
94
|
let!(:subscription) do
|
95
|
-
lelylan.update_subscription('1',
|
95
|
+
lelylan.update_subscription('1', event: 'delete')
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'returns the subscription' do
|
@@ -100,7 +100,7 @@ describe Lelylan::Client::Subscription do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
it 'sends the request' do
|
103
|
-
|
103
|
+
a_request(:put, 'http://id:secret@api.lelylan.com/subscriptions/1').with(body: { event: 'delete' }).should have_been_made
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -108,7 +108,7 @@ describe Lelylan::Client::Subscription do
|
|
108
108
|
describe '#delete_subscription' do
|
109
109
|
|
110
110
|
before do
|
111
|
-
|
111
|
+
stub_request(:delete, 'http://id:secret@api.lelylan.com/subscriptions/1').to_return(body: fixture('subscription.json'))
|
112
112
|
end
|
113
113
|
|
114
114
|
let!(:subscription) do
|
@@ -120,10 +120,11 @@ describe Lelylan::Client::Subscription do
|
|
120
120
|
end
|
121
121
|
|
122
122
|
it 'sends the request' do
|
123
|
-
|
123
|
+
a_request(:delete, 'http://id:secret@api.lelylan.com/subscriptions/1').should have_been_made
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
+
|
127
128
|
describe 'when a client param misses' do
|
128
129
|
|
129
130
|
let(:client) do
|
@@ -133,7 +134,7 @@ describe Lelylan::Client::Subscription do
|
|
133
134
|
describe '#subscription' do
|
134
135
|
|
135
136
|
before do
|
136
|
-
|
137
|
+
stub_request(:get, 'http://id:secret@api.lelylan.com/subscriptions/1').to_return(body: fixture('subscription.json'))
|
137
138
|
end
|
138
139
|
|
139
140
|
it 'raises a Lelylan::Error' do
|