yt 0.9.0 → 0.9.1
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 +2 -0
- data/README.md +3 -1
- data/lib/yt/collections/references.rb +36 -0
- data/lib/yt/models/content_owner.rb +4 -0
- data/lib/yt/models/playlist.rb +34 -9
- data/lib/yt/models/reference.rb +178 -0
- data/lib/yt/version.rb +1 -1
- data/spec/models/reference_spec.rb +249 -0
- data/spec/requests/as_account/playlist_spec.rb +59 -11
- data/spec/requests/as_content_owner/content_owner_spec.rb +28 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8853f3441a92a6cb17f3a73193f1b21b7f3a5a3d
|
4
|
+
data.tar.gz: f23617ccbf92ae86d002de6a412a083db7015d93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39f3ac3e556b1194961d346da9c13ddbc6ce370e44c9063af679c834fa290ca9b6ae110fb63456fa1e973ee7dad7e9cc6d42b6626a230912239e18c440b1d2d0
|
7
|
+
data.tar.gz: e7cd4d3d44ba2fa7faeb0b1d3da548f07098f2c55a6dba2b0d35decf8dcdecbf134d39a039ddf6d259a0228de14f9138ebb212a2a4db74e550d78ab8bf452816
|
data/.travis.yml
CHANGED
@@ -28,3 +28,4 @@ env:
|
|
28
28
|
- secure: WICaR3cq/6SS4855tAJSZx0H/EkovfZZsxHY66y/lQ20p+DYJ0l6Jc6CRaZNvDPtj6Zp9Lu72CB2v6J2AO1WkrAvVBiMEj5zkPtVHwCcHxH0FasQCTFaLWy/zvcQeEIvidcBqABMsq1Pqv8p7UD8BRoQq22Vfe2LEjT/X2/eJwY=
|
29
29
|
- secure: E1ZoB5XyFxn3b9RVnXgt/JY+ikKLw57+CGcim0us8SdIwKctH8IWv0U7MggWATw2KtLgxEt1YU5MRFBxdO3nWY7XkvsYVCbLpmyFFzSDGZLNaaSLRZqon/N1lwias1pvOFL8cN2yLFXj6qMH67dBCyuQ1Q9LhejlWiGRBiLjfF8=
|
30
30
|
- secure: TnQ7HnvTM7pTwO0G7gYj+UjxxhPd0TOYAgHiafExrfr2nG+mkv1tc2OY/f1iB6kNp3+KEw+sNuyVZd1M9pFL93ARhla6FKqi/JoYFR0E2CxiVzAbLcabdtglqb8Jxw9a73YG7zFABZBWdTo5eR0TvpIK+rdTneUaEyCNU+Plh1E=
|
31
|
+
- secure: bZs3JaE02u3eS7hx7CXNZrUigSdYpbnKUdaHfNj7If0emfh15Tv6WaIszcKPVFUj1hMy6jeJcGJlAkYPA6iczLlmkD/1vzr75t1cNhXdCVq27uH3KWF6TN+/XsX1s4A29eIQTuHZ9q5qJyFyZVujqg1hvGjt0CSJYPxO+0muucE=
|
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -41,7 +41,7 @@ To install on your system, run
|
|
41
41
|
|
42
42
|
To use inside a bundled Ruby project, add this line to the Gemfile:
|
43
43
|
|
44
|
-
gem 'yt', '~> 0.9.
|
44
|
+
gem 'yt', '~> 0.9.1'
|
45
45
|
|
46
46
|
Since the gem follows [Semantic Versioning](http://semver.org),
|
47
47
|
indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
|
@@ -105,6 +105,8 @@ content_owner.partnered_channels.first #=> #<Yt::Models::Channel @id=...>
|
|
105
105
|
|
106
106
|
content_owner.claims.where(q: 'Fullscreen').count #=> 24
|
107
107
|
content_owner.claims.first #=> #<Yt::Models::Claim @id=...>
|
108
|
+
|
109
|
+
content_owner.references.where(asset_id: "ABCDEFG").first => #<Yt::Models::Reference @id=...>
|
108
110
|
```
|
109
111
|
|
110
112
|
*All the above methods require authentication (see below).*
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/reference'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Collections
|
6
|
+
# Provides methods to interact with a collection of Content ID references.
|
7
|
+
#
|
8
|
+
# Resources with references are: {Yt::Models::ContentOwner content owners}.
|
9
|
+
class References < Base
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def new_item(data)
|
14
|
+
Yt::Reference.new data: data
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Hash] the parameters to submit to YouTube to list references
|
18
|
+
# administered by the content owner.
|
19
|
+
# @see https://developers.google.com/youtube/partner/docs/v1/references/list
|
20
|
+
def list_params
|
21
|
+
super.tap do |params|
|
22
|
+
params[:params] = references_params
|
23
|
+
params[:path] = '/youtube/partner/v1/references'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def references_params
|
28
|
+
{onBehalfOfContentOwner: @parent.owner_name}.tap do |params|
|
29
|
+
(@extra_params ||= {}).each do |key, value|
|
30
|
+
params[key.to_s.camelize :lower] = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -15,6 +15,10 @@ module Yt
|
|
15
15
|
# @return [Yt::Collection::Claims] the claims administered by the content owner.
|
16
16
|
has_many :claims
|
17
17
|
|
18
|
+
# @!attribute [r] references
|
19
|
+
# @return [Yt::Collection::References] the references administered by the content owner.
|
20
|
+
has_many :references
|
21
|
+
|
18
22
|
def initialize(options = {})
|
19
23
|
super options
|
20
24
|
@owner_name = options[:owner_name]
|
data/lib/yt/models/playlist.rb
CHANGED
@@ -23,17 +23,23 @@ module Yt
|
|
23
23
|
!exists?
|
24
24
|
end
|
25
25
|
|
26
|
-
def update(
|
27
|
-
|
28
|
-
options[:description] ||= description
|
29
|
-
options[:tags] ||= tags
|
30
|
-
options[:privacy_status] ||= privacy_status
|
26
|
+
def update(attributes = {})
|
27
|
+
underscore_keys! attributes
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
body = {id: @id}.tap do |body|
|
30
|
+
update_parts.each do |part, options|
|
31
|
+
if (options[:keys] & attributes.keys).any? || options[:required]
|
32
|
+
body[part] = {}.tap do |hash|
|
33
|
+
options[:keys].map do |key|
|
34
|
+
hash[camelize key] = attributes[key] || send(key)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
35
40
|
|
36
|
-
|
41
|
+
part = body.except(:id).keys.join(',')
|
42
|
+
do_update(params: {part: part}, body: body) do |data|
|
37
43
|
@id = data['id']
|
38
44
|
@snippet = Snippet.new data: data['snippet'] if data['snippet']
|
39
45
|
@status = Status.new data: data['status'] if data['status']
|
@@ -75,6 +81,25 @@ module Yt
|
|
75
81
|
|
76
82
|
private
|
77
83
|
|
84
|
+
# @see https://developers.google.com/youtube/v3/docs/playlists/update
|
85
|
+
def update_parts
|
86
|
+
snippet = {keys: [:title, :description, :tags], required: true}
|
87
|
+
status = {keys: [:privacy_status]}
|
88
|
+
{snippet: snippet, status: status}
|
89
|
+
end
|
90
|
+
|
91
|
+
# @note If we dropped support for ActiveSupport 3, then we could simply
|
92
|
+
# invoke transform_keys!{|key| key.to_s.underscore.to_sym}
|
93
|
+
def underscore_keys!(hash)
|
94
|
+
hash.dup.each_key do |key|
|
95
|
+
hash[key.to_s.underscore.to_sym] = hash.delete key
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def camelize(value)
|
100
|
+
value.to_s.camelize(:lower).to_sym
|
101
|
+
end
|
102
|
+
|
78
103
|
def video_params(video_id)
|
79
104
|
{id: video_id, kind: :video}
|
80
105
|
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'yt/models/base'
|
2
|
+
|
3
|
+
module Yt
|
4
|
+
module Models
|
5
|
+
# Provides methods to interact with YouTube ContentID references.
|
6
|
+
# @see https://developers.google.com/youtube/partner/docs/v1/references
|
7
|
+
class Reference < Base
|
8
|
+
def initialize(options = {})
|
9
|
+
@data = options[:data]
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String] the ID that YouTube assigns and uses to uniquely
|
13
|
+
# identify the reference.
|
14
|
+
def id
|
15
|
+
@id ||= @data['id']
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String] the ID that uniquely identifies the asset that the
|
19
|
+
# reference is associated with.
|
20
|
+
def asset_id
|
21
|
+
@asset_id ||= @data["assetId"]
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Float] The length of the reference in seconds
|
25
|
+
def length
|
26
|
+
@length ||= @data["length"]
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String] the ID of the source video. This field is only present
|
30
|
+
# if the reference was created by associating an asset with an existing
|
31
|
+
# YouTube video that was uploaded to a YouTube channel linked to your
|
32
|
+
# CMS account.
|
33
|
+
def video_id
|
34
|
+
@video_id ||= @data["videoId"]
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String] the claim ID that represents the resulting association
|
38
|
+
# between the asset and the video. This field is only present if the
|
39
|
+
# reference was created by associating an asset with an existing
|
40
|
+
# YouTube video that was uploaded to a YouTube channel linked to your
|
41
|
+
# CMS account.
|
42
|
+
def claim_id
|
43
|
+
@claim_id ||= @data["claimId"]
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [boolean] whether or not the reference content is included in
|
47
|
+
# YouTube's AudioSwap program. Set this field's value to true to
|
48
|
+
# indicate that the reference content should be included in YouTube's
|
49
|
+
# AudioSwap program.
|
50
|
+
def audioswap_enabled?
|
51
|
+
@audioswap_enabled ||= @data["audioswapEnabled"]
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [boolean] should the reference be used to generate claims. Set
|
55
|
+
# this value to true to indicate that the reference should not be used
|
56
|
+
# to generate claims. This field is only used on AudioSwap references.
|
57
|
+
def ignore_fp_match?
|
58
|
+
@ignore_fp_match ||= @data["ignoreFpMatch"]
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Boolean] the urgent status of the reference file.
|
62
|
+
# Set this value to true to indicate that YouTube should prioritize
|
63
|
+
# Content ID processing for a video file. YouTube processes urgent
|
64
|
+
# video files before other files that are not marked as urgent.
|
65
|
+
# This setting is primarily used for videos of live events or other
|
66
|
+
# videos that require time-sensitive processing.
|
67
|
+
# The sooner YouTube completes Content ID processing for a video, the
|
68
|
+
# sooner YouTube can match user-uploaded videos to that video.
|
69
|
+
def urgent?
|
70
|
+
@urgent ||= @data["urgent"]
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [String] An explanation of how a reference entered its current
|
74
|
+
# state. This value is only present if the reference’s status is either
|
75
|
+
# inactive or deleted.
|
76
|
+
def status_reason
|
77
|
+
@status_reason ||= @data["statusReason"]
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [String] The ID that uniquely identifies the reference that
|
81
|
+
# this reference duplicates. This field is only present if the
|
82
|
+
# reference’s status is duplicate_on_hold.
|
83
|
+
def duplicate_leader
|
84
|
+
@duplicate_leader ||= @data["duplicateLeader"]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Status
|
88
|
+
|
89
|
+
STATUSES = %q(activating active checking computing_fingerprint deleted
|
90
|
+
duplicate_on_hold inactive live_streaming_processing
|
91
|
+
urgent_reference_processing)
|
92
|
+
|
93
|
+
# @return [String] the reference’s status. Valid values are: activating,
|
94
|
+
# active, checking, computing_fingerprint, deleted, duplicate_on_hold,
|
95
|
+
# inactive, live_streaming_processing, and urgent_reference_processing.
|
96
|
+
def status
|
97
|
+
@status ||= @data["status"]
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Boolean] whether the reference is pending.
|
101
|
+
def activating?
|
102
|
+
status == 'activating'
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Boolean] whether the reference is active.
|
106
|
+
def active?
|
107
|
+
status == 'active'
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [Boolean] whether the reference is being compared to existing
|
111
|
+
# references to identify any reference conflicts that might exist.
|
112
|
+
def checking?
|
113
|
+
status == 'checking'
|
114
|
+
end
|
115
|
+
|
116
|
+
# @return [Boolean] whether the reference’s fingerprint is being
|
117
|
+
# computed.
|
118
|
+
def computing_fingerprint?
|
119
|
+
status == 'computing_fingerprint'
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return [Boolean] whether the reference is deleted.
|
123
|
+
def deleted?
|
124
|
+
status == 'deleted'
|
125
|
+
end
|
126
|
+
|
127
|
+
# @return [Boolean] whether the reference iis a duplicate and is on hold.
|
128
|
+
def duplicate_on_hold?
|
129
|
+
status == 'duplicate_on_hold'
|
130
|
+
end
|
131
|
+
|
132
|
+
# @return [Boolean] whether the reference is inactive.
|
133
|
+
def inactive?
|
134
|
+
status == 'inactive'
|
135
|
+
end
|
136
|
+
|
137
|
+
# @return [Boolean] whether the reference is being processed from a live
|
138
|
+
# video stream.
|
139
|
+
def live_streaming_processing?
|
140
|
+
status == 'live_streaming_processing'
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Boolean] whether the reference is urgent_reference_processing.
|
144
|
+
def urgent_reference_processing?
|
145
|
+
status == 'urgent_reference_processing'
|
146
|
+
end
|
147
|
+
|
148
|
+
# Content Type
|
149
|
+
|
150
|
+
CONTENT_TYPES = %q(audio video audiovisual)
|
151
|
+
|
152
|
+
# @return [String] whether the reference covers the audio, video, or
|
153
|
+
# audiovisual portion of the claimed content. Valid values are: audio,
|
154
|
+
# audiovisual, video.
|
155
|
+
def content_type
|
156
|
+
@content_type ||= @data["contentType"]
|
157
|
+
end
|
158
|
+
|
159
|
+
# @return [Boolean] whether the reference covers the audio of the
|
160
|
+
# content.
|
161
|
+
def audio?
|
162
|
+
content_type == 'audio'
|
163
|
+
end
|
164
|
+
|
165
|
+
# @return [Boolean] whether the reference covers the video of the
|
166
|
+
# content.
|
167
|
+
def video?
|
168
|
+
content_type == 'video'
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [Boolean] whether the reference covers the audiovisual of the
|
172
|
+
# content.
|
173
|
+
def audiovisual?
|
174
|
+
content_type == 'audiovisual'
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
data/lib/yt/version.rb
CHANGED
@@ -0,0 +1,249 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/models/reference'
|
3
|
+
|
4
|
+
describe Yt::Reference do
|
5
|
+
subject(:reference) { Yt::Reference.new data: data }
|
6
|
+
|
7
|
+
describe '#id' do
|
8
|
+
context 'given fetching a reference returns an id' do
|
9
|
+
let(:data) { {"id"=>"aBcD1EfGHIk"} }
|
10
|
+
it { expect(reference.id).to eq 'aBcD1EfGHIk' }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#asset_id' do
|
15
|
+
context 'given fetching a reference returns an assetId' do
|
16
|
+
let(:data) { {"assetId"=>"A123456789012601"} }
|
17
|
+
it { expect(reference.asset_id).to eq 'A123456789012601' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#status' do
|
22
|
+
context 'given fetching a reference returns a status' do
|
23
|
+
let(:data) { {"status"=>"active"} }
|
24
|
+
it { expect(reference.status).to eq 'active' }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#activating?' do
|
29
|
+
context 'given fetching a reference returns an activating status' do
|
30
|
+
let(:data) { {"status"=>"activating"} }
|
31
|
+
it { expect(reference).to be_activating }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'given fetching a reference does not return an activating status' do
|
35
|
+
let(:data) { {"status"=>"unknown"} }
|
36
|
+
it { expect(reference).not_to be_activating }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#active?' do
|
41
|
+
context 'given fetching a reference returns an active status' do
|
42
|
+
let(:data) { {"status"=>"active"} }
|
43
|
+
it { expect(reference).to be_active }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'given fetching a reference does not return an active status' do
|
47
|
+
let(:data) { {"status"=>"unknown"} }
|
48
|
+
it { expect(reference).not_to be_active }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#checking?' do
|
53
|
+
context 'given fetching a reference returns an checking status' do
|
54
|
+
let(:data) { {"status"=>"checking"} }
|
55
|
+
it { expect(reference).to be_checking }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'given fetching a reference does not return an checking status' do
|
59
|
+
let(:data) { {"status"=>"unknown"} }
|
60
|
+
it { expect(reference).not_to be_checking }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#computing_fingerprint?' do
|
65
|
+
context 'given fetching a reference returns an computing_fingerprint status' do
|
66
|
+
let(:data) { {"status"=>"computing_fingerprint"} }
|
67
|
+
it { expect(reference).to be_computing_fingerprint }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'given fetching a reference does not return an computing_fingerprint status' do
|
71
|
+
let(:data) { {"status"=>"unknown"} }
|
72
|
+
it { expect(reference).not_to be_computing_fingerprint }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#deleted?' do
|
77
|
+
context 'given fetching a reference returns an deleted status' do
|
78
|
+
let(:data) { {"status"=>"deleted"} }
|
79
|
+
it { expect(reference).to be_deleted }
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'given fetching a reference does not return an deleted status' do
|
83
|
+
let(:data) { {"status"=>"unknown"} }
|
84
|
+
it { expect(reference).not_to be_deleted }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#duplicate_on_hold?' do
|
89
|
+
context 'given fetching a reference returns an duplicate_on_hold status' do
|
90
|
+
let(:data) { {"status"=>"duplicate_on_hold"} }
|
91
|
+
it { expect(reference).to be_duplicate_on_hold }
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'given fetching a reference does not return an duplicate_on_hold status' do
|
95
|
+
let(:data) { {"status"=>"unknown"} }
|
96
|
+
it { expect(reference).not_to be_duplicate_on_hold }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#inactive?' do
|
101
|
+
context 'given fetching a reference returns an inactive status' do
|
102
|
+
let(:data) { {"status"=>"inactive"} }
|
103
|
+
it { expect(reference).to be_inactive }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'given fetching a reference does not return an inactive status' do
|
107
|
+
let(:data) { {"status"=>"unknown"} }
|
108
|
+
it { expect(reference).not_to be_inactive }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#live_streaming_processing?' do
|
113
|
+
context 'given fetching a reference returns an live_streaming_processing status' do
|
114
|
+
let(:data) { {"status"=>"live_streaming_processing"} }
|
115
|
+
it { expect(reference).to be_live_streaming_processing }
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'given fetching a reference does not return an live_streaming_processing status' do
|
119
|
+
let(:data) { {"status"=>"unknown"} }
|
120
|
+
it { expect(reference).not_to be_live_streaming_processing }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#urgent_reference_processing?' do
|
125
|
+
context 'given fetching a reference returns an urgent_reference_processing status' do
|
126
|
+
let(:data) { {"status"=>"urgent_reference_processing"} }
|
127
|
+
it { expect(reference).to be_urgent_reference_processing }
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'given fetching a reference does not return an urgent_reference_processing status' do
|
131
|
+
let(:data) { {"status"=>"unknown"} }
|
132
|
+
it { expect(reference).not_to be_urgent_reference_processing }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '#status_reason' do
|
137
|
+
context 'given fetching a reference returns a statusReason' do
|
138
|
+
let(:data) { {"statusReason"=>"explanation"} }
|
139
|
+
it { expect(reference.status_reason).to eq 'explanation' }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#duplicate_leader' do
|
144
|
+
context 'given fetching a reference returns a duplicateLeader' do
|
145
|
+
let(:data) { {"duplicateLeader"=>"123456"} }
|
146
|
+
it { expect(reference.duplicate_leader).to eq '123456' }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#length' do
|
151
|
+
context 'given fetching a reference returns a length' do
|
152
|
+
let(:data) { {"length"=>354.66} }
|
153
|
+
it { expect(reference.length).to eq 354.66 }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#video_id' do
|
158
|
+
context 'given fetching a reference returns an videoId' do
|
159
|
+
let(:data) { {"videoId"=>"MESycYJytkU"} }
|
160
|
+
it { expect(reference.video_id).to eq 'MESycYJytkU' }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '#claim_id' do
|
165
|
+
context 'given fetching a reference returns an claimId' do
|
166
|
+
let(:data) { {"claimId"=>"aBcD1EfGHIk"} }
|
167
|
+
it { expect(reference.claim_id).to eq 'aBcD1EfGHIk' }
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe '#urgent?' do
|
172
|
+
context 'given fetching a reference returns an urgent status true' do
|
173
|
+
let(:data) { {"urgent"=>true} }
|
174
|
+
it { expect(reference).to be_urgent }
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'given fetching a reference returns an urgent status false' do
|
178
|
+
let(:data) { {"urgent"=>false} }
|
179
|
+
it { expect(reference).not_to be_urgent }
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe '#content_type' do
|
184
|
+
context 'given fetching a reference returns a content type' do
|
185
|
+
let(:data) { {"contentType"=>"audio"} }
|
186
|
+
it { expect(reference.content_type).to eq 'audio' }
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe '#audio?' do
|
191
|
+
context 'given fetching a reference returns an audio content type' do
|
192
|
+
let(:data) { {"contentType"=>"audio"} }
|
193
|
+
it { expect(reference).to be_audio }
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'given fetching a reference does not return an audio content type' do
|
197
|
+
let(:data) { {"contentType"=>"audiovisual"} }
|
198
|
+
it { expect(reference).not_to be_audio }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe '#video?' do
|
203
|
+
context 'given fetching a reference returns an video content type' do
|
204
|
+
let(:data) { {"contentType"=>"video"} }
|
205
|
+
it { expect(reference).to be_video }
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'given fetching a reference does not return an video content type' do
|
209
|
+
let(:data) { {"contentType"=>"audiovisual"} }
|
210
|
+
it { expect(reference).not_to be_video }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe '#audiovisual?' do
|
215
|
+
context 'given fetching a reference returns an audiovisual content type' do
|
216
|
+
let(:data) { {"contentType"=>"audiovisual"} }
|
217
|
+
it { expect(reference).to be_audiovisual }
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'given fetching a reference does not return an audiovisual content type' do
|
221
|
+
let(:data) { {"contentType"=>"audio"} }
|
222
|
+
it { expect(reference).not_to be_audiovisual }
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe '#audioswap_enabled?' do
|
227
|
+
context 'given fetching a reference returns audioswapEnabled true' do
|
228
|
+
let(:data) { {"audioswapEnabled"=>true} }
|
229
|
+
it { expect(reference).to be_audioswap_enabled }
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'given fetching a reference returns audioswapEnabled false' do
|
233
|
+
let(:data) { {"audioswap_enabled"=>false} }
|
234
|
+
it { expect(reference).not_to be_audioswap_enabled }
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe '#ignore_fp_match?' do
|
239
|
+
context 'given fetching a reference returns ignoreFpMatch true' do
|
240
|
+
let(:data) { {"ignoreFpMatch"=>true} }
|
241
|
+
it { expect(reference.ignore_fp_match?).to be true }
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'given fetching a reference returns ignoreFpMatch false' do
|
245
|
+
let(:data) { {"ignoreFpMatch"=>false} }
|
246
|
+
it { expect(reference.ignore_fp_match?).to be false }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -51,20 +51,68 @@ describe Yt::Playlist, :device_app do
|
|
51
51
|
before(:all) { @my_playlist = $account.create_playlist title: "Yt Test Update Playlist #{rand}" }
|
52
52
|
after(:all) { @my_playlist.delete }
|
53
53
|
let(:id) { @my_playlist.id }
|
54
|
+
let!(:old_title) { @my_playlist.title }
|
55
|
+
let!(:old_privacy_status) { @my_playlist.privacy_status }
|
56
|
+
let(:update) { @my_playlist.update attrs }
|
57
|
+
|
58
|
+
context 'given I update the title' do
|
59
|
+
# NOTE: The use of UTF-8 characters is to test that we can pass up to
|
60
|
+
# 50 characters, independently of their representation
|
61
|
+
let(:attrs) { {title: "Yt Example Update Playlist #{rand} - ®•♡❥❦❧☙"} }
|
62
|
+
|
63
|
+
specify 'only updates the title' do
|
64
|
+
expect(update).to be true
|
65
|
+
expect(@my_playlist.title).not_to eq old_title
|
66
|
+
expect(@my_playlist.privacy_status).to eq old_privacy_status
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'given I update the description' do
|
71
|
+
let!(:old_description) { @my_playlist.description }
|
72
|
+
let(:attrs) { {description: "Yt Example Description #{rand} - ®•♡❥❦❧☙"} }
|
73
|
+
|
74
|
+
specify 'only updates the description' do
|
75
|
+
expect(update).to be true
|
76
|
+
expect(@my_playlist.description).not_to eq old_description
|
77
|
+
expect(@my_playlist.title).to eq old_title
|
78
|
+
expect(@my_playlist.privacy_status).to eq old_privacy_status
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'given I update the tags' do
|
83
|
+
let!(:old_tags) { @my_playlist.tags }
|
84
|
+
let(:attrs) { {tags: ["Yt Test Tag #{rand}"]} }
|
54
85
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
86
|
+
specify 'only updates the tag' do
|
87
|
+
expect(update).to be true
|
88
|
+
expect(@my_playlist.tags).not_to eq old_tags
|
89
|
+
expect(@my_playlist.title).to eq old_title
|
90
|
+
expect(@my_playlist.privacy_status).to eq old_privacy_status
|
91
|
+
end
|
59
92
|
end
|
60
93
|
|
61
|
-
|
62
|
-
let(:
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
94
|
+
context 'given I update the privacy status' do
|
95
|
+
let!(:new_privacy_status) { old_privacy_status == 'private' ? 'unlisted' : 'private' }
|
96
|
+
|
97
|
+
context 'passing the parameter in underscore syntax' do
|
98
|
+
let(:attrs) { {privacy_status: new_privacy_status} }
|
99
|
+
|
100
|
+
specify 'only updates the privacy status' do
|
101
|
+
expect(update).to be true
|
102
|
+
expect(@my_playlist.privacy_status).not_to eq old_privacy_status
|
103
|
+
expect(@my_playlist.title).to eq old_title
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'passing the parameter in camel-case syntax' do
|
108
|
+
let(:attrs) { {privacyStatus: new_privacy_status} }
|
109
|
+
|
110
|
+
specify 'only updates the privacy status' do
|
111
|
+
expect(update).to be true
|
112
|
+
expect(@my_playlist.privacy_status).not_to eq old_privacy_status
|
113
|
+
expect(@my_playlist.title).to eq old_title
|
114
|
+
end
|
115
|
+
end
|
68
116
|
end
|
69
117
|
|
70
118
|
context 'given an existing video' do
|
@@ -85,4 +85,32 @@ describe Yt::ContentOwner, :partner do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
describe '.references' do
|
90
|
+
describe '.where(id: reference_id)' do
|
91
|
+
let(:reference) { $content_owner.references.where(id: reference_id).first }
|
92
|
+
|
93
|
+
context 'given the ID of a reference administered by the content owner' do
|
94
|
+
let(:reference_id) { ENV['YT_TEST_PARTNER_REFERENCE_ID'] }
|
95
|
+
|
96
|
+
it 'returns valid metadata' do
|
97
|
+
expect(reference.id).to be_a String
|
98
|
+
expect(reference.asset_id).to be_a String
|
99
|
+
expect(reference.length).to be_a Float
|
100
|
+
expect(reference.video_id).to be_a String
|
101
|
+
expect(reference.claim_id).to be_a String
|
102
|
+
expect(reference.audioswap_enabled?).to be_in [true, false]
|
103
|
+
expect(reference.ignore_fp_match?).to be_in [true, false]
|
104
|
+
expect(reference.urgent?).to be_in [true, false]
|
105
|
+
expect(reference.status).to be_in Yt::Reference::STATUSES
|
106
|
+
expect(reference.content_type).to be_in Yt::Reference::CONTENT_TYPES
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'given an unknown reference ID' do
|
111
|
+
let(:reference_id) { '--not-a-matching-reference-id--' }
|
112
|
+
it { expect(reference).not_to be }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
88
116
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Baccigalupo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/yt/collections/playlist_items.rb
|
142
142
|
- lib/yt/collections/playlists.rb
|
143
143
|
- lib/yt/collections/ratings.rb
|
144
|
+
- lib/yt/collections/references.rb
|
144
145
|
- lib/yt/collections/reports.rb
|
145
146
|
- lib/yt/collections/resources.rb
|
146
147
|
- lib/yt/collections/resumable_sessions.rb
|
@@ -173,6 +174,7 @@ files:
|
|
173
174
|
- lib/yt/models/playlist.rb
|
174
175
|
- lib/yt/models/playlist_item.rb
|
175
176
|
- lib/yt/models/rating.rb
|
177
|
+
- lib/yt/models/reference.rb
|
176
178
|
- lib/yt/models/request.rb
|
177
179
|
- lib/yt/models/resource.rb
|
178
180
|
- lib/yt/models/resumable_session.rb
|
@@ -208,6 +210,7 @@ files:
|
|
208
210
|
- spec/models/playlist_item_spec.rb
|
209
211
|
- spec/models/playlist_spec.rb
|
210
212
|
- spec/models/rating_spec.rb
|
213
|
+
- spec/models/reference_spec.rb
|
211
214
|
- spec/models/request_spec.rb
|
212
215
|
- spec/models/resource_spec.rb
|
213
216
|
- spec/models/snippet_spec.rb
|
@@ -289,6 +292,7 @@ test_files:
|
|
289
292
|
- spec/models/playlist_item_spec.rb
|
290
293
|
- spec/models/playlist_spec.rb
|
291
294
|
- spec/models/rating_spec.rb
|
295
|
+
- spec/models/reference_spec.rb
|
292
296
|
- spec/models/request_spec.rb
|
293
297
|
- spec/models/resource_spec.rb
|
294
298
|
- spec/models/snippet_spec.rb
|