yt 0.8.0 → 0.8.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 +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
|
+

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