sauce_whisk 0.0.9 → 0.0.10

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