Files
shaka-player/test/offline/offline_integration.js
T
Joey Parrish 8c80b6cefa Wait for close(), but timeout after 1s
An improved workaround for https://crbug.com/690583 and #1093, on top
of PR #1168.

If we don't wait at all, we end up trying to use the same session ID
too quickly, which causes a playback failure.

Change-Id: I8c9d1a0f09432054b862e033b80b0c2f47739c74
2017-12-05 16:47:54 -08:00

285 lines
9.3 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('Offline', /** @suppress {accessControls} */ function() {
var Scheme = shaka.offline.OfflineScheme;
/** @const {string} */
var dbName = 'shaka-offline-integration-test-db';
var mockSEFactory = new shaka.test.MockStorageEngineFactory();
/** @const {number} */
var dbUpdateRetries = 5;
/** @type {!shaka.offline.IStorageEngine} */
var engine;
/** @type {!shaka.offline.Storage} */
var storage;
/** @type {!shaka.Player} */
var player;
/** @type {!HTMLVideoElement} */
var video;
/** @type {shakaExtern.SupportType} */
var support;
beforeAll(function(done) {
video = /** @type {!HTMLVideoElement} */ (document.createElement('video'));
video.width = 600;
video.height = 400;
video.muted = true;
document.body.appendChild(video);
shaka.Player.probeSupport().then(function(data) {
support = data;
}).catch(fail).then(done);
});
beforeEach(function(done) {
mockSEFactory.overrideCreate(function() {
/** @type {!shaka.offline.DBEngine} */
var engine = new shaka.offline.DBEngine(dbName, dbUpdateRetries);
return engine.init().then(function() { return engine; });
});
player = new shaka.Player(video);
player.addEventListener('error', fail);
storage = new shaka.offline.Storage(player);
// Ensure we start with a clean slate.
return shaka.offline.DBEngine.deleteDatabase(dbName)
.then(function() {
return shaka.offline.StorageEngineFactory.createStorageEngine();
})
.then(function(storageEngine) {
engine = storageEngine;
}).catch(fail).then(done);
});
afterEach(function(done) {
Promise.all([storage.destroy(), player.destroy(), engine.destroy()])
.catch(fail)
.then(done);
});
afterAll(function() {
document.body.removeChild(video);
});
it('stores and plays clear content', function(done) {
if (!support['offline']) {
pending('Offline storage not supported');
}
var storedContent;
storage.store('test:sintel')
.then(function(content) {
storedContent = content;
return player.load(storedContent.offlineUri);
})
.then(function() {
video.play();
return shaka.test.Util.delay(15);
})
.then(function() {
expect(video.currentTime).toBeGreaterThan(3);
expect(video.ended).toBe(false);
return player.unload();
})
.then(function() {
return storage.remove(storedContent);
})
.catch(fail)
.then(done);
});
drm_it('stores, plays, and deletes protected content', function(done) {
// TODO: Add a PlayReady version once Edge supports offline.
if (!support['offline'] ||
!support.drm['com.widevine.alpha'] ||
!support.drm['com.widevine.alpha'].persistentState) {
pending('Persistent licenses not supported');
}
shaka.test.TestScheme.setupPlayer(player, 'sintel-enc');
var onError = function(e) {
// We should only get a not-found error.
var expected = new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.DRM,
shaka.util.Error.Code.OFFLINE_SESSION_REMOVED);
shaka.test.Util.expectToEqualError(e, expected);
};
var storedContent;
var sessionId;
/** @type {!shaka.media.DrmEngine} */
var drmEngine;
storage.store('test:sintel-enc')
.then(function(content) {
storedContent = content;
/** @type {string} */
var uri = storedContent.offlineUri;
/** @type {?number} */
var id = Scheme.uriToManifestId(uri);
goog.asserts.assert(
id != null,
uri + ' should be a valid offline manifest uri.');
return engine.getManifest(id);
})
.then(function(manifestDb) {
// Did we store a persistent license?
expect(manifestDb).toBeTruthy();
expect(manifestDb.sessionIds.length).toBeGreaterThan(0);
sessionId = manifestDb.sessionIds[0];
// Create a DrmEngine now so we can use it to try to load the session
// later, after the content has been deleted.
var OfflineManifestParser = shaka.offline.OfflineManifestParser;
var manifest = OfflineManifestParser.reconstructManifest(manifestDb);
var netEngine = player.getNetworkingEngine();
goog.asserts.assert(netEngine, 'Must have a NetworkingEngine');
drmEngine = new shaka.media.DrmEngine({
netEngine: netEngine,
onError: onError,
onKeyStatus: function() {},
onExpirationUpdated: function() {},
onEvent: function() {}
});
drmEngine.configure(player.getConfiguration().drm);
return drmEngine.init(manifest, true /* isOffline */);
})
.then(function() {
// Load the stored content.
return player.load(storedContent.offlineUri);
})
.then(function() {
// Let it play some.
video.play();
return shaka.test.Util.delay(15);
})
.then(function() {
// Is it playing?
expect(video.currentTime).toBeGreaterThan(3);
expect(video.ended).toBe(false);
return player.unload();
})
.then(function() {
// Remove the content.
return storage.remove(storedContent);
})
.then(
/**
* @suppress {accessControls}
* @return {!Promise.<MediaKeySession>}
*/
function() {
// Should fail, will call |onError| and resolve with null.
return drmEngine.loadOfflineSession_(sessionId);
}
)
.then(function(session) {
// We should not have been able to load the session.
// Removing the content should have deleted the session.
expect(session).toBeFalsy();
return drmEngine.destroy();
})
.catch(function(error) {
fail(error);
// Make sure we clean up the extra DrmEngine even if the Promise
// chain and test fail.
if (drmEngine) {
return drmEngine.destroy();
}
})
.then(done);
});
drm_it(
'stores, plays, and deletes protected content with a temporary license',
function(done) {
// Because this does not rely on persistent licenses, it should be
// testable with PlayReady as well as Widevine.
if (!support['offline'] ||
!support.drm['com.widevine.alpha'] ||
!support.drm['com.microsoft.playready']) {
pending('Offline or DRM not supported');
}
shaka.test.TestScheme.setupPlayer(player, 'sintel-enc');
var storedContent;
storage.configure({ usePersistentLicense: false });
storage.store('test:sintel-enc')
.then(function(content) {
storedContent = content;
/** @type {string} */
var uri = storedContent.offlineUri;
/** @type {?number} */
var id = Scheme.uriToManifestId(uri);
goog.asserts.assert(
id != null,
uri + ' should be a valid offline manifest uri.');
return engine.getManifest(id);
})
.then(function(manifestDb) {
// There should not be any licenses stored.
expect(manifestDb).toBeTruthy();
expect(manifestDb.sessionIds.length).toEqual(0);
// Load the stored content.
return player.load(storedContent.offlineUri);
})
.then(function() {
// Let it play some.
video.play();
return shaka.test.Util.delay(10);
})
.then(function() {
// Is it playing?
expect(video.currentTime).toBeGreaterThan(3);
expect(video.ended).toBe(false);
return player.unload();
})
.then(function() {
// Remove the content.
return storage.remove(storedContent);
})
.then(function() {
/** @type {string} */
var uri = storedContent.offlineUri;
/** @type {?number} */
var id = Scheme.uriToManifestId(uri);
goog.asserts.assert(
id != null,
uri + ' should be a valid offline manifest uri.');
return engine.getManifest(id);
})
.then(function(manifestDb) {
expect(manifestDb).toBeFalsy();
})
.catch(fail)
.then(done);
});
});