UNPKG

6.2 kBJavaScriptView Raw
1import QUnit from 'qunit';
2import sinon from 'sinon';
3import videojs from 'video.js';
4import window from 'global/window';
5import sharedModuleHooks from './lib/shared-module-hooks.js';
6import _ from 'lodash';
7
8const sharedHooks = sharedModuleHooks();
9
10const timerExists = function(env, id) {
11 return env.clock.timers.hasOwnProperty(id);
12};
13
14// Stub mobile browsers to force cancelContentPlay to be used
15const fakeVideojs = function() {
16 this.videojs = sinon.stub(videojs, 'browser').get(() => {
17 return {
18 IS_ANDROID: true,
19 IS_IOS: true
20 };
21 });
22};
23
24// Restore original videojs behavior
25const restoreVideojs = function() {
26 this.videojs.restore();
27};
28
29// Run custom hooks before sharedModuleHooks, as videojs must be
30// modified before setting up the player and videojs-contrib-ads
31QUnit.module('Cancel Content Play', {
32 beforeEach: _.flow(function() {
33 this.adsOptions = {};
34 }, fakeVideojs, sharedHooks.beforeEach),
35 afterEach: _.flow(function() {
36 this.adsOptions = null;
37 }, restoreVideojs, sharedHooks.afterEach)
38});
39
40QUnit.test('pauses to wait for prerolls when the plugin loads BEFORE play', function(assert) {
41 const spy = sinon.spy(this.player, 'pause');
42
43 this.player.paused = function() {
44 return false;
45 };
46
47 this.player.trigger('adsready');
48 this.player.trigger('play');
49 this.clock.tick(1);
50 this.player.trigger('play');
51 this.clock.tick(1);
52
53 assert.strictEqual(spy.callCount, 2, 'play attempts are paused');
54});
55
56QUnit.test('pauses to wait for prerolls when the plugin loads AFTER play', function(assert) {
57 const pauseSpy = sinon.spy(this.player, 'pause');
58
59 this.player.paused = function() {
60 return false;
61 };
62
63 this.player.trigger('play');
64 this.clock.tick(1);
65 this.player.trigger('play');
66 this.clock.tick(1);
67 assert.equal(pauseSpy.callCount, 2, 'play attempts are paused');
68});
69
70QUnit.test('stops canceling play events when an ad is playing', function(assert) {
71 const setTimeoutSpy = sinon.spy(window, 'setTimeout');
72 const pauseSpy = sinon.spy(this.player, 'pause');
73
74 // Throughout this test, we check both that the expected timeout is
75 // populated on the `clock` _and_ that `setTimeout` has been called the
76 // expected number of times.
77 assert.notOk(this.player.ads._cancelledPlay, 'we have not canceled a play event');
78
79 this.player.paused = () => {
80 return false;
81 };
82 this.player.trigger('play');
83 assert.strictEqual(setTimeoutSpy.callCount, 1, 'one timer was created (`_prerollTimeout`)');
84 assert.ok(timerExists(this, this.player.ads._state._timeout), 'preroll timeout exists after play');
85 assert.equal(this.player.ads._cancelledPlay, true);
86
87 this.clock.tick(1);
88 assert.equal(pauseSpy.callCount, 1);
89
90 this.player.trigger('adsready');
91 assert.ok(timerExists(this, this.player.ads._state._timeout), 'preroll timeout exists after adsready');
92
93 this.player.ads.startLinearAdMode();
94 assert.notOk(timerExists(this, this.player.ads._state._timeout), 'preroll timeout no longer exists');
95
96 this.player.trigger('play');
97 assert.equal(pauseSpy.callCount, 1, 'pause is not called while in an ad break');
98
99 window.setTimeout.restore();
100});
101
102QUnit.test("cancelContentPlay doesn\'t block play in content playback", function(assert) {
103 const pauseSpy = sinon.spy(this.player, 'pause');
104
105 this.player.trigger('loadstart');
106 this.player.trigger('adscanceled');
107 this.player.paused = () => {
108 return false;
109 };
110 this.player.trigger('play');
111 assert.strictEqual(pauseSpy.callCount, 1, 'pause should have been called');
112 assert.strictEqual(
113 this.player.ads._cancelledPlay, true,
114 'cancelContentPlay is called while resuming'
115 );
116
117 // enters ContentPlayback
118 this.player.trigger('playing');
119 this.player.trigger('play');
120
121 assert.strictEqual(pauseSpy.callCount, 1, 'pause should not have been called again');
122 assert.notOk(this.player.ads._cancelledPlay, 'cancelContentPlay does nothing in content playback');
123});
124
125QUnit.test('content is resumed after ads if a user initiated play event is canceled', function(assert) {
126 const playSpy = sinon.spy(this.player, 'play');
127 const setTimeoutSpy = sinon.spy(window, 'setTimeout');
128 const pauseSpy = sinon.spy(this.player, 'pause');
129
130 this.player.paused = () => {
131 return false;
132 };
133
134 this.player.trigger('play');
135 this.player.trigger('adsready');
136
137 assert.strictEqual(setTimeoutSpy.callCount, 1, 'one timer was created (`_prerollTimeout`)');
138 assert.ok(timerExists(this, this.player.ads._state._timeout), 'preroll timeout exists');
139 assert.ok(this.player.ads._cancelledPlay, true, 'play has been canceled');
140 assert.ok(pauseSpy.callCount, 1, 'pause was called');
141
142 this.player.ads.startLinearAdMode();
143 this.player.ads.endLinearAdMode();
144 assert.strictEqual(playSpy.callCount, 1, 'play should be called by the snapshot restore');
145
146 this.player.trigger('play');
147 assert.ok(pauseSpy.callCount, 1, 'pause was not called again');
148});
149
150// Set up contrib-ads options and run custom hooks before sharedModuleHooks, as
151// videojs must be modified before setting up the player and videojs-contrib-ads
152QUnit.module('Cancel Content Play (w/ Stitched Ads)', {
153 beforeEach: _.flow(function() {
154 this.adsOptions = {
155 stitchedAds: true
156 };
157 }, fakeVideojs, sharedHooks.beforeEach),
158 afterEach: _.flow(function() {
159 this.adsOptions = null;
160 }, restoreVideojs, sharedHooks.afterEach)
161});
162
163QUnit.test('does not pause to wait for prerolls when the plugin loads BEFORE play', function(assert) {
164 const spy = sinon.spy(this.player, 'pause');
165
166 this.player.paused = function() {
167 return false;
168 };
169
170 this.player.trigger('adsready');
171 this.player.trigger('play');
172 this.clock.tick(1);
173 this.player.trigger('play');
174 this.clock.tick(1);
175
176 assert.strictEqual(spy.callCount, 0, 'play attempts are not paused');
177});
178
179QUnit.test('does not pause to wait for prerolls when the plugin loads AFTER play', function(assert) {
180 const pauseSpy = sinon.spy(this.player, 'pause');
181
182 this.player.paused = function() {
183 return false;
184 };
185
186 this.player.trigger('play');
187 this.clock.tick(1);
188 this.player.trigger('play');
189 this.clock.tick(1);
190 assert.equal(pauseSpy.callCount, 0, 'play attempts are not paused');
191});