yt 0.11.1 → 0.11.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -0
  4. data/CHANGELOG.md +31 -33
  5. data/README.md +94 -3
  6. data/lib/yt.rb +1 -0
  7. data/lib/yt/actions/base.rb +19 -0
  8. data/lib/yt/actions/insert.rb +2 -0
  9. data/lib/yt/actions/list.rb +0 -7
  10. data/lib/yt/actions/modify.rb +2 -0
  11. data/lib/yt/collections/assets.rb +32 -0
  12. data/lib/yt/collections/authentications.rb +1 -0
  13. data/lib/yt/collections/claims.rb +16 -1
  14. data/lib/yt/collections/ownerships.rb +34 -0
  15. data/lib/yt/collections/references.rb +2 -12
  16. data/lib/yt/collections/resources.rb +0 -10
  17. data/lib/yt/models/account.rb +1 -1
  18. data/lib/yt/models/advertising_options_set.rb +33 -0
  19. data/lib/yt/models/asset.rb +100 -0
  20. data/lib/yt/models/channel.rb +1 -1
  21. data/lib/yt/models/claim.rb +22 -0
  22. data/lib/yt/models/content_owner.rb +16 -4
  23. data/lib/yt/models/match_policy.rb +2 -12
  24. data/lib/yt/models/ownership.rb +70 -0
  25. data/lib/yt/models/reference.rb +1 -1
  26. data/lib/yt/models/request.rb +13 -2
  27. data/lib/yt/models/resource.rb +0 -10
  28. data/lib/yt/models/resumable_session.rb +1 -0
  29. data/lib/yt/models/right_owner.rb +69 -0
  30. data/lib/yt/version.rb +1 -1
  31. data/spec/models/asset_spec.rb +20 -0
  32. data/spec/models/ownership_spec.rb +59 -0
  33. data/spec/models/right_owner_spec.rb +71 -0
  34. data/spec/requests/as_content_owner/advertising_options_set_spec.rb +15 -0
  35. data/spec/requests/as_content_owner/asset_spec.rb +12 -0
  36. data/spec/requests/as_content_owner/content_owner_spec.rb +37 -2
  37. data/spec/requests/as_content_owner/ownership_spec.rb +19 -0
  38. metadata +21 -3
  39. data/Gemfile.lock +0 -69
@@ -39,6 +39,7 @@ module Yt
39
39
  params[:path] = @uri.path
40
40
  params[:expected_response] = Net::HTTPSuccess
41
41
  params[:headers] = @headers
42
+ params[:camelize_params] = false
42
43
  params[:params] = session_params
43
44
  end
44
45
  end
@@ -0,0 +1,69 @@
1
+ require 'yt/models/description'
2
+
3
+ module Yt
4
+ module Models
5
+ # Encapsulates information about the various types of owners of an asset.
6
+ # @see https://developers.google.com/youtube/partner/docs/v1/ownership#resource
7
+ class RightOwner
8
+ def initialize(options = {})
9
+ @data = options[:data]
10
+ end
11
+
12
+ # @return [Float] the percentage of the asset that the owner controls or
13
+ # administers. For composition assets, the value can be any value
14
+ # between 0 and 100 inclusive. For all other assets, the only valid
15
+ # values are 100, which indicates that the owner completely owns the
16
+ # asset in the specified territories, and 0, which indicates that you
17
+ # are removing ownership of the asset in the specified territories.
18
+ def ratio
19
+ @ratio ||= @data['ratio'].to_f
20
+ end
21
+
22
+ # @return [String] the name of the asset’s owner or rights administrator.
23
+ def owner
24
+ @owner ||= @data['owner']
25
+ end
26
+
27
+ # @return [String] if the asset is a composition asset and the asset
28
+ # owner is not known to have a formal relationship established with
29
+ # YouTube, the name of the asset’s publisher or rights administrator.
30
+ # @return [nil] otherwise.
31
+ def publisher
32
+ @publisher ||= @data['publisher']
33
+ end
34
+
35
+ # Return the list of territories where the owner owns the asset.
36
+ # Each territory is an ISO 3166 two-letter country code.
37
+ # @return [Array<String>] if the ownership lists 'included' territories,
38
+ # the territories where the owner owns the asset.
39
+ # @return [nil] if the ownership does not list 'included' territories,
40
+ def included_territories
41
+ territories if type == 'include'
42
+ end
43
+
44
+ # Return the list of territories where the owner does not own the asset.
45
+ # Each territory is an ISO 3166 two-letter country code.
46
+ # @return [Array<String>] if the ownership lists 'excluded' territories,
47
+ # the territories where the owner does not own the asset.
48
+ # @return [nil] if the ownership does not list 'excluded' territories,
49
+ def excluded_territories
50
+ territories if type == 'exclude'
51
+ end
52
+
53
+ # @return [Boolean] whether the ownership applies to the whole world.
54
+ def everywhere?
55
+ excluded_territories == []
56
+ end
57
+
58
+ private
59
+
60
+ def type
61
+ @type ||= @data['type']
62
+ end
63
+
64
+ def territories
65
+ @territories ||= @data.fetch 'territories', []
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.11.1'
2
+ VERSION = '0.11.2'
3
3
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/asset'
3
+
4
+ describe Yt::Asset do
5
+ subject(:asset) { Yt::Asset.new data: data }
6
+
7
+ describe '#id' do
8
+ context 'given fetching a asset returns an id' do
9
+ let(:data) { {"id"=>"A123456789012345"} }
10
+ it { expect(asset.id).to eq 'A123456789012345' }
11
+ end
12
+ end
13
+
14
+ describe '#type' do
15
+ context 'given fetching a asset returns an type' do
16
+ let(:data) { {"type"=>"web"} }
17
+ it { expect(asset.type).to eq 'web' }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/ownership'
3
+
4
+ describe Yt::Ownership do
5
+ subject(:ownership) { Yt::Ownership.new data: data }
6
+ let(:data) { {} }
7
+
8
+ describe '#general_owners' do
9
+ context 'given fetching an ownership returns a general owner' do
10
+ let(:general) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
11
+ let(:data) { {"general"=>[general]} }
12
+ it { expect(ownership.general_owners.size).to be 1 }
13
+ it { expect(ownership.general_owners.first).to be_a Yt::RightOwner }
14
+ end
15
+
16
+ context 'given fetching an ownership does not return general owners' do
17
+ it { expect(ownership.general_owners).to be_empty }
18
+ end
19
+ end
20
+
21
+ describe '#performance_owners' do
22
+ context 'given fetching an ownership returns a performance owner' do
23
+ let(:performance) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
24
+ let(:data) { {"performance"=>[performance]} }
25
+ it { expect(ownership.performance_owners.size).to be 1 }
26
+ it { expect(ownership.performance_owners.first).to be_a Yt::RightOwner }
27
+ end
28
+
29
+ context 'given fetching an ownership does not return performance owners' do
30
+ it { expect(ownership.performance_owners).to be_empty }
31
+ end
32
+ end
33
+
34
+ describe '#synchronization_owners' do
35
+ context 'given fetching an ownership returns a synchronization owner' do
36
+ let(:synchronization) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
37
+ let(:data) { {"synchronization"=>[synchronization]} }
38
+ it { expect(ownership.synchronization_owners.size).to be 1 }
39
+ it { expect(ownership.synchronization_owners.first).to be_a Yt::RightOwner }
40
+ end
41
+
42
+ context 'given fetching an ownership does not return synchronization owners' do
43
+ it { expect(ownership.synchronization_owners).to be_empty }
44
+ end
45
+ end
46
+
47
+ describe '#mechanical_owners' do
48
+ context 'given fetching an ownership returns a mechanical owner' do
49
+ let(:mechanical) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
50
+ let(:data) { {"mechanical"=>[mechanical]} }
51
+ it { expect(ownership.mechanical_owners.size).to be 1 }
52
+ it { expect(ownership.mechanical_owners.first).to be_a Yt::RightOwner }
53
+ end
54
+
55
+ context 'given fetching an ownership does not return mechanical owners' do
56
+ it { expect(ownership.mechanical_owners).to be_empty }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/right_owner'
3
+
4
+ describe Yt::RightOwner do
5
+ subject(:right_owner) { Yt::RightOwner.new data: data }
6
+ let(:data) { {} }
7
+
8
+ describe '#ratio' do
9
+ context 'given fetching an owner returns a ratio' do
10
+ let(:data) { {"ratio"=>"20.0"} }
11
+ it { expect(right_owner.ratio).to eq 20 }
12
+ end
13
+ end
14
+
15
+ describe '#owner' do
16
+ context 'given fetching an owner returns an owner name' do
17
+ let(:data) { {"owner"=>"FullScreen"} }
18
+ it { expect(right_owner.owner).to eq 'FullScreen' }
19
+ end
20
+ end
21
+
22
+ describe '#owner' do
23
+ context 'given fetching an owner returns a publisher name' do
24
+ let(:data) { {"publisher"=>"Third Party"} }
25
+ it { expect(right_owner.publisher).to eq 'Third Party' }
26
+ end
27
+
28
+ context 'given fetching an owner does not return a publisher name' do
29
+ it { expect(right_owner.publisher).to be_nil }
30
+ end
31
+ end
32
+
33
+ describe '#included_territories' do
34
+ context 'given fetching an owner returns included territories' do
35
+ let(:data) { {"type"=>"include", "territories"=>["US", "CA"]} }
36
+ it { expect(right_owner.included_territories).to eq %w(US CA) }
37
+ end
38
+
39
+ context 'given fetching an owner does not return included territories' do
40
+ it { expect(right_owner.included_territories).to be_nil }
41
+ end
42
+ end
43
+
44
+ describe '#excluded_territories' do
45
+ context 'given fetching an owner returns excluded territories' do
46
+ let(:data) { {"type"=>"exclude", "territories"=>["US", "CA"]} }
47
+ it { expect(right_owner.excluded_territories).to eq %w(US CA) }
48
+ end
49
+
50
+ context 'given fetching an owner does not return excluded territories' do
51
+ it { expect(right_owner.excluded_territories).to be_nil }
52
+ end
53
+ end
54
+
55
+ describe '#everywhere?' do
56
+ context 'given fetching an owner returns zero excluded territories' do
57
+ let(:data) { {"type"=>"exclude", "territories"=>[]} }
58
+ it { expect(right_owner).to be_everywhere }
59
+ end
60
+
61
+ context 'given fetching an owner returns no excluded territories' do
62
+ let(:data) { {"type"=>"exclude"} }
63
+ it { expect(right_owner).to be_everywhere }
64
+ end
65
+
66
+ context 'given fetching an owner returns included territories' do
67
+ let(:data) { {"type"=>"include", "territories"=>[]} }
68
+ it { expect(right_owner).not_to be_everywhere }
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/advertising_options_set'
3
+
4
+ describe Yt::AdvertisingOptionsSet, :partner do
5
+ subject(:advertising_options_set) { Yt::AdvertisingOptionsSet.new video_id: video_id, auth: $content_owner }
6
+
7
+ context 'given a video managed by the authenticated Content Owner' do
8
+ let(:video_id) { ENV['YT_TEST_PARTNER_CLAIMABLE_VIDEO_ID'] }
9
+
10
+ describe 'the advertising options can be updated' do
11
+ let(:params) { {ad_formats: %w(standard_instream long)} }
12
+ it { expect(advertising_options_set.update params).to be true }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/content_owner'
3
+
4
+ describe Yt::Asset, :partner do
5
+ describe '.ownership' do
6
+ let(:asset) { Yt::Asset.new id: asset_id, auth: $content_owner }
7
+ describe 'given an asset administered by the content owner' do
8
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
9
+ it { expect(asset.ownership).to be_a Yt::Ownership }
10
+ end
11
+ end
12
+ end
@@ -10,8 +10,31 @@ describe Yt::ContentOwner, :partner do
10
10
  it { expect($content_owner.partnered_channels.size).to be > 0 }
11
11
  end
12
12
 
13
+ describe 'claims' do
14
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
15
+ let(:policy_id) { ENV['YT_TEST_PARTNER_POLICY_ID'] }
16
+ let(:video_id) { ENV['YT_TEST_PARTNER_CLAIMABLE_VIDEO_ID'] }
17
+ let(:params) { {asset_id: asset_id, video_id: video_id, policy_id: policy_id, content_type: 'audiovisual'} }
18
+
19
+ specify 'can be added' do
20
+ begin
21
+ expect($content_owner.create_claim params).to be_a Yt::Claim
22
+ rescue Yt::Errors::RequestError => e
23
+ # @note: Every time this test runs, a claim is inserted for the same
24
+ # video and asset, but YouTube does not allow this, and responds with
25
+ # an error message like "Video is already claimed. Existing claims
26
+ # on this video: AbCdEFg1234".
27
+ # For the sake of testing, we delete the duplicate and try again.
28
+ raise unless e.reasons.include? 'alreadyClaimed'
29
+ id = e.kind['message'].match(/this video: (.*?)$/) {|re| re[1]}
30
+ Yt::Claim.new(id: id, auth: $content_owner).delete
31
+ expect($content_owner.create_claim params).to be_a Yt::Claim
32
+ end
33
+ end
34
+ end
35
+
13
36
  describe '.claims' do
14
- describe 'given the content owner has policies' do
37
+ describe 'given the content owner has claims' do
15
38
  let(:claim) { $content_owner.claims.first }
16
39
 
17
40
  it 'returns valid metadata' do
@@ -43,7 +66,7 @@ describe Yt::ContentOwner, :partner do
43
66
  let(:count) { $content_owner.claims.where(asset_id: asset_id).count }
44
67
 
45
68
  context 'given the asset ID of a claim administered by the content owner' do
46
- let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
69
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_WITH_CLAIM_ID'] }
47
70
  it { expect(count).to be > 0 }
48
71
  end
49
72
 
@@ -175,4 +198,16 @@ describe Yt::ContentOwner, :partner do
175
198
  it { expect(policy).not_to be }
176
199
  end
177
200
  end
201
+
202
+ # @note: The following test works, but YouTube API endpoint to mark
203
+ # an asset as 'invalid' (soft-delete) does not work, and apparently
204
+ # there is no way to update the status of a asset.
205
+ # Therefore, the test is commented out, otherwise a new asset would
206
+ # be created every time the test is run.
207
+ # describe 'assets can be added' do
208
+ # let(:params) { {type: 'web'} }
209
+ # before { @asset = $content_owner.create_asset params }
210
+ # after { @asset.delete } # This does not seem to work
211
+ # it { expect(@asset).to be_a Yt::Asset }
212
+ # end
178
213
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/ownership'
3
+
4
+ describe Yt::Ownership, :partner do
5
+ subject(:ownership) { Yt::Ownership.new asset_id: asset_id, auth: $content_owner }
6
+
7
+ context 'given an asset managed by the authenticated Content Owner' do
8
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
9
+
10
+ describe 'the ownership can be updated' do
11
+ let(:general_owner) { {ratio: 100, owner: 'FullScreen', type: 'include', territories: ['US', 'CA']} }
12
+ it { expect(ownership.update general: [general_owner]).to be true }
13
+ end
14
+
15
+ describe 'the complete ownership can be obtained' do
16
+ it { expect(ownership.obtain!).to be true }
17
+ end
18
+ end
19
+ 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.11.1
4
+ version: 0.11.2
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-08-17 00:00:00.000000000 Z
11
+ date: 2014-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,7 +108,6 @@ files:
108
108
  - ".yardopts"
109
109
  - CHANGELOG.md
110
110
  - Gemfile
111
- - Gemfile.lock
112
111
  - MIT-LICENSE
113
112
  - README.md
114
113
  - Rakefile
@@ -117,6 +116,7 @@ files:
117
116
  - gemfiles/Gemfile.activesupport-3.x
118
117
  - gemfiles/Gemfile.activesupport-4.x
119
118
  - lib/yt.rb
119
+ - lib/yt/actions/base.rb
120
120
  - lib/yt/actions/delete.rb
121
121
  - lib/yt/actions/delete_all.rb
122
122
  - lib/yt/actions/insert.rb
@@ -130,6 +130,7 @@ files:
130
130
  - lib/yt/associations/has_reports.rb
131
131
  - lib/yt/associations/has_viewer_percentages.rb
132
132
  - lib/yt/collections/annotations.rb
133
+ - lib/yt/collections/assets.rb
133
134
  - lib/yt/collections/authentications.rb
134
135
  - lib/yt/collections/base.rb
135
136
  - lib/yt/collections/channels.rb
@@ -140,6 +141,7 @@ files:
140
141
  - lib/yt/collections/device_flows.rb
141
142
  - lib/yt/collections/ids.rb
142
143
  - lib/yt/collections/live_streaming_details.rb
144
+ - lib/yt/collections/ownerships.rb
143
145
  - lib/yt/collections/partnered_channels.rb
144
146
  - lib/yt/collections/playlist_items.rb
145
147
  - lib/yt/collections/playlists.rb
@@ -164,7 +166,9 @@ files:
164
166
  - lib/yt/errors/server_error.rb
165
167
  - lib/yt/errors/unauthorized.rb
166
168
  - lib/yt/models/account.rb
169
+ - lib/yt/models/advertising_options_set.rb
167
170
  - lib/yt/models/annotation.rb
171
+ - lib/yt/models/asset.rb
168
172
  - lib/yt/models/authentication.rb
169
173
  - lib/yt/models/base.rb
170
174
  - lib/yt/models/channel.rb
@@ -179,6 +183,7 @@ files:
179
183
  - lib/yt/models/iterator.rb
180
184
  - lib/yt/models/live_streaming_detail.rb
181
185
  - lib/yt/models/match_policy.rb
186
+ - lib/yt/models/ownership.rb
182
187
  - lib/yt/models/playlist.rb
183
188
  - lib/yt/models/playlist_item.rb
184
189
  - lib/yt/models/policy.rb
@@ -188,6 +193,7 @@ files:
188
193
  - lib/yt/models/request.rb
189
194
  - lib/yt/models/resource.rb
190
195
  - lib/yt/models/resumable_session.rb
196
+ - lib/yt/models/right_owner.rb
191
197
  - lib/yt/models/snippet.rb
192
198
  - lib/yt/models/statistics_set.rb
193
199
  - lib/yt/models/status.rb
@@ -210,6 +216,7 @@ files:
210
216
  - spec/errors/unauthorized_spec.rb
211
217
  - spec/models/account_spec.rb
212
218
  - spec/models/annotation_spec.rb
219
+ - spec/models/asset_spec.rb
213
220
  - spec/models/channel_spec.rb
214
221
  - spec/models/claim_spec.rb
215
222
  - spec/models/configuration_spec.rb
@@ -217,6 +224,7 @@ files:
217
224
  - spec/models/content_owner_detail_spec.rb
218
225
  - spec/models/description_spec.rb
219
226
  - spec/models/live_streaming_detail_spec.rb
227
+ - spec/models/ownership_spec.rb
220
228
  - spec/models/playlist_item_spec.rb
221
229
  - spec/models/playlist_spec.rb
222
230
  - spec/models/policy_rule_spec.rb
@@ -225,6 +233,7 @@ files:
225
233
  - spec/models/reference_spec.rb
226
234
  - spec/models/request_spec.rb
227
235
  - spec/models/resource_spec.rb
236
+ - spec/models/right_owner_spec.rb
228
237
  - spec/models/snippet_spec.rb
229
238
  - spec/models/statistics_set_spec.rb
230
239
  - spec/models/status_spec.rb
@@ -241,9 +250,12 @@ files:
241
250
  - spec/requests/as_account/video.mp4
242
251
  - spec/requests/as_account/video_spec.rb
243
252
  - spec/requests/as_content_owner/account_spec.rb
253
+ - spec/requests/as_content_owner/advertising_options_set_spec.rb
254
+ - spec/requests/as_content_owner/asset_spec.rb
244
255
  - spec/requests/as_content_owner/channel_spec.rb
245
256
  - spec/requests/as_content_owner/content_owner_spec.rb
246
257
  - spec/requests/as_content_owner/match_policy_spec.rb
258
+ - spec/requests/as_content_owner/ownership_spec.rb
247
259
  - spec/requests/as_content_owner/video_spec.rb
248
260
  - spec/requests/as_server_app/channel_spec.rb
249
261
  - spec/requests/as_server_app/playlist_item_spec.rb
@@ -295,6 +307,7 @@ test_files:
295
307
  - spec/errors/unauthorized_spec.rb
296
308
  - spec/models/account_spec.rb
297
309
  - spec/models/annotation_spec.rb
310
+ - spec/models/asset_spec.rb
298
311
  - spec/models/channel_spec.rb
299
312
  - spec/models/claim_spec.rb
300
313
  - spec/models/configuration_spec.rb
@@ -302,6 +315,7 @@ test_files:
302
315
  - spec/models/content_owner_detail_spec.rb
303
316
  - spec/models/description_spec.rb
304
317
  - spec/models/live_streaming_detail_spec.rb
318
+ - spec/models/ownership_spec.rb
305
319
  - spec/models/playlist_item_spec.rb
306
320
  - spec/models/playlist_spec.rb
307
321
  - spec/models/policy_rule_spec.rb
@@ -310,6 +324,7 @@ test_files:
310
324
  - spec/models/reference_spec.rb
311
325
  - spec/models/request_spec.rb
312
326
  - spec/models/resource_spec.rb
327
+ - spec/models/right_owner_spec.rb
313
328
  - spec/models/snippet_spec.rb
314
329
  - spec/models/statistics_set_spec.rb
315
330
  - spec/models/status_spec.rb
@@ -326,9 +341,12 @@ test_files:
326
341
  - spec/requests/as_account/video.mp4
327
342
  - spec/requests/as_account/video_spec.rb
328
343
  - spec/requests/as_content_owner/account_spec.rb
344
+ - spec/requests/as_content_owner/advertising_options_set_spec.rb
345
+ - spec/requests/as_content_owner/asset_spec.rb
329
346
  - spec/requests/as_content_owner/channel_spec.rb
330
347
  - spec/requests/as_content_owner/content_owner_spec.rb
331
348
  - spec/requests/as_content_owner/match_policy_spec.rb
349
+ - spec/requests/as_content_owner/ownership_spec.rb
332
350
  - spec/requests/as_content_owner/video_spec.rb
333
351
  - spec/requests/as_server_app/channel_spec.rb
334
352
  - spec/requests/as_server_app/playlist_item_spec.rb