yt 0.9.0 → 0.9.1

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 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