yt 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|