Skip to content

Commit

Permalink
Add tests for setPlaybackRate & setStallState in VideoModel
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-coward committed Oct 17, 2024
1 parent 5fedc6d commit 606cd6b
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/streaming/models/VideoModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function VideoModel() {

let instance,
logger,
settings,
element,
_currentTime,
setCurrentTimeReadyStateFunction,
Expand All @@ -61,11 +62,11 @@ function VideoModel() {

const context = this.context;
const eventBus = EventBus(context).getInstance();
const settings = Settings(context).getInstance();
const stalledStreams = [];

function setup() {
logger = Debug(context).getInstance().getLogger(instance);
settings = Settings(context).getInstance();
_currentTime = NaN;
}

Expand All @@ -76,6 +77,17 @@ function VideoModel() {
function reset() {
clearTimeout(timeout);
eventBus.off(Events.PLAYBACK_PLAYING, onPlaying, this);
stalledStreams.length = 0;
}

function setConfig(config) {
if (!config) {
return;
}

if (config.settings) {
settings = config.settings;
}
}

function setPlaybackRate(value, ignoreReadyState = false) {
Expand Down Expand Up @@ -540,6 +552,7 @@ function VideoModel() {
removeChild,
removeEventListener,
reset,
setConfig,
setCurrentTime,
setDisableRemotePlayback,
setElement,
Expand Down
35 changes: 35 additions & 0 deletions test/unit/mocks/VideoElementMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class VideoElementMock {
this.nodeName = 'VIDEO';
this.videoWidth = 800;
this.videoHeight = 600;
this.readyState = 0;
this.events = {};
}

constructor() {
Expand All @@ -46,6 +48,39 @@ class VideoElementMock {
return textTrack.getCurrentCue();
}

addEventListener(type, handler) {
if (this.events.hasOwnProperty(type)) {
this.events[type].push(handler);
} else {
this.events[type] = [handler];
}
}

removeEventListener(type, handler) {
if (!this.events.hasOwnProperty(type)) {
return;
}

let index = this.events[type].indexOf(handler);
if (index != -1) {
this.events[type].splice(index, 1);
}
}

dispatchEvent(event) {
const { type } = event;

if (!this.events.hasOwnProperty(type)) {
return;
}

let evs = this.events[type];
let l = evs.length;
for (let i = 0; i < l; i++) {
evs[i]();
}
}

reset() {
this.setup();
}
Expand Down
71 changes: 71 additions & 0 deletions test/unit/test/streaming/streaming.models.VideoModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import VideoModel from '../../../../src/streaming/models/VideoModel.js';
import VideoElementMock from '../../mocks/VideoElementMock.js';
import Settings from '../../../../src/core/Settings.js';
import Constants from '../../../../src/streaming/constants/Constants.js';

import {expect} from 'chai';

describe('VideoModel', () => {
const context = {};
const videoModel = VideoModel(context).getInstance();
const videoElementMock = new VideoElementMock();
const settings = Settings(context).getInstance();

beforeEach(() => {
videoModel.setElement(videoElementMock);
});

afterEach(() => {
videoModel.reset();
videoElementMock.reset();
settings.reset();
});

describe('setPlaybackRate()', () => {
it('Should always set playback rate even when not in ready state if ignoring ready state', () => {
videoElementMock.playbackRate = 1;
videoElementMock.readyState = Constants.VIDEO_ELEMENT_READY_STATES.HAVE_NOTHING;

videoModel.setPlaybackRate(0, true);
expect(videoElementMock.playbackRate).to.equal(0);
});

it('Should set playback rate if the video element is in ready state', () => {
videoElementMock.playbackRate = 1;
videoElementMock.readyState = Constants.VIDEO_ELEMENT_READY_STATES.HAVE_FUTURE_DATA;

videoModel.setPlaybackRate(0.5, false);
expect(videoElementMock.playbackRate).to.equal(0.5);
});
});

describe('setStallState()', () => {
describe('syntheticStallEvents enabled', () => {
beforeEach(() => {
settings.update({ streaming: { buffer: { syntheticStallEvents: { enabled: true, ignoreReadyState: false } }}});
videoModel.setConfig({ settings });
})

it('Should set playback rate to 0 on stall if video element is in ready state', () => {
videoElementMock.playbackRate = 1;
videoElementMock.readyState = Constants.VIDEO_ELEMENT_READY_STATES.HAVE_FUTURE_DATA;

videoModel.setStallState('video', true);

expect(videoElementMock.playbackRate).to.equal(0);
});

it('Should emit a waiting event on stall if video element is in ready state', (done) => {
videoElementMock.readyState = Constants.VIDEO_ELEMENT_READY_STATES.HAVE_FUTURE_DATA;

const onWaiting = () => {
videoElementMock.removeEventListener('waiting', onWaiting);
done();
};
videoElementMock.addEventListener('waiting', onWaiting);

videoModel.setStallState('video', true);
});
});
});
});

0 comments on commit 606cd6b

Please sign in to comment.