Source code

Revision control

Copy as Markdown

Other Tools

import { ActivityStreamStorage } from "lib/ActivityStreamStorage.sys.mjs";
import { GlobalOverrider } from "test/unit/utils";
let overrider = new GlobalOverrider();
describe("ActivityStreamStorage", () => {
let sandbox;
let indexedDB;
let storage;
beforeEach(() => {
sandbox = sinon.createSandbox();
indexedDB = {
open: sandbox.stub().resolves({}),
deleteDatabase: sandbox.stub().resolves(),
};
overrider.set({ IndexedDB: indexedDB });
storage = new ActivityStreamStorage({
storeNames: ["storage_test"],
telemetry: { handleUndesiredEvent: sandbox.stub() },
});
});
afterEach(() => {
sandbox.restore();
});
it("should throw if required arguments not provided", () => {
assert.throws(() => new ActivityStreamStorage({ telemetry: true }));
});
describe(".db", () => {
it("should not throw an error when accessing db", async () => {
assert.ok(storage.db);
});
it("should delete and recreate the db if opening db fails", async () => {
const newDb = {};
indexedDB.open.onFirstCall().rejects(new Error("fake error"));
indexedDB.open.onSecondCall().resolves(newDb);
const db = await storage.db;
assert.calledOnce(indexedDB.deleteDatabase);
assert.calledTwice(indexedDB.open);
assert.equal(db, newDb);
});
});
describe("#getDbTable", () => {
let testStorage;
let storeStub;
beforeEach(() => {
storeStub = {
getAll: sandbox.stub().resolves(),
getAllKeys: sandbox.stub().resolves(),
get: sandbox.stub().resolves(),
put: sandbox.stub().resolves(),
};
sandbox.stub(storage, "_getStore").resolves(storeStub);
testStorage = storage.getDbTable("storage_test");
});
it("should reverse key value parameters for put", async () => {
await testStorage.set("key", "value");
assert.calledOnce(storeStub.put);
assert.calledWith(storeStub.put, "value", "key");
});
it("should return the correct value for get", async () => {
storeStub.get.withArgs("foo").resolves("foo");
const result = await testStorage.get("foo");
assert.calledOnce(storeStub.get);
assert.equal(result, "foo");
});
it("should return the correct value for getAll", async () => {
storeStub.getAll.resolves(["bar"]);
const result = await testStorage.getAll();
assert.calledOnce(storeStub.getAll);
assert.deepEqual(result, ["bar"]);
});
it("should return the correct value for getAllKeys", async () => {
storeStub.getAllKeys.resolves(["key1", "key2", "key3"]);
const result = await testStorage.getAllKeys();
assert.calledOnce(storeStub.getAllKeys);
assert.deepEqual(result, ["key1", "key2", "key3"]);
});
it("should query the correct object store", async () => {
await testStorage.get();
assert.calledOnce(storage._getStore);
assert.calledWithExactly(storage._getStore, "storage_test");
});
it("should throw if table is not found", () => {
assert.throws(() => storage.getDbTable("undefined_store"));
});
});
it("should get the correct objectStore when calling _getStore", async () => {
const objectStoreStub = sandbox.stub();
indexedDB.open.resolves({ objectStore: objectStoreStub });
await storage._getStore("foo");
assert.calledOnce(objectStoreStub);
assert.calledWithExactly(objectStoreStub, "foo", "readwrite");
});
it("should create a db with the correct store name", async () => {
const dbStub = {
createObjectStore: sandbox.stub(),
objectStoreNames: { contains: sandbox.stub().returns(false) },
};
await storage.db;
// call the cb with a stub
indexedDB.open.args[0][2](dbStub);
assert.calledOnce(dbStub.createObjectStore);
assert.calledWithExactly(dbStub.createObjectStore, "storage_test");
});
it("should handle an array of object store names", async () => {
storage = new ActivityStreamStorage({
storeNames: ["store1", "store2"],
telemetry: {},
});
const dbStub = {
createObjectStore: sandbox.stub(),
objectStoreNames: { contains: sandbox.stub().returns(false) },
};
await storage.db;
// call the cb with a stub
indexedDB.open.args[0][2](dbStub);
assert.calledTwice(dbStub.createObjectStore);
assert.calledWith(dbStub.createObjectStore, "store1");
assert.calledWith(dbStub.createObjectStore, "store2");
});
it("should skip creating existing stores", async () => {
storage = new ActivityStreamStorage({
storeNames: ["store1", "store2"],
telemetry: {},
});
const dbStub = {
createObjectStore: sandbox.stub(),
objectStoreNames: { contains: sandbox.stub().returns(true) },
};
await storage.db;
// call the cb with a stub
indexedDB.open.args[0][2](dbStub);
assert.notCalled(dbStub.createObjectStore);
});
describe("#_requestWrapper", () => {
it("should return a successful result", async () => {
const result = await storage._requestWrapper(() =>
Promise.resolve("foo")
);
assert.equal(result, "foo");
assert.notCalled(storage.telemetry.handleUndesiredEvent);
});
it("should report failures", async () => {
try {
await storage._requestWrapper(() => Promise.reject(new Error()));
} catch (e) {
assert.calledOnce(storage.telemetry.handleUndesiredEvent);
}
});
});
});