yt 0.16.0 → 0.17.0
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/CHANGELOG.md +13 -0
- data/README.md +1 -1
- data/lib/yt/associations/has_reports.rb +69 -10
- data/lib/yt/associations/has_viewer_percentages.rb +2 -2
- data/lib/yt/collections/resumable_sessions.rb +1 -1
- data/lib/yt/models/advertising_options_set.rb +0 -5
- data/lib/yt/models/content_detail.rb +4 -18
- data/lib/yt/models/file_detail.rb +0 -6
- data/lib/yt/models/live_streaming_detail.rb +0 -19
- data/lib/yt/models/player.rb +0 -2
- data/lib/yt/models/resource.rb +6 -3
- data/lib/yt/models/snippet.rb +6 -35
- data/lib/yt/models/status.rb +3 -270
- data/lib/yt/models/video.rb +467 -172
- data/lib/yt/request.rb +2 -4
- data/lib/yt/version.rb +1 -1
- data/spec/models/content_detail_spec.rb +0 -48
- data/spec/models/file_detail_spec.rb +0 -21
- data/spec/models/live_streaming_detail_spec.rb +0 -80
- data/spec/models/player_spec.rb +0 -8
- data/spec/models/statistics_set_spec.rb +1 -0
- data/spec/models/status_spec.rb +0 -302
- data/spec/models/video_spec.rb +494 -0
- data/spec/requests/as_account/account_spec.rb +1 -1
- metadata +2 -2
data/spec/models/video_spec.rb
CHANGED
@@ -11,6 +11,500 @@ describe Yt::Video do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
describe '#deleted?' do
|
15
|
+
context 'given fetching a status returns uploadStatus "deleted"' do
|
16
|
+
let(:attrs) { {status: {"uploadStatus"=>"deleted"}} }
|
17
|
+
it { expect(video).to be_deleted }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'given fetching a status does not return uploadStatus "deleted"' do
|
21
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
22
|
+
it { expect(video).not_to be_deleted }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#failed?' do
|
27
|
+
context 'given fetching a status returns uploadStatus "failed"' do
|
28
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
29
|
+
it { expect(video).to be_failed }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'given fetching a status does not return uploadStatus "failed"' do
|
33
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
34
|
+
it { expect(video).not_to be_failed }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#processed?' do
|
39
|
+
context 'given fetching a status returns uploadStatus "processed"' do
|
40
|
+
let(:attrs) { {status: {"uploadStatus"=>"processed"}} }
|
41
|
+
it { expect(video).to be_processed }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'given fetching a status does not return uploadStatus "processed"' do
|
45
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
46
|
+
it { expect(video).not_to be_processed }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#rejected?' do
|
51
|
+
context 'given fetching a status returns uploadStatus "rejected"' do
|
52
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
53
|
+
it { expect(video).to be_rejected }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'given fetching a status does not return uploadStatus "rejected"' do
|
57
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
58
|
+
it { expect(video).not_to be_rejected }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#uploading?' do
|
63
|
+
context 'given fetching a status returns uploadStatus "uploaded"' do
|
64
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
65
|
+
it { expect(video).to be_uploading }
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'given fetching a status does not return uploadStatus "uploaded"' do
|
69
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
70
|
+
it { expect(video).not_to be_uploading }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#uses_unsupported_codec?' do
|
75
|
+
context 'given fetching a status returns failureReason "codec"' do
|
76
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed", "failureReason"=>"codec"}} }
|
77
|
+
it { expect(video.uses_unsupported_codec?).to be true }
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'given fetching a status does not return failureReason "codec"' do
|
81
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
82
|
+
it { expect(video.uses_unsupported_codec?).to be false }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#conversion_failed?' do
|
87
|
+
context 'given fetching a status returns failureReason "conversion"' do
|
88
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed", "failureReason"=>"conversion"}} }
|
89
|
+
it { expect(video).to have_failed_conversion }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'given fetching a status does not return failureReason "conversion"' do
|
93
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
94
|
+
it { expect(video).not_to have_failed_conversion }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#empty_file?' do
|
99
|
+
context 'given fetching a status returns failureReason "emptyFile"' do
|
100
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed", "failureReason"=>"emptyFile"}} }
|
101
|
+
it { expect(video).to be_empty }
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'given fetching a status does not return failureReason "emptyFile"' do
|
105
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
106
|
+
it { expect(video).not_to be_empty }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#invalid_file?' do
|
111
|
+
context 'given fetching a status returns failureReason "invalidFile"' do
|
112
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed", "failureReason"=>"invalidFile"}} }
|
113
|
+
it { expect(video).to be_invalid }
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'given fetching a status does not return failureReason "invalidFile"' do
|
117
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
118
|
+
it { expect(video).not_to be_invalid }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#too_small?' do
|
123
|
+
context 'given fetching a status returns failureReason "tooSmall"' do
|
124
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed", "failureReason"=>"tooSmall"}} }
|
125
|
+
it { expect(video).to be_too_small }
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'given fetching a status does not return failureReason "tooSmall"' do
|
129
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
130
|
+
it { expect(video).not_to be_too_small }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#upload_aborted?' do
|
135
|
+
context 'given fetching a status returns failureReason "uploadAborted"' do
|
136
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed", "failureReason"=>"uploadAborted"}} }
|
137
|
+
it { expect(video).to be_aborted }
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'given fetching a status does not return failureReason "uploadAborted"' do
|
141
|
+
let(:attrs) { {status: {"uploadStatus"=>"failed"}} }
|
142
|
+
it { expect(video).not_to be_aborted }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#claimed?' do
|
147
|
+
context 'given fetching a status returns rejectionReason "claim"' do
|
148
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"claim"}} }
|
149
|
+
it { expect(video).to be_claimed }
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'given fetching a status does not return rejectionReason "claim"' do
|
153
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
154
|
+
it { expect(video).not_to be_claimed }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe '#infringes_copyright?' do
|
159
|
+
context 'given fetching a status returns rejectionReason "copyright"' do
|
160
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"copyright"}} }
|
161
|
+
it { expect(video.infringes_copyright?).to be true }
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'given fetching a status does not return rejectionReason "copyright"' do
|
165
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
166
|
+
it { expect(video.infringes_copyright?).to be false }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe '#duplicate?' do
|
171
|
+
context 'given fetching a status returns rejectionReason "duplicate"' do
|
172
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"duplicate"}} }
|
173
|
+
it { expect(video).to be_duplicate }
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'given fetching a status does not return rejectionReason "duplicate"' do
|
177
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
178
|
+
it { expect(video).not_to be_duplicate }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe '#inappropriate?' do
|
183
|
+
context 'given fetching a status returns rejectionReason "inappropriate"' do
|
184
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"inappropriate"}} }
|
185
|
+
it { expect(video).to be_inappropriate }
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'given fetching a status does not return rejectionReason "inappropriate"' do
|
189
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
190
|
+
it { expect(video).not_to be_inappropriate }
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe '#too_long?' do
|
195
|
+
context 'given fetching a status returns rejectionReason "length"' do
|
196
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"length"}} }
|
197
|
+
it { expect(video).to be_too_long }
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'given fetching a status does not return rejectionReason "length"' do
|
201
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
202
|
+
it { expect(video).not_to be_too_long }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#violates_terms_of_use?' do
|
207
|
+
context 'given fetching a status returns rejectionReason "termsOfUse"' do
|
208
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"termsOfUse"}} }
|
209
|
+
it { expect(video.violates_terms_of_use?).to be true }
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'given fetching a status does not return rejectionReason "termsOfUse"' do
|
213
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
214
|
+
it { expect(video.violates_terms_of_use?).to be false }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe '#infringes_trademark?' do
|
219
|
+
context 'given fetching a status returns rejectionReason "trademark"' do
|
220
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"trademark"}} }
|
221
|
+
it { expect(video.infringes_trademark?).to be true }
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'given fetching a status does not return rejectionReason "trademark"' do
|
225
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
226
|
+
it { expect(video.infringes_trademark?).to be false }
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '#belongs_to_closed_account?' do
|
231
|
+
context 'given fetching a status returns rejectionReason "uploaderAccountClosed"' do
|
232
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"uploaderAccountClosed"}} }
|
233
|
+
it { expect(video.belongs_to_closed_account?).to be true }
|
234
|
+
end
|
235
|
+
|
236
|
+
context 'given fetching a status does not return rejectionReason "uploaderAccountClosed"' do
|
237
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
238
|
+
it { expect(video.belongs_to_closed_account?).to be false }
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe '#belongs_to_suspended_account?' do
|
243
|
+
context 'given fetching a status returns rejectionReason "uploaderAccountSuspended"' do
|
244
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected", "rejectionReason"=>"uploaderAccountSuspended"}} }
|
245
|
+
it { expect(video.belongs_to_suspended_account?).to be true }
|
246
|
+
end
|
247
|
+
|
248
|
+
context 'given fetching a status does not return rejectionReason "uploaderAccountSuspended"' do
|
249
|
+
let(:attrs) { {status: {"uploadStatus"=>"rejected"}} }
|
250
|
+
it { expect(video.belongs_to_suspended_account?).to be false }
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe '#scheduled_at and #scheduled' do
|
255
|
+
context 'given fetching a status returns "publishAt"' do
|
256
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded", "privacyStatus"=>"private", "publishAt"=>"2014-04-22T19:14:49.000Z"}} }
|
257
|
+
it { expect(video).to be_scheduled }
|
258
|
+
it { expect(video.scheduled_at.year).to be 2014 }
|
259
|
+
end
|
260
|
+
|
261
|
+
context 'given fetching a status does not returns "publishAt"' do
|
262
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded", "privacyStatus"=>"private"}} }
|
263
|
+
it { expect(video).not_to be_scheduled }
|
264
|
+
it { expect(video.scheduled_at).not_to be }
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe '#licensed_as_creative_commons?' do
|
269
|
+
context 'given fetching a status returns license "creativeCommon"' do
|
270
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded", "license"=>"creativeCommon"}} }
|
271
|
+
it { expect(video).to be_licensed_as_creative_commons }
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'given fetching a status does not return license "creativeCommon"' do
|
275
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
276
|
+
it { expect(video).not_to be_licensed_as_creative_commons }
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
describe '#licensed_as_standard_youtube?' do
|
281
|
+
context 'given fetching a status returns license "youtube"' do
|
282
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded", "license"=>"youtube"}} }
|
283
|
+
it { expect(video).to be_licensed_as_standard_youtube }
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'given fetching a status does not return license "youtube"' do
|
287
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded"}} }
|
288
|
+
it { expect(video).not_to be_licensed_as_standard_youtube }
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
describe '#embeddable?' do
|
293
|
+
context 'given fetching a status returns "embeddable" true' do
|
294
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded", "embeddable"=>true}} }
|
295
|
+
it { expect(video).to be_embeddable }
|
296
|
+
end
|
297
|
+
|
298
|
+
context 'given fetching a status returns "embeddable" false' do
|
299
|
+
let(:attrs) { {status: {"uploadStatus"=>"uploaded", "embeddable"=>false}} }
|
300
|
+
it { expect(video).not_to be_embeddable }
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe '#has_public_stats_viewable?' do
|
305
|
+
context 'given fetching a status returns "publicStatsViewable" true' do
|
306
|
+
let(:attrs) { {status: {"publicStatsViewable"=>true}} }
|
307
|
+
it { expect(video).to have_public_stats_viewable }
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'given fetching a status returns "publicStatsViewable" false' do
|
311
|
+
let(:attrs) { {status: {"publicStatsViewable"=>false}} }
|
312
|
+
it { expect(video).not_to have_public_stats_viewable }
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
describe '#stereoscopic?' do
|
317
|
+
context 'given a 3D video' do
|
318
|
+
let(:attrs) { {content_details: {"dimension"=>"3d"}} }
|
319
|
+
it { expect(video).to be_stereoscopic }
|
320
|
+
end
|
321
|
+
|
322
|
+
context 'given a 2D video' do
|
323
|
+
let(:attrs) { {content_details: {"dimension"=>"2d"}} }
|
324
|
+
it { expect(video).not_to be_stereoscopic }
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
describe '#hd?' do
|
329
|
+
context 'given a high-definition video' do
|
330
|
+
let(:attrs) { {content_details: {"definition"=>"hd"}} }
|
331
|
+
it { expect(video).to be_hd }
|
332
|
+
end
|
333
|
+
|
334
|
+
context 'given a standard-definition video' do
|
335
|
+
let(:attrs) { {content_details: {"definition"=>"sd"}} }
|
336
|
+
it { expect(video).not_to be_hd }
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
describe '#captioned?' do
|
341
|
+
context 'given a video with captions' do
|
342
|
+
let(:attrs) { {content_details: {"caption"=>"true"}} }
|
343
|
+
it { expect(video).to be_captioned }
|
344
|
+
end
|
345
|
+
|
346
|
+
context 'given a video without captions' do
|
347
|
+
let(:attrs) { {content_details: {"caption"=>"false"}} }
|
348
|
+
it { expect(video).not_to be_captioned }
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
describe '#licensed?' do
|
353
|
+
context 'given a video with licensed content' do
|
354
|
+
let(:attrs) { {content_details: {"licensedContent"=>true}} }
|
355
|
+
it { expect(video).to be_licensed }
|
356
|
+
end
|
357
|
+
|
358
|
+
context 'given a video without licensed content' do
|
359
|
+
let(:attrs) { {content_details: {"licensedContent"=>false}} }
|
360
|
+
it { expect(video).not_to be_licensed }
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe '#file_size' do
|
365
|
+
context 'given a video with fileSize' do
|
366
|
+
let(:attrs) { {file_details: {"fileSize"=>"8000000"}} }
|
367
|
+
it { expect(video.file_size).to be 8_000_000 }
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
describe '#file_type' do
|
372
|
+
context 'given a video with fileType' do
|
373
|
+
let(:attrs) { {file_details: {"fileType"=>"video"}} }
|
374
|
+
it { expect(video.file_type).to eq 'video' }
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe '#container' do
|
379
|
+
context 'given a video with container' do
|
380
|
+
let(:attrs) { {file_details: {"container"=>"mov"}} }
|
381
|
+
it { expect(video.container).to eq 'mov' }
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
describe '#actual_start_time' do
|
386
|
+
context 'given a non-live streaming video' do
|
387
|
+
let(:attrs) { {live_streaming_details: {}} }
|
388
|
+
it { expect(video.actual_start_time).to be_nil }
|
389
|
+
end
|
390
|
+
|
391
|
+
context 'given a live streaming video that has not started yet' do
|
392
|
+
let(:attrs) { {live_streaming_details: {"scheduledStartTime"=>"2017-07-10T00:00:00.000Z"}} }
|
393
|
+
it { expect(video.actual_start_time).to be_nil }
|
394
|
+
end
|
395
|
+
|
396
|
+
context 'given a live streaming video that has started' do
|
397
|
+
let(:attrs) { {live_streaming_details: {"actualStartTime"=>"2014-08-01T17:48:40.678Z"}} }
|
398
|
+
it { expect(video.actual_start_time.year).to be 2014 }
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
describe '#actual_end_time' do
|
403
|
+
context 'given a non-live streaming video' do
|
404
|
+
let(:attrs) { {live_streaming_details: {}} }
|
405
|
+
it { expect(video.actual_end_time).to be_nil }
|
406
|
+
end
|
407
|
+
|
408
|
+
context 'given a live streaming video that has not ended yet' do
|
409
|
+
let(:attrs) { {live_streaming_details: {"scheduledStartTime"=>"2017-07-10T00:00:00.000Z"}} }
|
410
|
+
it { expect(video.actual_end_time).to be_nil }
|
411
|
+
end
|
412
|
+
|
413
|
+
context 'given a live streaming video that has ended' do
|
414
|
+
let(:attrs) { {live_streaming_details: {"actualEndTime"=>"2014-08-01T17:48:40.678Z"}} }
|
415
|
+
it { expect(video.actual_end_time.year).to be 2014 }
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe '#scheduled_start_time' do
|
420
|
+
context 'given a non-live streaming video' do
|
421
|
+
let(:attrs) { {live_streaming_details: {}} }
|
422
|
+
it { expect(video.scheduled_start_time).to be_nil }
|
423
|
+
end
|
424
|
+
|
425
|
+
context 'given a live streaming video' do
|
426
|
+
let(:attrs) { {live_streaming_details: {"scheduledStartTime"=>"2017-07-10T00:00:00.000Z"}} }
|
427
|
+
it { expect(video.scheduled_start_time.year).to be 2017 }
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
describe '#scheduled_end_time' do
|
432
|
+
context 'given a non-live streaming video' do
|
433
|
+
let(:attrs) { {live_streaming_details: {}} }
|
434
|
+
it { expect(video.scheduled_end_time).to be_nil }
|
435
|
+
end
|
436
|
+
|
437
|
+
context 'given a live streaming video that broadcasts indefinitely' do
|
438
|
+
let(:attrs) { {live_streaming_details: {"scheduledStartTime"=>"2017-07-10T00:00:00.000Z"}} }
|
439
|
+
it { expect(video.scheduled_end_time).to be_nil }
|
440
|
+
end
|
441
|
+
|
442
|
+
context 'given a live streaming video with a scheduled ednd' do
|
443
|
+
let(:attrs) { {live_streaming_details: {"scheduledEndTime"=>"2014-08-01T17:48:40.678Z"}} }
|
444
|
+
it { expect(video.scheduled_end_time.year).to be 2014 }
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe '#concurrent_viewers' do
|
449
|
+
context 'given a non-live streaming video' do
|
450
|
+
let(:attrs) { {live_streaming_details: {}} }
|
451
|
+
it { expect(video.concurrent_viewers).to be_nil }
|
452
|
+
end
|
453
|
+
|
454
|
+
context 'given a current live streaming video with viewers' do
|
455
|
+
let(:attrs) { {live_streaming_details: {"concurrentViewers"=>"1"}} }
|
456
|
+
it { expect(video.concurrent_viewers).to be 1 }
|
457
|
+
end
|
458
|
+
|
459
|
+
context 'given a past live streaming video' do
|
460
|
+
let(:attrs) { {live_streaming_details: {"actualEndTime"=>"2013-08-01T17:48:40.678Z"}} }
|
461
|
+
it { expect(video.concurrent_viewers).to be_nil }
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
describe '#view_count' do
|
466
|
+
context 'given a video with views' do
|
467
|
+
let(:attrs) { {statistics: { "viewCount"=>"123"}} }
|
468
|
+
it { expect(video.view_count).to be 123 }
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
describe '#comment_count' do
|
473
|
+
context 'given a video with comments' do
|
474
|
+
let(:attrs) { {statistics: { "commentCount"=>"45"}} }
|
475
|
+
it { expect(video.comment_count).to be 45 }
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
describe '#like_count' do
|
480
|
+
context 'given a video with likes' do
|
481
|
+
let(:attrs) { {statistics: { "likeCount"=>"6"}} }
|
482
|
+
it { expect(video.like_count).to be 6 }
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
describe '#dislike_count' do
|
487
|
+
context 'given a video with dislikes' do
|
488
|
+
let(:attrs) { {statistics: { "dislikeCount"=>"9"}} }
|
489
|
+
it { expect(video.dislike_count).to be 9 }
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
describe '#favorite_count' do
|
494
|
+
context 'given a video with favorites' do
|
495
|
+
let(:attrs) { {statistics: { "favoriteCount"=>"44"}} }
|
496
|
+
it { expect(video.favorite_count).to be 44 }
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
describe '#embed_html' do
|
501
|
+
context 'given a video with embedHtml' do
|
502
|
+
let(:html) { "<iframe type='text/html' src='http://www.youtube.com/embed/BPNYv0vd78A' width='640' height='360' frameborder='0' allowfullscreen='true'/>" }
|
503
|
+
let(:attrs) { {player: {"embedHtml"=>html}} }
|
504
|
+
it { expect(video.embed_html).to be html }
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
14
508
|
describe '#statistics_set' do
|
15
509
|
context 'given fetching a video returns statistics' do
|
16
510
|
let(:attrs) { {statistics: {"viewCount"=>"202"}} }
|