Files
shaka-player/test/cast/cast_proxy_unit.js
T
Jacob Trimble 0dd64074b9 Only allow one statement per line.
With the new style rule, we cannot have two statements on the same line.
So we can no longer have an "if" on a single line and we cannot have
an arrow function with a body on the same line as when it is used.
This is mostly a manual change.

Change-Id: I2285202dd5ecbad764308bc725e6d317ff2ee7f0
2019-05-13 22:11:50 +00:00

745 lines
26 KiB
JavaScript

/**
* @license
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
describe('CastProxy', () => {
const CastProxy = shaka.cast.CastProxy;
const FakeEvent = shaka.util.FakeEvent;
const Util = shaka.test.Util;
const originalCastSender = shaka.cast.CastSender;
const fakeAppId = 'fake app ID';
let mockPlayer;
let mockSender;
/** @type {!shaka.test.FakeVideo} */
let mockVideo;
/** @type {!jasmine.Spy} */
let mockCastSenderConstructor;
/** @type {shaka.cast.CastProxy} */
let proxy;
beforeAll(() => {
mockCastSenderConstructor = jasmine.createSpy('CastSender constructor');
mockCastSenderConstructor.and.callFake(createMockCastSender);
shaka.cast.CastSender = Util.spyFunc(mockCastSenderConstructor);
});
afterAll(() => {
shaka.cast.CastSender = originalCastSender;
});
beforeEach(() => {
mockVideo = new shaka.test.FakeVideo();
mockPlayer = createMockPlayer();
mockSender = null;
proxy = new CastProxy(mockVideo, mockPlayer, fakeAppId);
});
afterEach((done) => {
proxy.destroy().catch(fail).then(done);
});
describe('constructor', () => {
it('creates and initializes a CastSender', () => {
expect(mockCastSenderConstructor).toHaveBeenCalled();
expect(mockSender).toBeTruthy();
expect(mockSender.init).toHaveBeenCalled();
});
it('listens for video and player events', () => {
expect(Object.keys(mockVideo.on).length).toBeGreaterThan(0);
expect(Object.keys(mockPlayer.listeners).length).toBeGreaterThan(0);
});
it('creates proxies for video and player', () => {
expect(proxy.getVideo()).toBeTruthy();
expect(proxy.getVideo()).not.toBe(mockVideo);
expect(proxy.getPlayer()).toBeTruthy();
expect(proxy.getPlayer()).not.toBe(mockPlayer);
});
});
describe('canCast', () => {
it('is true if the API is ready and we have receivers', () => {
mockSender.apiReady.and.returnValue(false);
mockSender.hasReceivers.and.returnValue(false);
expect(proxy.canCast()).toBe(false);
mockSender.apiReady.and.returnValue(true);
expect(proxy.canCast()).toBe(false);
mockSender.hasReceivers.and.returnValue(true);
expect(proxy.canCast()).toBe(true);
});
});
describe('isCasting', () => {
it('delegates directly to the sender', () => {
mockSender.isCasting.and.returnValue(false);
expect(proxy.isCasting()).toBe(false);
mockSender.isCasting.and.returnValue(true);
expect(proxy.isCasting()).toBe(true);
});
});
describe('receiverName', () => {
it('delegates directly to the sender', () => {
mockSender.receiverName.and.returnValue('abc');
expect(proxy.receiverName()).toBe('abc');
mockSender.receiverName.and.returnValue('xyz');
expect(proxy.receiverName()).toBe('xyz');
});
});
describe('setAppData', () => {
it('delegates directly to the sender', () => {
const fakeAppData = {key: 'value'};
expect(mockSender.setAppData).not.toHaveBeenCalled();
proxy.setAppData(fakeAppData);
expect(mockSender.setAppData).toHaveBeenCalledWith(fakeAppData);
});
});
describe('disconnect', () => {
it('delegates directly to the sender', () => {
expect(mockSender.showDisconnectDialog).not.toHaveBeenCalled();
proxy.suggestDisconnect();
expect(mockSender.showDisconnectDialog).toHaveBeenCalled();
});
});
describe('cast', () => {
it('pauses the local video', () => {
proxy.cast();
expect(mockVideo.pause).toHaveBeenCalled();
});
it('passes initial state to sender', () => {
mockVideo.loop = true;
mockVideo.playbackRate = 3;
mockVideo.currentTime = 12;
const fakeConfig = {key: 'value'};
mockPlayer.getConfiguration.and.returnValue(fakeConfig);
mockPlayer.isTextTrackVisible.and.returnValue(false);
const fakeManifestUri = 'foo://bar';
mockPlayer.getAssetUri.and.returnValue(fakeManifestUri);
proxy.cast();
const calls = mockSender.cast.calls;
expect(calls.count()).toBe(1);
if (calls.count()) {
const state = calls.argsFor(0)[0];
// Video state goes directly:
expect(state.video.loop).toEqual(mockVideo.loop);
expect(state.video.playbackRate).toEqual(mockVideo.playbackRate);
// Player state uses corresponding setter names:
expect(state.player.configure).toEqual(fakeConfig);
expect(state['playerAfterLoad'].setTextTrackVisibility).toBe(false);
// Manifest URI:
expect(state.manifest).toEqual(fakeManifestUri);
// Start time:
expect(state.startTime).toEqual(mockVideo.currentTime);
}
});
it('does not provide a start time if the video has ended', () => {
mockVideo.ended = true;
mockVideo.currentTime = 12;
proxy.cast();
const calls = mockSender.cast.calls;
expect(calls.count()).toBe(1);
if (calls.count()) {
const state = calls.argsFor(0)[0];
expect(state.startTime).toBe(null);
}
});
it('unloads the local player after casting is complete', (done) => {
const p = new shaka.util.PublicPromise();
mockSender.cast.and.returnValue(p);
proxy.cast();
shaka.test.Util.delay(0.1).then(() => {
// unload() has not been called yet.
expect(mockPlayer.unload).not.toHaveBeenCalled();
// Resolve the cast() promise.
p.resolve();
return shaka.test.Util.delay(0.1);
}).then(() => {
// unload() has now been called.
expect(mockPlayer.unload).toHaveBeenCalled();
}).catch(fail).then(done);
});
});
describe('video proxy', () => {
describe('get', () => {
it('returns local values when we are playing back locally', () => {
mockVideo.currentTime = 12;
mockVideo.paused = true;
expect(proxy.getVideo().currentTime).toEqual(mockVideo.currentTime);
expect(proxy.getVideo().paused).toEqual(mockVideo.paused);
expect(mockVideo.play).not.toHaveBeenCalled();
proxy.getVideo().play();
expect(mockVideo.play).toHaveBeenCalled();
// The local method call was properly bound:
expect(mockVideo.play.calls.mostRecent().object).toBe(mockVideo);
});
it('returns cached remote values when we are casting', () => {
// Local values that will be ignored:
mockVideo.currentTime = 12;
mockVideo.paused = true;
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
// Simulate remote values:
const cache = {video: {
currentTime: 24,
paused: false,
play: jasmine.createSpy('play'),
}};
mockSender.get.and.callFake((targetName, property) => {
expect(targetName).toEqual('video');
return cache.video[property];
});
expect(proxy.getVideo().currentTime).not.toEqual(mockVideo.currentTime);
expect(proxy.getVideo().currentTime).toEqual(cache.video.currentTime);
expect(proxy.getVideo().paused).not.toEqual(mockVideo.paused);
expect(proxy.getVideo().paused).toEqual(cache.video.paused);
// Call a method:
expect(mockVideo.play).not.toHaveBeenCalled();
proxy.getVideo().play();
// The call was routed to the remote video.
expect(mockVideo.play).not.toHaveBeenCalled();
expect(cache.video.play).toHaveBeenCalled();
});
it('returns local values when we have no remote values yet', () => {
mockVideo.currentTime = 12;
mockVideo.paused = true;
// Set up the sender in casting mode, but without any remote values:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(false);
// Simulate remote method:
const playSpy = jasmine.createSpy('play');
mockSender.get.and.callFake((targetName, property) => {
expect(targetName).toEqual('video');
expect(property).toEqual('play');
return playSpy;
});
// Without remote values, we should still return the local ones.
expect(proxy.getVideo().currentTime).toEqual(mockVideo.currentTime);
expect(proxy.getVideo().paused).toEqual(mockVideo.paused);
// Call a method:
expect(mockVideo.play).not.toHaveBeenCalled();
proxy.getVideo().play();
// The call was still routed to the remote video.
expect(mockVideo.play).not.toHaveBeenCalled();
expect(playSpy).toHaveBeenCalled();
});
});
describe('set', () => {
it('writes local values when we are playing back locally', () => {
mockVideo.currentTime = 12;
expect(proxy.getVideo().currentTime).toEqual(12);
// Writes to the proxy are reflected immediately in both the proxy and
// the local video.
proxy.getVideo().currentTime = 24;
expect(proxy.getVideo().currentTime).toEqual(24);
expect(mockVideo.currentTime).toEqual(24);
});
it('writes values remotely when we are casting', () => {
mockVideo.currentTime = 12;
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
// Set the value of currentTime:
expect(mockSender.set).not.toHaveBeenCalled();
proxy.getVideo().currentTime = 24;
expect(mockSender.set).toHaveBeenCalledWith('video', 'currentTime', 24);
// The local value was unaffected.
expect(mockVideo.currentTime).toEqual(12);
});
});
describe('local events', () => {
it('forward to the proxy when we are playing back locally', () => {
const proxyListener = jasmine.createSpy('listener');
proxy.getVideo().addEventListener(
'timeupdate', Util.spyFunc(proxyListener));
expect(proxyListener).not.toHaveBeenCalled();
const fakeEvent = new FakeEvent('timeupdate', {detail: 8675309});
mockVideo.on['timeupdate'](fakeEvent);
expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({
type: 'timeupdate',
detail: 8675309,
}));
});
it('are ignored when we are casting', () => {
const proxyListener = jasmine.createSpy('listener');
proxy.getVideo().addEventListener(
'timeupdate', Util.spyFunc(proxyListener));
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
expect(proxyListener).not.toHaveBeenCalled();
const fakeEvent = new FakeEvent('timeupdate', {detail: 8675309});
mockVideo.on['timeupdate'](fakeEvent);
expect(proxyListener).not.toHaveBeenCalled();
});
});
describe('remote events', () => {
it('forward to the proxy when we are casting', () => {
const proxyListener = jasmine.createSpy('listener');
proxy.getVideo().addEventListener(
'timeupdate', Util.spyFunc(proxyListener));
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
expect(proxyListener).not.toHaveBeenCalled();
const fakeEvent = new FakeEvent('timeupdate', {detail: 8675309});
mockSender.onRemoteEvent('video', fakeEvent);
expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({
type: 'timeupdate',
detail: 8675309,
}));
});
});
});
describe('player proxy', () => {
describe('get', () => {
it('returns local values when we are playing back locally', () => {
const fakeConfig = {key: 'value'};
mockPlayer.getConfiguration.and.returnValue(fakeConfig);
expect(proxy.getPlayer().getConfiguration()).toEqual(fakeConfig);
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
proxy.getPlayer().trickPlay(5);
expect(mockPlayer.trickPlay).toHaveBeenCalledWith(5);
// The local method call was properly bound:
expect(mockPlayer.trickPlay.calls.mostRecent().object).toBe(mockPlayer);
});
it('returns cached remote values when we are casting', () => {
// Local values that will be ignored:
const fakeConfig = {key: 'value'};
mockPlayer.getConfiguration.and.returnValue(fakeConfig);
mockPlayer.isTextTrackVisible.and.returnValue(false);
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
// Simulate remote values:
const fakeConfig2 = {key2: 'value2'};
const cache = {player: {
getConfiguration: fakeConfig2,
isTextTrackVisible: true,
trickPlay: jasmine.createSpy('trickPlay'),
}};
mockSender.get.and.callFake((targetName, property) => {
expect(targetName).toEqual('player');
const value = cache.player[property];
if (typeof value == 'function') {
// methods:
return value;
} else {
// getters:
return () => value;
}
});
expect(proxy.getPlayer().getConfiguration()).toEqual(fakeConfig2);
expect(proxy.getPlayer().isTextTrackVisible()).toBe(true);
// Call a method:
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
proxy.getPlayer().trickPlay(5);
// The call was routed to the remote player.
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
expect(cache.player.trickPlay).toHaveBeenCalledWith(5);
});
it('returns local values when we have no remote values yet', () => {
const fakeConfig = {key: 'value'};
mockPlayer.getConfiguration.and.returnValue(fakeConfig);
mockPlayer.isTextTrackVisible.and.returnValue(true);
// Set up the sender in casting mode, but without any remote values:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(false);
// Simulate remote method:
const trickPlaySpy = jasmine.createSpy('trickPlay');
mockSender.get.and.callFake((targetName, property) => {
expect(targetName).toEqual('player');
expect(property).toEqual('trickPlay');
return trickPlaySpy;
});
// Without remote values, we should still return the local ones.
expect(proxy.getPlayer().getConfiguration()).toEqual(fakeConfig);
expect(proxy.getPlayer().isTextTrackVisible()).toBe(true);
// Call a method:
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
proxy.getPlayer().trickPlay(5);
// The call was still routed to the remote player.
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
expect(trickPlaySpy).toHaveBeenCalledWith(5);
});
it('always returns a local NetworkingEngine', () => {
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
expect(mockPlayer.getNetworkingEngine).not.toHaveBeenCalled();
proxy.getPlayer().getNetworkingEngine();
expect(mockPlayer.getNetworkingEngine).toHaveBeenCalled();
// The local method call was properly bound:
expect(mockPlayer.getNetworkingEngine.calls.mostRecent().object).toBe(
mockPlayer);
});
});
describe('local events', () => {
it('forward to the proxy when we are playing back locally', () => {
const proxyListener = jasmine.createSpy('listener');
proxy.getPlayer().addEventListener(
'buffering', Util.spyFunc(proxyListener));
expect(proxyListener).not.toHaveBeenCalled();
const fakeEvent = new FakeEvent('buffering', {detail: 8675309});
mockPlayer.listeners['buffering'](fakeEvent);
expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({
type: 'buffering',
detail: 8675309,
}));
});
it('are ignored when we are casting', () => {
const proxyListener = jasmine.createSpy('listener');
proxy.getPlayer().addEventListener(
'buffering', Util.spyFunc(proxyListener));
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
expect(proxyListener).not.toHaveBeenCalled();
const fakeEvent = new FakeEvent('buffering', {detail: 8675309});
mockPlayer.listeners['buffering'](fakeEvent);
expect(proxyListener).not.toHaveBeenCalled();
});
});
describe('remote events', () => {
it('forward to the proxy when we are casting', () => {
const proxyListener = jasmine.createSpy('listener');
proxy.getPlayer().addEventListener(
'buffering', Util.spyFunc(proxyListener));
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
mockSender.hasRemoteProperties.and.returnValue(true);
expect(proxyListener).not.toHaveBeenCalled();
const fakeEvent = new FakeEvent('buffering', {detail: 8675309});
mockSender.onRemoteEvent('player', fakeEvent);
expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({
type: 'buffering',
detail: 8675309,
}));
});
});
});
describe('"caststatuschanged" event', () => {
it('is triggered by the sender', () => {
const listener = jasmine.createSpy('listener');
proxy.addEventListener('caststatuschanged', Util.spyFunc(listener));
expect(listener).not.toHaveBeenCalled();
mockSender.onCastStatusChanged();
expect(listener).toHaveBeenCalledWith(jasmine.objectContaining({
type: 'caststatuschanged',
}));
});
});
describe('synthetic video events from onFirstCastStateUpdate', () => {
it('sends a pause event if the video is paused', () => {
mockVideo.paused = true;
const proxyListener = jasmine.createSpy('listener');
proxy.getVideo().addEventListener('pause', Util.spyFunc(proxyListener));
expect(proxyListener).not.toHaveBeenCalled();
mockSender.onFirstCastStateUpdate();
expect(proxyListener).toHaveBeenCalled();
});
it('sends a play event if the video is playing', () => {
mockVideo.paused = false;
const proxyListener = jasmine.createSpy('listener');
proxy.getVideo().addEventListener('play', Util.spyFunc(proxyListener));
expect(proxyListener).not.toHaveBeenCalled();
mockSender.onFirstCastStateUpdate();
expect(proxyListener).toHaveBeenCalled();
});
});
describe('resume local playback', () => {
let cache;
beforeEach(() => {
// Simulate cached remote state:
cache = {
video: {
loop: true,
playbackRate: 5,
},
player: {
getConfiguration: {key: 'value'},
isTextTrackVisisble: true,
},
};
mockSender.get.and.callFake((targetName, property) => {
if (targetName == 'player') {
return () => cache[targetName][property];
} else {
return cache[targetName][property];
}
});
});
it('transfers remote state back to local objects', (done) => {
// Nothing has been set yet:
expect(mockPlayer.configure).not.toHaveBeenCalled();
expect(mockPlayer.setTextTrackVisibility).not.toHaveBeenCalled();
expect(mockVideo.loop).toBe(false);
expect(mockVideo.playbackRate).toBe(1);
// Resume local playback.
mockSender.onResumeLocal();
// Initial Player state first:
expect(mockPlayer.configure).toHaveBeenCalledWith(
cache.player.getConfiguration);
// Nothing else yet:
expect(mockPlayer.setTextTrackVisibility).not.toHaveBeenCalled();
expect(mockVideo.loop).toBe(false);
expect(mockVideo.playbackRate).toBe(1);
// The rest is done async:
shaka.test.Util.delay(0.1).then(() => {
expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith(
cache.player.isTextTrackVisible);
expect(mockVideo.loop).toEqual(cache.video.loop);
expect(mockVideo.playbackRate).toEqual(cache.video.playbackRate);
}).catch(fail).then(done);
});
it('loads the manifest', () => {
cache.video.currentTime = 12;
cache.player.getAssetUri = 'foo://bar';
expect(mockPlayer.load).not.toHaveBeenCalled();
mockSender.onResumeLocal();
expect(mockPlayer.load).toHaveBeenCalledWith('foo://bar', 12);
});
it('does not provide a start time if the video has ended', () => {
cache.video.currentTime = 12;
cache.video.ended = true;
cache.player.getAssetUri = 'foo://bar';
expect(mockPlayer.load).not.toHaveBeenCalled();
mockSender.onResumeLocal();
expect(mockPlayer.load).toHaveBeenCalledWith('foo://bar', null);
});
it('plays the video after loading', (done) => {
cache.player.getAssetUri = 'foo://bar';
// Should play even if the video was paused remotely.
cache.video.paused = true;
mockVideo.autoplay = true;
mockSender.onResumeLocal();
// Video autoplay inhibited:
expect(mockVideo.autoplay).toBe(false);
shaka.test.Util.delay(0.1).then(() => {
expect(mockVideo.play).toHaveBeenCalled();
// Video autoplay restored:
expect(mockVideo.autoplay).toBe(true);
}).catch(fail).then(done);
});
it('does not load or play without a manifest URI', (done) => {
cache.player.getAssetUri = null;
mockSender.onResumeLocal();
shaka.test.Util.delay(0.1).then(() => {
// Nothing loaded or played:
expect(mockPlayer.load).not.toHaveBeenCalled();
expect(mockVideo.play).not.toHaveBeenCalled();
// State was still transferred, though:
expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith(
cache.player.isTextTrackVisible);
expect(mockVideo.loop).toEqual(cache.video.loop);
expect(mockVideo.playbackRate).toEqual(cache.video.playbackRate);
}).catch(fail).then(done);
});
it('triggers an "error" event if load fails', (done) => {
cache.player.getAssetUri = 'foo://bar';
const fakeError = new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.UNABLE_TO_GUESS_MANIFEST_TYPE);
mockPlayer.load.and.returnValue(Promise.reject(fakeError));
mockSender.onResumeLocal();
shaka.test.Util.delay(0.1).then(() => {
expect(mockPlayer.load).toHaveBeenCalled();
expect(mockPlayer.dispatchEvent).toHaveBeenCalledWith(
jasmine.objectContaining({type: 'error', detail: fakeError}));
}).catch(fail).then(done);
});
});
describe('destroy', () => {
it('destroys the local player and the sender', (done) => {
expect(mockPlayer.destroy).not.toHaveBeenCalled();
expect(mockSender.destroy).not.toHaveBeenCalled();
expect(mockSender.forceDisconnect).not.toHaveBeenCalled();
proxy.destroy().catch(fail).then(done);
expect(mockPlayer.destroy).toHaveBeenCalled();
expect(mockSender.destroy).toHaveBeenCalled();
expect(mockSender.forceDisconnect).not.toHaveBeenCalled();
});
it('optionally forces the sender to disconnect', (done) => {
expect(mockSender.destroy).not.toHaveBeenCalled();
expect(mockSender.forceDisconnect).not.toHaveBeenCalled();
proxy.destroy(true).catch(fail).then(done);
expect(mockSender.destroy).toHaveBeenCalled();
expect(mockSender.forceDisconnect).toHaveBeenCalled();
});
});
/**
* @param {string} appId
* @param {Function} onCastStatusChanged
* @param {Function} onFirstCastStateUpdate
* @param {Function} onRemoteEvent
* @param {Function} onResumeLocal
* @return {!Object}
*/
function createMockCastSender(
appId, onCastStatusChanged, onFirstCastStateUpdate,
onRemoteEvent, onResumeLocal) {
expect(appId).toEqual(fakeAppId);
mockSender = {
init: jasmine.createSpy('init'),
destroy: jasmine.createSpy('destroy'),
apiReady: jasmine.createSpy('apiReady'),
hasReceivers: jasmine.createSpy('hasReceivers'),
isCasting: jasmine.createSpy('isCasting'),
receiverName: jasmine.createSpy('receiverName'),
hasRemoteProperties: jasmine.createSpy('hasRemoteProperties'),
setAppData: jasmine.createSpy('setAppData'),
forceDisconnect: jasmine.createSpy('forceDisconnect'),
showDisconnectDialog: jasmine.createSpy('showDisconnectDialog'),
cast: jasmine.createSpy('cast'),
get: jasmine.createSpy('get'),
set: jasmine.createSpy('set'),
// For convenience:
onCastStatusChanged: onCastStatusChanged,
onFirstCastStateUpdate: onFirstCastStateUpdate,
onRemoteEvent: onRemoteEvent,
onResumeLocal: onResumeLocal,
};
mockSender.cast.and.returnValue(Promise.resolve());
return mockSender;
}
function createMockPlayer() {
const player = {
load: jasmine.createSpy('load'),
unload: jasmine.createSpy('unload'),
getNetworkingEngine: jasmine.createSpy('getNetworkingEngine'),
getAssetUri: jasmine.createSpy('getAssetUri'),
getConfiguration: jasmine.createSpy('getConfiguration'),
configure: jasmine.createSpy('configure'),
isTextTrackVisible: jasmine.createSpy('isTextTrackVisible'),
setTextTrackVisibility: jasmine.createSpy('setTextTrackVisibility'),
trickPlay: jasmine.createSpy('trickPlay'),
destroy: jasmine.createSpy('destroy'),
addEventListener: function(eventName, listener) {
player.listeners[eventName] = listener;
},
removeEventListener: function(eventName, listener) {
delete player.listeners[eventName];
},
dispatchEvent: jasmine.createSpy('dispatchEvent'),
// For convenience:
listeners: {},
};
player.load.and.returnValue(Promise.resolve());
player.unload.and.returnValue(Promise.resolve());
return player;
}
});