sauce_whisk 0.0.9 → 0.0.10

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTgwOTc5ZTkyZmNiZjU3ZmMwZmI3MDBiZTc2M2ZlZTU1ZGU2NzQ5Yw==
4
+ MmJlNDVjYjkzMTZmMDQ4OGQ0MzhhMGZkOTM1M2ZiYzBlMjIzZGY4Yg==
5
5
  data.tar.gz: !binary |-
6
- NzBiNDA1MmFkNTEzNjJhYzE1NTc1ZDhiMDBjZGI3YzM4NDNhYTdkMg==
6
+ OWUyY2Y2NGQyMmZjZTllOGM0MTI2ZDdjOGIxZjBlMjFlMTczZGNiMg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZGQ4ODNiZDQ5YTA5ZDI4ZGFlZTk1Y2MxYTRhOWJlNTA3YzM2NDhhNTJjMzg5
10
- ODhiYzA1NGI5NTVlZGM5Y2I3ZjY5NTJiOTM2NTExYmI5NDVlOTdhNmVmNGY0
11
- ODJjMjZmYjgwZWFkMzQyMTk1YTBlOTZlMjBmOWUzNDc2YTUxYTI=
9
+ MThlODBkNGFmMDZiNzM2NmRiYmFhMzAxMTE2NGFlMjZjNWRmYzc0MzMyOWQ3
10
+ NmRiZjcwZTI5YTVmMjQwYmE5MmZjMDE5NTkwZGIyZTk0NzIyMmY4ZDYzMmIy
11
+ MzI4MDFiNmNkOGEzMGUzZmI1ZGI3MDU1OTBhMmZkZjg4YjExOWQ=
12
12
  data.tar.gz: !binary |-
13
- YWJlYWVhZjc3NzBkMjBiMzk4ZDdjYjAzZWY0MjNhYmM2Yjc2MzEwZDMxMTc5
14
- NjQzMWEyYWJjZmFmYzBjY2YyNTZmODVhNjgzMjgyY2Y5ZTI1MmNkZGEyM2U1
15
- YzI1YzhiMGQ1OTVjNTc5OWM2YzYyNTQwNDk1OTQwZGE3MmMxMjc=
13
+ ODEyMTE1YjFjZWRhOGM2MzI2ODdmZTYyMDgzZTViYjEwODI1NDJiZWEwMzBj
14
+ MmEyYWQ4NTRmYmVkNWQxYjIwYjkyOGQ4NTRlNWIzN2FkNzgzZTRlZjI5ODUw
15
+ ZDFmYTY3YTcxZGMwZmU4Y2RlM2RmOTVjMjVlZDMwMWM0NzVkYmY=
data/README.md CHANGED
@@ -44,10 +44,10 @@ There are two ways to create a Job object.
44
44
 
45
45
  ```ruby
46
46
  # Create an 'empty' job (i.e. don't retrieve job details from the API)
47
- empty_job = Job.new job_id
47
+ empty_job = SauceWhisk::Job.new job_id
48
48
 
49
49
  # Create a job with details fetched from the API
50
- fully_detailed_job = Jobs.fetch job_id
50
+ fully_detailed_job = SauceWhisk::Jobs.fetch job_id
51
51
  ```
52
52
 
53
53
  Use the first form when you just want a simple way to push details to the API. Use the last form when you want to fetch details from the API.
@@ -57,7 +57,7 @@ NB: It's not possible to create a new job on Sauce Labs' infrastructure with the
57
57
  ### Updating Job Metadata
58
58
 
59
59
  ```ruby
60
- job = Job.new job_id
60
+ job = SauceWhisk::Jobs.fetch job_id
61
61
  job.build = "12.3.04-beta"
62
62
  job.visibility = "public"
63
63
  job.tags = "new_user"
@@ -77,14 +77,14 @@ There are three types of asset for Sauce Labs jobs: screenshots, video and logs.
77
77
  #### Screenshots
78
78
 
79
79
  ```ruby
80
- job = Job.fetch job_id
80
+ job = SauceWhisk::Jobs.fetch job_id
81
81
  screenshots = job.screenshots # An array of Screenshot assets
82
82
  ```
83
83
 
84
84
  #### Video
85
85
 
86
86
  ```ruby
87
- job = Job.fetch job_id
87
+ job = SauceWhisk::Jobs.fetch job_id
88
88
  video = job.video # A single Asset, holding the video
89
89
  ```
90
90
 
@@ -210,7 +210,7 @@ SauceWhisk.logger defaults to STDOUT.
210
210
 
211
211
  ## Contributing
212
212
 
213
- 1. Fork the [sauce-labs version](https://github.com/sauce-labs/sauce_whisk) of this repository
213
+ 1. Fork the [sauce-labs version](https://github.com/saucelabs/sauce_whisk) of this repository
214
214
  2. Create your feature branch (`git checkout -b my-new-feature`)
215
215
  3. Commit your changes (`git commit -am 'Add some feature'`)
216
216
  4. Push to the branch (`git push origin my-new-feature`)
@@ -1,4 +1,8 @@
1
1
  module SauceWhisk
2
+ class AccountError < StandardError; end
3
+ class SubAccountCreationError < AccountError; end
4
+ class InvalidAccountError < StandardError; end
5
+
2
6
  class Accounts
3
7
  extend SauceWhisk::RestRequestBuilder
4
8
 
@@ -8,6 +12,8 @@ module SauceWhisk
8
12
 
9
13
  account_parameters = user_parameters.merge concurrencies
10
14
  return Account.new(account_parameters)
15
+ rescue RestClient::ResourceNotFound
16
+ raise InvalidAccountError, "Account #{user_id} does not exist"
11
17
  end
12
18
 
13
19
  def self.concurrency_for(job_id = ENV["SAUCE_USERNAME"], type = :both)
@@ -24,7 +30,27 @@ module SauceWhisk
24
30
  end
25
31
  end
26
32
 
33
+ #TODO what happens if not a valid parent?
34
+ def self.create_subaccount(parent, name, username, email, password)
35
+ payload = {
36
+ :username => username,
37
+ :password => password,
38
+ :name => name,
39
+ :email => email
40
+ }
41
+ begin
42
+ response = post :resource => "users/#{parent.username}", :payload => payload
43
+ rescue RestClient::BadRequest => e
44
+ decoded_body = JSON.parse e.http_body, :symbolize_names => true
45
+ raise SubAccountCreationError, decoded_body[:errors]
46
+ rescue RestClient::ResourceNotFound => e
47
+ raise InvalidAccountError, "Parent account #{parent.username} does not exist"
48
+ end
49
+
50
+ new_subaccount = SubAccount.new parent, JSON.parse(response)
51
+ end
27
52
  end
53
+
28
54
  class Account
29
55
  attr_reader :access_key, :username, :minutes, :total_concurrency, :mac_concurrency
30
56
  def initialize(options)
@@ -34,5 +60,18 @@ module SauceWhisk
34
60
  @total_concurrency = options[:total_concurrency]
35
61
  @mac_concurrency = options[:mac_concurrency]
36
62
  end
63
+
64
+ def add_subaccount(name, username, email, password)
65
+ SauceWhisk::Accounts.create_subaccount(self, name, username, email, password)
66
+ end
67
+ end
68
+
69
+ class SubAccount < Account
70
+ attr_reader :parent
71
+
72
+ def initialize(parent, options)
73
+ @parent = parent
74
+ super(options)
75
+ end
37
76
  end
38
77
  end
@@ -28,18 +28,24 @@ module SauceWhisk
28
28
  RestClient::Request.execute({:method => :delete, :url => resource_to_delete}.merge auth_details)
29
29
  end
30
30
 
31
- def post(resource_parameters)
31
+ def post(opts)
32
+ payload = (opts[:payload].to_json)
33
+ resource_id = opts[:resource] || nil
34
+
32
35
  url = fully_qualified_resource
33
- length = resource_parameters.length
36
+ url << "/#{resource_id}" if resource_id
37
+
38
+ length = payload.length
34
39
  headers = {"Content-Length" => length}
35
40
  req_params = {
36
41
  :method => :post,
37
42
  :url => url,
38
- :payload => resource_parameters,
39
43
  :content_type => "application/json",
40
44
  :headers => headers
41
45
  }
42
46
 
47
+ req_params.merge!({:payload => payload}) unless payload.nil?
48
+
43
49
  RestClient::Request.execute(req_params.merge auth_details)
44
50
 
45
51
  end
@@ -23,9 +23,17 @@ module SauceWhisk
23
23
  return tunnels
24
24
  end
25
25
 
26
- def self.open(opts)
27
- #opts[:tunnel_identifier] = opts.delete :tunnel_id
28
- new_tunnel_parameters = JSON.parse post opts.to_json
26
+ def self.open(opts, wait_until_ready = true)
27
+ new_tunnel_parameters = JSON.parse((post :payload => opts), :symbolize_names => true)
28
+ STDERR.puts "PERMS #{new_tunnel_parameters}"
29
+ new_tunnel = fetch new_tunnel_parameters[:id]
30
+
31
+ while(["starting", "booting"].include? new_tunnel.status)
32
+
33
+ new_tunnel = fetch new_tunnel_parameters[:id]
34
+ end
35
+
36
+ return new_tunnel
29
37
  end
30
38
 
31
39
  def self.stop tunnel_id
@@ -33,13 +41,16 @@ module SauceWhisk
33
41
  end
34
42
 
35
43
  def self.fetch tunnel_id
36
- tunnel_parameters = JSON.parse get tunnel_id
44
+ unless tunnel_id
45
+ raise ArgumentError, "Can't fetch a tunnel without an id (you provided blank or nil)"
46
+ end
47
+ tunnel_parameters = JSON.parse(get(tunnel_id), :symbolize_names => true)
37
48
  Tunnel.new tunnel_parameters
38
49
  end
39
50
  end
40
51
 
41
52
  class Tunnel
42
- attr_reader :id, :owner, :status, :host, :creation_time
53
+ attr_reader :id, :owner, :status, :host, :creation_time, :ssh_port
43
54
 
44
55
  def initialize(params)
45
56
  params.each do |param, val|
@@ -1,3 +1,3 @@
1
1
  module SauceWhisk
2
- VERSION = "0.0.9"
2
+ VERSION = "0.0.10"
3
3
  end
@@ -89,4 +89,291 @@ http_interactions:
89
89
  string: '{"mac_concurrency": 5, "concurrency": 20}'
90
90
  http_version:
91
91
  recorded_at: Mon, 17 Jun 2013 12:30:47 GMT
92
+ - request:
93
+ method: post
94
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/users/<SAUCE_USERNAME>
95
+ body:
96
+ encoding: UTF-8
97
+ string: '{"username":"newsub77","password":"davesdisease","name":"Manny","email":"Manny@blackbooks.co.uk"}'
98
+ headers:
99
+ Accept:
100
+ - '*/*; q=0.5, application/xml'
101
+ Accept-Encoding:
102
+ - gzip, deflate
103
+ Content-Length:
104
+ - '97'
105
+ User-Agent:
106
+ - Ruby
107
+ response:
108
+ status:
109
+ code: 201
110
+ message: Created
111
+ headers:
112
+ Server:
113
+ - nginx/0.7.62
114
+ Date:
115
+ - Wed, 28 Aug 2013 20:55:46 GMT
116
+ Content-Type:
117
+ - application/json
118
+ Location:
119
+ - https://saucelabs.com/rest/v1/users/newsub77
120
+ Connection:
121
+ - keep-alive
122
+ Pragma:
123
+ - no-cache
124
+ Cache-Control:
125
+ - no-cache
126
+ X-Frame-Options:
127
+ - DENY
128
+ Set-Cookie:
129
+ - csrf_token=eab7d96896e5296aee29b037fb5469d9; expires="Wed, 28-Aug-2013 21:14:44
130
+ GMT"; Max-Age=600; Path=/
131
+ - metrics=885a220fc548623dd57098d7d59489760cec3b2beaf8245688754773b074267ebb2e8c8e;
132
+ Path=/
133
+ Content-Length:
134
+ - '148'
135
+ body:
136
+ encoding: US-ASCII
137
+ string: '{"access_key": "699d9039-baab-49a8-8830-63d43d9d45ac", "name": null,
138
+ "subscribed": false, "can_run_manual": true, "minutes": 1122, "id": "newsub77"}'
139
+ http_version:
140
+ recorded_at: Wed, 28 Aug 2013 21:04:45 GMT
141
+ - request:
142
+ method: post
143
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/users/<SAUCE_USERNAME>
144
+ body:
145
+ encoding: UTF-8
146
+ string: '{"username":"duplicate","password":"davesdisease","name":"Manny","email":"Manny@blackbooks.co.uk"}'
147
+ headers:
148
+ Accept:
149
+ - '*/*; q=0.5, application/xml'
150
+ Accept-Encoding:
151
+ - gzip, deflate
152
+ Content-Length:
153
+ - '98'
154
+ User-Agent:
155
+ - Ruby
156
+ response:
157
+ status:
158
+ code: 400
159
+ message: Bad request
160
+ headers:
161
+ Server:
162
+ - nginx/0.7.62
163
+ Date:
164
+ - Thu, 29 Aug 2013 01:14:07 GMT
165
+ Content-Type:
166
+ - application/json
167
+ Connection:
168
+ - keep-alive
169
+ Pragma:
170
+ - no-cache
171
+ Cache-Control:
172
+ - no-cache
173
+ X-Frame-Options:
174
+ - DENY
175
+ Set-Cookie:
176
+ - csrf_token=750f4cdca985d7f7f9fcbbd0bfc58fc3; expires="Thu, 29-Aug-2013 01:33:06
177
+ GMT"; Max-Age=600; Path=/
178
+ - metrics=4e602fa8932a373223341b7af992f9b7fa7563dff2c7d1d2eef24680a9be7e752de3233b;
179
+ Path=/
180
+ - metrics=a6431e82448e473a873bf07761f858e431227be3f26941e865a24ac88318aed9f4b32dc4;
181
+ Path=/
182
+ Content-Length:
183
+ - '52'
184
+ body:
185
+ encoding: US-ASCII
186
+ string: '{"errors": "User already exists with that username"}'
187
+ http_version:
188
+ recorded_at: Thu, 29 Aug 2013 01:23:06 GMT
189
+ - request:
190
+ method: post
191
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/users/<SAUCE_USERNAME>
192
+ body:
193
+ encoding: UTF-8
194
+ string: '{"username":"toomany","password":"davesdisease","name":"Manny","email":"Manny@blackbooks.co.uk"}'
195
+ headers:
196
+ Accept:
197
+ - '*/*; q=0.5, application/xml'
198
+ Accept-Encoding:
199
+ - gzip, deflate
200
+ Content-Length:
201
+ - '96'
202
+ User-Agent:
203
+ - Ruby
204
+ response:
205
+ status:
206
+ code: 400
207
+ message: Bad request
208
+ headers:
209
+ Server:
210
+ - nginx/0.7.62
211
+ Date:
212
+ - Thu, 29 Aug 2013 01:14:07 GMT
213
+ Content-Type:
214
+ - application/json
215
+ Connection:
216
+ - keep-alive
217
+ Pragma:
218
+ - no-cache
219
+ Cache-Control:
220
+ - no-cache
221
+ X-Frame-Options:
222
+ - DENY
223
+ Set-Cookie:
224
+ - csrf_token=750f4cdca985d7f7f9fcbbd0bfc58fc3; expires="Thu, 29-Aug-2013 01:33:06
225
+ GMT"; Max-Age=600; Path=/
226
+ - metrics=4e602fa8932a373223341b7af992f9b7fa7563dff2c7d1d2eef24680a9be7e752de3233b;
227
+ Path=/
228
+ - metrics=a6431e82448e473a873bf07761f858e431227be3f26941e865a24ac88318aed9f4b32dc4;
229
+ Path=/
230
+ Content-Length:
231
+ - '44'
232
+ body:
233
+ encoding: US-ASCII
234
+ string: '{"errors": "Subaccount capacity exhausted."}'
235
+ http_version:
236
+ recorded_at: Thu, 29 Aug 2013 01:24:25 GMT
237
+ - request:
238
+ method: post
239
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/users/<SAUCE_USERNAME>
240
+ body:
241
+ encoding: UTF-8
242
+ string: '{"username":"deeptree","password":"davesdisease","name":"Manny","email":"Manny@blackbooks.co.uk"}'
243
+ headers:
244
+ Accept:
245
+ - '*/*; q=0.5, application/xml'
246
+ Accept-Encoding:
247
+ - gzip, deflate
248
+ Content-Length:
249
+ - '96'
250
+ User-Agent:
251
+ - Ruby
252
+ response:
253
+ status:
254
+ code: 400
255
+ message: Bad request
256
+ headers:
257
+ Server:
258
+ - nginx/0.7.62
259
+ Date:
260
+ - Thu, 29 Aug 2013 01:14:07 GMT
261
+ Content-Type:
262
+ - application/json
263
+ Connection:
264
+ - keep-alive
265
+ Pragma:
266
+ - no-cache
267
+ Cache-Control:
268
+ - no-cache
269
+ X-Frame-Options:
270
+ - DENY
271
+ Set-Cookie:
272
+ - csrf_token=750f4cdca985d7f7f9fcbbd0bfc58fc3; expires="Thu, 29-Aug-2013 01:33:06
273
+ GMT"; Max-Age=600; Path=/
274
+ - metrics=4e602fa8932a373223341b7af992f9b7fa7563dff2c7d1d2eef24680a9be7e752de3233b;
275
+ Path=/
276
+ - metrics=a6431e82448e473a873bf07761f858e431227be3f26941e865a24ac88318aed9f4b32dc4;
277
+ Path=/
278
+ Content-Length:
279
+ - '53'
280
+ body:
281
+ encoding: US-ASCII
282
+ string: '{"errors": "Subaccount tree depth is limited to 10."}'
283
+ http_version:
284
+ recorded_at: Thu, 29 Aug 2013 01:24:25 GMT
285
+ - request:
286
+ method: post
287
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/users/nopenotaperson
288
+ body:
289
+ encoding: UTF-8
290
+ string: '{"username":"deeptree","password":"davesdisease","name":"Manny","email":"Manny@blackbooks.co.uk"}'
291
+ headers:
292
+ Accept:
293
+ - '*/*; q=0.5, application/xml'
294
+ Accept-Encoding:
295
+ - gzip, deflate
296
+ Content-Length:
297
+ - '97'
298
+ User-Agent:
299
+ - Ruby
300
+ response:
301
+ status:
302
+ code: 404
303
+ message: Not Found
304
+ headers:
305
+ Server:
306
+ - nginx/0.7.62
307
+ Date:
308
+ - Fri, 30 Aug 2013 01:42:07 GMT
309
+ Content-Type:
310
+ - application/json
311
+ Connection:
312
+ - keep-alive
313
+ Pragma:
314
+ - no-cache
315
+ Cache-Control:
316
+ - no-cache
317
+ X-Frame-Options:
318
+ - DENY
319
+ Set-Cookie:
320
+ - csrf_token=61a20e3c835c0c8d755d559f06fef7af; expires="Fri, 30-Aug-2013 02:01:08
321
+ GMT"; Max-Age=600; Path=/
322
+ - metrics=64e2fb23b34c01d956f2c94b397ad0e8f8da99061432ad554e2147b8abc39f4c0b59ab84;
323
+ Path=/
324
+ - metrics=eff66bcc694eb3de5e91eccbd2915a58ad3553ba428c68734d9a4390aa98899f3f6127e4;
325
+ Path=/
326
+ Content-Length:
327
+ - '45'
328
+ body:
329
+ encoding: US-ASCII
330
+ string: '{"error": "That resource could not be found"}'
331
+ http_version:
332
+ recorded_at: Fri, 30 Aug 2013 01:51:08 GMT
333
+ - request:
334
+ method: get
335
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/users/IDontExist
336
+ body:
337
+ encoding: US-ASCII
338
+ string: ''
339
+ headers:
340
+ Accept:
341
+ - '*/*; q=0.5, application/xml'
342
+ Accept-Encoding:
343
+ - gzip, deflate
344
+ User-Agent:
345
+ - Ruby
346
+ response:
347
+ status:
348
+ code: 404
349
+ message: Not Found
350
+ headers:
351
+ Server:
352
+ - nginx/0.7.62
353
+ Date:
354
+ - Fri, 30 Aug 2013 18:50:29 GMT
355
+ Content-Type:
356
+ - application/json
357
+ Connection:
358
+ - keep-alive
359
+ Pragma:
360
+ - no-cache
361
+ Cache-Control:
362
+ - no-cache
363
+ X-Frame-Options:
364
+ - DENY
365
+ Set-Cookie:
366
+ - csrf_token=ab87b5190e3649606fa26185f3bbdcc3; expires="Fri, 30-Aug-2013 19:09:31
367
+ GMT"; Max-Age=600; Path=/
368
+ - metrics=83aa4f4693e8f686608e6ff1da43f9dee7720fc9176863ee18574df8b331f23801337a5b;
369
+ Path=/
370
+ - metrics=da0d871a67933f3e2a96ec2e9c41b4e1e2c817cc7ae6265e9b054fcbba5bf3c8f83720ad;
371
+ Path=/
372
+ Content-Length:
373
+ - '45'
374
+ body:
375
+ encoding: US-ASCII
376
+ string: '{"error": "That resource could not be found"}'
377
+ http_version:
378
+ recorded_at: Fri, 30 Aug 2013 18:59:31 GMT
92
379
  recorded_with: VCR 2.5.0
@@ -233,11 +233,99 @@ http_interactions:
233
233
  - '352'
234
234
  body:
235
235
  encoding: US-ASCII
236
- string: '{"status": "new", "direct_domains": null, "shutdown_time": null, "ssh_port":
237
- 9123, "user_shutdown": null, "use_caching_proxy": false, "creation_time":
238
- 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
239
- "KarlMarx", "host": null, "owner": "<SAUCE_USERNAME>", "use_kgp": true, "id":
240
- "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
236
+ string: &1 !ruby/string
237
+ str: '{"status": "new", "direct_domains": null, "shutdown_time": null, "ssh_port":
238
+ 9123, "user_shutdown": null, "use_caching_proxy": false, "creation_time":
239
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
240
+ "KarlMarx", "host": null, "owner": "<SAUCE_USERNAME>", "use_kgp": true,
241
+ "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
242
+ net_http_res: !ruby/object:Net::HTTPOK
243
+ http_version: '1.0'
244
+ code: '200'
245
+ message: OK
246
+ header:
247
+ server:
248
+ - nginx/0.7.62
249
+ date:
250
+ - Tue, 30 Jul 2013 08:38:22 GMT
251
+ content-type:
252
+ - application/json
253
+ connection:
254
+ - keep-alive
255
+ pragma:
256
+ - no-cache
257
+ cache-control:
258
+ - no-cache
259
+ x-frame-options:
260
+ - DENY
261
+ set-cookie:
262
+ - csrf_token=3c66b97477a4dedd1255faf05ce90d66; expires="Tue, 30-Jul-2013
263
+ 08:56:35 GMT"; Max-Age=600; Path=/
264
+ - metrics=034bd00d05345d3992282b0f28e816878971ff1a86e9ab91ce174a2e89dcab18527fa539;
265
+ Path=/
266
+ content-length:
267
+ - '352'
268
+ body: *1
269
+ read: true
270
+ __read_body_previously_called: true
271
+ args:
272
+ :method: :post
273
+ :url: https://saucelabs.com/rest/v1/dylanatsauce/tunnels
274
+ :content_type: application/json
275
+ :headers:
276
+ Content-Length: 85
277
+ :payload: '{"tunnel_identifier":"bees","ssh_port":9123,"use_caching_proxy":false,"use_kgp":true}'
278
+ :user: dylanatsauce
279
+ :password: 8f5210dd-f0cf-477f-b720-9f721a9679a4
280
+ code: 200
241
281
  http_version:
242
282
  recorded_at: Tue, 30 Jul 2013 08:46:35 GMT
283
+ - request:
284
+ method: get
285
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels/4824d6b282e04d1184daff5401a52e1e
286
+ body:
287
+ encoding: US-ASCII
288
+ string: ''
289
+ headers:
290
+ Accept:
291
+ - '*/*; q=0.5, application/xml'
292
+ Accept-Encoding:
293
+ - gzip, deflate
294
+ User-Agent:
295
+ - Ruby
296
+ response:
297
+ status:
298
+ code: 200
299
+ message: OK
300
+ headers:
301
+ Server:
302
+ - nginx/0.7.62
303
+ Date:
304
+ - Thu, 01 Aug 2013 03:20:06 GMT
305
+ Content-Type:
306
+ - application/json
307
+ Connection:
308
+ - keep-alive
309
+ Pragma:
310
+ - no-cache
311
+ Cache-Control:
312
+ - no-cache
313
+ X-Frame-Options:
314
+ - DENY
315
+ Set-Cookie:
316
+ - csrf_token=752c68b4d3f9188498845b26a9938b1d; expires="Thu, 01-Aug-2013 03:38:25
317
+ GMT"; Max-Age=600; Path=/
318
+ - metrics=6b0e2bf3f0246ea3a0837eab992cb753bf68300f3484e2ba8e39494d95d2c9408df53458;
319
+ Path=/
320
+ Content-Length:
321
+ - '385'
322
+ body:
323
+ encoding: US-ASCII
324
+ string: '{"status": "terminated", "direct_domains": null, "shutdown_time": null,
325
+ "ssh_port": 9123, "user_shutdown": true, "use_caching_proxy": false, "creation_time":
326
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
327
+ "bees", "host": "maki11122.miso.saucelabs.com", "owner": "<SAUCE_USERNAME>",
328
+ "use_kgp": true, "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
329
+ http_version:
330
+ recorded_at: Thu, 01 Aug 2013 03:28:18 GMT
243
331
  recorded_with: VCR 2.5.0
@@ -0,0 +1,393 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"tunnel_identifier":"KarlMarx"}'
9
+ headers:
10
+ Accept:
11
+ - '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Length:
15
+ - '85'
16
+ User-Agent:
17
+ - Ruby
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx/0.7.62
25
+ Date:
26
+ - Tue, 30 Jul 2013 08:38:22 GMT
27
+ Content-Type:
28
+ - application/json
29
+ Connection:
30
+ - keep-alive
31
+ Pragma:
32
+ - no-cache
33
+ Cache-Control:
34
+ - no-cache
35
+ X-Frame-Options:
36
+ - DENY
37
+ Set-Cookie:
38
+ - csrf_token=3c66b97477a4dedd1255faf05ce90d66; expires="Tue, 30-Jul-2013 08:56:35
39
+ GMT"; Max-Age=600; Path=/
40
+ - metrics=034bd00d05345d3992282b0f28e816878971ff1a86e9ab91ce174a2e89dcab18527fa539;
41
+ Path=/
42
+ Content-Length:
43
+ - '352'
44
+ body:
45
+ encoding: US-ASCII
46
+ string: &1 !ruby/string
47
+ str: '{"status": "new", "direct_domains": null, "shutdown_time": null, "ssh_port":
48
+ 9123, "user_shutdown": null, "use_caching_proxy": false, "creation_time":
49
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
50
+ "KarlMarx", "host": null, "owner": "<SAUCE_USERNAME>", "use_kgp": true,
51
+ "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
52
+ net_http_res: !ruby/object:Net::HTTPOK
53
+ http_version: '1.0'
54
+ code: '200'
55
+ message: OK
56
+ header:
57
+ server:
58
+ - nginx/0.7.62
59
+ date:
60
+ - Tue, 30 Jul 2013 08:38:22 GMT
61
+ content-type:
62
+ - application/json
63
+ connection:
64
+ - keep-alive
65
+ pragma:
66
+ - no-cache
67
+ cache-control:
68
+ - no-cache
69
+ x-frame-options:
70
+ - DENY
71
+ set-cookie:
72
+ - csrf_token=3c66b97477a4dedd1255faf05ce90d66; expires="Tue, 30-Jul-2013
73
+ 08:56:35 GMT"; Max-Age=600; Path=/
74
+ - metrics=034bd00d05345d3992282b0f28e816878971ff1a86e9ab91ce174a2e89dcab18527fa539;
75
+ Path=/
76
+ content-length:
77
+ - '352'
78
+ body: *1
79
+ read: true
80
+ __read_body_previously_called: true
81
+ args:
82
+ :method: :post
83
+ :url: https://saucelabs.com/rest/v1/dylanatsauce/tunnels
84
+ :content_type: application/json
85
+ :headers:
86
+ Content-Length: 85
87
+ :payload: '{"tunnel_identifier":"bees","ssh_port":9123,"use_caching_proxy":false,"use_kgp":true}'
88
+ :user: dylanatsauce
89
+ :password: 8f5210dd-f0cf-477f-b720-9f721a9679a4
90
+ code: 200
91
+ http_version:
92
+ recorded_at: Tue, 30 Jul 2013 08:46:35 GMT
93
+ - request:
94
+ method: get
95
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels/4824d6b282e04d1184daff5401a52e1e
96
+ body:
97
+ encoding: US-ASCII
98
+ string: ''
99
+ headers:
100
+ Accept:
101
+ - '*/*; q=0.5, application/xml'
102
+ Accept-Encoding:
103
+ - gzip, deflate
104
+ User-Agent:
105
+ - Ruby
106
+ response:
107
+ status:
108
+ code: 200
109
+ message: OK
110
+ headers:
111
+ Server:
112
+ - nginx/0.7.62
113
+ Date:
114
+ - Thu, 01 Aug 2013 03:20:06 GMT
115
+ Content-Type:
116
+ - application/json
117
+ Connection:
118
+ - keep-alive
119
+ Pragma:
120
+ - no-cache
121
+ Cache-Control:
122
+ - no-cache
123
+ X-Frame-Options:
124
+ - DENY
125
+ Set-Cookie:
126
+ - csrf_token=752c68b4d3f9188498845b26a9938b1d; expires="Thu, 01-Aug-2013 03:38:25
127
+ GMT"; Max-Age=600; Path=/
128
+ - metrics=6b0e2bf3f0246ea3a0837eab992cb753bf68300f3484e2ba8e39494d95d2c9408df53458;
129
+ Path=/
130
+ Content-Length:
131
+ - '385'
132
+ body:
133
+ encoding: US-ASCII
134
+ string: &2 !ruby/string
135
+ str: '{"status": "starting", "direct_domains": null, "shutdown_time": null,
136
+ "ssh_port": 9123, "user_shutdown": true, "use_caching_proxy": false, "creation_time":
137
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
138
+ "bees", "host": "maki11122.miso.saucelabs.com", "owner": "<SAUCE_USERNAME>",
139
+ "use_kgp": true, "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
140
+ net_http_res: !ruby/object:Net::HTTPOK
141
+ http_version: '1.0'
142
+ code: '200'
143
+ message: OK
144
+ header:
145
+ server:
146
+ - nginx/0.7.62
147
+ date:
148
+ - Thu, 01 Aug 2013 03:20:06 GMT
149
+ content-type:
150
+ - application/json
151
+ connection:
152
+ - keep-alive
153
+ pragma:
154
+ - no-cache
155
+ cache-control:
156
+ - no-cache
157
+ x-frame-options:
158
+ - DENY
159
+ set-cookie:
160
+ - csrf_token=752c68b4d3f9188498845b26a9938b1d; expires="Thu, 01-Aug-2013
161
+ 03:38:25 GMT"; Max-Age=600; Path=/
162
+ - metrics=6b0e2bf3f0246ea3a0837eab992cb753bf68300f3484e2ba8e39494d95d2c9408df53458;
163
+ Path=/
164
+ content-length:
165
+ - '385'
166
+ body: *2
167
+ read: true
168
+ __read_body_previously_called: true
169
+ args:
170
+ :method: :get
171
+ :url: https://saucelabs.com/rest/v1/dylanatsauce/tunnels/4824d6b282e04d1184daff5401a52e1e
172
+ :user: dylanatsauce
173
+ :password: 8f5210dd-f0cf-477f-b720-9f721a9679a4
174
+ code: 200
175
+ http_version:
176
+ recorded_at: Thu, 01 Aug 2013 03:28:18 GMT
177
+ - request:
178
+ method: get
179
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels/4824d6b282e04d1184daff5401a52e1e
180
+ body:
181
+ encoding: US-ASCII
182
+ string: ''
183
+ headers:
184
+ Accept:
185
+ - '*/*; q=0.5, application/xml'
186
+ Accept-Encoding:
187
+ - gzip, deflate
188
+ User-Agent:
189
+ - Ruby
190
+ response:
191
+ status:
192
+ code: 200
193
+ message: OK
194
+ headers:
195
+ Server:
196
+ - nginx/0.7.62
197
+ Date:
198
+ - Thu, 01 Aug 2013 06:23:17 GMT
199
+ Content-Type:
200
+ - application/json
201
+ Connection:
202
+ - keep-alive
203
+ Pragma:
204
+ - no-cache
205
+ Cache-Control:
206
+ - no-cache
207
+ X-Frame-Options:
208
+ - DENY
209
+ Set-Cookie:
210
+ - csrf_token=6049fff0dc34a51764c1ef3da112e657; expires="Thu, 01-Aug-2013 06:41:36
211
+ GMT"; Max-Age=600; Path=/
212
+ - metrics=cf830e9e8889594d0c2b8aaa17e07faea4ddf1865ac81c3321174484bb0d5100342edcc8;
213
+ Path=/
214
+ Content-Length:
215
+ - '385'
216
+ body:
217
+ encoding: US-ASCII
218
+ string: &3 !ruby/string
219
+ str: '{"status": "starting", "direct_domains": null, "shutdown_time": null,
220
+ "ssh_port": 9123, "user_shutdown": true, "use_caching_proxy": false, "creation_time":
221
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
222
+ "bees", "host": "maki11122.miso.saucelabs.com", "owner": "<SAUCE_USERNAME>",
223
+ "use_kgp": true, "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
224
+ net_http_res: !ruby/object:Net::HTTPOK
225
+ http_version: '1.0'
226
+ code: '200'
227
+ message: OK
228
+ header:
229
+ server:
230
+ - nginx/0.7.62
231
+ date:
232
+ - Thu, 01 Aug 2013 06:23:17 GMT
233
+ content-type:
234
+ - application/json
235
+ connection:
236
+ - keep-alive
237
+ pragma:
238
+ - no-cache
239
+ cache-control:
240
+ - no-cache
241
+ x-frame-options:
242
+ - DENY
243
+ set-cookie:
244
+ - csrf_token=6049fff0dc34a51764c1ef3da112e657; expires="Thu, 01-Aug-2013
245
+ 06:41:36 GMT"; Max-Age=600; Path=/
246
+ - metrics=cf830e9e8889594d0c2b8aaa17e07faea4ddf1865ac81c3321174484bb0d5100342edcc8;
247
+ Path=/
248
+ content-length:
249
+ - '385'
250
+ body: *3
251
+ read: true
252
+ __read_body_previously_called: true
253
+ args:
254
+ :method: :get
255
+ :url: https://saucelabs.com/rest/v1/dylanatsauce/tunnels/4824d6b282e04d1184daff5401a52e1e
256
+ :user: dylanatsauce
257
+ :password: 8f5210dd-f0cf-477f-b720-9f721a9679a4
258
+ code: 200
259
+ http_version:
260
+ recorded_at: Thu, 01 Aug 2013 06:31:36 GMT
261
+ - request:
262
+ method: get
263
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels/4824d6b282e04d1184daff5401a52e1e
264
+ body:
265
+ encoding: US-ASCII
266
+ string: ''
267
+ headers:
268
+ Accept:
269
+ - '*/*; q=0.5, application/xml'
270
+ Accept-Encoding:
271
+ - gzip, deflate
272
+ User-Agent:
273
+ - Ruby
274
+ response:
275
+ status:
276
+ code: 200
277
+ message: OK
278
+ headers:
279
+ Server:
280
+ - nginx/0.7.62
281
+ Date:
282
+ - Thu, 01 Aug 2013 06:24:17 GMT
283
+ Content-Type:
284
+ - application/json
285
+ Connection:
286
+ - keep-alive
287
+ Pragma:
288
+ - no-cache
289
+ Cache-Control:
290
+ - no-cache
291
+ X-Frame-Options:
292
+ - DENY
293
+ Set-Cookie:
294
+ - csrf_token=6049fff0dc34a51764c1ef3da112e657; expires="Thu, 01-Aug-2013 06:42:36
295
+ GMT"; Max-Age=600; Path=/
296
+ - metrics=cf830e9e8889594d0c2b8aaa17e07faea4ddf1865ac81c3321174484bb0d5100342edcc8;
297
+ Path=/
298
+ Content-Length:
299
+ - '385'
300
+ body:
301
+ encoding: US-ASCII
302
+ string: &4 !ruby/string
303
+ str: '{"status": "starting", "direct_domains": null, "shutdown_time": null,
304
+ "ssh_port": 9123, "user_shutdown": true, "use_caching_proxy": false, "creation_time":
305
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
306
+ "bees", "host": "maki11122.miso.saucelabs.com", "owner": "<SAUCE_USERNAME>",
307
+ "use_kgp": true, "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
308
+ net_http_res: !ruby/object:Net::HTTPOK
309
+ http_version: '1.0'
310
+ code: '200'
311
+ message: OK
312
+ header:
313
+ server:
314
+ - nginx/0.7.62
315
+ date:
316
+ - Thu, 01 Aug 2013 06:24:17 GMT
317
+ content-type:
318
+ - application/json
319
+ connection:
320
+ - keep-alive
321
+ pragma:
322
+ - no-cache
323
+ cache-control:
324
+ - no-cache
325
+ x-frame-options:
326
+ - DENY
327
+ set-cookie:
328
+ - csrf_token=6049fff0dc34a51764c1ef3da112e657; expires="Thu, 01-Aug-2013
329
+ 06:42:36 GMT"; Max-Age=600; Path=/
330
+ - metrics=cf830e9e8889594d0c2b8aaa17e07faea4ddf1865ac81c3321174484bb0d5100342edcc8;
331
+ Path=/
332
+ content-length:
333
+ - '385'
334
+ body: *4
335
+ read: true
336
+ __read_body_previously_called: true
337
+ args:
338
+ :method: :get
339
+ :url: https://saucelabs.com/rest/v1/dylanatsauce/tunnels/4824d6b282e04d1184daff5401a52e1e
340
+ :user: dylanatsauce
341
+ :password: 8f5210dd-f0cf-477f-b720-9f721a9679a4
342
+ code: 200
343
+ http_version:
344
+ recorded_at: Thu, 01 Aug 2013 06:32:36 GMT
345
+ - request:
346
+ method: get
347
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels/4824d6b282e04d1184daff5401a52e1e
348
+ body:
349
+ encoding: US-ASCII
350
+ string: ''
351
+ headers:
352
+ Accept:
353
+ - '*/*; q=0.5, application/xml'
354
+ Accept-Encoding:
355
+ - gzip, deflate
356
+ User-Agent:
357
+ - Ruby
358
+ response:
359
+ status:
360
+ code: 200
361
+ message: OK
362
+ headers:
363
+ Server:
364
+ - nginx/0.7.62
365
+ Date:
366
+ - Thu, 01 Aug 2013 06:29:10 GMT
367
+ Content-Type:
368
+ - application/json
369
+ Connection:
370
+ - keep-alive
371
+ Pragma:
372
+ - no-cache
373
+ Cache-Control:
374
+ - no-cache
375
+ X-Frame-Options:
376
+ - DENY
377
+ Set-Cookie:
378
+ - csrf_token=dcc651346d3a6b3e229c42284cee3c47; expires="Thu, 01-Aug-2013 06:47:29
379
+ GMT"; Max-Age=600; Path=/
380
+ - metrics=e3721320f41cb6f479b7c8bbe10c5939da9b818100af52ea0c0d4e4fae0d523dc0de5ed4;
381
+ Path=/
382
+ Content-Length:
383
+ - '385'
384
+ body:
385
+ encoding: US-ASCII
386
+ string: '{"status": "terminated", "direct_domains": null, "shutdown_time": null,
387
+ "ssh_port": 9123, "user_shutdown": true, "use_caching_proxy": false, "creation_time":
388
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
389
+ "bees", "host": "maki11122.miso.saucelabs.com", "owner": "<SAUCE_USERNAME>",
390
+ "use_kgp": true, "id": "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
391
+ http_version:
392
+ recorded_at: Thu, 01 Aug 2013 06:37:30 GMT
393
+ recorded_with: VCR 2.5.0
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe SauceWhisk::Account do
4
- describe "#new" do
4
+ describe "##new" do
5
5
  it "sets any options passed in as a hash" do
6
6
  options = {
7
7
  :access_key => 12345,
@@ -26,4 +26,12 @@ describe SauceWhisk::Account do
26
26
  test_account.total_concurrency.should eq 100
27
27
  end
28
28
  end
29
+
30
+ describe "#add_subaccount", :vcr => {:cassette_name => "accounts"} do
31
+ let(:parent) {SauceWhisk::Account.new(:access_key => 12345, :minutes => 23, :id => ENV["SAUCE_USERNAME"])}
32
+
33
+ it "creates a subaccount" do
34
+ subaccount = parent.add_subaccount("Manny", "newsub77", "Manny@blackbooks.co.uk", "davesdisease")
35
+ end
36
+ end
29
37
  end
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe SauceWhisk::Accounts, :vcr => {:cassette_name => "accounts"} do
3
+ describe SauceWhisk::Accounts, :vcr => {:cassette_name => "accounts", :match_requests_on => [:uri, :body]} do
4
4
  let(:auth) {"#{ENV["SAUCE_USERNAME"]}:#{ENV["SAUCE_ACCESS_KEY"]}"}
5
5
 
6
6
  describe "#fetch" do
@@ -30,6 +30,14 @@ describe SauceWhisk::Accounts, :vcr => {:cassette_name => "accounts"} do
30
30
  assert_not_requested :get, "https://#{auth}@saucelabs.com/rest/v1/#{ENV["SAUCE_USERNAME"]}/limits"
31
31
  account.total_concurrency.should be_nil
32
32
  end
33
+
34
+ context "with an invalid account" do
35
+ it "Raises an InvalidAccountError" do
36
+ expect{
37
+ SauceWhisk::Accounts.fetch "IDontExist"
38
+ }.to raise_error SauceWhisk::InvalidAccountError
39
+ end
40
+ end
33
41
  end
34
42
 
35
43
  describe "#concurrency_for" do
@@ -51,4 +59,78 @@ describe SauceWhisk::Accounts, :vcr => {:cassette_name => "accounts"} do
51
59
  SauceWhisk::Accounts.concurrency_for(ENV["SAUCE_USERNAME"], :total).should eq 20
52
60
  end
53
61
  end
62
+
63
+ describe "#create_subaccount" do
64
+ let(:params) {{
65
+ :username => "newsub77",
66
+ :password => "davesdisease",
67
+ :name => "Manny",
68
+ :email => "Manny@blackbooks.co.uk"
69
+ }}
70
+
71
+ let(:parent) {SauceWhisk::Account.new(:access_key => 12345, :minutes => 23, :id => ENV["SAUCE_USERNAME"])}
72
+
73
+ it "calls the correct url" do
74
+ SauceWhisk::Accounts.create_subaccount(parent,
75
+ "Manny", "newsub77", "Manny@blackbooks.co.uk", "davesdisease")
76
+
77
+ assert_requested(:post,
78
+ "https://#{auth}@saucelabs.com/rest/v1/users/#{ENV["SAUCE_USERNAME"]}",
79
+ :body => params.to_json
80
+ )
81
+ end
82
+
83
+ it "returns a Subaccount object" do
84
+ sub = SauceWhisk::Accounts.create_subaccount(parent, "Manny", "newsub77",
85
+ "Manny@blackbooks.co.uk", "davesdisease")
86
+
87
+ sub.should be_a_kind_of SauceWhisk::Account
88
+ end
89
+
90
+ it "returns a Subaccount, parented to the Parent account" do
91
+ parent = SauceWhisk::Accounts.fetch ENV["SAUCE_USERNAME"]
92
+
93
+ sub = SauceWhisk::Accounts.create_subaccount(parent, "Manny", "newsub77",
94
+ "Manny@blackbooks.co.uk", "davesdisease")
95
+
96
+ sub.parent.should be parent
97
+ end
98
+
99
+ context "trying to create too many subaccounts" do
100
+ it "should throw SubaccountCreationError" do
101
+ expect{
102
+ SauceWhisk::Accounts.create_subaccount(parent, "Manny", "toomany",
103
+ "Manny@blackbooks.co.uk", "davesdisease")
104
+ }.to raise_error SauceWhisk::SubAccountCreationError
105
+ end
106
+ end
107
+
108
+ context "trying to create a subaccount which already exists" do
109
+ it "should throw SubaccountCreationError" do
110
+ expect{
111
+ SauceWhisk::Accounts.create_subaccount(parent, "Manny", "duplicate",
112
+ "Manny@blackbooks.co.uk", "davesdisease")
113
+ }.to raise_error SauceWhisk::SubAccountCreationError
114
+ end
115
+ end
116
+
117
+ context "trying to create a subaccount which causes the tree to be too deep" do
118
+ it "should throw SubaccountCreationError" do
119
+ expect{
120
+ SauceWhisk::Accounts.create_subaccount(parent, "Manny", "deeptree",
121
+ "Manny@blackbooks.co.uk", "davesdisease")
122
+ }.to raise_error SauceWhisk::SubAccountCreationError
123
+ end
124
+ end
125
+
126
+ context "with a non-existant parent" do
127
+ let(:parent) {SauceWhisk::Account.new(:access_key => 12345, :minutes => 23, :id =>"nopenotaperson")}
128
+ it "should throw SubaccountCreationError" do
129
+ expect{
130
+ SauceWhisk::Accounts.create_subaccount(parent, "Manny", "deeptree",
131
+ "Manny@blackbooks.co.uk", "davesdisease")
132
+ }.to raise_error SauceWhisk::InvalidAccountError
133
+ end
134
+ end
135
+ end
54
136
  end
@@ -71,38 +71,45 @@ describe SauceWhisk::RestRequestBuilder do
71
71
 
72
72
  begin
73
73
  describe "#post", :vcr => {:cassette_name => 'tunnels'} do
74
- let(:expected_payload) {{:tunnel_identifier => "KarlMarx"}.to_json}
74
+ let(:expected_payload) {{:tunnel_identifier => "KarlMarx"}}
75
75
  it "calls the base URL" do
76
76
  expected_url = "#{SauceWhisk.base_url}/#{dummy_client.resource}"
77
77
  RestClient::Request.should_receive(:execute).with(hash_including({:url => expected_url}))
78
78
 
79
- dummy_client.post expected_payload
79
+ dummy_client.post(:payload => expected_payload)
80
80
  end
81
81
 
82
82
  it "uses the correct method" do
83
83
  RestClient::Request.should_receive(:execute).with(hash_including({:method => :post}))
84
- dummy_client.post expected_payload
84
+ dummy_client.post(:payload => expected_payload)
85
85
  end
86
86
 
87
- it "includes the correct payload" do
88
- RestClient::Request.should_receive(:execute).with(hash_including({:payload => expected_payload}))
89
- dummy_client.post expected_payload
87
+ it "includes the correct payload, in JSON" do
88
+ RestClient::Request.should_receive(:execute).with(hash_including({:payload => expected_payload.to_json}))
89
+ dummy_client.post(:payload => expected_payload)
90
90
  end
91
91
 
92
92
  it "includes the correct content_type" do
93
93
  RestClient::Request.should_receive(:execute).with(hash_including({:content_type => "application/json"}))
94
- dummy_client.post expected_payload
94
+ dummy_client.post(:payload => expected_payload)
95
95
  end
96
96
 
97
97
  it "includes the correct length" do
98
- expected_length = expected_payload.length
98
+ expected_length = expected_payload.to_json.length
99
99
  RestClient::Request.should_receive(:execute).with(hash_including({:headers => {"Content-Length" => expected_length}}))
100
- dummy_client.post expected_payload
100
+ dummy_client.post(:payload => expected_payload)
101
101
  end
102
102
 
103
103
  it "includes the authentication parameters" do
104
104
  RestClient::Request.should_receive(:execute).with(hash_including(mock_auth))
105
- dummy_client.post expected_payload
105
+ dummy_client.post(:payload => expected_payload)
106
+ end
107
+
108
+ it "allows for base resource additions" do
109
+ expected_url = "#{SauceWhisk.base_url}/#{dummy_client.resource}/dummy_res"
110
+ RestClient::Request.should_receive(:execute).with(hash_including({:payload => expected_payload.to_json, :url => expected_url}))
111
+
112
+ dummy_client.post(:payload => expected_payload, :resource =>"dummy_res")
106
113
  end
107
114
  end
108
115
  end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe "a subaccount" do
4
+ let(:parent) {SauceWhisk::Account.new(:id => ENV["SAUCE_USERNAME"], :access_key => "12345", :minutes=>12)}
5
+ let(:params) {{:access_key => 12345, :minutes => 23, :id => "someone"}}
6
+
7
+ it "is an Account object" do
8
+ sub = SauceWhisk::SubAccount.new(parent, params)
9
+ sub.should be_a_kind_of SauceWhisk::Account
10
+ end
11
+
12
+ it "takes a parent as a parameter" do
13
+ sub = SauceWhisk::SubAccount.new(parent, params)
14
+ sub.parent.should be parent
15
+ end
16
+ end
@@ -41,6 +41,11 @@ describe SauceWhisk::Tunnels, :vcr => {:cassette_name => "tunnels"} do
41
41
  it "returns instances of Tunnel" do
42
42
  tunnel = SauceWhisk::Tunnels.fetch job_id
43
43
  tunnel.should be_an_instance_of SauceWhisk::Tunnel
44
+ STDERR.puts "Tunnel port #{tunnel.ssh_port} #{tunnel.ssh_port.class}"
45
+ end
46
+
47
+ it "raises an exception with called without an id" do
48
+ expect {SauceWhisk::Tunnels.fetch(nil)}.to raise_exception ArgumentError
44
49
  end
45
50
  end
46
51
 
@@ -53,11 +58,33 @@ describe SauceWhisk::Tunnels, :vcr => {:cassette_name => "tunnels"} do
53
58
  end
54
59
 
55
60
  describe "##open" do
61
+ let(:params) {{:tunnel_identifier => "bees", :ssh_port => 9123, :use_caching_proxy => false, :use_kgp => true}}
56
62
  it "calls the correct API method" do
57
- params = {:tunnel_identifier => "bees", :ssh_port => 9123, :use_caching_proxy => false, :use_kgp => true}
58
-
59
63
  SauceWhisk::Tunnels.open params
60
64
  assert_requested(:post, "https://#{auth}@saucelabs.com/rest/v1/dylanatsauce/tunnels",:body => params.to_json)
61
65
  end
66
+
67
+ it "returns an instance of tunnel" do
68
+ tunnel = SauceWhisk::Tunnels.open params
69
+ tunnel.should be_an_instance_of SauceWhisk::Tunnel
70
+
71
+ # These aren't magic, they're taken from the tunnels fixture. <3 VCR.
72
+ tunnel.id.should eq "4824d6b282e04d1184daff5401a52e1e"
73
+ tunnel.ssh_port.should eq 9123
74
+ end
75
+
76
+ context "When asked to wait until running", :vcr => {:cassette_name => 'tunnels_with_wait'} do
77
+ it "calls fetch on the opened tunnel until the status is running" do
78
+ requested_tunnel = SauceWhisk::Tunnels.open params
79
+ t_id = requested_tunnel.id
80
+
81
+ # There are 3 failing and 1 passing examples in the fixture
82
+ assert_requested :get, "https://#{auth}@saucelabs.com/rest/v1/dylanatsauce/tunnels/#{t_id}", :times => 4
83
+ end
84
+
85
+ it "throws an exception if the timeout is exceeded" do
86
+ requested_tunnel = SauceWhisk::Tunnels.open params
87
+ end
88
+ end
62
89
  end
63
- end
90
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sauce_whisk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Lacey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-31 00:00:00.000000000 Z
11
+ date: 2013-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -113,6 +113,7 @@ files:
113
113
  - spec/fixtures/vcr_cassettes/no_tunnels.yml
114
114
  - spec/fixtures/vcr_cassettes/rest_request.yml
115
115
  - spec/fixtures/vcr_cassettes/tunnels.yml
116
+ - spec/fixtures/vcr_cassettes/tunnels_with_wait.yml
116
117
  - spec/lib/sauce_whisk/account_spec.rb
117
118
  - spec/lib/sauce_whisk/accounts_spec.rb
118
119
  - spec/lib/sauce_whisk/asset_spec.rb
@@ -122,6 +123,7 @@ files:
122
123
  - spec/lib/sauce_whisk/jobs_spec.rb
123
124
  - spec/lib/sauce_whisk/rest_request_builder_spec.rb
124
125
  - spec/lib/sauce_whisk/sauce_whisk_spec.rb
126
+ - spec/lib/sauce_whisk/subaccounts_spec.rb
125
127
  - spec/lib/sauce_whisk/tunnel_spec.rb
126
128
  - spec/lib/sauce_whisk/tunnels_spec.rb
127
129
  - spec/spec_helper.rb
@@ -205,6 +207,7 @@ test_files:
205
207
  - spec/fixtures/vcr_cassettes/no_tunnels.yml
206
208
  - spec/fixtures/vcr_cassettes/rest_request.yml
207
209
  - spec/fixtures/vcr_cassettes/tunnels.yml
210
+ - spec/fixtures/vcr_cassettes/tunnels_with_wait.yml
208
211
  - spec/lib/sauce_whisk/account_spec.rb
209
212
  - spec/lib/sauce_whisk/accounts_spec.rb
210
213
  - spec/lib/sauce_whisk/asset_spec.rb
@@ -214,6 +217,7 @@ test_files:
214
217
  - spec/lib/sauce_whisk/jobs_spec.rb
215
218
  - spec/lib/sauce_whisk/rest_request_builder_spec.rb
216
219
  - spec/lib/sauce_whisk/sauce_whisk_spec.rb
220
+ - spec/lib/sauce_whisk/subaccounts_spec.rb
217
221
  - spec/lib/sauce_whisk/tunnel_spec.rb
218
222
  - spec/lib/sauce_whisk/tunnels_spec.rb
219
223
  - spec/spec_helper.rb