playable
Version:
Video player based on HTML5Video
353 lines • 20.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var chai_1 = require("chai");
var sinon = (0, tslib_1.__importStar)(require("sinon"));
var constants_1 = require("../../constants");
var testkit_1 = (0, tslib_1.__importStar)(require("../../testkit"));
describe('LiveStateEngine', function () {
var testkit;
var engine;
var liveStateEngine;
var eventEmitter;
beforeEach(function () {
testkit = (0, testkit_1.default)();
engine = testkit.getModule('engine');
liveStateEngine = testkit.getModule('liveStateEngine');
eventEmitter = testkit.getModule('eventEmitter');
sinon.spy(eventEmitter, 'emitAsync');
});
afterEach(function () {
eventEmitter.emitAsync.restore();
});
it('should reset state on `STATES.SRC_SET`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var prevState;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
prevState = constants_1.LiveState.NOT_SYNC;
liveStateEngine._setState(prevState);
(0, chai_1.expect)(liveStateEngine.state, 'not `LiveState.NONE` before `SRC_SET`').to.not.equal(constants_1.LiveState.NONE);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.SRC_SET,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.NONE);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: prevState,
nextState: constants_1.LiveState.NONE,
}), 'new live state emitted').to.equal(true);
return [2 /*return*/];
}
});
});
});
describe('with dynamic content', function () {
beforeEach(function () {
(0, testkit_1.setProperty)(engine, 'isDynamicContent', true);
});
afterEach(function () {
(0, testkit_1.resetProperty)(engine, 'isDynamicContent');
});
it('should set `INITIAL` state on `METADATA_LOADED`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.SRC_SET,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state, '`LiveState.NONE` before `METADATA_LOADED`').to.equal(constants_1.LiveState.NONE);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.METADATA_LOADED,
})];
case 2:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.INITIAL);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.NONE,
nextState: constants_1.LiveState.INITIAL,
}), 'new live state emitted').to.equal(true);
return [2 /*return*/];
}
});
});
});
describe('after `INITIAL`', function () {
beforeEach(function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.SRC_SET,
})];
case 1:
_a.sent();
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.METADATA_LOADED,
})];
case 2:
_a.sent();
return [2 /*return*/];
}
});
});
});
it('should sync to live on `PLAY_REQUESTED`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var syncWithLiveSpy;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
syncWithLiveSpy = sinon.stub(engine, 'syncWithLive');
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAY_REQUESTED,
})];
case 1:
_a.sent();
(0, chai_1.expect)(syncWithLiveSpy.called).to.equal(true);
syncWithLiveSpy.restore();
return [2 /*return*/];
}
});
});
});
describe('on `PLAYING`', function () {
it('should set `SYNC` if `isSyncWithLive`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isSyncWithLive', true);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAYING,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.SYNC);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.INITIAL,
nextState: constants_1.LiveState.SYNC,
}), 'new live state emitted').to.equal(true);
(0, testkit_1.resetProperty)(engine, 'isSyncWithLive');
return [2 /*return*/];
}
});
});
});
it('should set `NOT_SYNC` if not `isSyncWithLive`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isSyncWithLive', false);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAYING,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.NOT_SYNC);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.INITIAL,
nextState: constants_1.LiveState.NOT_SYNC,
}), 'new live state emitted').to.equal(true);
(0, testkit_1.resetProperty)(engine, 'isSyncWithLive');
return [2 /*return*/];
}
});
});
});
});
});
describe('after `NOT_SYNC` on `PLAYING`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
beforeEach(function () {
liveStateEngine._setState(constants_1.LiveState.NOT_SYNC);
});
it('should set `SYNC` if `isSyncWithLive`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isSyncWithLive', true);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAYING,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.SYNC);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.NOT_SYNC,
nextState: constants_1.LiveState.SYNC,
}), 'new live state emitted').to.equal(true);
(0, testkit_1.resetProperty)(engine, 'isSyncWithLive');
return [2 /*return*/];
}
});
});
});
it('should ignore if not `isSyncWithLive`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isSyncWithLive', false);
// reset spy state before test
eventEmitter.emitAsync.resetHistory();
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAYING,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.NOT_SYNC);
// NOTE: ensure emit is not called with new `LiveState`
(0, chai_1.expect)(eventEmitter.emitAsync.callCount).to.equal(1);
(0, testkit_1.resetProperty)(engine, 'isSyncWithLive');
return [2 /*return*/];
}
});
});
});
return [2 /*return*/];
});
});
});
describe('on `PLAYING` after seek', function () {
beforeEach(function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
engine._output._stateEngine.setState(constants_1.EngineState.PLAYING);
liveStateEngine._setState(constants_1.LiveState.SYNC);
// emulate seek by UI
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_CHANGE)];
case 1:
// emulate seek by UI
_a.sent();
return [2 /*return*/];
}
});
});
});
it('should ignore if `isSyncWithLive`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isSyncWithLive', true);
// reset spy state before test
eventEmitter.emitAsync.resetHistory();
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAYING,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.SYNC);
// NOTE: ensure emit is not called with new `LiveState`
(0, chai_1.expect)(eventEmitter.emitAsync.callCount).to.equal(1);
(0, testkit_1.resetProperty)(engine, 'isSyncWithLive');
return [2 /*return*/];
}
});
});
});
it('should set `NOT_SYNC` if not `isSyncWithLive`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isSyncWithLive', false);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.PLAYING,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.NOT_SYNC);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.SYNC,
nextState: constants_1.LiveState.NOT_SYNC,
}), 'new live state emitted').to.equal(true);
(0, testkit_1.resetProperty)(engine, 'isSyncWithLive');
return [2 /*return*/];
}
});
});
});
});
it('should set `NOT_SYNC` on `PAUSE` by UI', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
liveStateEngine._setState(constants_1.LiveState.SYNC);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
prevState: constants_1.EngineState.PLAYING,
nextState: constants_1.EngineState.PAUSED,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.NOT_SYNC);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.SYNC,
nextState: constants_1.LiveState.NOT_SYNC,
}), 'new live state emitted').to.equal(true);
return [2 /*return*/];
}
});
});
});
it('should set `ENDED` on stream ended', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
liveStateEngine._setState(constants_1.LiveState.SYNC);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.DYNAMIC_CONTENT_ENDED)];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.ENDED);
(0, chai_1.expect)(eventEmitter.emitAsync.lastCall.calledWith(constants_1.VideoEvent.LIVE_STATE_CHANGED, {
prevState: constants_1.LiveState.SYNC,
nextState: constants_1.LiveState.ENDED,
}), 'new live state emitted').to.equal(true);
return [2 /*return*/];
}
});
});
});
});
it('should ignore events if not `isDynamicContent`', function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
(0, testkit_1.setProperty)(engine, 'isDynamicContent', false);
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.SRC_SET,
})];
case 1:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state, '`LiveState.NONE` before `METADATA_LOADED`').to.equal(constants_1.LiveState.NONE);
// reset spy state before test
eventEmitter.emitAsync.resetHistory();
return [4 /*yield*/, eventEmitter.emitAsync(constants_1.VideoEvent.STATE_CHANGED, {
nextState: constants_1.EngineState.METADATA_LOADED,
})];
case 2:
_a.sent();
(0, chai_1.expect)(liveStateEngine.state).to.equal(constants_1.LiveState.NONE);
// NOTE: ensure emit is not called with new `LiveState`
(0, chai_1.expect)(eventEmitter.emitAsync.callCount).to.equal(1);
(0, testkit_1.resetProperty)(engine, 'isDynamicContent');
return [2 /*return*/];
}
});
});
});
});
//# sourceMappingURL=live-state-engine.spec.js.map