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 +4 -4
- data/Gemfile.lock +1 -1
- data/HISTORY.md +1 -0
- data/README.md +46 -16
- data/lib/yt/models/snippet.rb +2 -0
- data/lib/yt/models/status.rb +295 -9
- data/lib/yt/models/video.rb +9 -0
- data/lib/yt/version.rb +1 -1
- data/spec/models/status_spec.rb +306 -4
- data/spec/requests/as_account/channel_spec.rb +8 -7
- data/spec/requests/as_account/playlist_item_spec.rb +4 -4
- data/spec/requests/as_account/playlist_spec.rb +3 -5
- data/spec/requests/as_account/video_spec.rb +40 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82e7f06077dbcb70fc043948d27f297d26583085
|
4
|
+
data.tar.gz: 6b0d5b8bca60d7ce6595105ec076942675b1d448
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 311d30cd632fcdbbee8887fa4e834afc0be54640522530152bc758b0423ea3c852ee1a0b7fefee0a4bbd6f7f6b8ce77005422172dafaecd99463cedffe8f21cb
|
7
|
+
data.tar.gz: 89a54825dfb15fe1d94b4f2aec38395355d8cd51d2d336ce98184557e41ec99e9fe31eb87a8e9349e4f92cff5cff3fb5504f10714dd774332d382ebca71469c4
|
data/Gemfile.lock
CHANGED
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.
|
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
|
-
|
575
|
-
|
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)
|
data/lib/yt/models/snippet.rb
CHANGED
@@ -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.
|
data/lib/yt/models/status.rb
CHANGED
@@ -1,32 +1,318 @@
|
|
1
1
|
module Yt
|
2
2
|
module Models
|
3
|
-
#
|
4
|
-
#
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
data/lib/yt/models/video.rb
CHANGED
@@ -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
|
data/lib/yt/version.rb
CHANGED
data/spec/models/status_spec.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
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::
|
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
|
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
|
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
|
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
|
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
|
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.
|
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-
|
11
|
+
date: 2014-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|