lelylan-rb 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|