yt 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/HISTORY.md +3 -0
- data/README.md +5 -1
- data/TODO.md +0 -2
- data/bin/yt +2 -0
- data/lib/yt/actions/delete_all.rb +2 -2
- data/lib/yt/associations/authentications.rb +17 -2
- data/lib/yt/collections/base.rb +6 -0
- data/lib/yt/collections/statuses.rb +22 -0
- data/lib/yt/collections/subscriptions.rb +1 -1
- data/lib/yt/collections/videos.rb +6 -1
- data/lib/yt/models/account.rb +6 -12
- data/lib/yt/models/base.rb +28 -2
- data/lib/yt/models/channel.rb +37 -2
- data/lib/yt/models/playlist.rb +24 -0
- data/lib/yt/models/video.rb +19 -0
- data/lib/yt/version.rb +1 -1
- data/spec/associations/device_auth/account_spec.rb +31 -0
- data/spec/associations/device_auth/channel_spec.rb +114 -0
- data/spec/associations/device_auth/content_owner_spec.rb +8 -0
- data/spec/associations/device_auth/earnings_spec.rb +2 -0
- data/spec/associations/device_auth/playlist_spec.rb +136 -0
- data/spec/associations/device_auth/{ids_spec.rb → resource_spec.rb} +2 -2
- data/spec/associations/device_auth/video_spec.rb +42 -0
- data/spec/associations/no_auth/video_spec.rb +13 -0
- data/spec/associations/server_auth/channel_spec.rb +50 -0
- data/spec/associations/server_auth/playlist_spec.rb +36 -0
- data/spec/associations/server_auth/{ids_spec.rb → resource_spec.rb} +2 -2
- data/spec/associations/server_auth/video_spec.rb +22 -0
- data/spec/models/channel_spec.rb +7 -0
- metadata +25 -60
- data/lib/yt/associations.rb +0 -38
- data/lib/yt/associations/annotations.rb +0 -15
- data/lib/yt/associations/channels.rb +0 -20
- data/lib/yt/associations/details_sets.rb +0 -20
- data/lib/yt/associations/ids.rb +0 -20
- data/lib/yt/associations/partnered_channels.rb +0 -14
- data/lib/yt/associations/playlist_items.rb +0 -34
- data/lib/yt/associations/playlists.rb +0 -22
- data/lib/yt/associations/ratings.rb +0 -39
- data/lib/yt/associations/snippets.rb +0 -20
- data/lib/yt/associations/statuses.rb +0 -14
- data/lib/yt/associations/subscriptions.rb +0 -34
- data/lib/yt/associations/user_infos.rb +0 -21
- data/lib/yt/associations/videos.rb +0 -14
- data/spec/associations/device_auth/channels_spec.rb +0 -8
- data/spec/associations/device_auth/details_sets_spec.rb +0 -18
- data/spec/associations/device_auth/partnered_channels_spec.rb +0 -15
- data/spec/associations/device_auth/playlist_items_spec.rb +0 -79
- data/spec/associations/device_auth/playlists_spec.rb +0 -61
- data/spec/associations/device_auth/ratings_spec.rb +0 -28
- data/spec/associations/device_auth/snippets_spec.rb +0 -28
- data/spec/associations/device_auth/subscriptions_spec.rb +0 -35
- data/spec/associations/device_auth/user_infos_spec.rb +0 -12
- data/spec/associations/device_auth/videos_spec.rb +0 -20
- data/spec/associations/no_auth/annotations_spec.rb +0 -15
- data/spec/associations/server_auth/channels_spec.rb +0 -2
- data/spec/associations/server_auth/details_sets_spec.rb +0 -18
- data/spec/associations/server_auth/playlist_items_spec.rb +0 -17
- data/spec/associations/server_auth/playlists_spec.rb +0 -17
- data/spec/associations/server_auth/ratings_spec.rb +0 -2
- data/spec/associations/server_auth/snippets_spec.rb +0 -28
- data/spec/associations/server_auth/subscriptions_spec.rb +0 -2
- data/spec/associations/server_auth/user_infos_spec.rb +0 -2
- data/spec/associations/server_auth/videos_spec.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4e025834f30276ff685e3ff61e3bd1330fc42b4
|
4
|
+
data.tar.gz: 725a5254897a04ff2ff0694125b58101dd6689aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 582c36cde9977d2d0b7585fea15950ee1f09292ed373e39a9b99f53ae8ce32a8bdb198106d8afe00d78c60f28890eab1d9ec81f2ba5d6e9495fbc9f60c35943d
|
7
|
+
data.tar.gz: 3e9bb4cda3a7fec3d604c92d3c8d609b7463a20a8e833cb01ff8b8c09e40b0bf05e106d35bfc68d76a7655e6b3095e09e650244c1293555e45ae54de2175deba
|
data/.travis.yml
CHANGED
@@ -22,3 +22,4 @@ env:
|
|
22
22
|
- secure: Ejj8tsuwyrRVmCc/R9ubKWCHWhCGpe0Dy6fc1UuPCkcMZyXq9ZC02v2obWsTQQ7epEgsCYZAO4v/gWpuv1b1huGcWdfJzMW7RCoY87cEf9HnAK0lSwGx4+/pYkEMe8y5p149C3vAR8nqczvEavN1fUq/WwPUqp+JyDP7kwFTs2Y=
|
23
23
|
- secure: gE5kAT1R54hmS+W3YYGcUtlD8ZskvTctVR3sr+C5CUjVPdq6Ktx5Q/a6EJyAVVrhxpaCOuk3LG+VkzdQIVFUNRiDPcOulkond4HkSQDoy+IJ/wTXvUS+lIJ1ERUnWega+APrQUjH5s2WayPGZUBqWt/u8Tt9EmSUZfuKZSEXqZk=
|
24
24
|
- secure: ZUx5v/wHW/TENg8NfFINiiMoe2D031ntDTiuIBdf88c/bMClkEtRRgomtK9RBkFonEyGEOkXxUm2SLzRf340V3eIXWQhil7ab1lcYs8X59aVS/NK/GqChH8Nia17gc3OTQ9k6rYvj4Lp60Dh9WG1cijLPd4/OvPmf6qX9uYfJMw=
|
25
|
+
- secure: DumQVO01Y3Ki1skuOYOZzosDb6jS0XyG1O8Agy3mVxXGJzQE+s1z2UFz4gMpsU9o/gmiNMddp7I6+RtbZjo9hN3H7vlRRwEeB7tuUMiDyomSx1FlHcCFfPdTmhxGg8X78SErMWqNC6eReGrCTgBdIq1ho7dIu53qJNxTEFqx7eI=
|
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
@@ -2,6 +2,9 @@ v0.6 - 2014/06/05
|
|
2
2
|
-----------------
|
3
3
|
|
4
4
|
* [breaking change] Rename Channel#earning to Channel#earnings_on
|
5
|
+
* [breaking change] Account#videos shows *all* videos owned by account (public and private)
|
6
|
+
* Add the .status association to *every* type of resource (Channel, Video, Playlist)
|
7
|
+
* Allow account.videos to be chained with .where, such as in account.videos.where(q: 'query')
|
5
8
|
|
6
9
|
v0.5 - 2014/05/16
|
7
10
|
-----------------
|
data/README.md
CHANGED
@@ -16,12 +16,14 @@ After [registering your app](#configuring-your-app), you can run commands like:
|
|
16
16
|
channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow'
|
17
17
|
channel.title #=> "Fullscreen"
|
18
18
|
channel.description #=> "The first media company for the connected generation."
|
19
|
+
channel.public? #=> true
|
19
20
|
channel.videos.count #=> 12
|
20
21
|
```
|
21
22
|
|
22
23
|
```ruby
|
23
24
|
video = Yt::Video.new id: 'MESycYJytkU'
|
24
25
|
video.title #=> "Fullscreen Creator Platform"
|
26
|
+
video.public? #=> true
|
25
27
|
video.duration #=> 86
|
26
28
|
video.annotations.count #=> 1
|
27
29
|
```
|
@@ -84,6 +86,7 @@ Use [Yt::Channel](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Chan
|
|
84
86
|
channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow'
|
85
87
|
channel.title #=> "Fullscreen"
|
86
88
|
channel.description.has_link_to_playlist? #=> false
|
89
|
+
channel.public? #=> true
|
87
90
|
|
88
91
|
channel.videos.count #=> 12
|
89
92
|
channel.videos.first #=> #<Yt::Video @id=...>
|
@@ -136,6 +139,7 @@ video = Yt::Video.new id: 'MESycYJytkU'
|
|
136
139
|
video.title #=> "Fullscreen Creator Platform"
|
137
140
|
video.duration #=> 63
|
138
141
|
video.description.has_link_to_subscribe? #=> false
|
142
|
+
video.public? #=> true
|
139
143
|
|
140
144
|
video.annotations.count #=> 1
|
141
145
|
video.annotations.first #=> #<Yt::Annotation @id=...>
|
@@ -326,7 +330,7 @@ To install on your system, run
|
|
326
330
|
|
327
331
|
To use inside a bundled Ruby project, add this line to the Gemfile:
|
328
332
|
|
329
|
-
gem 'yt', '~> 0.6.
|
333
|
+
gem 'yt', '~> 0.6.2'
|
330
334
|
|
331
335
|
Since the gem follows [Semantic Versioning](http://semver.org),
|
332
336
|
indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
|
data/TODO.md
CHANGED
@@ -8,8 +8,6 @@ seconds fixes it, so we should retry every 500 at least
|
|
8
8
|
* Google accounts?
|
9
9
|
* ENV support
|
10
10
|
|
11
|
-
* add has_one :status to video
|
12
|
-
|
13
11
|
* operations like subscribe that require authentication should not fail if
|
14
12
|
called on Yt::Channel without auth but, similarly to account, show the prompt
|
15
13
|
or ask for the device code
|
data/bin/yt
CHANGED
@@ -14,6 +14,7 @@ channel = Yt::Channel.new id: ARGV[0] || 'UCxO1tY8h1AhOz0T4ENwmpow'
|
|
14
14
|
puts "Title: #{channel.title}"
|
15
15
|
puts "Description: #{channel.description}"
|
16
16
|
puts "Thumbnail: #{channel.thumbnail_url}"
|
17
|
+
puts "Public? #{channel.public?}"
|
17
18
|
puts "Videos: "
|
18
19
|
channel.videos.each do |video|
|
19
20
|
puts " Annotations: #{video.annotations.count}"
|
@@ -21,4 +22,5 @@ channel.videos.each do |video|
|
|
21
22
|
puts " Title: #{video.title}"
|
22
23
|
puts " Description: #{video.description}"
|
23
24
|
puts " Thumbnail: #{video.thumbnail_url}"
|
25
|
+
puts " Public? #{video.public?}"
|
24
26
|
end
|
@@ -9,12 +9,12 @@ module Yt
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def do_delete_all(params = {})
|
12
|
-
|
12
|
+
list_all(params).map do |item|
|
13
13
|
item.delete
|
14
14
|
end.tap { @items = [] }
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def list_all(params = {})
|
18
18
|
list.find_all do |item|
|
19
19
|
params.all? do |method, value|
|
20
20
|
# TODO: could be symbol etc...
|
@@ -5,10 +5,25 @@ require 'yt/errors/unauthorized'
|
|
5
5
|
|
6
6
|
module Yt
|
7
7
|
module Associations
|
8
|
-
# Provides
|
8
|
+
# Provides authentication methods to YouTube resources, which
|
9
9
|
# allows to access to content detail set-specific methods like `access_token`.
|
10
|
-
# YouTube resources with
|
10
|
+
# YouTube resources with authentication are: accounts.
|
11
11
|
module Authentications
|
12
|
+
delegate :access_token, :refresh_token, :expires_at, to: :authentication
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@access_token = options[:access_token]
|
16
|
+
@refresh_token = options[:refresh_token]
|
17
|
+
@expires_at = options[:expires_at]
|
18
|
+
@authorization_code = options[:authorization_code]
|
19
|
+
@redirect_uri = options[:redirect_uri]
|
20
|
+
@scopes = options[:scopes]
|
21
|
+
end
|
22
|
+
|
23
|
+
def auth
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
12
27
|
def authentication
|
13
28
|
@authentication = current_authentication
|
14
29
|
@authentication ||= new_authentication || refreshed_authentication!
|
data/lib/yt/collections/base.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/status'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Collections
|
6
|
+
class Statuses < Base
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def new_item(data)
|
11
|
+
Yt::Status.new data: data['status']
|
12
|
+
end
|
13
|
+
|
14
|
+
def list_params
|
15
|
+
super.tap do |params|
|
16
|
+
params[:params] = {id: @parent.id, part: 'status'}
|
17
|
+
params[:path] = "/youtube/v3/#{@parent.kind.pluralize}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -29,7 +29,7 @@ module Yt
|
|
29
29
|
# To overcome this, if we have just updated the subscription, we must
|
30
30
|
# wait some time before requesting it again.
|
31
31
|
#
|
32
|
-
def throttle(seconds =
|
32
|
+
def throttle(seconds = 11)
|
33
33
|
@last_changed_at ||= Time.now - seconds
|
34
34
|
wait = [@last_changed_at - Time.now + seconds, 0].max
|
35
35
|
sleep wait
|
@@ -13,10 +13,15 @@ module Yt
|
|
13
13
|
|
14
14
|
def list_params
|
15
15
|
super.tap do |params|
|
16
|
-
params[:params] =
|
16
|
+
params[:params] = @parent.videos_params.merge videos_params
|
17
17
|
params[:path] = '/youtube/v3/search'
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
def videos_params
|
22
|
+
@extra_params ||= {}
|
23
|
+
{type: :video, maxResults: 50, part: 'snippet'}.merge @extra_params
|
24
|
+
end
|
20
25
|
end
|
21
26
|
end
|
22
27
|
end
|
data/lib/yt/models/account.rb
CHANGED
@@ -1,24 +1,18 @@
|
|
1
1
|
require 'yt/models/base'
|
2
|
+
require 'yt/associations/authentications'
|
2
3
|
|
3
4
|
module Yt
|
4
5
|
module Models
|
5
6
|
# Provides methods to access a YouTube account.
|
6
7
|
class Account < Base
|
8
|
+
include Associations::Authentications
|
9
|
+
|
7
10
|
has_one :channel, delegate: [:videos, :playlists, :create_playlist, :delete_playlists, :update_playlists]
|
8
11
|
has_one :user_info, delegate: [:id, :email, :has_verified_email?, :gender, :name, :given_name, :family_name, :profile_url, :avatar_url, :locale, :hd]
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(options = {})
|
12
|
-
@access_token = options[:access_token]
|
13
|
-
@refresh_token = options[:refresh_token]
|
14
|
-
@expires_at = options[:expires_at]
|
15
|
-
@authorization_code = options[:authorization_code]
|
16
|
-
@redirect_uri = options[:redirect_uri]
|
17
|
-
@scopes = options[:scopes]
|
18
|
-
end
|
12
|
+
has_many :videos
|
19
13
|
|
20
|
-
def
|
21
|
-
|
14
|
+
def videos_params
|
15
|
+
{forMine: true}
|
22
16
|
end
|
23
17
|
end
|
24
18
|
end
|
data/lib/yt/models/base.rb
CHANGED
@@ -1,14 +1,40 @@
|
|
1
|
-
require 'yt/associations'
|
2
1
|
require 'yt/actions/delete'
|
3
2
|
require 'yt/actions/update'
|
4
3
|
require 'yt/errors/request_error'
|
5
4
|
|
5
|
+
require 'active_support/core_ext/module/delegation' # for delegate
|
6
|
+
require 'active_support/core_ext/string/inflections' # for camelize
|
7
|
+
|
8
|
+
|
6
9
|
module Yt
|
7
10
|
module Models
|
8
11
|
class Base
|
9
|
-
extend Associations
|
10
12
|
include Actions::Delete
|
11
13
|
include Actions::Update
|
14
|
+
|
15
|
+
def self.has_many(attributes)
|
16
|
+
attributes = attributes.to_s
|
17
|
+
require "yt/collections/#{attributes}"
|
18
|
+
mod = attributes.sub(/.*\./, '').camelize
|
19
|
+
collection = "Yt::Collections::#{mod.pluralize}".constantize
|
20
|
+
|
21
|
+
define_method attributes do
|
22
|
+
ivar = instance_variable_get "@#{attributes}"
|
23
|
+
instance_variable_set "@#{attributes}", ivar || collection.of(self)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.has_one(attribute, options = {})
|
28
|
+
delegate *options[:delegate], to: attribute if options[:delegate]
|
29
|
+
|
30
|
+
attributes = attribute.to_s.pluralize
|
31
|
+
has_many attributes
|
32
|
+
|
33
|
+
define_method attribute do
|
34
|
+
ivar = instance_variable_get "@#{attribute}"
|
35
|
+
instance_variable_set "@#{attribute}", ivar || send(attributes).first!
|
36
|
+
end
|
37
|
+
end
|
12
38
|
end
|
13
39
|
end
|
14
40
|
|
data/lib/yt/models/channel.rb
CHANGED
@@ -1,13 +1,48 @@
|
|
1
1
|
require 'yt/models/resource'
|
2
|
+
require 'yt/associations/earnings'
|
3
|
+
require 'yt/associations/views'
|
2
4
|
|
3
5
|
module Yt
|
4
6
|
module Models
|
5
7
|
class Channel < Resource
|
8
|
+
include Associations::Earnings
|
9
|
+
include Associations::Views
|
10
|
+
|
6
11
|
has_many :subscriptions
|
7
12
|
has_many :videos
|
8
13
|
has_many :playlists
|
9
|
-
|
10
|
-
|
14
|
+
|
15
|
+
def subscribed?
|
16
|
+
subscriptions.any?{|s| s.exists?}
|
17
|
+
end
|
18
|
+
|
19
|
+
def subscribe
|
20
|
+
subscriptions.insert ignore_errors: true
|
21
|
+
end
|
22
|
+
|
23
|
+
def subscribe!
|
24
|
+
subscriptions.insert
|
25
|
+
end
|
26
|
+
|
27
|
+
def unsubscribe
|
28
|
+
subscriptions.delete_all({}, ignore_errors: true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def unsubscribe!
|
32
|
+
subscriptions.delete_all
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_playlist(params = {})
|
36
|
+
playlists.insert params
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_playlists(attrs = {})
|
40
|
+
playlists.delete_all attrs
|
41
|
+
end
|
42
|
+
|
43
|
+
def videos_params
|
44
|
+
{channelId: id}
|
45
|
+
end
|
11
46
|
end
|
12
47
|
end
|
13
48
|
end
|
data/lib/yt/models/playlist.rb
CHANGED
@@ -32,6 +32,26 @@ module Yt
|
|
32
32
|
!@id.nil?
|
33
33
|
end
|
34
34
|
|
35
|
+
def add_video(video_id)
|
36
|
+
playlist_items.insert video_params(video_id), ignore_errors: true
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_video!(video_id)
|
40
|
+
playlist_items.insert video_params(video_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_videos(video_ids = [])
|
44
|
+
video_ids.map{|video_id| add_video video_id}
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_videos!(video_ids = [])
|
48
|
+
video_ids.map{|video_id| add_video! video_id}
|
49
|
+
end
|
50
|
+
|
51
|
+
def delete_playlist_items(attrs = {})
|
52
|
+
playlist_items.delete_all attrs
|
53
|
+
end
|
54
|
+
|
35
55
|
private
|
36
56
|
|
37
57
|
def delete_params
|
@@ -48,6 +68,10 @@ module Yt
|
|
48
68
|
params[:expected_response] = Net::HTTPOK
|
49
69
|
end
|
50
70
|
end
|
71
|
+
|
72
|
+
def video_params(video_id)
|
73
|
+
{id: video_id, kind: :video}
|
74
|
+
end
|
51
75
|
end
|
52
76
|
end
|
53
77
|
end
|
data/lib/yt/models/video.rb
CHANGED
@@ -6,6 +6,25 @@ module Yt
|
|
6
6
|
has_one :details_set, delegate: [:duration]
|
7
7
|
has_one :rating
|
8
8
|
has_many :annotations
|
9
|
+
|
10
|
+
def liked?
|
11
|
+
rating.rating == :like
|
12
|
+
end
|
13
|
+
|
14
|
+
def like
|
15
|
+
rating.update :like
|
16
|
+
liked?
|
17
|
+
end
|
18
|
+
|
19
|
+
def dislike
|
20
|
+
rating.update :dislike
|
21
|
+
!liked?
|
22
|
+
end
|
23
|
+
|
24
|
+
def unlike
|
25
|
+
rating.update :none
|
26
|
+
!liked?
|
27
|
+
end
|
9
28
|
end
|
10
29
|
end
|
11
30
|
end
|
data/lib/yt/version.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/models/account'
|
3
|
+
|
4
|
+
describe Yt::Account, :device_app do
|
5
|
+
describe '.channel' do
|
6
|
+
it { expect($account.channel).to be_a Yt::Channel }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.user_info' do
|
10
|
+
it { expect($account.user_info).to be_a Yt::UserInfo }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.videos' do
|
14
|
+
it { expect($account.videos).to be_a Yt::Collections::Videos }
|
15
|
+
it { expect($account.videos.first).to be_a Yt::Video }
|
16
|
+
|
17
|
+
describe '.where(q: query_string)' do
|
18
|
+
let(:count) { $account.videos.where(q: query).count }
|
19
|
+
|
20
|
+
context 'given a query string that matches any video owned by the account' do
|
21
|
+
let(:query) { ENV['YT_TEST_MATCHING_QUERY_STRING'] }
|
22
|
+
it { expect(count).to be > 0 }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'given a query string that does not match any video owned by the account' do
|
26
|
+
let(:query) { '--not-a-matching-query-string--' }
|
27
|
+
it { expect(count).to be_zero }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'yt/models/channel'
|
5
|
+
|
6
|
+
describe Yt::Channel, :device_app do
|
7
|
+
let(:channel) { Yt::Channel.new id: id, auth: $account }
|
8
|
+
|
9
|
+
describe '.snippet of existing channel' do
|
10
|
+
let(:id) { 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
11
|
+
it { expect(channel.snippet).to be_a Yt::Snippet }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.snippet of unknown channel' do
|
15
|
+
let(:id) { 'not-a-channel-id' }
|
16
|
+
it { expect{channel.snippet}.to raise_error Yt::Errors::NoItems }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.status of existing channel' do
|
20
|
+
let(:id) { 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
21
|
+
it { expect(channel.status).to be_a Yt::Status }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.status of unknown channel' do
|
25
|
+
let(:id) { 'not-a-channel-id' }
|
26
|
+
it { expect{channel.status}.to raise_error Yt::Errors::NoItems }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.videos of existing channel' do
|
30
|
+
let(:id) { 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
31
|
+
it { expect(channel.videos).to be_a Yt::Collections::Videos }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.videos of unknown channel starting with UC' do
|
35
|
+
let(:id) { 'UC-not-a-channel-id' }
|
36
|
+
|
37
|
+
# NOTE: This test is just a reflection of YouTube irrational behavior of
|
38
|
+
# returns 0 results if the name of an unknown channel starts with UC, but
|
39
|
+
# returning 100,000 results otherwise (ignoring the channel filter).
|
40
|
+
it { expect(channel.videos.count).to be 0 }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '.subscriptions to an existing channel' do
|
44
|
+
let(:id) { 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
45
|
+
it { expect(channel.subscriptions).to be_a Yt::Collections::Subscriptions }
|
46
|
+
|
47
|
+
# NOTE: These tests are slow because we *must* wait some seconds between
|
48
|
+
# subscribing and unsubscribing to a channel, otherwise YouTube will show
|
49
|
+
# wrong (cached) data, such as a user is subscribed when he is not.
|
50
|
+
context 'can be added', :slow do
|
51
|
+
before { channel.unsubscribe }
|
52
|
+
it { expect(channel.subscribed?).to be false }
|
53
|
+
it { expect(channel.subscribe!).to be_truthy }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'can be removed', :slow do
|
57
|
+
before { channel.subscribe }
|
58
|
+
it { expect(channel.subscribed?).to be true }
|
59
|
+
it { expect(channel.unsubscribe!).to be_truthy }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '.subscriptions to an unknown channel' do
|
64
|
+
let(:id) { 'not-a-channel-id' }
|
65
|
+
it { expect{channel.subscribe}.to raise_error Yt::Errors::RequestError }
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.subscriptions to my own channel' do
|
69
|
+
let(:id) { $account.channel.id }
|
70
|
+
|
71
|
+
# NOTE: This test is just a reflection of YouTube irrational behavior of
|
72
|
+
# raising a 500 error when you try to subscribe to your own channel, rather
|
73
|
+
# than a more logical 4xx error. Hopefully this will get fixed and this
|
74
|
+
# code (and test) removed.
|
75
|
+
it { expect{channel.subscribe}.to raise_error Yt::Errors::ServerError }
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '.playlists of my own channel' do
|
79
|
+
let(:id) { $account.channel.id }
|
80
|
+
let(:title) { 'Yt Test title' }
|
81
|
+
let(:description) { 'Yt Test description' }
|
82
|
+
let(:tags) { ['Yt Test Tag 1', 'Yt Test Tag 2'] }
|
83
|
+
let(:privacy_status) { 'unlisted' }
|
84
|
+
let(:params) { {title: title, description: description, tags: tags, privacy_status: privacy_status} }
|
85
|
+
|
86
|
+
it { expect(channel.playlists).to be_a Yt::Collections::Playlists }
|
87
|
+
|
88
|
+
describe 'can be created' do
|
89
|
+
after { channel.delete_playlists params }
|
90
|
+
it { expect(channel.create_playlist params).to be_a Yt::Playlist }
|
91
|
+
it { expect{channel.create_playlist params}.to change{channel.playlists.count}.by(1) }
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'can be deleted' do
|
95
|
+
let(:title) { "Yt Test Delete All Playlists #{rand}" }
|
96
|
+
before { channel.create_playlist params }
|
97
|
+
|
98
|
+
it { expect(channel.delete_playlists title: %r{#{params[:title]}}).to eq [true] }
|
99
|
+
it { expect(channel.delete_playlists params).to eq [true] }
|
100
|
+
it { expect{channel.delete_playlists params}.to change{channel.playlists.count}.by(-1) }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '.playlists of someone else’s channel' do
|
105
|
+
let(:id) { 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
106
|
+
|
107
|
+
it { expect(channel.playlists).to be_a Yt::Collections::Playlists }
|
108
|
+
|
109
|
+
describe 'cannot be created or destroyed' do
|
110
|
+
it { expect{channel.create_playlist}.to raise_error Yt::Errors::RequestError }
|
111
|
+
it { expect{channel.delete_playlists}.to raise_error Yt::Errors::RequestError }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|