netflix 0.1.1 → 0.2.0

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.
@@ -0,0 +1 @@
1
+ pkg/
data/Rakefile CHANGED
@@ -1,17 +1,39 @@
1
1
  require 'rake/testtask'
2
2
  require 'rubygems/package_task'
3
3
 
4
- Rake::TestTask.new("test") { |t|
4
+ Rake::TestTask.new("test:unit") { |t|
5
5
  t.libs << 'test'
6
- t.test_files = Dir.glob( "test/**/*_test.rb" ).sort
6
+ t.test_files = Dir.glob( "test/*_test.rb" ).sort
7
7
 
8
8
  t.verbose = true
9
9
  t.warning = true
10
10
  }
11
+ require File.join(File.dirname(__FILE__), 'test/integration/rake_test_helper')
12
+
13
+ file "test/integration/oauth_settings.yml" do |t|
14
+ credentials = IntegrationTestHelper.obtain_credentials
15
+ open("test/integration/oauth_settings.yml", 'wb') do |f|
16
+ YAML.dump(credentials, f)
17
+ end
18
+ end
19
+
20
+ Rake::TestTask.new("test:integration") { |t|
21
+ #t.description = "Run integration tests against a REAL netflix account you supply"
22
+ t.libs << 'test'
23
+ t.test_files = Dir.glob( "test/integration/**/*_test.rb" ).sort
24
+
25
+ t.verbose = true
26
+ t.warning = true
27
+ }
28
+
29
+ task "test:integration" => "test/integration/oauth_settings.yml"
30
+
31
+ desc "run unit tests only"
32
+ task :test => "test:unit"
11
33
 
12
34
  gem_spec = Gem::Specification.new do |s|
13
35
  s.name = "netflix"
14
- s.version = "0.1.1"
36
+ s.version = "0.2.0"
15
37
  s.authors = ["Dean Holdren"]
16
38
  s.date = %q{2012-01-09}
17
39
  s.description = "Ruby Netflix API wrapper"
@@ -1,4 +1,6 @@
1
- require 'netflix/json_resource'
1
+ #require 'netflix/json_resource'
2
+ require 'netflix/errors'
3
+ require 'netflix/response'
2
4
  require 'netflix/client'
3
5
  require 'netflix/user'
4
6
  require 'netflix/queue'
@@ -16,6 +16,8 @@ module Netflix
16
16
  :authorize_url => "https://api-user.netflix.com/oauth/login")
17
17
  if user_access_token && user_access_secret
18
18
  @oauth_access_token = oauth_access_token(user_access_token, user_access_secret)
19
+ #automatically determine if error should be thrown based on response codes
20
+ @oauth_access_token.extend(ResponseErrorDecorator)
19
21
  elsif !!user_access_token ^ !!user_access_secret
20
22
  raise ArgumentError 'Must specify both user_access_token and user_access_secret if specifying either'
21
23
  end
@@ -36,6 +38,8 @@ module Netflix
36
38
  authorize_url = request_token.authorize_url(:oauth_consumer_key =>
37
39
  Netflix::Client.consumer_key)
38
40
  Launchy.open(authorize_url)
41
+ puts "Go to browser, a page has been opened to establish oauth"
42
+ printf "Pin from Netflix:"
39
43
  pin = gets.chomp
40
44
  access_token = request_token.get_access_token(:oauth_verifier => pin)
41
45
  end
@@ -0,0 +1,44 @@
1
+ require 'json'
2
+
3
+ module Netflix
4
+ module Error
5
+ class ResponseError < StandardError
6
+ def initialize(body, headers)
7
+ @body = body
8
+ @headers = headers
9
+ body_obj = JSON.parse(body)
10
+ message = body_obj["status"]["message"]
11
+ super(message)
12
+ end
13
+ end
14
+ #4xx level errors
15
+ class ClientError < ResponseError
16
+ end
17
+ #5xx level errors
18
+ class ServerError < ResponseError
19
+ end
20
+ #400
21
+ class BadRequest < ClientError
22
+ end
23
+ #403
24
+ class Forbidden < ClientError
25
+ end
26
+ #404
27
+ class NotFound < ClientError
28
+ end
29
+ #401
30
+ class Unauthorized < ClientError
31
+ end
32
+ #420 (?)
33
+ class RateLimit < ClientError
34
+ end
35
+
36
+ CODEMAP = {400 => BadRequest, 403 => Forbidden, 404 => NotFound, 401 => Unauthorized, 420 => RateLimit}
37
+ def self.for(response)
38
+ #codemap = {400 => BadRequest, 403 => Forbidden, 404 => NotFound, 401 => Unauthorized, 420 => RateLimit}
39
+ code = response.code.to_i
40
+ (CODEMAP[code] || ResponseError).new(response.body, response.header)
41
+ #codemap[code].new(response.body, response.header)
42
+ end
43
+ end
44
+ end
@@ -22,20 +22,29 @@ module Netflix
22
22
 
23
23
  def add(title_ref, position=nil)
24
24
  response = @oauth_access_token.post "/users/#{@user_id}/queues/#{@type}?output=json", {:etag => etag, :title_ref => title_ref, :position=> position}
25
- if response && response.code_type == Net::HTTPOK
26
- #TODO refresh
27
- else
28
- raise "Error adding title #{title_ref} to user #{@user_id}"
29
- end
25
+ #@map = retrieve
26
+ #netflix is wacky. GET after an add can be STALE. ughg
27
+ #so recreate the contents programattically instead
28
+ response_obj = JSON.parse(response.body)
29
+ new_queue_item = response_obj["status"]["resources_created"]["queue_item"]
30
+ new_etag = response_obj["status"]["etag"]
31
+ repopulate(new_queue_item, new_etag)
32
+ self
30
33
  end
31
34
 
32
35
  def remove(position)
33
- response = @oauth_access_token.delete "/users/#{@user_id}/queues/#{@type}/available/#{position}?output=json" #, {:etag => etag})
34
- if response && response.code_type == Net::HTTPOK
35
- #TODO refresh
36
- else
37
- raise "Error removing title #{title_ref} to user #{@user_id}"
38
- end
36
+ id = discs[position-1].id
37
+ #response = @oauth_access_token.delete "/users/#{@user_id}/queues/#{@type}/available/#{position}?output=json" , {'etag' => etag}
38
+ response = @oauth_access_token.delete "#{id}?output=json"
39
+ @map = retrieve
40
+ self
41
+ end
42
+
43
+ def remove_by_title_ref(title_ref)
44
+ disc = discs.find {|disc| disc =~ /\/#{title_ref}\//}
45
+ response = @oauth_access_token.delete "#{disc.id}?output=json"
46
+ @map = retrieve
47
+ self
39
48
  end
40
49
 
41
50
  def discs
@@ -47,13 +56,35 @@ module Netflix
47
56
  end
48
57
  end
49
58
 
59
+ def refresh
60
+ @map = retrieve(etag)
61
+ self
62
+ end
63
+
50
64
  private
51
- def retrieve
52
- response = @oauth_access_token.get "/users/#{@user_id}/queues/#{@type}?max_results=#{MAX_RESULTS}&output=json"
53
- if response && response.body && response.code_type == Net::HTTPOK
54
- JSON.parse(response.body)["queue"]
65
+ def retrieve(etag = nil)
66
+ url = "/users/#{@user_id}/queues/#{@type}/available?max_results=#{MAX_RESULTS}&output=json"
67
+ if (etag)
68
+ response = @oauth_access_token.get(url, { 'etag' => etag.to_s })
69
+ else
70
+ response = @oauth_access_token.get(url)
71
+ end
72
+ JSON.parse(response.body)["queue"]
73
+ end
74
+
75
+ def repopulate(new_queue_item, new_etag)
76
+ @map["etag"] = new_etag
77
+ new_queue_item_index = new_queue_item["position"].to_i
78
+ if @map["queue_item"] #single or array
79
+ @map["queue_item"] = [@map["queue_item"]].flatten
80
+ @map["queue_item"].insert((new_queue_item_index - 1), new_queue_item)
81
+ @map["queue_item"][new_queue_item_index..-1].each {|queue_item|
82
+ new_position = (queue_item["position"].to_i + 1).to_s
83
+ queue_item["position"] = new_position
84
+ queue_item["id"] = queue_item["id"].gsub(/\/(\d+)\/(\d+)/,"/#{new_position}/\\2")
85
+ }
55
86
  else
56
- raise "Error retrieving queue for user #{@user_id}"
87
+ @map["queue_item"] = [new_queue_item]
57
88
  end
58
89
  end
59
90
 
@@ -0,0 +1,29 @@
1
+ module Netflix
2
+ module ResponseErrorDecorator
3
+ def get(*args)
4
+ response = super(*args)
5
+ response_or_raise_error(response)
6
+ end
7
+ def delete(*args)
8
+ response = super(*args)
9
+ response_or_raise_error(response)
10
+ end
11
+ def post(*args)
12
+ response = super(*args)
13
+ response_or_raise_error(response)
14
+ end
15
+ def put(*args)
16
+ response = super(*args)
17
+ response_or_raise_error(response)
18
+ end
19
+
20
+ private
21
+ def response_or_raise_error(response)
22
+ if response && response.is_a?(Net::HTTPSuccess)
23
+ response
24
+ else
25
+ raise Error.for(response)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -17,11 +17,7 @@ module Netflix
17
17
  private
18
18
  def retrieve
19
19
  response = @oauth_access_token.get "/users/#{@user_id}?output=json"
20
- if response && response.body && response.code_type == Net::HTTPOK
21
- JSON.parse(response.body)["user"]
22
- else
23
- raise "Error retrieving user #{@user_id}"
24
- end
20
+ JSON.parse(response.body)["user"]
25
21
  end
26
22
 
27
23
  end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class ErrorTest < Test::Unit::TestCase
4
+ def setup
5
+ stub_netflix_for_user('nuid_one')
6
+ end
7
+
8
+ def test_handle_404_on_delete
9
+ #add to disc queue
10
+ FakeWeb.register_uri(:delete, %r|http://api\.netflix\.com/users/nuid_one/queues/disc/available|,
11
+ :body => '{"status": {
12
+ "message": "Title is not in Queue",
13
+ "status_code": 404,
14
+ "sub_code": 610
15
+ }}',
16
+ :status => ['404', 'Not Found'])
17
+
18
+ user = Netflix::Client.new('nuid_access_key', 'nuid_access_secret').user('nuid_one')
19
+ available_disc_queue = user.available_disc_queue
20
+ assert available_disc_queue
21
+ assert_raises(Netflix::Error::NotFound) do
22
+ available_disc_queue.remove(2)
23
+ end
24
+
25
+ end
26
+ end
27
+
@@ -324,7 +324,129 @@ nuid_one:
324
324
  ]
325
325
  }}
326
326
  post:
327
- body:
327
+ body: |
328
+ {"status": {
329
+ "resources_created": {"queue_item": {
330
+ "average_rating": "3.7",
331
+ "box_art": {
332
+ "large": "http://cdn-3.nflximg.com/us/boxshots/large/70071613.jpg",
333
+ "small": "http://cdn-3.nflximg.com/us/boxshots/tiny/70071613.jpg",
334
+ "medium": "http://cdn-3.nflximg.com/us/boxshots/small/70071613.jpg"
335
+ },
336
+ "category": [
337
+ {
338
+ "term": "available now",
339
+ "content": "Available Now",
340
+ "scheme": "http://api.netflix.com/categories/queue_availability",
341
+ "label": "available now"
342
+ },
343
+ {
344
+ "term": "Blu-ray",
345
+ "scheme": "http://api.netflix.com/categories/title_formats",
346
+ "label": "Blu-ray"
347
+ },
348
+ {
349
+ "term": "R",
350
+ "scheme": "http://api.netflix.com/categories/mpaa_ratings",
351
+ "label": "R"
352
+ },
353
+ {
354
+ "term": "Thrillers",
355
+ "scheme": "http://api.netflix.com/categories/genres",
356
+ "label": "Thrillers"
357
+ },
358
+ {
359
+ "term": "Crime Thrillers",
360
+ "scheme": "http://api.netflix.com/categories/genres",
361
+ "label": "Crime Thrillers"
362
+ },
363
+ {
364
+ "term": "Suspense",
365
+ "scheme": "http://api.netflix.com/categories/genres",
366
+ "label": "Suspense"
367
+ },
368
+ {
369
+ "term": "Dramas Based on Contemporary Literature",
370
+ "scheme": "http://api.netflix.com/categories/genres",
371
+ "label": "Dramas Based on Contemporary Literature"
372
+ },
373
+ {
374
+ "term": "Dramas Based on the Book",
375
+ "scheme": "http://api.netflix.com/categories/genres",
376
+ "label": "Dramas Based on the Book"
377
+ }
378
+ ],
379
+ "updated": "1276960028",
380
+ "id": "http://api.netflix.com/users/nuid_one/queues/disc/available/4/70071613",
381
+ "link": [
382
+ {
383
+ "href": "http://api.netflix.com/users/nuid_one/queues/disc/available",
384
+ "rel": "http://schemas.netflix.com/queues.available",
385
+ "title": "available queue"
386
+ },
387
+ {
388
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613",
389
+ "rel": "http://schemas.netflix.com/catalog/title",
390
+ "title": "No Country for Old Men"
391
+ },
392
+ {
393
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/synopsis",
394
+ "rel": "http://schemas.netflix.com/catalog/titles/synopsis",
395
+ "title": "synopsis"
396
+ },
397
+ {
398
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/cast",
399
+ "rel": "http://schemas.netflix.com/catalog/people.cast",
400
+ "title": "cast"
401
+ },
402
+ {
403
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/directors",
404
+ "rel": "http://schemas.netflix.com/catalog/people.directors",
405
+ "title": "directors"
406
+ },
407
+ {
408
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/format_availability",
409
+ "rel": "http://schemas.netflix.com/catalog/titles/format_availability",
410
+ "title": "formats"
411
+ },
412
+ {
413
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/awards",
414
+ "rel": "http://schemas.netflix.com/catalog/titles/awards",
415
+ "title": "awards"
416
+ },
417
+ {
418
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/screen_formats",
419
+ "rel": "http://schemas.netflix.com/catalog/titles/screen_formats",
420
+ "title": "screen formats"
421
+ },
422
+ {
423
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/languages_and_audio",
424
+ "rel": "http://schemas.netflix.com/catalog/titles/languages_and_audio",
425
+ "title": "languages and audio"
426
+ },
427
+ {
428
+ "href": "http://api.netflix.com/catalog/titles/movies/70071613/similars",
429
+ "rel": "http://schemas.netflix.com/catalog/titles.similars",
430
+ "title": "similars"
431
+ },
432
+ {
433
+ "href": "http://www.netflix.com/Movie/No_Country_for_Old_Men/70071613",
434
+ "rel": "alternate",
435
+ "title": "web page"
436
+ }
437
+ ],
438
+ "position": "4",
439
+ "runtime": "7320",
440
+ "title": {
441
+ "regular": "No Country for Old Men",
442
+ "short": "No Country for Old Men"
443
+ },
444
+ "release_year": "2007"
445
+ }},
446
+ "status_code": "201",
447
+ "message": "Move successful",
448
+ "etag": "82198468425"
449
+ }}
328
450
  delete:
329
451
  body: |
330
452
  {"status": {
@@ -1192,6 +1314,108 @@ empty_queue:
1192
1314
  "number_of_results": "0"
1193
1315
  }}
1194
1316
  post:
1195
- body:
1317
+ body: |
1318
+ {"status": {
1319
+ "resources_created": {"queue_item": {
1320
+ "average_rating": "3.4",
1321
+ "box_art": {
1322
+ "large": "http://cdn-2.nflximg.com/us/boxshots/large/70167072.jpg",
1323
+ "small": "http://cdn-2.nflximg.com/us/boxshots/tiny/70167072.jpg",
1324
+ "medium": "http://cdn-2.nflximg.com/us/boxshots/small/70167072.jpg"
1325
+ },
1326
+ "category": [
1327
+ {
1328
+ "term": "available now",
1329
+ "content": "Available Now",
1330
+ "scheme": "http://api.netflix.com/categories/queue_availability",
1331
+ "label": "available now"
1332
+ },
1333
+ {
1334
+ "term": "Blu-ray",
1335
+ "scheme": "http://api.netflix.com/categories/title_formats",
1336
+ "label": "Blu-ray"
1337
+ },
1338
+ {
1339
+ "term": "PG-13",
1340
+ "scheme": "http://api.netflix.com/categories/mpaa_ratings",
1341
+ "label": "PG-13"
1342
+ },
1343
+ {
1344
+ "term": "Comedy",
1345
+ "scheme": "http://api.netflix.com/categories/genres",
1346
+ "label": "Comedy"
1347
+ },
1348
+ {
1349
+ "term": "Romantic Comedies",
1350
+ "scheme": "http://api.netflix.com/categories/genres",
1351
+ "label": "Romantic Comedies"
1352
+ }
1353
+ ],
1354
+ "updated": "1323539988",
1355
+ "id": "http://api.netflix.com/users/empty_queue/queues/disc/available/1/70167072",
1356
+ "link": [
1357
+ {
1358
+ "href": "http://api.netflix.com/users/empty_queue/queues/disc/available",
1359
+ "rel": "http://schemas.netflix.com/queues.available",
1360
+ "title": "available queue"
1361
+ },
1362
+ {
1363
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072",
1364
+ "rel": "http://schemas.netflix.com/catalog/title",
1365
+ "title": "Arthur"
1366
+ },
1367
+ {
1368
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/synopsis",
1369
+ "rel": "http://schemas.netflix.com/catalog/titles/synopsis",
1370
+ "title": "synopsis"
1371
+ },
1372
+ {
1373
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/cast",
1374
+ "rel": "http://schemas.netflix.com/catalog/people.cast",
1375
+ "title": "cast"
1376
+ },
1377
+ {
1378
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/directors",
1379
+ "rel": "http://schemas.netflix.com/catalog/people.directors",
1380
+ "title": "directors"
1381
+ },
1382
+ {
1383
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/format_availability",
1384
+ "rel": "http://schemas.netflix.com/catalog/titles/format_availability",
1385
+ "title": "formats"
1386
+ },
1387
+ {
1388
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/screen_formats",
1389
+ "rel": "http://schemas.netflix.com/catalog/titles/screen_formats",
1390
+ "title": "screen formats"
1391
+ },
1392
+ {
1393
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/languages_and_audio",
1394
+ "rel": "http://schemas.netflix.com/catalog/titles/languages_and_audio",
1395
+ "title": "languages and audio"
1396
+ },
1397
+ {
1398
+ "href": "http://api.netflix.com/catalog/titles/movies/70167072/similars",
1399
+ "rel": "http://schemas.netflix.com/catalog/titles.similars",
1400
+ "title": "similars"
1401
+ },
1402
+ {
1403
+ "href": "http://www.netflix.com/Movie/Arthur/70167072",
1404
+ "rel": "alternate",
1405
+ "title": "web page"
1406
+ }
1407
+ ],
1408
+ "position": "1",
1409
+ "runtime": "6600",
1410
+ "title": {
1411
+ "regular": "Arthur",
1412
+ "short": "Arthur"
1413
+ },
1414
+ "release_year": "2011"
1415
+ }},
1416
+ "status_code": "201",
1417
+ "message": "Move successful",
1418
+ "etag": "82198468425"
1419
+ }}
1196
1420
  delete:
1197
1421
  body:
@@ -0,0 +1 @@
1
+ oauth_settings.yml
@@ -0,0 +1,72 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib"))
2
+
3
+ require 'test/unit'
4
+ require 'yaml'
5
+ require 'netflix'
6
+
7
+ class QueueTest < Test::Unit::TestCase
8
+ def setup
9
+ @oauth_settings = YAML.load_file(File.join(File.dirname(__FILE__),"oauth_settings.yml"))
10
+ #puts @oauth_settings
11
+ Netflix::Client.consumer_key = @oauth_settings[:consumer_key]
12
+ Netflix::Client.consumer_secret = @oauth_settings[:consumer_secret]
13
+ @client = Netflix::Client.new(@oauth_settings[:user][:access_token], @oauth_settings[:user][:access_secret])
14
+
15
+ #Do direct oauth gem retrieval of queue and deletion of all queue entries to get a clean start
16
+ oauth_access_token = @client.instance_variable_get(:@oauth_access_token)
17
+ #user_response = oauth_access_token.get "/users/current?output=json"
18
+ #puts "current_user: #{JSON.parse(user_response.body)}"
19
+ queue_response = oauth_access_token.get "/users/#{@oauth_settings[:user][:user_id]}/queues/disc/available?output=json"
20
+ queue_response_json = queue_response.body
21
+ queue_response_obj = JSON.parse(queue_response_json)
22
+ puts "get queue response: #{queue_response_obj}"
23
+ queue = queue_response_obj["queue"]
24
+ queue_items = queue && queue["queue_item"] && [queue["queue_item"]].flatten
25
+ if queue_items
26
+ queue_item_urls = queue_items.map() {|queue_item| queue_item["id"]}
27
+ queue_item_urls.reverse.each {|queue_item_url|
28
+ sleep 0.25 # for netflix api queries per second limit
29
+ response = oauth_access_token.delete queue_item_url
30
+ puts "delete response= #{response.body}"
31
+ }
32
+ end
33
+ sleep 0.25 # for netflix api queries per second limit
34
+ @user = @client.user(@oauth_settings[:user][:user_id])
35
+ end
36
+
37
+ def test_get_available_disc_queue
38
+ available_disc_queue = @user.available_disc_queue
39
+ assert available_disc_queue, "Expecting user to have a disc_queue"
40
+ end
41
+
42
+ def test_get_discs_add_and_remove
43
+ sleep 0.25 # for netflix api queries per second limit
44
+ queue = @user.available_disc_queue
45
+ assert queue, "Expecting queue"
46
+ assert_equal 0, queue.etag, "Initial etag should be 0 when no discs"
47
+ discs = queue.discs
48
+ assert discs, "Expecting the queue to respond to #discs"
49
+ assert_equal 0, discs.size, "Expecting the discs list to have size 0 at start"
50
+
51
+ sleep 0.25 # for netflix api queries per second limit
52
+ queue.add("http://api.netflix.com/catalog/titles/movies/70167072")
53
+ queue_after_add = @user.available_disc_queue
54
+ assert_not_equal 0, queue.etag, "Etag should not be 0 after a disc is added"
55
+ discs = queue_after_add.discs
56
+ assert discs, "Expecting the queue to respond to #discs"
57
+ assert_equal 1, discs.size, "Expecting the discs list to have size 1 after add"
58
+
59
+ disc_one = discs[0]
60
+ assert_equal "http://api.netflix.com/users/#{@oauth_settings[:user][:user_id]}/queues/disc/available/1/70167072", disc_one.id
61
+ assert_equal "Arthur", disc_one.title
62
+
63
+ sleep 0.25 # for netflix api queries per second limit
64
+ queue.remove(1)
65
+ sleep 0.25 # for netflix api queries per second limit
66
+ queue_after_remove = @user.available_disc_queue
67
+ discs = queue_after_remove.discs
68
+ assert discs, "Expecting the queue to respond to #discs"
69
+ assert_equal 0, discs.size, "Expecting the discs list to have size 0 after remove"
70
+
71
+ end
72
+ end
@@ -0,0 +1,42 @@
1
+ require 'oauth'
2
+ require 'launchy'
3
+
4
+ class IntegrationTestHelper
5
+ def self.obtain_credentials
6
+ puts "Enter Consumer Key/Secret info before running integration tests, you should have registered with http://developer.netflix.com"
7
+ printf "Consumer Key:"
8
+ consumer_key = STDIN.gets.chomp
9
+ printf "Consumer Secret:"
10
+ consumer_secret = STDIN. gets.chomp
11
+ printf "Do you have an access token/secret? ([Y]/n)"
12
+ answer = STDIN.gets.chomp
13
+ if ["N","n","No","no"].include?(answer)
14
+ puts "Launching netflix oauth page, login to TEST account and allow this application"
15
+ oauth_consumer = OAuth::Consumer.new(consumer_key, consumer_secret,
16
+ :site => "http://api.netflix.com",
17
+ :request_token_url => "http://api.netflix.com/oauth/request_token",
18
+ :access_token_url => "http://api.netflix.com/oauth/access_token",
19
+ :authorize_url => "https://api-user.netflix.com/oauth/login")
20
+ request_token = oauth_consumer.get_request_token
21
+ authorize_url = request_token.authorize_url(:oauth_consumer_key => consumer_key)
22
+ Launchy.open(authorize_url)
23
+ puts "Go to browser, a page has been opened to establish oauth"
24
+ printf "Pin from Netflix:"
25
+ pin = STDIN.gets.chomp
26
+ access_token_response = request_token.get_access_token(:oauth_verifier => pin)
27
+ access_token = access_token_response.token
28
+ access_secret = access_token_response.secret
29
+ user_id = access_token_response.params["user_id"]
30
+ else
31
+ printf "Access Token:"
32
+ access_token = STDIN.gets.chomp
33
+ printf "Access Secret:"
34
+ access_secret = STDIN.gets.chomp
35
+ printf "User id:"
36
+ user_id = STDIN.gets.chomp
37
+ end
38
+
39
+ {:consumer_key => consumer_key, :consumer_secret => consumer_secret, :user => {:access_token => access_token, :access_secret => access_secret, :user_id => user_id}}
40
+
41
+ end
42
+ end
@@ -3,6 +3,7 @@ require 'test_helper'
3
3
  class QueueTest < Test::Unit::TestCase
4
4
  def setup
5
5
  stub_netflix_for_user('nuid_one')
6
+ stub_netflix_for_user('nuid_sub1')
6
7
  Netflix::Client.consumer_key = 'foo_consumer_key'
7
8
  Netflix::Client.consumer_secret = 'foo_consumer_secret'
8
9
  end
@@ -25,18 +26,48 @@ class QueueTest < Test::Unit::TestCase
25
26
  assert_equal "Arthur", disc_one.title
26
27
  end
27
28
 
28
- def test_add_item_to_queue
29
+ def test_add_item_to_queue_end_the_default
29
30
  user = Netflix::Client.new('nuid_access_key', 'nuid_access_secret').user('nuid_one')
30
31
  available_disc_queue = user.available_disc_queue
31
32
  assert available_disc_queue
32
- available_disc_queue.add('70071613')
33
+ #pre tests
34
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/1/70167072", available_disc_queue.discs[0].id
35
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/2/70142826", available_disc_queue.discs[1].id
36
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/3/70108988", available_disc_queue.discs[2].id
37
+ assert_equal "115673854498", available_disc_queue.etag
38
+ #operation and tests
39
+ new_queue = available_disc_queue.add("http://api.netflix.com/catalog/titles/movies/70071613")
40
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/1/70167072", new_queue.discs[0].id
41
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/2/70142826", new_queue.discs[1].id
42
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/3/70108988", new_queue.discs[2].id
43
+ assert_equal "http://api.netflix.com/users/nuid_one/queues/disc/available/4/70071613", new_queue.discs[3].id
44
+ assert_equal "1", new_queue.discs[0].instance_variable_get(:@map)["position"]
45
+ assert_equal "2", new_queue.discs[1].instance_variable_get(:@map)["position"]
46
+ assert_equal "3", new_queue.discs[2].instance_variable_get(:@map)["position"]
47
+ assert_equal "4", new_queue.discs[3].instance_variable_get(:@map)["position"]
48
+ assert_equal "82198468425", new_queue.etag
33
49
  end
34
50
 
35
51
  def test_add_item_to_queue_top
36
- user = Netflix::Client.new('nuid_access_key', 'nuid_access_secret').user('nuid_one')
52
+ user = Netflix::Client.new('nuid_access_key', 'nuid_access_secret').user('nuid_sub1')
37
53
  available_disc_queue = user.available_disc_queue
38
54
  assert available_disc_queue
39
- available_disc_queue.add('70071613', 1)
55
+ #pre tests
56
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/1/70071613", available_disc_queue.discs[0].id
57
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/2/70117306", available_disc_queue.discs[1].id
58
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/3/70105135", available_disc_queue.discs[2].id
59
+ assert_equal "115673854498", available_disc_queue.etag
60
+ #operation and tests
61
+ new_queue = available_disc_queue.add("http://api.netflix.com/catalog/titles/movies/70167072", 1)
62
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/1/70167072", new_queue.discs[0].id
63
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/2/70071613", new_queue.discs[1].id
64
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/3/70117306", new_queue.discs[2].id
65
+ assert_equal "http://api.netflix.com/users/nuid_sub1/queues/disc/available/4/70105135", new_queue.discs[3].id
66
+ assert_equal "1", new_queue.discs[0].instance_variable_get(:@map)["position"]
67
+ assert_equal "2", new_queue.discs[1].instance_variable_get(:@map)["position"]
68
+ assert_equal "3", new_queue.discs[2].instance_variable_get(:@map)["position"]
69
+ assert_equal "4", new_queue.discs[3].instance_variable_get(:@map)["position"]
70
+ assert_equal "82198468425", new_queue.etag
40
71
  end
41
72
 
42
73
  def test_remove_item_from_queue_by_index
@@ -46,21 +77,6 @@ class QueueTest < Test::Unit::TestCase
46
77
  available_disc_queue.remove(2)
47
78
  end
48
79
 
49
- #def test_add_item_to_stale_queue_fails
50
- # user = Netflix::Client.new('nuid_access_key', 'nuid_access_secret').user('nuid_one')
51
- # available_disc_queue = user.available_disc_queue
52
- # assert available_disc_queue
53
- # available_disc_queue.add('70071613')
54
- # old_available_disc_queue = available_disc_queue
55
- #
56
- # available_disc_queue = user.available_disc_queue
57
- # available_disc_queue.add('70117306')
58
- #
59
- # assert_raises() {
60
- # old_available_disc_queue.add('70105135')
61
- # }
62
- #end
63
-
64
80
  def test_empty_queue
65
81
  stub_netflix_for_user('empty_queue')
66
82
  user = Netflix::Client.new('nuid_access_key', 'nuid_access_secret').user('empty_queue')
@@ -68,6 +84,7 @@ class QueueTest < Test::Unit::TestCase
68
84
  assert available_disc_queue, "Expected a disc_queue"
69
85
  assert available_disc_queue.discs, "Expected the disc_queue to have a discs attribute"
70
86
  assert_equal 0, available_disc_queue.discs.size, "Expected discs to be empty array #{available_disc_queue.discs[0]}}"
87
+ new_queue = available_disc_queue.add("http://api.netflix.com/catalog/titles/movies/70167072")
71
88
  end
72
89
 
73
90
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netflix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-09 00:00:00.000000000Z
12
+ date: 2012-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oauth
16
- requirement: &2165140260 !ruby/object:Gem::Requirement
16
+ requirement: &2155382740 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2165140260
24
+ version_requirements: *2155382740
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: json
27
- requirement: &2165139740 !ruby/object:Gem::Requirement
27
+ requirement: &2155382320 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2165139740
35
+ version_requirements: *2155382320
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: launchy
38
- requirement: &2165139320 !ruby/object:Gem::Requirement
38
+ requirement: &2155381900 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2165139320
46
+ version_requirements: *2155381900
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: fakeweb
49
- requirement: &2165138840 !ruby/object:Gem::Requirement
49
+ requirement: &2155381480 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2165138840
57
+ version_requirements: *2155381480
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: yaml
60
- requirement: &2165138360 !ruby/object:Gem::Requirement
60
+ requirement: &2155381060 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,24 +65,31 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2165138360
68
+ version_requirements: *2155381060
69
69
  description: Ruby Netflix API wrapper
70
70
  email: deanholdren@gmail.com
71
71
  executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
+ - .gitignore
75
76
  - LICENSE
76
77
  - README.rdoc
77
78
  - Rakefile
78
79
  - lib/netflix.rb
79
80
  - lib/netflix/client.rb
80
81
  - lib/netflix/disc.rb
82
+ - lib/netflix/errors.rb
81
83
  - lib/netflix/json_resource.rb
82
84
  - lib/netflix/queue.rb
85
+ - lib/netflix/response.rb
83
86
  - lib/netflix/user.rb
87
+ - test/error_test.rb
84
88
  - test/http_fixtures/netflix_queue_responses.yml
85
89
  - test/http_fixtures/netflix_user_responses.yml
90
+ - test/integration/.gitignore
91
+ - test/integration/queue_test.rb
92
+ - test/integration/rake_test_helper.rb
86
93
  - test/non_user_client.rb
87
94
  - test/queue_test.rb
88
95
  - test/test_helper.rb
@@ -107,13 +114,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
114
  version: '0'
108
115
  requirements: []
109
116
  rubyforge_project:
110
- rubygems_version: 1.8.10
117
+ rubygems_version: 1.8.15
111
118
  signing_key:
112
119
  specification_version: 3
113
120
  summary: Ruby Netflix API wrapper
114
121
  test_files:
122
+ - test/error_test.rb
115
123
  - test/http_fixtures/netflix_queue_responses.yml
116
124
  - test/http_fixtures/netflix_user_responses.yml
125
+ - test/integration/.gitignore
126
+ - test/integration/queue_test.rb
127
+ - test/integration/rake_test_helper.rb
117
128
  - test/non_user_client.rb
118
129
  - test/queue_test.rb
119
130
  - test/test_helper.rb