yt 0.0.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/.yardopts +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +78 -0
- data/HISTORY.md +37 -0
- data/MIT-LICENSE +20 -0
- data/README.md +325 -0
- data/Rakefile +1 -0
- data/TODO.md +11 -0
- data/bin/yt +31 -0
- data/lib/yt.rb +2 -0
- data/lib/yt/actions/delete.rb +27 -0
- data/lib/yt/actions/delete_all.rb +28 -0
- data/lib/yt/actions/insert.rb +29 -0
- data/lib/yt/actions/list.rb +65 -0
- data/lib/yt/actions/update.rb +25 -0
- data/lib/yt/associations.rb +33 -0
- data/lib/yt/associations/annotations.rb +15 -0
- data/lib/yt/associations/channels.rb +20 -0
- data/lib/yt/associations/details_sets.rb +20 -0
- data/lib/yt/associations/playlist_items.rb +26 -0
- data/lib/yt/associations/playlists.rb +22 -0
- data/lib/yt/associations/ratings.rb +39 -0
- data/lib/yt/associations/snippets.rb +20 -0
- data/lib/yt/associations/statuses.rb +14 -0
- data/lib/yt/associations/subscriptions.rb +38 -0
- data/lib/yt/associations/user_infos.rb +21 -0
- data/lib/yt/associations/videos.rb +14 -0
- data/lib/yt/collections/annotations.rb +43 -0
- data/lib/yt/collections/base.rb +13 -0
- data/lib/yt/collections/channels.rb +32 -0
- data/lib/yt/collections/details_sets.rb +32 -0
- data/lib/yt/collections/playlist_items.rb +50 -0
- data/lib/yt/collections/playlists.rb +56 -0
- data/lib/yt/collections/ratings.rb +32 -0
- data/lib/yt/collections/snippets.rb +38 -0
- data/lib/yt/collections/subscriptions.rb +67 -0
- data/lib/yt/collections/user_infos.rb +41 -0
- data/lib/yt/collections/videos.rb +32 -0
- data/lib/yt/config.rb +55 -0
- data/lib/yt/models/account.rb +68 -0
- data/lib/yt/models/annotation.rb +137 -0
- data/lib/yt/models/base.rb +11 -0
- data/lib/yt/models/channel.rb +17 -0
- data/lib/yt/models/configuration.rb +29 -0
- data/lib/yt/models/description.rb +98 -0
- data/lib/yt/models/details_set.rb +31 -0
- data/lib/yt/models/playlist.rb +65 -0
- data/lib/yt/models/playlist_item.rb +42 -0
- data/lib/yt/models/rating.rb +28 -0
- data/lib/yt/models/snippet.rb +48 -0
- data/lib/yt/models/status.rb +26 -0
- data/lib/yt/models/subscription.rb +35 -0
- data/lib/yt/models/user_info.rb +66 -0
- data/lib/yt/models/video.rb +16 -0
- data/lib/yt/utils/request.rb +85 -0
- data/lib/yt/version.rb +3 -0
- data/spec/associations/device_auth/channels_spec.rb +10 -0
- data/spec/associations/device_auth/details_sets_spec.rb +19 -0
- data/spec/associations/device_auth/playlist_items_spec.rb +42 -0
- data/spec/associations/device_auth/playlists_spec.rb +42 -0
- data/spec/associations/device_auth/ratings_spec.rb +30 -0
- data/spec/associations/device_auth/snippets_spec.rb +30 -0
- data/spec/associations/device_auth/subscriptions_spec.rb +27 -0
- data/spec/associations/device_auth/user_infos_spec.rb +10 -0
- data/spec/associations/device_auth/videos_spec.rb +22 -0
- data/spec/associations/no_auth/annotations_spec.rb +15 -0
- data/spec/associations/server_auth/channels_spec.rb +2 -0
- data/spec/associations/server_auth/details_sets_spec.rb +18 -0
- data/spec/associations/server_auth/playlist_items_spec.rb +17 -0
- data/spec/associations/server_auth/playlists_spec.rb +17 -0
- data/spec/associations/server_auth/ratings_spec.rb +2 -0
- data/spec/associations/server_auth/snippets_spec.rb +28 -0
- data/spec/associations/server_auth/subscriptions_spec.rb +2 -0
- data/spec/associations/server_auth/user_infos_spec.rb +2 -0
- data/spec/associations/server_auth/videos_spec.rb +20 -0
- data/spec/collections/annotations_spec.rb +6 -0
- data/spec/collections/channels_spec.rb +6 -0
- data/spec/collections/details_sets_spec.rb +6 -0
- data/spec/collections/playlist_items_spec.rb +23 -0
- data/spec/collections/playlists_spec.rb +26 -0
- data/spec/collections/ratings_spec.rb +6 -0
- data/spec/collections/snippets_spec.rb +6 -0
- data/spec/collections/subscriptions_spec.rb +30 -0
- data/spec/collections/user_infos_spec.rb +6 -0
- data/spec/collections/videos_spec.rb +6 -0
- data/spec/models/annotation_spec.rb +131 -0
- data/spec/models/channel_spec.rb +13 -0
- data/spec/models/description_spec.rb +94 -0
- data/spec/models/details_set_spec.rb +23 -0
- data/spec/models/playlist_item_spec.rb +32 -0
- data/spec/models/playlist_spec.rb +52 -0
- data/spec/models/rating_spec.rb +13 -0
- data/spec/models/snippet_spec.rb +66 -0
- data/spec/models/status_spec.rb +42 -0
- data/spec/models/subscription_spec.rb +37 -0
- data/spec/models/user_info_spec.rb +69 -0
- data/spec/models/video_spec.rb +13 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/device_app.rb +16 -0
- data/spec/support/server_app.rb +10 -0
- data/yt.gemspec +30 -0
- metadata +209 -17
data/lib/yt/version.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/channels'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::Channels, scenario: :device_app do
|
|
5
|
+
let(:account) { Yt.configuration.account }
|
|
6
|
+
|
|
7
|
+
describe '#channel' do
|
|
8
|
+
it { require 'pry'; binding.pry; true; expect(account.channel).to be_a Yt::Channel }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/details_sets'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::DetailsSets, scenario: :device_app do
|
|
5
|
+
let(:account) { Yt.configuration.account }
|
|
6
|
+
let(:video) { Yt::Video.new id: 'fsdfsfsdMESycYJytkU', auth: account.auth }
|
|
7
|
+
|
|
8
|
+
describe '#details_set' do
|
|
9
|
+
context 'given an existing video' do
|
|
10
|
+
let(:video) { Yt::Video.new id: 'MESycYJytkU', auth: account }
|
|
11
|
+
it { expect(video.details_set).to be_a Yt::DetailsSet }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'given an unknown video' do
|
|
15
|
+
let(:video) { Yt::Video.new id: 'not-a-video-id', auth: account }
|
|
16
|
+
it { expect(video.details_set).to be_nil }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/playlist_items'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::PlaylistItems, scenario: :device_app do
|
|
5
|
+
before :all do
|
|
6
|
+
account = Yt.configuration.account
|
|
7
|
+
@playlist = account.create_playlist title: "Yt Test Playlist Items"
|
|
8
|
+
end
|
|
9
|
+
after(:all) { @playlist.delete }
|
|
10
|
+
|
|
11
|
+
describe '#playlist_items' do
|
|
12
|
+
let(:video_id) { 'MESycYJytkU' }
|
|
13
|
+
before { @playlist.add_video video_id }
|
|
14
|
+
# TODO: after, delete playlist item
|
|
15
|
+
|
|
16
|
+
it { expect(@playlist.playlist_items.count).to be > 0 }
|
|
17
|
+
it { require 'pry'; binding.pry; true; expect(@playlist.playlist_items.first).to be_a Yt::PlaylistItem }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#add_video' do
|
|
21
|
+
let(:video_id) { 'MESycYJytkU' }
|
|
22
|
+
# TODO: after, delete playlist item
|
|
23
|
+
it { expect(@playlist.add_video video_id).to be_a Yt::PlaylistItem }
|
|
24
|
+
it { expect{@playlist.add_video video_id}.to change{@playlist.playlist_items.count}.by(1) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#add_videos' do
|
|
28
|
+
let(:video_ids) { ['MESycYJytkU'] * 2 }
|
|
29
|
+
# TODO: after, delete playlist items
|
|
30
|
+
it { expect(@playlist.add_videos video_ids).to have(2).items }
|
|
31
|
+
it { expect{@playlist.add_videos video_ids}.to change{@playlist.playlist_items.count}.by(2) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
describe '#delete_playlist_items' do
|
|
36
|
+
let(:video_id) { 'MESycYJytkU' }
|
|
37
|
+
before { @playlist.add_video video_id }
|
|
38
|
+
|
|
39
|
+
it { expect(@playlist.delete_playlist_items).to eq [true] }
|
|
40
|
+
it { expect{@playlist.delete_playlist_items}.to change{@playlist.playlist_items.count}.by(-1) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/playlists'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::Playlists, scenario: :device_app do
|
|
5
|
+
let(:account) { Yt.configuration.account }
|
|
6
|
+
|
|
7
|
+
describe '#playlists' do
|
|
8
|
+
let(:params) { {title: "Yt Test Playlists" } }
|
|
9
|
+
before { account.create_playlist params }
|
|
10
|
+
after { account.delete_playlists params }
|
|
11
|
+
|
|
12
|
+
it { expect(account.playlists.count).to be > 0 }
|
|
13
|
+
it { expect(account.playlists.first).to be_a Yt::Playlist }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#create_playlist' do
|
|
17
|
+
let(:params) { {title: "Yt Test Create Playlist" } }
|
|
18
|
+
after { account.delete_playlists params }
|
|
19
|
+
|
|
20
|
+
it { expect(account.create_playlist params).to be_a Yt::Playlist }
|
|
21
|
+
it { expect{account.create_playlist params}.to change{account.playlists.count}.by(1) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe '#delete_playlists' do
|
|
25
|
+
let(:params) { {title: "Yt Test Delete Playlist #{rand}" } }
|
|
26
|
+
before { account.create_playlist params }
|
|
27
|
+
|
|
28
|
+
it { expect(account.delete_playlists params).to eq [true] }
|
|
29
|
+
it { expect{account.delete_playlists params}.to change{account.playlists.count}.by(-1) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe 'update a playlist' do
|
|
33
|
+
let(:old_title) { "Yt Test Before Update Playlist" }
|
|
34
|
+
let(:new_title) { "Yt Test After Update Playlist" }
|
|
35
|
+
before { @playlist = account.create_playlist title: old_title }
|
|
36
|
+
after { @playlist.delete }
|
|
37
|
+
|
|
38
|
+
it { expect(@playlist.update title: new_title).to eq true }
|
|
39
|
+
it { expect{@playlist.update title: new_title}.to change{@playlist.title} }
|
|
40
|
+
it { expect{@playlist.update privacy_status: 'unlisted'}.to change{@playlist.privacy_status} }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/models/video'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::Ratings, scenario: :device_app do
|
|
5
|
+
let(:account) { Yt.configuration.account }
|
|
6
|
+
|
|
7
|
+
describe '#rating' do
|
|
8
|
+
context 'given an existing video' do
|
|
9
|
+
let(:video) { Yt::Video.new id: 'MESycYJytkU', auth: account }
|
|
10
|
+
|
|
11
|
+
context 'that I like' do
|
|
12
|
+
before { video.like }
|
|
13
|
+
it { expect(video).to be_liked }
|
|
14
|
+
it { expect(video.dislike).to be_true }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'that I dislike' do
|
|
18
|
+
before { video.dislike }
|
|
19
|
+
it { expect(video).not_to be_liked }
|
|
20
|
+
it { expect(video.like).to be_true }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'that I am indifferent to' do
|
|
24
|
+
before { video.unlike }
|
|
25
|
+
it { expect(video).not_to be_liked }
|
|
26
|
+
it { expect(video.like).to be_true }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/snippets'
|
|
3
|
+
require 'yt/models/channel'
|
|
4
|
+
require 'yt/models/video'
|
|
5
|
+
|
|
6
|
+
describe Yt::Associations::Snippets, scenario: :device_app do
|
|
7
|
+
let(:account) { Yt.configuration.account }
|
|
8
|
+
|
|
9
|
+
describe '#snippet' do
|
|
10
|
+
context 'given an existing video resource' do
|
|
11
|
+
let(:video) { Yt::Video.new id: 'MESycYJytkU', auth: account }
|
|
12
|
+
it { expect(video.snippet).to be_a Yt::Snippet }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'given an unknown video resource' do
|
|
16
|
+
let(:video) { Yt::Video.new id: 'not-a-video-id', auth: account }
|
|
17
|
+
it { expect(video.snippet).to be_nil }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'given an existing channel resource' do
|
|
21
|
+
let(:channel) { Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow', auth: account }
|
|
22
|
+
it { expect(channel.snippet).to be_a Yt::Snippet }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'given an unknown channel resource' do
|
|
26
|
+
let(:channel) { Yt::Channel.new id: 'not-a-channel-id', auth: account }
|
|
27
|
+
it { expect(channel.snippet).to be_nil }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/models/channel'
|
|
3
|
+
|
|
4
|
+
# NOTE: This test is slow because we *must* wait for some seconds between
|
|
5
|
+
# subscribing and unsubscribing to a channel, otherwise YouTube will show
|
|
6
|
+
# wrong (cached) data, such as a user is subscribed when he is not.
|
|
7
|
+
describe Yt::Associations::Subscriptions, scenario: :device_app do
|
|
8
|
+
let(:account) { Yt.configuration.account }
|
|
9
|
+
|
|
10
|
+
describe '#subscription' do
|
|
11
|
+
context 'given an existing channel' do
|
|
12
|
+
let(:channel) { Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow', auth: account }
|
|
13
|
+
|
|
14
|
+
context 'that I am not subscribed to' do
|
|
15
|
+
before { channel.unsubscribe }
|
|
16
|
+
it { expect(channel.subscribed?).to be_false }
|
|
17
|
+
it { expect(channel.subscribe!).to be_true }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'that I am subscribed to' do
|
|
21
|
+
before { channel.subscribe }
|
|
22
|
+
it { expect(channel.subscribed?).to be_true }
|
|
23
|
+
it { expect(channel.unsubscribe!).to be_true }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/user_infos'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::UserInfos, scenario: :device_app do
|
|
5
|
+
let(:account) { Yt.configuration.account }
|
|
6
|
+
|
|
7
|
+
describe '#user_info' do
|
|
8
|
+
it { expect(account.user_info).to be_a Yt::UserInfo }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/videos'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::Videos, scenario: :device_app do
|
|
5
|
+
let(:account) { Yt.configuration.account }
|
|
6
|
+
|
|
7
|
+
describe '#videos' do
|
|
8
|
+
context 'given a channel with videos' do
|
|
9
|
+
let(:channel) { Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow', auth: account }
|
|
10
|
+
it { expect(channel.videos.count).to be > 0 }
|
|
11
|
+
it { expect(channel.videos.first).to be_a Yt::Video }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# NOTE: with an unknown channel id, YouTube behaves weirdly: if the
|
|
15
|
+
# wrong channel ID starts with "UC" then it returns 0 results, otherwise
|
|
16
|
+
# it ignores the channel filter and returns 100,000 results.
|
|
17
|
+
context 'given an unknown channel starting with UC' do
|
|
18
|
+
let(:channel) { Yt::Channel.new id: 'UC-not-a-channel', auth: account }
|
|
19
|
+
it { expect(channel.videos.count).to be 0 }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/annotations'
|
|
3
|
+
require 'yt/models/video'
|
|
4
|
+
|
|
5
|
+
describe Yt::Associations::Annotations do
|
|
6
|
+
subject(:annotations) { video.annotations }
|
|
7
|
+
|
|
8
|
+
describe '#annotations' do
|
|
9
|
+
context 'given an existing video with annotations' do
|
|
10
|
+
let(:video) { Yt::Video.new id: 'MESycYJytkU' }
|
|
11
|
+
it { expect(annotations.count).to be > 0 }
|
|
12
|
+
it { expect(annotations.first).to be_a Yt::Annotation }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/details_sets'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::DetailsSets, scenario: :server_app do
|
|
5
|
+
let(:video) { Yt::Video.new id: 'fsdfsfsdMESycYJytkU' }
|
|
6
|
+
|
|
7
|
+
describe '#details_set' do
|
|
8
|
+
context 'given an existing video' do
|
|
9
|
+
let(:video) { Yt::Video.new id: 'MESycYJytkU' }
|
|
10
|
+
it { expect(video.details_set).to be_a Yt::DetailsSet }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'given an unknown video' do
|
|
14
|
+
let(:video) { Yt::Video.new id: 'not-a-video-id' }
|
|
15
|
+
it { expect(video.details_set).to be_nil }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/models/playlist'
|
|
3
|
+
require 'yt/models/playlist_item'
|
|
4
|
+
|
|
5
|
+
describe Yt::Associations::PlaylistItems, scenario: :server_app do
|
|
6
|
+
describe '#playlist_items' do
|
|
7
|
+
subject(:playlist_items) { playlist.playlist_items }
|
|
8
|
+
|
|
9
|
+
context 'given an existing playlist with items' do
|
|
10
|
+
let(:playlist) { Yt::Playlist.new id: 'PLSWYkYzOrPMRCK6j0UgryI8E0NHhoVdRc' }
|
|
11
|
+
it { expect(playlist_items.first).to be_a Yt::PlaylistItem }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Creating and deleting playlist items cannot be tested with a server
|
|
16
|
+
# app because only authenticated clients can perform those actions
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/models/channel'
|
|
3
|
+
require 'yt/models/playlist'
|
|
4
|
+
|
|
5
|
+
describe Yt::Associations::Playlists, scenario: :server_app do
|
|
6
|
+
describe '#playlists' do
|
|
7
|
+
subject(:playlists) { channel.playlists }
|
|
8
|
+
|
|
9
|
+
context 'given an existing channel with playlists' do
|
|
10
|
+
let(:channel) { Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
|
11
|
+
it { expect(playlists.first).to be_a Yt::Playlist }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Creating and deleting playlist cannot be tested with a server app because
|
|
16
|
+
# only authenticated clients can perform those actions
|
|
17
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/snippets'
|
|
3
|
+
require 'yt/models/channel'
|
|
4
|
+
require 'yt/models/video'
|
|
5
|
+
|
|
6
|
+
describe Yt::Associations::Snippets, scenario: :server_app do
|
|
7
|
+
describe '#snippet' do
|
|
8
|
+
context 'given an existing video resource' do
|
|
9
|
+
let(:video) { Yt::Video.new id: 'MESycYJytkU' }
|
|
10
|
+
it { expect(video.snippet).to be_a Yt::Snippet }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'given an unknown video resource' do
|
|
14
|
+
let(:video) { Yt::Video.new id: 'not-a-video-id' }
|
|
15
|
+
it { expect(video.snippet).to be_nil }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'given an existing channel resource' do
|
|
19
|
+
let(:channel) { Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
|
20
|
+
it { expect(channel.snippet).to be_a Yt::Snippet }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'given an unknown channel resource' do
|
|
24
|
+
let(:channel) { Yt::Channel.new id: 'not-a-channel-id' }
|
|
25
|
+
it { expect(channel.snippet).to be_nil }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/associations/videos'
|
|
3
|
+
|
|
4
|
+
describe Yt::Associations::Videos, scenario: :server_app do
|
|
5
|
+
describe '#videos' do
|
|
6
|
+
context 'given a channel with videos' do
|
|
7
|
+
let(:channel) { Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow' }
|
|
8
|
+
it { expect(channel.videos.count).to be > 0 }
|
|
9
|
+
it { expect(channel.videos.first).to be_a Yt::Video }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# NOTE: with an unknown channel id, YouTube behaves weirdly: if the
|
|
13
|
+
# wrong channel ID starts with "UC" then it returns 0 results, otherwise
|
|
14
|
+
# it ignores the channel filter and returns 100,000 results.
|
|
15
|
+
context 'given an unknown channel starting with UC' do
|
|
16
|
+
let(:channel) { Yt::Channel.new id: 'UC-not-a-channel' }
|
|
17
|
+
it { expect(channel.videos.count).to be 0 }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/models/playlist'
|
|
3
|
+
require 'yt/collections/playlist_items'
|
|
4
|
+
|
|
5
|
+
describe Yt::Collections::PlaylistItems do
|
|
6
|
+
subject(:collection) { Yt::Collections::PlaylistItems.new playlist: playlist }
|
|
7
|
+
let(:playlist) { Yt::Playlist.new }
|
|
8
|
+
|
|
9
|
+
describe '#insert' do
|
|
10
|
+
let(:playlist_item) { Yt::PlaylistItem.new }
|
|
11
|
+
# TODO: separate stubs to show options translate into do_insert params
|
|
12
|
+
before { collection.stub(:do_insert).and_return playlist_item }
|
|
13
|
+
|
|
14
|
+
it { expect(collection.insert).to eq playlist_item }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
describe '#delete_all' do
|
|
19
|
+
before { collection.stub(:do_delete_all).and_return [true] }
|
|
20
|
+
|
|
21
|
+
it { expect(collection.delete_all).to eq [true] }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yt/collections/playlists'
|
|
3
|
+
|
|
4
|
+
describe Yt::Collections::Playlists do
|
|
5
|
+
subject(:collection) { Yt::Collections::Playlists.new }
|
|
6
|
+
|
|
7
|
+
describe '#insert' do
|
|
8
|
+
let(:playlist) { Yt::Playlist.new }
|
|
9
|
+
# TODO: separate stubs to show options translate into do_insert params
|
|
10
|
+
before { collection.stub(:do_insert).and_return playlist }
|
|
11
|
+
|
|
12
|
+
it { expect(collection.insert).to eq playlist }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#delete_all' do
|
|
16
|
+
before { collection.stub(:do_delete_all).and_return [true] }
|
|
17
|
+
|
|
18
|
+
it { expect(collection.delete_all).to eq [true] }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#delete_all' do
|
|
22
|
+
before { collection.stub(:do_delete_all).and_return [true] }
|
|
23
|
+
|
|
24
|
+
it { expect(collection.delete_all).to eq [true] }
|
|
25
|
+
end
|
|
26
|
+
end
|