yt 0.8.0 → 0.8.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: 61f559b96e49f82854993bc9fa8be3e6afab9aaa
4
- data.tar.gz: cd332a6c0162c3c28abadd06c7c50cce24823924
3
+ metadata.gz: 82e7f06077dbcb70fc043948d27f297d26583085
4
+ data.tar.gz: 6b0d5b8bca60d7ce6595105ec076942675b1d448
5
5
  SHA512:
6
- metadata.gz: e310ae789d8cb9c390c2b39681faa251ec90b3b0c0189aec22d3e81719c1b13a65ca6ede2e996a108956eb0d5c342c1a99198405bd61a4eed371623f819b990e
7
- data.tar.gz: ac16bdf814bcab2fb1f6bb704ed00c890b13fe07824cb8d1dcaa27f2d940dd08c5492ba1623110c188ef0923eca874512f74e40426faf6274dfb7c8698f3510d
6
+ metadata.gz: 311d30cd632fcdbbee8887fa4e834afc0be54640522530152bc758b0423ea3c852ee1a0b7fefee0a4bbd6f7f6b8ce77005422172dafaecd99463cedffe8f21cb
7
+ data.tar.gz: 89a54825dfb15fe1d94b4f2aec38395355d8cd51d2d336ce98184557e41ec99e9fe31eb87a8e9349e4f92cff5cff3fb5504f10714dd774332d382ebca71469c4
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yt (0.8.0)
4
+ yt (0.8.1)
5
5
  activesupport
6
6
 
7
7
  GEM
data/HISTORY.md CHANGED
@@ -2,6 +2,7 @@ v0.8 - 2014/07/18
2
2
  -----------------
3
3
 
4
4
  * [breaking change] channel.subscribe returns nil (not raise an error) when trying to subscribe to your own channel
5
+ * Add all the status fields to Video (upload status, failure reason, rejection reason, scheduled time, license, embeddable, public stats viewable)
5
6
 
6
7
  v0.7 - 2014/06/18
7
8
  -----------------
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.8.0'
44
+ gem 'yt', '~> 0.8.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*)
@@ -201,13 +201,40 @@ video.description #=> "The new Fullscreen Creator Platform gives creators and br
201
201
  video.description.has_link_to_channel? #=> true
202
202
  video.thumbnail_url #=> "https://i1.ytimg.com/vi/MESycYJytkU/default.jpg"
203
203
  video.published_at #=> 2013-07-09 16:27:32 UTC
204
- video.public? #=> true
205
204
  video.tags #=> []
206
205
  video.channel_id #=> "UCxO1tY8h1AhOz0T4ENwmpow"
207
206
  video.channel_title #=> "Fullscreen"
208
207
  video.category_id #=> "22"
209
208
  video.live_broadcast_content #=> "none"
210
209
 
210
+ video.public? #=> true
211
+ video.uploaded? #=> false
212
+ video.rejected? #=> false
213
+ video.failed? #=> true
214
+ video.processed? #=> false
215
+ video.deleted? #=> false
216
+ video.uses_unsupported_codec? #=> true
217
+ video.has_failed_conversion? #=> false
218
+ video.empty? #=> false
219
+ video.invalid? #=> false
220
+ video.too_small? #=> false
221
+ video.aborted? #=> false
222
+ video.claimed? #=> false
223
+ video.infringes_copyright? #=> false
224
+ video.duplicate? #=> false
225
+ video.inappropriate? #=> false
226
+ video.too_long? #=> false
227
+ video.violates_terms_of_use? #=> false
228
+ video.infringes_trademark? #=> false
229
+ video.belongs_to_closed_account? #=> false
230
+ video.belongs_to_suspended_account? #=> false
231
+ video.scheduled? #=> true
232
+ video.scheduled_at #=> Tue, 27 May 2014 12:50:00
233
+ video.licensed_as_creative_commons? #=> true
234
+ video.licensed_as_standard_youtube? #=> false
235
+ video.embeddable? #=> false
236
+ video.has_public_stats_viewable? #=> false
237
+
211
238
  video.duration #=> 86
212
239
  video.hd? #=> true
213
240
  video.stereoscopic? #=> false
@@ -544,18 +571,6 @@ This will fail unless you have set up a test YouTube application and some
544
571
  tests YouTube accounts to hit the API. Once again, you probably don’t need
545
572
  this, since Travis CI already takes care of running this kind of tests.
546
573
 
547
- How to contribute
548
- =================
549
-
550
- Yt needs your support!
551
- The goal of Yt is to provide a Ruby interface for all the methods exposed by
552
- the [YouTube Data API (v3)](https://developers.google.com/youtube/v3) and by
553
- the [YouTube Analytics API](https://developers.google.com/youtube/analytics).
554
-
555
- If you find that a method is missing, fork the project, add the missing code,
556
- write the appropriate tests, then submit a pull request, and it will gladly
557
- be merged!
558
-
559
574
  How to release new versions
560
575
  ===========================
561
576
 
@@ -571,5 +586,20 @@ Remember that the yt gem follows [Semantic Versioning](http://semver.org).
571
586
  Any new release that is fully backward-compatible should bump the *patch* version (0.0.x).
572
587
  Any new version that breaks compatibility should bump the *minor* version (0.x.0)
573
588
 
574
- Don’t hesitate to send code comments, issues or pull requests through GitHub!
575
- All feedback is appreciated. A [googol](http://en.wikipedia.org/wiki/Googol) of thanks! :)
589
+ How to contribute
590
+ =================
591
+
592
+ Yt needs your support!
593
+ The goal of Yt is to provide a Ruby interface for all the methods exposed by
594
+ the [YouTube Data API (v3)](https://developers.google.com/youtube/v3) and by
595
+ the [YouTube Analytics API](https://developers.google.com/youtube/analytics).
596
+
597
+ If you find that a method is missing, fork the project, add the missing code,
598
+ write the appropriate tests, then submit a pull request, and it will gladly
599
+ be merged!
600
+
601
+ Don’t hesitate to send code comments, issues or pull requests through GitHub
602
+ and to spread the love on Twitter by following [@ytgem](https://twitter.com/intent/user?screen_name=ytgem) – 
603
+ all feedback is appreciated.
604
+
605
+ ![yt4](https://cloud.githubusercontent.com/assets/7408595/3638115/0ef9d6bc-1037-11e4-831a-787204e9b979.png)
@@ -115,6 +115,8 @@ module Yt
115
115
  @category_id ||= @data['categoryId']
116
116
  end
117
117
 
118
+ BROADCAST_TYPES = %q(live none upcoming)
119
+
118
120
  # @return [String] if the resource is a video, whether the resource is a
119
121
  # live broadcast. Valid values are: live, none, upcoming.
120
122
  # @return [nil] if the resource is a channel.
@@ -1,32 +1,318 @@
1
1
  module Yt
2
2
  module Models
3
- # Encapsulates information about the privacy status of a resource, for
4
- # instance a channel.
3
+ # Contains information about the status of a resource. The details of the
4
+ # status are different for the different types of resources.
5
+ #
6
+ # Resources with a
7
+ # status are: channels, playlists, playlist items and videos.
5
8
  # @see https://developers.google.com/youtube/v3/docs/channels#resource
9
+ # @see https://developers.google.com/youtube/v3/docs/videos#resource
10
+ # @see https://developers.google.com/youtube/v3/docs/playlists#resource
11
+ # @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
6
12
  class Status
7
13
  def initialize(options = {})
8
14
  @data = options[:data]
9
15
  end
10
16
 
11
- # @return [Boolean] whether the resource is public
17
+ # Privacy status
18
+
19
+ PRIVACY_STATUSES = %q(private public unlisted)
20
+
21
+ # @return [String] the privacy status of the resource. Valid values are:
22
+ # private, public, unlisted.
23
+ def privacy_status
24
+ @privacy_status ||= @data['privacyStatus']
25
+ end
26
+
27
+ # @return [Boolean] whether the resource is public.
12
28
  def public?
13
29
  privacy_status == 'public'
14
30
  end
15
31
 
16
- # @return [Boolean] whether the resource is private
32
+ # @return [Boolean] whether the resource is private.
17
33
  def private?
18
34
  privacy_status == 'private'
19
35
  end
20
36
 
21
- # @return [Boolean] whether the resource is unlisted
37
+ # @return [Boolean] whether the resource is unlisted.
22
38
  def unlisted?
23
39
  privacy_status == 'unlisted'
24
40
  end
25
41
 
26
- # @return [String] the privacy status of the channel.
27
- # Valid values are: private, public, unlisted
28
- def privacy_status
29
- @privacy_status ||= @data['privacyStatus']
42
+ # Upload status (Video only)
43
+
44
+ # Returns the upload status of a video.
45
+ # @return [String] if the resource is a video, the status of the
46
+ # uploaded video. Valid values are: deleted, failed, processed,
47
+ # rejected, uploaded.
48
+ # @return [nil] if the resource is not a video.
49
+ def upload_status
50
+ @upload_status ||= @data['uploadStatus']
51
+ end
52
+
53
+ # Returns whether an uploaded video was deleted.
54
+ # @return [Boolean] if the resource is a video, whether the uploaded
55
+ # video was deleted by the user.
56
+ # @return [nil] if the resource is not a video.
57
+ def deleted?
58
+ upload_status == 'deleted' if video?
59
+ end
60
+
61
+ # Returns whether a video failed to upload. If true, the reason why
62
+ # the video upload failed can be obtained with +failure_reason+.
63
+ # @return [Boolean] if the resource is a video, whether the video failed
64
+ # to upload.
65
+ # @return [nil] if the resource is not a video.
66
+ def failed?
67
+ upload_status == 'failed' if video?
68
+ end
69
+
70
+ # Returns whether an uploaded video is being processed by YouTube.
71
+ # @return [Boolean] if the resource is a video, whether the uploaded
72
+ # video is being processed by YouTube.
73
+ # @return [nil] if the resource is not a video.
74
+ def processed?
75
+ upload_status == 'processed' if video?
76
+ end
77
+
78
+ # Returns whether the video was rejected by YouTube. If true, the reason
79
+ # why the video was rejected can be obtained with +rejection_reason+.
80
+ # @return [Boolean] if the resource is a video, whether the video was
81
+ # rejected by YouTube.
82
+ # @return [nil] if the resource is not a video.
83
+ def rejected?
84
+ upload_status == 'rejected' if video?
85
+ end
86
+
87
+ # Returns whether a video was successfully uploaded to YouTube.
88
+ # @return [Boolean] if the resource is a video, whether the video was
89
+ # successfully uploaded.
90
+ # @return [nil] if the resource is not a video.
91
+ def uploaded?
92
+ upload_status == 'uploaded' if video?
93
+ end
94
+
95
+ # Failure reason (Video only)
96
+
97
+ # Returns the reason why a video failed to upload.
98
+ # @return [String] if resource is a video with a 'failed' upload status,
99
+ # the reason why the video failed to upload. Valid values are: codec,
100
+ # conversion, emptyFile, invalidFile, tooSmall, uploadAborted.
101
+ # @return [nil] if the resource is not a video or upload has not failed.
102
+ def failure_reason
103
+ @failure_reason ||= @data['failureReason']
104
+ end
105
+
106
+ # Returns whether a video upload failed because of the codec.
107
+ # @return [Boolean] if the resource is a video, whether the video uses
108
+ # a codec not supported by YouTube.
109
+ # @return [nil] if the resource is not a video or upload has not failed.
110
+ # @see https://support.google.com/youtube/answer/1722171
111
+ def uses_unsupported_codec?
112
+ failure_reason == 'codec' if video?
113
+ end
114
+
115
+ # Returns whether YouTube was unable to convert an uploaded video.
116
+ # @return [Boolean] if the resource is a video, whether YouTube was
117
+ # unable to convert the video.
118
+ # @return [nil] if the resource is not a video or upload has not failed.
119
+ def has_failed_conversion?
120
+ failure_reason == 'conversion' if video?
121
+ end
122
+
123
+ # Returns whether a video upload failed because the file was empty.
124
+ # @return [Boolean] if the resource is a video, whether the video file
125
+ # is empty.
126
+ # @return [nil] if the resource is not a video or upload has not failed.
127
+ def empty?
128
+ failure_reason == 'emptyFile' if video?
129
+ end
130
+
131
+ # Returns whether a video upload failed because of the file format.
132
+ # @return [Boolean] if the resource is a video, whether the video uses
133
+ # a file format not supported by YouTube.
134
+ # @return [nil] if the resource is not a video or upload has not failed.
135
+ # @see https://support.google.com/youtube/troubleshooter/2888402?hl=en
136
+ def invalid?
137
+ failure_reason == 'invalidFile' if video?
138
+ end
139
+
140
+ # Returns whether a video upload failed because the file was too small.
141
+ # @return [Boolean] if the resource is a video, whether the video file
142
+ # is too small for YouTube.
143
+ # @return [nil] if the resource is not a video or upload has not failed.
144
+ def too_small?
145
+ failure_reason == 'tooSmall' if video?
146
+ end
147
+
148
+ # Returns whether a video upload failed because the upload was aborted.
149
+ # @return [Boolean] if the resource is a video, whether the uploading
150
+ # process was aborted.
151
+ # @return [nil] if the resource is not a video or upload has not failed.
152
+ def aborted?
153
+ failure_reason == 'uploadAborted' if video?
154
+ end
155
+
156
+ # Rejection reason (Video only)
157
+
158
+ # Returns the reason why a video was rejected by YouTube.
159
+ # @return [String] if resource is a video with a 'rejected' upload
160
+ # status, the reason why the video was rejected. Valid values are:
161
+ # claim, copyright, duplicate, inappropriate, length, termsOfUse,
162
+ # trademark, uploaderAccountClosed, uploaderAccountSuspended.
163
+ # @return [nil] if the resource is not a rejected video.
164
+ def rejection_reason
165
+ @rejection_reason ||= @data['rejectionReason']
166
+ end
167
+
168
+ # Returns whether a video was rejected because it was claimed.
169
+ # @return [Boolean] if the resource is a rejected video, whether the
170
+ # video was claimed by a different account.
171
+ # @return [nil] if the resource is not a rejected video.
172
+ def claimed?
173
+ rejection_reason == 'claim' if video?
174
+ end
175
+
176
+ # Returns whether a video was rejected because of copyright infringement.
177
+ # @return [Boolean] if the resource is a rejected video, whether the
178
+ # video commits a copyright infringement.
179
+ # @return [nil] if the resource is not a rejected video.
180
+ def infringes_copyright?
181
+ rejection_reason == 'copyright' if video?
182
+ end
183
+
184
+ # Returns whether a video was rejected because it is a duplicate.
185
+ # @return [Boolean] if the resource is a rejected video, whether the
186
+ # video is a duplicate of another uploaded video.
187
+ # @return [nil] if the resource is not a rejected video.
188
+ def duplicate?
189
+ rejection_reason == 'duplicate' if video?
190
+ end
191
+
192
+ # Returns whether a video was rejected because of inappropriate content.
193
+ # @return [Boolean] if the resource is a rejected video, whether the
194
+ # video contains inappropriate content.
195
+ # @return [nil] if the resource is not a rejected video.
196
+ def inappropriate?
197
+ rejection_reason == 'inappropriate' if video?
198
+ end
199
+
200
+ # Returns whether a video was rejected because it is too long.
201
+ # @return [Boolean] if the resource is a rejected video, whether the
202
+ # video exceeds the maximum duration.
203
+ # @return [nil] if the resource is not a rejected video.
204
+ # @see https://support.google.com/youtube/answer/71673?hl=en
205
+ def too_long?
206
+ rejection_reason == 'length' if video?
207
+ end
208
+
209
+ # Returns whether a video was rejected because it violates terms of use.
210
+ # @return [Boolean] if the resource is a rejected video, whether the
211
+ # video commits a terms of use violation.
212
+ # @return [nil] if the resource is not a rejected video.
213
+ def violates_terms_of_use?
214
+ rejection_reason == 'termsOfUse' if video?
215
+ end
216
+
217
+ # Returns whether a video was rejected because of trademark infringement.
218
+ # @return [Boolean] if the resource is a rejected video, whether the
219
+ # video commits a trademark infringement.
220
+ # @return [nil] if the resource is not a rejected video.
221
+ # @see https://support.google.com/youtube/answer/2801979?hl=en
222
+ def infringes_trademark?
223
+ rejection_reason == 'trademark' if video?
224
+ end
225
+
226
+ # Returns whether a video was rejected because the account was closed.
227
+ # @return [Boolean] if the resource is a rejected video, whether the
228
+ # account associated with the video has been closed.
229
+ # @return [nil] if the resource is not a rejected video.
230
+ def belongs_to_closed_account?
231
+ rejection_reason == 'uploaderAccountClosed' if video?
232
+ end
233
+
234
+ # Returns whether a video was rejected because the account was suspended.
235
+ # @return [Boolean] if the resource is a rejected video, whether the
236
+ # account associated with the video has been suspended.
237
+ # @return [nil] if the resource is not a rejected video.
238
+ def belongs_to_suspended_account?
239
+ rejection_reason == 'uploaderAccountSuspended' if video?
240
+ end
241
+
242
+ # Scheduled publication (Video only)
243
+
244
+ # Returns the date and time when a video is scheduled to be published.
245
+ # @return [Time] if resource is a private video scheduled to be
246
+ # published, the date and time when the video is scheduled to publish.
247
+ # @return [nil] if the resource is not a private video scheduled to be
248
+ # published.
249
+ def scheduled_at
250
+ @scheduled_at ||= Time.parse @data['publishAt'] if scheduled?
251
+ end
252
+
253
+ # Returns whether the video is scheduled to be published.
254
+ # @return [Boolean] if the resource is a video, whether it is currently
255
+ # private and is scheduled to become public in the future.
256
+ # @return [nil] if the resource is not a video.
257
+ def scheduled?
258
+ private? && @data['publishAt'] if video?
259
+ end
260
+
261
+ # License (Video only)
262
+
263
+ # Returns the video’s license.
264
+ # @return [String] if resource is a video, its license. Valid values are:
265
+ # creativeCommon, youtube.
266
+ # @return [nil] if the resource is not a video.
267
+ def license
268
+ @license ||= @data['license']
269
+ end
270
+
271
+ # Returns whether the video uses a Creative Commons license.
272
+ # @return [Boolean] if the resource is a video, whether it uses a
273
+ # Creative Commons license.
274
+ # @return [nil] if the resource is not a video.
275
+ # @see https://support.google.com/youtube/answer/2797468?hl=en
276
+ def licensed_as_creative_commons?
277
+ license == 'creativeCommon' if video?
278
+ end
279
+
280
+ # Returns whether the video uses the Standard YouTube license.
281
+ # @return [Boolean] if the resource is a video, whether it uses the
282
+ # Standard YouTube license.
283
+ # @return [nil] if the resource is not a video.
284
+ # @see https://www.youtube.com/static?template=terms
285
+ def licensed_as_standard_youtube?
286
+ license == 'youtube' if video?
287
+ end
288
+
289
+ # Embed (Video only)
290
+
291
+ # Returns whether the video can be embedded on another website.
292
+ # @return [Boolean] if the resource is a video, whether it can be
293
+ # embedded on another website.
294
+ # @return [nil] if the resource is not a video.
295
+ def embeddable?
296
+ @embeddable ||= @data['embeddable']
297
+ end
298
+
299
+ # Public stats (Video only)
300
+
301
+ # Returns whether the video statistics are publicly viewable.
302
+ # @return [Boolean] if the resource is a video, whether the extended
303
+ # video statistics on the video’s watch page are publicly viewable.
304
+ # By default, those statistics are viewable, and statistics like a
305
+ # video’s viewcount and ratings will still be publicly visible even
306
+ # if this property’s value is set to false.
307
+ # @return [nil] if the resource is not a video.
308
+ def has_public_stats_viewable?
309
+ @public_stats_viewable ||= @data['publicStatsViewable']
310
+ end
311
+
312
+ private
313
+
314
+ def video?
315
+ upload_status.present?
30
316
  end
31
317
  end
32
318
  end
@@ -8,6 +8,15 @@ module Yt
8
8
  delegate :tags, :channel_id, :channel_title, :category_id,
9
9
  :live_broadcast_content, to: :snippet
10
10
 
11
+ delegate :deleted?, :failed?, :processed?, :rejected?, :uploaded?,
12
+ :uses_unsupported_codec?, :has_failed_conversion?, :empty?, :invalid?,
13
+ :too_small?, :aborted?, :claimed?, :infringes_copyright?, :duplicate?,
14
+ :scheduled_at, :scheduled?, :too_long?, :violates_terms_of_use?,
15
+ :inappropriate?, :infringes_trademark?, :belongs_to_closed_account?,
16
+ :belongs_to_suspended_account?, :licensed_as_creative_commons?,
17
+ :licensed_as_standard_youtube?, :has_public_stats_viewable?,
18
+ :embeddable?, to: :status
19
+
11
20
  # @!attribute [r] content_detail
12
21
  # @return [Yt::Models::ContentDetail] the video’s content details.
13
22
  has_one :content_detail
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.8.0'
2
+ VERSION = '0.8.1'
3
3
  end
@@ -10,7 +10,7 @@ describe Yt::Status do
10
10
  it { expect(status).to be_public }
11
11
  end
12
12
 
13
- context 'given fetching a status does not returns privacyStatus "public"' do
13
+ context 'given fetching a status does not return privacyStatus "public"' do
14
14
  let(:data) { {} }
15
15
  it { expect(status).not_to be_public }
16
16
  end
@@ -22,7 +22,7 @@ describe Yt::Status do
22
22
  it { expect(status).to be_private }
23
23
  end
24
24
 
25
- context 'given fetching a status does not returns privacyStatus "private"' do
25
+ context 'given fetching a status does not return privacyStatus "private"' do
26
26
  let(:data) { {} }
27
27
  it { expect(status).not_to be_private }
28
28
  end
@@ -34,9 +34,311 @@ describe Yt::Status do
34
34
  it { expect(status).to be_unlisted }
35
35
  end
36
36
 
37
- context 'given fetching a status does not returns privacyStatus "unlisted"' do
37
+ context 'given fetching a status does not return privacyStatus "unlisted"' do
38
38
  let(:data) { {} }
39
39
  it { expect(status).not_to be_unlisted }
40
40
  end
41
41
  end
42
- end
42
+
43
+ describe '#deleted?' do
44
+ context 'given fetching a status returns uploadStatus "deleted"' do
45
+ let(:data) { {"uploadStatus"=>"deleted"} }
46
+ it { expect(status).to be_deleted }
47
+ end
48
+
49
+ context 'given fetching a status does not return uploadStatus "deleted"' do
50
+ let(:data) { {"uploadStatus"=>"uploaded"} }
51
+ it { expect(status).not_to be_deleted }
52
+ end
53
+ end
54
+
55
+ describe '#failed?' do
56
+ context 'given fetching a status returns uploadStatus "failed"' do
57
+ let(:data) { {"uploadStatus"=>"failed"} }
58
+ it { expect(status).to be_failed }
59
+ end
60
+
61
+ context 'given fetching a status does not return uploadStatus "failed"' do
62
+ let(:data) { {"uploadStatus"=>"uploaded"} }
63
+ it { expect(status).not_to be_failed }
64
+ end
65
+ end
66
+
67
+ describe '#processed?' do
68
+ context 'given fetching a status returns uploadStatus "processed"' do
69
+ let(:data) { {"uploadStatus"=>"processed"} }
70
+ it { expect(status).to be_processed }
71
+ end
72
+
73
+ context 'given fetching a status does not return uploadStatus "processed"' do
74
+ let(:data) { {"uploadStatus"=>"uploaded"} }
75
+ it { expect(status).not_to be_processed }
76
+ end
77
+ end
78
+
79
+ describe '#rejected?' do
80
+ context 'given fetching a status returns uploadStatus "rejected"' do
81
+ let(:data) { {"uploadStatus"=>"rejected"} }
82
+ it { expect(status).to be_rejected }
83
+ end
84
+
85
+ context 'given fetching a status does not return uploadStatus "rejected"' do
86
+ let(:data) { {"uploadStatus"=>"uploaded"} }
87
+ it { expect(status).not_to be_rejected }
88
+ end
89
+ end
90
+
91
+ describe '#uploaded?' do
92
+ context 'given fetching a status returns uploadStatus "uploaded"' do
93
+ let(:data) { {"uploadStatus"=>"uploaded"} }
94
+ it { expect(status).to be_uploaded }
95
+ end
96
+
97
+ context 'given fetching a status does not return uploadStatus "uploaded"' do
98
+ let(:data) { {"uploadStatus"=>"failed"} }
99
+ it { expect(status).not_to be_uploaded }
100
+ end
101
+ end
102
+
103
+ describe '#uses_unsupported_codec?' do
104
+ context 'given fetching a status returns failureReason "codec"' do
105
+ let(:data) { {"uploadStatus"=>"failed", "failureReason"=>"codec"} }
106
+ it { expect(status.uses_unsupported_codec?).to be true }
107
+ end
108
+
109
+ context 'given fetching a status does not return failureReason "codec"' do
110
+ let(:data) { {"uploadStatus"=>"failed"} }
111
+ it { expect(status.uses_unsupported_codec?).to be false }
112
+ end
113
+ end
114
+
115
+ describe '#conversion_failed?' do
116
+ context 'given fetching a status returns failureReason "conversion"' do
117
+ let(:data) { {"uploadStatus"=>"failed", "failureReason"=>"conversion"} }
118
+ it { expect(status).to have_failed_conversion }
119
+ end
120
+
121
+ context 'given fetching a status does not return failureReason "conversion"' do
122
+ let(:data) { {"uploadStatus"=>"failed"} }
123
+ it { expect(status).not_to have_failed_conversion }
124
+ end
125
+ end
126
+
127
+ describe '#empty_file?' do
128
+ context 'given fetching a status returns failureReason "emptyFile"' do
129
+ let(:data) { {"uploadStatus"=>"failed", "failureReason"=>"emptyFile"} }
130
+ it { expect(status).to be_empty }
131
+ end
132
+
133
+ context 'given fetching a status does not return failureReason "emptyFile"' do
134
+ let(:data) { {"uploadStatus"=>"failed"} }
135
+ it { expect(status).not_to be_empty }
136
+ end
137
+ end
138
+
139
+ describe '#invalid_file?' do
140
+ context 'given fetching a status returns failureReason "invalidFile"' do
141
+ let(:data) { {"uploadStatus"=>"failed", "failureReason"=>"invalidFile"} }
142
+ it { expect(status).to be_invalid }
143
+ end
144
+
145
+ context 'given fetching a status does not return failureReason "invalidFile"' do
146
+ let(:data) { {"uploadStatus"=>"failed"} }
147
+ it { expect(status).not_to be_invalid }
148
+ end
149
+ end
150
+
151
+ describe '#too_small?' do
152
+ context 'given fetching a status returns failureReason "tooSmall"' do
153
+ let(:data) { {"uploadStatus"=>"failed", "failureReason"=>"tooSmall"} }
154
+ it { expect(status).to be_too_small }
155
+ end
156
+
157
+ context 'given fetching a status does not return failureReason "tooSmall"' do
158
+ let(:data) { {"uploadStatus"=>"failed"} }
159
+ it { expect(status).not_to be_too_small }
160
+ end
161
+ end
162
+
163
+ describe '#upload_aborted?' do
164
+ context 'given fetching a status returns failureReason "uploadAborted"' do
165
+ let(:data) { {"uploadStatus"=>"failed", "failureReason"=>"uploadAborted"} }
166
+ it { expect(status).to be_aborted }
167
+ end
168
+
169
+ context 'given fetching a status does not return failureReason "uploadAborted"' do
170
+ let(:data) { {"uploadStatus"=>"failed"} }
171
+ it { expect(status).not_to be_aborted }
172
+ end
173
+ end
174
+
175
+ describe '#claimed?' do
176
+ context 'given fetching a status returns rejectionReason "claim"' do
177
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"claim"} }
178
+ it { expect(status).to be_claimed }
179
+ end
180
+
181
+ context 'given fetching a status does not return rejectionReason "claim"' do
182
+ let(:data) { {"uploadStatus"=>"rejected"} }
183
+ it { expect(status).not_to be_claimed }
184
+ end
185
+ end
186
+
187
+ describe '#infringes_copyright?' do
188
+ context 'given fetching a status returns rejectionReason "copyright"' do
189
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"copyright"} }
190
+ it { expect(status.infringes_copyright?).to be true }
191
+ end
192
+
193
+ context 'given fetching a status does not return rejectionReason "copyright"' do
194
+ let(:data) { {"uploadStatus"=>"rejected"} }
195
+ it { expect(status.infringes_copyright?).to be false }
196
+ end
197
+ end
198
+
199
+ describe '#duplicate?' do
200
+ context 'given fetching a status returns rejectionReason "duplicate"' do
201
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"duplicate"} }
202
+ it { expect(status).to be_duplicate }
203
+ end
204
+
205
+ context 'given fetching a status does not return rejectionReason "duplicate"' do
206
+ let(:data) { {"uploadStatus"=>"rejected"} }
207
+ it { expect(status).not_to be_duplicate }
208
+ end
209
+ end
210
+
211
+ describe '#inappropriate?' do
212
+ context 'given fetching a status returns rejectionReason "inappropriate"' do
213
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"inappropriate"} }
214
+ it { expect(status).to be_inappropriate }
215
+ end
216
+
217
+ context 'given fetching a status does not return rejectionReason "inappropriate"' do
218
+ let(:data) { {"uploadStatus"=>"rejected"} }
219
+ it { expect(status).not_to be_inappropriate }
220
+ end
221
+ end
222
+
223
+ describe '#too_long?' do
224
+ context 'given fetching a status returns rejectionReason "length"' do
225
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"length"} }
226
+ it { expect(status).to be_too_long }
227
+ end
228
+
229
+ context 'given fetching a status does not return rejectionReason "length"' do
230
+ let(:data) { {"uploadStatus"=>"rejected"} }
231
+ it { expect(status).not_to be_too_long }
232
+ end
233
+ end
234
+
235
+ describe '#violates_terms_of_use?' do
236
+ context 'given fetching a status returns rejectionReason "termsOfUse"' do
237
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"termsOfUse"} }
238
+ it { expect(status.violates_terms_of_use?).to be true }
239
+ end
240
+
241
+ context 'given fetching a status does not return rejectionReason "termsOfUse"' do
242
+ let(:data) { {"uploadStatus"=>"rejected"} }
243
+ it { expect(status.violates_terms_of_use?).to be false }
244
+ end
245
+ end
246
+
247
+ describe '#infringes_trademark?' do
248
+ context 'given fetching a status returns rejectionReason "trademark"' do
249
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"trademark"} }
250
+ it { expect(status.infringes_trademark?).to be true }
251
+ end
252
+
253
+ context 'given fetching a status does not return rejectionReason "trademark"' do
254
+ let(:data) { {"uploadStatus"=>"rejected"} }
255
+ it { expect(status.infringes_trademark?).to be false }
256
+ end
257
+ end
258
+
259
+ describe '#belongs_to_closed_account?' do
260
+ context 'given fetching a status returns rejectionReason "uploaderAccountClosed"' do
261
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"uploaderAccountClosed"} }
262
+ it { expect(status.belongs_to_closed_account?).to be true }
263
+ end
264
+
265
+ context 'given fetching a status does not return rejectionReason "uploaderAccountClosed"' do
266
+ let(:data) { {"uploadStatus"=>"rejected"} }
267
+ it { expect(status.belongs_to_closed_account?).to be false }
268
+ end
269
+ end
270
+
271
+ describe '#belongs_to_suspended_account?' do
272
+ context 'given fetching a status returns rejectionReason "uploaderAccountSuspended"' do
273
+ let(:data) { {"uploadStatus"=>"rejected", "rejectionReason"=>"uploaderAccountSuspended"} }
274
+ it { expect(status.belongs_to_suspended_account?).to be true }
275
+ end
276
+
277
+ context 'given fetching a status does not return rejectionReason "uploaderAccountSuspended"' do
278
+ let(:data) { {"uploadStatus"=>"rejected"} }
279
+ it { expect(status.belongs_to_suspended_account?).to be false }
280
+ end
281
+ end
282
+
283
+ describe '#scheduled_at and #scheduled' do
284
+ context 'given fetching a status returns "publishAt"' do
285
+ let(:data) { {"uploadStatus"=>"uploaded", "privacyStatus"=>"private", "publishAt"=>"2014-04-22T19:14:49.000Z"} }
286
+ it { expect(status).to be_scheduled }
287
+ it { expect(status.scheduled_at.year).to be 2014 }
288
+ end
289
+
290
+ context 'given fetching a status does not returns "publishAt"' do
291
+ let(:data) { {"uploadStatus"=>"uploaded", "privacyStatus"=>"private"} }
292
+ it { expect(status).not_to be_scheduled }
293
+ it { expect(status.scheduled_at).not_to be }
294
+ end
295
+ end
296
+
297
+ describe '#licensed_as_creative_commons?' do
298
+ context 'given fetching a status returns license "creativeCommon"' do
299
+ let(:data) { {"uploadStatus"=>"uploaded", "license"=>"creativeCommon"} }
300
+ it { expect(status).to be_licensed_as_creative_commons }
301
+ end
302
+
303
+ context 'given fetching a status does not return license "creativeCommon"' do
304
+ let(:data) { {"uploadStatus"=>"uploaded"} }
305
+ it { expect(status).not_to be_licensed_as_creative_commons }
306
+ end
307
+ end
308
+
309
+ describe '#licensed_as_standard_youtube?' do
310
+ context 'given fetching a status returns license "youtube"' do
311
+ let(:data) { {"uploadStatus"=>"uploaded", "license"=>"youtube"} }
312
+ it { expect(status).to be_licensed_as_standard_youtube }
313
+ end
314
+
315
+ context 'given fetching a status does not return license "youtube"' do
316
+ let(:data) { {"uploadStatus"=>"uploaded"} }
317
+ it { expect(status).not_to be_licensed_as_standard_youtube }
318
+ end
319
+ end
320
+
321
+ describe '#embeddable?' do
322
+ context 'given fetching a status returns "embeddable" true' do
323
+ let(:data) { {"uploadStatus"=>"uploaded", "embeddable"=>true} }
324
+ it { expect(status).to be_embeddable }
325
+ end
326
+
327
+ context 'given fetching a status returns "embeddable" false' do
328
+ let(:data) { {"uploadStatus"=>"uploaded", "embeddable"=>false} }
329
+ it { expect(status).not_to be_embeddable }
330
+ end
331
+ end
332
+
333
+ describe '#has_public_stats_viewable?' do
334
+ context 'given fetching a status returns "publicStatsViewable" true' do
335
+ let(:data) { {"publicStatsViewable"=>true} }
336
+ it { expect(status).to have_public_stats_viewable }
337
+ end
338
+
339
+ context 'given fetching a status returns "publicStatsViewable" false' do
340
+ let(:data) { {"publicStatsViewable"=>false} }
341
+ it { expect(status).not_to have_public_stats_viewable }
342
+ end
343
+ end
344
+ end
@@ -8,19 +8,20 @@ describe Yt::Channel, :device_app do
8
8
  context 'given someone else’s channel' do
9
9
  let(:id) { 'UCxO1tY8h1AhOz0T4ENwmpow' }
10
10
 
11
- it 'returns valid snippet data' do
12
- expect(channel.snippet).to be_a Yt::Snippet
11
+ it 'returns valid metadata' do
13
12
  expect(channel.title).to be_a String
14
- expect(channel.description).to be_a Yt::Description
13
+ expect(channel.description).to be_a String
15
14
  expect(channel.thumbnail_url).to be_a String
16
15
  expect(channel.published_at).to be_a Time
16
+ expect(channel.privacy_status).to be_in Yt::Status::PRIVACY_STATUSES
17
+ expect(channel.view_count).to be_an Integer
18
+ expect(channel.comment_count).to be_an Integer
19
+ expect(channel.video_count).to be_an Integer
20
+ expect(channel.subscriber_count).to be_an Integer
21
+ expect(channel.subscriber_count_visible?).to be_in [true, false]
17
22
  end
18
23
 
19
- it { expect(channel.status).to be_a Yt::Status }
20
- it { expect(channel.statistics_set).to be_a Yt::StatisticsSet }
21
- it { expect(channel.videos).to be_a Yt::Collections::Videos }
22
24
  it { expect(channel.videos.first).to be_a Yt::Video }
23
- it { expect(channel.playlists).to be_a Yt::Collections::Playlists }
24
25
  it { expect(channel.playlists.first).to be_a Yt::Playlist }
25
26
  it { expect{channel.create_playlist}.to raise_error Yt::Errors::RequestError }
26
27
  it { expect{channel.delete_playlists}.to raise_error Yt::Errors::RequestError }
@@ -7,10 +7,9 @@ describe Yt::PlaylistItem, :device_app do
7
7
  context 'given an existing playlist item' do
8
8
  let(:id) { 'PLjW_GNR5Ir0GWEP_oveGBNjTvKkYyZfsna1TZDCBP-Z8' }
9
9
 
10
- it 'returns valid snippet data' do
11
- expect(item.snippet).to be_a Yt::Snippet
10
+ it 'returns valid metadata' do
12
11
  expect(item.title).to be_a String
13
- expect(item.description).to be_a Yt::Description
12
+ expect(item.description).to be_a String
14
13
  expect(item.thumbnail_url).to be_a String
15
14
  expect(item.published_at).to be_a Time
16
15
  expect(item.channel_id).to be_a String
@@ -18,7 +17,8 @@ describe Yt::PlaylistItem, :device_app do
18
17
  expect(item.playlist_id).to be_a String
19
18
  expect(item.position).to be_an Integer
20
19
  expect(item.video_id).to be_a String
21
- expect(item.video).to be_a Yt::Models::Video
20
+ expect(item.video).to be_a Yt::Video
21
+ expect(item.privacy_status).to be_in Yt::Status::PRIVACY_STATUSES
22
22
  end
23
23
  end
24
24
 
@@ -9,19 +9,17 @@ describe Yt::Playlist, :device_app do
9
9
  context 'given an existing playlist' do
10
10
  let(:id) { 'PLSWYkYzOrPMRCK6j0UgryI8E0NHhoVdRc' }
11
11
 
12
- it 'returns valid snippet data' do
13
- expect(playlist.snippet).to be_a Yt::Snippet
12
+ it 'returns valid metadata' do
14
13
  expect(playlist.title).to be_a String
15
- expect(playlist.description).to be_a Yt::Description
14
+ expect(playlist.description).to be_a String
16
15
  expect(playlist.thumbnail_url).to be_a String
17
16
  expect(playlist.published_at).to be_a Time
18
17
  expect(playlist.tags).to be_an Array
19
18
  expect(playlist.channel_id).to be_a String
20
19
  expect(playlist.channel_title).to be_a String
20
+ expect(playlist.privacy_status).to be_in Yt::Status::PRIVACY_STATUSES
21
21
  end
22
22
 
23
- it { expect(playlist.status).to be_a Yt::Status }
24
- it { expect(playlist.playlist_items).to be_a Yt::Collections::PlaylistItems }
25
23
  it { expect(playlist.playlist_items.first).to be_a Yt::PlaylistItem }
26
24
  end
27
25
 
@@ -11,22 +11,55 @@ describe Yt::Video, :device_app do
11
11
 
12
12
  it { expect(video.content_detail).to be_a Yt::ContentDetail }
13
13
 
14
- it 'returns valid snippet data' do
15
- expect(video.snippet).to be_a Yt::Snippet
14
+ it 'returns valid metadata' do
16
15
  expect(video.title).to be_a String
17
- expect(video.description).to be_a Yt::Description
16
+ expect(video.description).to be_a String
18
17
  expect(video.thumbnail_url).to be_a String
19
18
  expect(video.published_at).to be_a Time
19
+ expect(video.privacy_status).to be_in Yt::Status::PRIVACY_STATUSES
20
20
  expect(video.tags).to be_an Array
21
21
  expect(video.channel_id).to be_a String
22
22
  expect(video.channel_title).to be_a String
23
23
  expect(video.category_id).to be_a String
24
- expect(video.live_broadcast_content).to be_a String
24
+ expect(video.live_broadcast_content).to be_in Yt::Snippet::BROADCAST_TYPES
25
+ expect(video.view_count).to be_an Integer
26
+ expect(video.like_count).to be_an Integer
27
+ expect(video.dislike_count).to be_an Integer
28
+ expect(video.favorite_count).to be_an Integer
29
+ expect(video.comment_count).to be_an Integer
30
+ expect(video.duration).to be_an Integer
31
+ expect(video.hd?).to be_in [true, false]
32
+ expect(video.stereoscopic?).to be_in [true, false]
33
+ expect(video.captioned?).to be_in [true, false]
34
+ expect(video.licensed?).to be_in [true, false]
35
+ expect(video.deleted?).to be_in [true, false]
36
+ expect(video.failed?).to be_in [true, false]
37
+ expect(video.processed?).to be_in [true, false]
38
+ expect(video.rejected?).to be_in [true, false]
39
+ expect(video.uploaded?).to be_in [true, false]
40
+ expect(video.uses_unsupported_codec?).to be_in [true, false]
41
+ expect(video.has_failed_conversion?).to be_in [true, false]
42
+ expect(video.empty?).to be_in [true, false]
43
+ expect(video.invalid?).to be_in [true, false]
44
+ expect(video.too_small?).to be_in [true, false]
45
+ expect(video.aborted?).to be_in [true, false]
46
+ expect(video.claimed?).to be_in [true, false]
47
+ expect(video.infringes_copyright?).to be_in [true, false]
48
+ expect(video.duplicate?).to be_in [true, false]
49
+ expect(video.scheduled_at.class).to be_in [NilClass, Time]
50
+ expect(video.scheduled?).to be_in [true, false]
51
+ expect(video.too_long?).to be_in [true, false]
52
+ expect(video.violates_terms_of_use?).to be_in [true, false]
53
+ expect(video.inappropriate?).to be_in [true, false]
54
+ expect(video.infringes_trademark?).to be_in [true, false]
55
+ expect(video.belongs_to_closed_account?).to be_in [true, false]
56
+ expect(video.belongs_to_suspended_account?).to be_in [true, false]
57
+ expect(video.licensed_as_creative_commons?).to be_in [true, false]
58
+ expect(video.licensed_as_standard_youtube?).to be_in [true, false]
59
+ expect(video.has_public_stats_viewable?).to be_in [true, false]
60
+ expect(video.embeddable?).to be_in [true, false]
25
61
  end
26
62
 
27
- it { expect(video.rating).to be_a Yt::Rating }
28
- it { expect(video.status).to be_a Yt::Status }
29
- it { expect(video.statistics_set).to be_a Yt::StatisticsSet }
30
63
  it { expect{video.update}.to fail }
31
64
 
32
65
  context 'that I like' do
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.8.0
4
+ version: 0.8.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-19 00:00:00.000000000 Z
11
+ date: 2014-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport