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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 846cf65cd693a7468f2785fcfa6d5d3a8e207bc4
4
- data.tar.gz: ed6d1a9ec9d57f7367cbd1a6f2308296d3ec9f82
3
+ metadata.gz: 8853f3441a92a6cb17f3a73193f1b21b7f3a5a3d
4
+ data.tar.gz: f23617ccbf92ae86d002de6a412a083db7015d93
5
5
  SHA512:
6
- metadata.gz: d9afc53fa7a90fe4a5fe373356b5dbd95bcc929f4e0abc108f890042d3d3b80d715ce60c54e4df9b8f6d2699be930c8637e62d4be51cb13275266dedbd53b6de
7
- data.tar.gz: 5edb54c2610d58f5de2843b7a7d2d905ca3f3bc2028e6e6b03f2bbf529db367513cdab5c72e4d0e5a006d04e359d46618c77b57f46697214cc3d42018c5fd7b6
6
+ metadata.gz: 39f3ac3e556b1194961d346da9c13ddbc6ce370e44c9063af679c834fa290ca9b6ae110fb63456fa1e973ee7dad7e9cc6d42b6626a230912239e18c440b1d2d0
7
+ data.tar.gz: e7cd4d3d44ba2fa7faeb0b1d3da548f07098f2c55a6dba2b0d35decf8dcdecbf134d39a039ddf6d259a0228de14f9138ebb212a2a4db74e550d78ab8bf452816
@@ -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=
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yt (0.9.0)
4
+ yt (0.9.1)
5
5
  activesupport
6
6
 
7
7
  GEM
data/HISTORY.md CHANGED
@@ -2,6 +2,8 @@ v0.9 - 2014/07/28
2
2
  -----------------
3
3
 
4
4
  * [breaking change] Rename rating.update to rating.set
5
+ * Add content_owner.references to retrieve ContentID references
6
+
5
7
 
6
8
  v0.8 - 2014/07/18
7
9
  -----------------
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.0'
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]
@@ -23,17 +23,23 @@ module Yt
23
23
  !exists?
24
24
  end
25
25
 
26
- def update(options = {})
27
- options[:title] ||= title
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
- snippet = options.slice :title, :description, :tags
33
- status = {privacyStatus: options[:privacy_status]}
34
- body = {id: @id, snippet: snippet, status: status}
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
- do_update(params: {part: 'snippet,status'}, body: body) do |data|
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
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.1'
3
3
  end
@@ -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
- describe 'updates the attributes that I specify explicitly' do
56
- let(:attrs) { {title: "Yt Test Update Playlist #{rand} - new title"} }
57
- it { expect(playlist.update attrs).to eq true }
58
- it { expect{playlist.update attrs}.to change{playlist.title} }
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
- describe 'does not update the other attributes' do
62
- let(:attrs) { {} }
63
- it { expect(playlist.update attrs).to eq true }
64
- it { expect{playlist.update attrs}.not_to change{playlist.title} }
65
- it { expect{playlist.update attrs}.not_to change{playlist.description} }
66
- it { expect{playlist.update attrs}.not_to change{playlist.tags} }
67
- it { expect{playlist.update attrs}.not_to change{playlist.privacy_status} }
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.0
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-28 00:00:00.000000000 Z
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