netflix 0.1.1 → 0.2.0

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