yt 0.32.6 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -4
  3. data/CHANGELOG.md +19 -0
  4. data/README.md +22 -32
  5. data/YOUTUBE_IT.md +4 -4
  6. data/lib/yt.rb +0 -1
  7. data/lib/yt/associations/has_reports.rb +9 -14
  8. data/lib/yt/collections/reports.rb +5 -7
  9. data/lib/yt/models/resource.rb +69 -3
  10. data/lib/yt/models/url.rb +2 -60
  11. data/lib/yt/request.rb +6 -2
  12. data/lib/yt/version.rb +1 -1
  13. data/yt.gemspec +5 -2
  14. metadata +31 -169
  15. data/spec/collections/claims_spec.rb +0 -62
  16. data/spec/collections/comment_threads_spec.rb +0 -46
  17. data/spec/collections/playlist_items_spec.rb +0 -44
  18. data/spec/collections/playlists_spec.rb +0 -27
  19. data/spec/collections/policies_spec.rb +0 -30
  20. data/spec/collections/references_spec.rb +0 -30
  21. data/spec/collections/reports_spec.rb +0 -30
  22. data/spec/collections/subscriptions_spec.rb +0 -25
  23. data/spec/collections/videos_spec.rb +0 -43
  24. data/spec/constants/geography_spec.rb +0 -16
  25. data/spec/errors/forbidden_spec.rb +0 -10
  26. data/spec/errors/missing_auth_spec.rb +0 -24
  27. data/spec/errors/no_items_spec.rb +0 -10
  28. data/spec/errors/request_error_spec.rb +0 -44
  29. data/spec/errors/server_error_spec.rb +0 -10
  30. data/spec/errors/unauthorized_spec.rb +0 -10
  31. data/spec/models/account_spec.rb +0 -138
  32. data/spec/models/annotation_spec.rb +0 -180
  33. data/spec/models/asset_spec.rb +0 -32
  34. data/spec/models/channel_spec.rb +0 -127
  35. data/spec/models/claim_event_spec.rb +0 -62
  36. data/spec/models/claim_history_spec.rb +0 -27
  37. data/spec/models/claim_spec.rb +0 -223
  38. data/spec/models/comment_spec.rb +0 -40
  39. data/spec/models/comment_thread_spec.rb +0 -93
  40. data/spec/models/configuration_spec.rb +0 -44
  41. data/spec/models/content_detail_spec.rb +0 -52
  42. data/spec/models/content_owner_detail_spec.rb +0 -6
  43. data/spec/models/file_detail_spec.rb +0 -13
  44. data/spec/models/live_streaming_detail_spec.rb +0 -6
  45. data/spec/models/ownership_spec.rb +0 -59
  46. data/spec/models/player_spec.rb +0 -13
  47. data/spec/models/playlist_item_spec.rb +0 -120
  48. data/spec/models/playlist_spec.rb +0 -138
  49. data/spec/models/policy_rule_spec.rb +0 -63
  50. data/spec/models/policy_spec.rb +0 -41
  51. data/spec/models/rating_spec.rb +0 -12
  52. data/spec/models/reference_spec.rb +0 -249
  53. data/spec/models/request_spec.rb +0 -204
  54. data/spec/models/resource_spec.rb +0 -42
  55. data/spec/models/right_owner_spec.rb +0 -71
  56. data/spec/models/snippet_spec.rb +0 -13
  57. data/spec/models/statistics_set_spec.rb +0 -13
  58. data/spec/models/status_spec.rb +0 -13
  59. data/spec/models/subscription_spec.rb +0 -30
  60. data/spec/models/url_spec.rb +0 -78
  61. data/spec/models/video_category_spec.rb +0 -21
  62. data/spec/models/video_spec.rb +0 -669
  63. data/spec/requests/as_account/account_spec.rb +0 -143
  64. data/spec/requests/as_account/authentications_spec.rb +0 -127
  65. data/spec/requests/as_account/channel_spec.rb +0 -246
  66. data/spec/requests/as_account/channels_spec.rb +0 -18
  67. data/spec/requests/as_account/playlist_item_spec.rb +0 -55
  68. data/spec/requests/as_account/playlist_spec.rb +0 -218
  69. data/spec/requests/as_account/thumbnail.jpg +0 -0
  70. data/spec/requests/as_account/video.mp4 +0 -0
  71. data/spec/requests/as_account/video_spec.rb +0 -408
  72. data/spec/requests/as_content_owner/account_spec.rb +0 -29
  73. data/spec/requests/as_content_owner/advertising_options_set_spec.rb +0 -15
  74. data/spec/requests/as_content_owner/asset_spec.rb +0 -31
  75. data/spec/requests/as_content_owner/bulk_report_job_spec.rb +0 -19
  76. data/spec/requests/as_content_owner/channel_spec.rb +0 -1836
  77. data/spec/requests/as_content_owner/claim_history_spec.rb +0 -20
  78. data/spec/requests/as_content_owner/claim_spec.rb +0 -17
  79. data/spec/requests/as_content_owner/content_owner_spec.rb +0 -370
  80. data/spec/requests/as_content_owner/match_policy_spec.rb +0 -17
  81. data/spec/requests/as_content_owner/ownership_spec.rb +0 -25
  82. data/spec/requests/as_content_owner/playlist_spec.rb +0 -767
  83. data/spec/requests/as_content_owner/video_group_spec.rb +0 -112
  84. data/spec/requests/as_content_owner/video_spec.rb +0 -1223
  85. data/spec/requests/as_server_app/channel_spec.rb +0 -54
  86. data/spec/requests/as_server_app/comment_spec.rb +0 -22
  87. data/spec/requests/as_server_app/comment_thread_spec.rb +0 -27
  88. data/spec/requests/as_server_app/comment_threads_spec.rb +0 -41
  89. data/spec/requests/as_server_app/playlist_item_spec.rb +0 -30
  90. data/spec/requests/as_server_app/playlist_spec.rb +0 -33
  91. data/spec/requests/as_server_app/url_spec.rb +0 -94
  92. data/spec/requests/as_server_app/video_spec.rb +0 -60
  93. data/spec/requests/as_server_app/videos_spec.rb +0 -40
  94. data/spec/requests/unauthenticated/video_spec.rb +0 -14
  95. data/spec/spec_helper.rb +0 -20
  96. data/spec/support/fail_matcher.rb +0 -15
  97. data/spec/support/global_hooks.rb +0 -48
@@ -1,143 +0,0 @@
1
- # encoding: UTF-8
2
- require 'spec_helper'
3
- require 'yt/models/account'
4
-
5
- describe Yt::Account, :device_app do
6
- describe 'can create playlists', rate_limited: true do
7
- let(:params) { {title: 'Test Yt playlist', privacy_status: 'unlisted'} }
8
- before { @playlist = $account.create_playlist params }
9
- it { expect(@playlist).to be_a Yt::Playlist }
10
- after { @playlist.delete }
11
- end
12
-
13
- it { expect($account.channel).to be_a Yt::Channel }
14
- it { expect($account.playlists.first).to be_a Yt::Playlist }
15
- it { expect($account.subscribed_channels.first).to be_a Yt::Channel }
16
- it { expect($account.user_info).to be_a Yt::UserInfo }
17
-
18
- describe '.related_playlists' do
19
- let(:related_playlists) { $account.related_playlists }
20
-
21
- specify 'returns the list of associated playlist (Liked Videos, Uploads, ...)' do
22
- expect(related_playlists.first).to be_a Yt::Playlist
23
- end
24
-
25
- specify 'includes public related playlists (such as Liked Videos)' do
26
- uploads = related_playlists.select{|p| p.title.starts_with? 'Uploads'}
27
- expect(uploads).not_to be_empty
28
- end
29
- end
30
-
31
- describe '.videos' do
32
- let(:video) { $account.videos.where(order: 'viewCount').first }
33
-
34
- specify 'returns the videos uploaded by the account with their tags and category ID' do
35
- expect(video).to be_a Yt::Video
36
- expect(video.tags).not_to be_empty
37
- expect(video.category_id).not_to be_nil
38
- end
39
-
40
- describe '.where(q: query_string)' do
41
- let(:count) { $account.videos.where(q: query).count }
42
-
43
- context 'given a query string that matches any video owned by the account' do
44
- let(:query) { ENV['YT_TEST_MATCHING_QUERY_STRING'] }
45
- it { expect(count).to be > 0 }
46
- end
47
-
48
- context 'given a query string that does not match any video owned by the account' do
49
- let(:query) { '--not-a-matching-query-string--' }
50
- it { expect(count).to be_zero }
51
- end
52
- end
53
-
54
- describe 'ignores filters by ID (all the videos uploaded by the account are returned)' do
55
- let(:other_video) { $account.videos.where(order: 'viewCount', id: 'invalid').first }
56
- it { expect(other_video.id).to eq video.id }
57
- end
58
-
59
- describe 'ignores filters by chart (all the videos uploaded by the account are returned)' do
60
- let(:other_video) { $account.videos.where(order: 'viewCount', chart: 'invalid').first }
61
- it { expect(other_video.id).to eq video.id }
62
- end
63
-
64
- describe '.includes(:snippet)' do
65
- let(:video) { $account.videos.includes(:snippet).first }
66
-
67
- specify 'eager-loads the *full* snippet of each video' do
68
- expect(video.instance_variable_defined? :@snippet).to be true
69
- expect(video.channel_title).to be
70
- expect(video.snippet).to be_complete
71
- end
72
- end
73
-
74
- describe '.includes(:statistics, :status)' do
75
- let(:video) { $account.videos.includes(:statistics, :status).first }
76
-
77
- specify 'eager-loads the statistics and status of each video' do
78
- expect(video.instance_variable_defined? :@statistics_set).to be true
79
- expect(video.instance_variable_defined? :@status).to be true
80
- end
81
- end
82
-
83
- describe '.includes(:content_details)' do
84
- let(:video) { $account.videos.includes(:content_details).first }
85
-
86
- specify 'eager-loads the statistics of each video' do
87
- expect(video.instance_variable_defined? :@content_detail).to be true
88
- end
89
- end
90
- end
91
-
92
- describe '.video_groups' do
93
- let(:video_group) { $account.video_groups.first }
94
-
95
- specify 'returns the first video-group created by the account' do
96
- expect(video_group).to be_a Yt::VideoGroup
97
- expect(video_group.title).to be_a String
98
- expect(video_group.item_count).to be_an Integer
99
- expect(video_group.published_at).to be_a Time
100
- end
101
-
102
- specify 'allows to run reports against each video-group' do
103
- expect(video_group.views).to be
104
- end
105
- end
106
-
107
- describe '.upload_video' do
108
- let(:video_params) { {title: 'Test Yt upload', privacy_status: 'private', category_id: 17} }
109
- let(:video) { $account.upload_video path_or_url, video_params }
110
- after { video.delete }
111
-
112
- context 'given the path to a local video file' do
113
- let(:path_or_url) { File.expand_path '../video.mp4', __FILE__ }
114
-
115
- it { expect(video).to be_a Yt::Video }
116
- end
117
-
118
- context 'given the URL of a remote video file' do
119
- let(:path_or_url) { 'https://bit.ly/yt_test' }
120
-
121
- it { expect(video).to be_a Yt::Video }
122
- end
123
- end
124
-
125
- describe '.subscribers' do
126
- let(:subscriber) { $account.subscribers.first }
127
-
128
- # It could be only me, but it returns an empty array for "items".
129
- # Just in case, I currently have 2 subscribers.
130
- # {
131
- # "kind": "youtube#subscriptionListResponse",
132
- # "etag": "...",
133
- # "pageInfo": {
134
- # "totalResults": 2,
135
- # "resultsPerPage": 50
136
- # },
137
- # "items": []
138
- # }
139
- specify 'returns the channels who are subscribed to me' do
140
- expect(subscriber).to be_nil
141
- end
142
- end
143
- end
@@ -1,127 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/models/account'
3
-
4
- describe Yt::Account, :device_app do
5
- subject(:account) { Yt::Account.new attrs }
6
-
7
- describe '#refresh' do
8
- context 'given a valid refresh token' do
9
- let(:attrs) { {refresh_token: ENV['YT_TEST_DEVICE_REFRESH_TOKEN']} }
10
-
11
- # NOTE: When the token is refreshed, YouTube *might* actually return
12
- # the *same* access token if it is still valid. Typically, within the
13
- # same second, refreshing the token returns the same token. Still,
14
- # testing that *expires_at* changes is a guarantee that we attempted
15
- # to get a new token, which is what refresh is meant to do.
16
- it { expect{account.refreshed_access_token?}.to change{account.expires_at} }
17
- end
18
- end
19
-
20
- describe '#authentication' do
21
- context 'given a refresh token' do
22
- let(:attrs) { {refresh_token: refresh_token} }
23
-
24
- context 'that is valid' do
25
- let(:refresh_token) { ENV['YT_TEST_DEVICE_REFRESH_TOKEN'] }
26
- it { expect(account.authentication).to be_a Yt::Authentication }
27
- it { expect(account.refresh_token).to eq refresh_token }
28
- end
29
-
30
- context 'that is invalid' do
31
- let(:refresh_token) { '--not-a-valid-refresh-token--' }
32
- it { expect{account.authentication}.to raise_error Yt::Errors::Unauthorized }
33
- end
34
- end
35
-
36
- context 'given a redirect URI and an authorization code' do
37
- let(:attrs) { {authorization_code: authorization_code, redirect_uri: 'http://localhost/'} }
38
-
39
- context 'that is valid' do
40
- # cannot be tested "live"
41
- end
42
-
43
- context 'that is invalid' do
44
- let(:authorization_code) { rand(36**20).to_s(36) }
45
- it { expect{account.authentication}.to raise_error Yt::Errors::Unauthorized }
46
- end
47
- end
48
-
49
- context 'given an access token' do
50
- let(:attrs) { {access_token: access_token, expires_at: expires_at} }
51
-
52
- context 'that is valid' do
53
- let(:access_token) { $account.access_token }
54
-
55
- context 'that does not have an expiration date' do
56
- let(:expires_at) { nil }
57
- it { expect(account.authentication).to be_a Yt::Authentication }
58
- end
59
-
60
- context 'that has not expired' do
61
- let(:expires_at) { 1.day.from_now.to_s }
62
- it { expect(account.authentication).to be_a Yt::Authentication }
63
- end
64
-
65
- context 'that has expired' do
66
- let(:expires_at) { 1.day.ago.to_s }
67
-
68
- context 'and no refresh token' do
69
- it { expect{account.authentication}.to raise_error Yt::Errors::MissingAuth }
70
- end
71
-
72
- context 'and an invalid refresh token' do
73
- before { attrs[:refresh_token] = '--not-a-valid-refresh-token--' }
74
- it { expect{account.authentication}.to raise_error Yt::Errors::Unauthorized }
75
- end
76
-
77
- context 'and a valid refresh token' do
78
- before { attrs[:refresh_token] = ENV['YT_TEST_DEVICE_REFRESH_TOKEN'] }
79
- it { expect(account.authentication).to be_a Yt::Authentication }
80
- end
81
- end
82
- end
83
-
84
- context 'that is invalid' do
85
- let(:access_token) { '--not-a-valid-access-token--' }
86
- let(:expires_at) { 1.day.from_now }
87
-
88
- context 'and no refresh token' do
89
- it { expect{account.channel}.to raise_error Yt::Errors::Unauthorized }
90
- end
91
-
92
- context 'and a valid refresh token' do
93
- before { attrs[:refresh_token] = ENV['YT_TEST_DEVICE_REFRESH_TOKEN'] }
94
- it { expect{account.channel}.not_to raise_error }
95
- end
96
- end
97
- end
98
-
99
- context 'given scopes' do
100
- let(:attrs) { {scopes: ['userinfo.email', 'youtube']} }
101
-
102
- context 'and a redirect_uri' do
103
- before { attrs[:redirect_uri] = 'http://localhost/' }
104
-
105
- it { expect{account.authentication}.to raise_error Yt::Errors::MissingAuth }
106
- end
107
- end
108
-
109
- context 'given no token or code' do
110
- let(:attrs) { {} }
111
- it { expect{account.authentication}.to raise_error Yt::Errors::MissingAuth }
112
- end
113
- end
114
-
115
- describe '#authentication_url' do
116
- let(:auth_attrs) { {redirect_uri: 'http://localhost/', scopes: ['userinfo.email', 'userinfo.profile']} }
117
- context 'given a redirect URI and scopes' do
118
- let(:attrs) { auth_attrs }
119
- it { expect(account.authentication_url).to match 'access_type=offline' }
120
-
121
- context 'given a forced approval prompt' do
122
- let(:attrs) { auth_attrs.merge force: true }
123
- it { expect(account.authentication_url).to match 'approval_prompt=force' }
124
- end
125
- end
126
- end
127
- end
@@ -1,246 +0,0 @@
1
- # encoding: UTF-8
2
- require 'spec_helper'
3
- require 'yt/models/channel'
4
-
5
- describe Yt::Channel, :device_app do
6
- subject(:channel) { Yt::Channel.new id: id, auth: $account }
7
-
8
- context 'given someone else’s channel' do
9
- let(:id) { 'UCBR8-60-B28hp2BmDPdntcQ' } # YouTube Spotlight
10
-
11
- it 'returns valid metadata' do
12
- expect(channel.title).to be_a String
13
- expect(channel.description).to be_a String
14
- expect(channel.thumbnail_url).to be_a String
15
- # expect(channel.published_at).to be_a Time
16
- expect(channel.privacy_status).to be_a String
17
- expect(channel.view_count).to be_an Integer
18
- expect(channel.comment_count).to be_an Integer
19
- expect(channel.video_count).to be_an Integer
20
- expect(channel.subscriber_count).to be_an Integer
21
- expect(channel.subscriber_count_visible?).to be_in [true, false]
22
- end
23
-
24
- describe '.videos' do
25
- let(:video) { channel.videos.first }
26
-
27
- specify 'returns the videos in the channel without tags or category ID' do
28
- expect(video).to be_a Yt::Video
29
- expect(video.snippet).not_to be_complete
30
- end
31
-
32
- describe '.where(id: *anything*)' do
33
- let(:video) { channel.videos.where(id: 'invalid').first }
34
-
35
- specify 'is ignored (all the channel’s videos are returned)' do
36
- expect(video).to be_a Yt::Video
37
- end
38
- end
39
-
40
- describe '.where(chart: *anything*)' do
41
- let(:video) { channel.videos.where(chart: 'invalid').first }
42
-
43
- specify 'is ignored (all the channel’s videos are returned)' do
44
- expect(video).to be_a Yt::Video
45
- end
46
- end
47
-
48
- describe '.includes(:statistics, :status)' do
49
- let(:video) { channel.videos.includes(:statistics, :status).first }
50
-
51
- specify 'eager-loads the statistics and status of each video' do
52
- expect(video.instance_variable_defined? :@statistics_set).to be true
53
- expect(video.instance_variable_defined? :@status).to be true
54
- end
55
- end
56
-
57
- describe '.includes(:content_details)' do
58
- let(:video) { channel.videos.includes(:content_details).first }
59
-
60
- specify 'eager-loads the statistics of each video' do
61
- expect(video.instance_variable_defined? :@content_detail).to be true
62
- end
63
- end
64
-
65
- describe '.includes(:category)' do
66
- let(:video) { channel.videos.includes(:category, :status).first }
67
-
68
- specify 'eager-loads the category (id and title) of each video' do
69
- expect(video.instance_variable_defined? :@snippet).to be true
70
- expect(video.instance_variable_defined? :@video_category).to be true
71
- end
72
- end
73
-
74
- describe 'when the channel has more than 500 videos' do
75
- let(:id) { 'UC0v-tlzsn0QZwJnkiaUSJVQ' } # FBE
76
-
77
- specify 'the estimated and actual number of videos can be retrieved' do
78
- # @note: in principle, the following three counters should match, but
79
- # in reality +video_count+ and +size+ are only approximations.
80
- expect(channel.video_count).to be > 500
81
- expect(channel.videos.size).to be > 500
82
- end
83
- end
84
- end
85
-
86
- describe '.playlists' do
87
- describe '.includes(:content_details)' do
88
- let(:playlist) { channel.playlists.includes(:content_details).first }
89
-
90
- specify 'eager-loads the content details of each playlist' do
91
- expect(playlist.instance_variable_defined? :@content_detail).to be true
92
- end
93
- end
94
- end
95
-
96
- it { expect(channel.playlists.first).to be_a Yt::Playlist }
97
- it { expect{channel.delete_playlists}.to raise_error Yt::Errors::RequestError }
98
-
99
- describe '.related_playlists' do
100
- let(:related_playlists) { channel.related_playlists }
101
-
102
- specify 'returns the list of associated playlist (Liked Videos, Uploads, ...)' do
103
- expect(related_playlists.first).to be_a Yt::Playlist
104
- end
105
-
106
- specify 'includes public related playlists (such as Liked Videos)' do
107
- uploads = related_playlists.select{|p| p.title.starts_with? 'Uploads'}
108
- expect(uploads).not_to be_empty
109
- end
110
-
111
- # NOTE: this test is commented out because today the private playlist is
112
- # included on channel.related_playlists, but I couldn't find if this change
113
- # has been documented.
114
- # specify 'does not includes private playlists (such as Watch Later)' do
115
- # watch_later = related_playlists.select{|p| p.title.starts_with? 'Watch'}
116
- # expect(watch_later).to be_empty
117
- # end
118
- end
119
-
120
- specify 'with a public list of subscriptions' do
121
- expect(channel.subscribed_channels.first).to be_a Yt::Channel
122
- end
123
-
124
- context 'with a hidden list of subscriptions' do
125
- let(:id) { 'UCUZHFZ9jIKrLroW8LcyJEQQ' } # YouTube Creators - better make our own one
126
- it { expect{channel.subscribed_channels.size}.to raise_error Yt::Errors::Forbidden }
127
- end
128
-
129
- # NOTE: These tests are slow because we *must* wait some seconds between
130
- # subscribing and unsubscribing to a channel, otherwise YouTube will show
131
- # wrong (cached) data, such as a user is subscribed when he is not.
132
- context 'that I am not subscribed to', :slow do
133
- let(:id) { 'UCCj956IF62FbT7Gouszaj9w' } # BBC
134
- before { channel.throttle_subscriptions }
135
-
136
- it { expect(channel.subscribed?).to be false }
137
- it { expect(channel.unsubscribe).to be_falsey }
138
- it { expect{channel.unsubscribe!}.to raise_error Yt::Errors::RequestError }
139
-
140
- context 'when I subscribe' do
141
- before { channel.subscribe }
142
- after { channel.unsubscribe }
143
-
144
- it { expect(channel.subscribed?).to be true }
145
- it { expect(channel.unsubscribe!).to be_truthy }
146
- end
147
- end
148
-
149
- context 'that I am subscribed to', :slow do
150
- let(:id) { 'UCBR8-60-B28hp2BmDPdntcQ' } # YouTube Spotlight
151
- before { channel.throttle_subscriptions }
152
-
153
- it { expect(channel.subscribed?).to be true }
154
- # NOTE: These tests are commented out because YouTube randomly changed the
155
- # behavior of the API without changing the documentation, so subscribing
156
- # to a channel you are already subscribed to does not raise an error
157
- # anymore.
158
- # it { expect(channel.subscribe).to be_falsey }
159
- # it { expect{channel.subscribe!}.to raise_error Yt::Errors::RequestError }
160
-
161
- context 'when I unsubscribe' do
162
- before { channel.unsubscribe }
163
- after { channel.subscribe }
164
-
165
- it { expect(channel.subscribed?).to be false }
166
- it { expect(channel.subscribe!).to be_truthy }
167
- end
168
- end
169
- end
170
-
171
- context 'given my own channel' do
172
- let(:id) { $account.channel.id }
173
- let(:title) { 'Yt Test <title>' }
174
- let(:description) { 'Yt Test <description>' }
175
- let(:tags) { ['Yt Test Tag 1', 'Yt Test <Tag> 2'] }
176
- let(:privacy_status) { 'unlisted' }
177
- let(:params) { {title: title, description: description, tags: tags, privacy_status: privacy_status} }
178
-
179
- specify 'subscriptions can be listed (hidden or public)' do
180
- expect(channel.subscriptions.size).to be
181
- end
182
-
183
- describe 'playlists can be deleted', rate_limited: true do
184
- let(:title) { "Yt Test Delete All Playlists #{rand}" }
185
- before { $account.create_playlist params }
186
-
187
- it { expect(channel.delete_playlists title: %r{#{params[:title]}}).to eq [true] }
188
- it { expect(channel.delete_playlists params).to eq [true] }
189
- it { expect{channel.delete_playlists params}.to change{sleep 1; channel.playlists.count}.by(-1) }
190
- end
191
-
192
- # Can't subscribe to your own channel.
193
- it { expect{channel.subscribe!}.to raise_error Yt::Errors::RequestError }
194
- it { expect(channel.subscribe).to be_falsey }
195
-
196
- it 'returns valid reports for channel-related metrics' do
197
- # Some reports are only available to Content Owners.
198
- # See content owner test for more details about what the methods return.
199
- expect{channel.views}.not_to raise_error
200
- expect{channel.comments}.not_to raise_error
201
- expect{channel.likes}.not_to raise_error
202
- expect{channel.dislikes}.not_to raise_error
203
- expect{channel.shares}.not_to raise_error
204
- expect{channel.subscribers_gained}.not_to raise_error
205
- expect{channel.subscribers_lost}.not_to raise_error
206
- expect{channel.videos_added_to_playlists}.not_to raise_error
207
- expect{channel.videos_removed_from_playlists}.not_to raise_error
208
- expect{channel.estimated_minutes_watched}.not_to raise_error
209
- expect{channel.average_view_duration}.not_to raise_error
210
- expect{channel.average_view_percentage}.not_to raise_error
211
- expect{channel.annotation_clicks}.not_to raise_error
212
- expect{channel.annotation_click_through_rate}.not_to raise_error
213
- expect{channel.annotation_close_rate}.not_to raise_error
214
- expect{channel.card_impressions}.not_to raise_error
215
- expect{channel.card_clicks}.not_to raise_error
216
- expect{channel.card_click_rate}.not_to raise_error
217
- expect{channel.card_teaser_impressions}.not_to raise_error
218
- expect{channel.card_teaser_clicks}.not_to raise_error
219
- expect{channel.card_teaser_click_rate}.not_to raise_error
220
- expect{channel.viewer_percentage}.not_to raise_error
221
- expect{channel.estimated_revenue}.to raise_error Yt::Errors::Unauthorized
222
- expect{channel.ad_impressions}.to raise_error Yt::Errors::Unauthorized
223
- expect{channel.monetized_playbacks}.to raise_error Yt::Errors::Unauthorized
224
- expect{channel.playback_based_cpm}.to raise_error Yt::Errors::Unauthorized
225
- end
226
- end
227
-
228
- context 'given an unknown channel' do
229
- let(:id) { 'not-a-channel-id' }
230
-
231
- it { expect{channel.snippet}.to raise_error Yt::Errors::NoItems }
232
- it { expect{channel.status}.to raise_error Yt::Errors::NoItems }
233
- it { expect{channel.statistics_set}.to raise_error Yt::Errors::NoItems }
234
- it { expect{channel.subscribe}.to raise_error Yt::Errors::RequestError }
235
-
236
- describe 'starting with UC' do
237
- let(:id) { 'UC-not-a-channel-id' }
238
-
239
- # NOTE: This test is just a reflection of YouTube irrational behavior of
240
- # returns 0 results if the name of an unknown channel starts with UC, but
241
- # returning 100,000 results otherwise (ignoring the channel filter).
242
- it { expect(channel.videos.count).to be_zero }
243
- it { expect(channel.videos.size).to be_zero }
244
- end
245
- end
246
- end