queue/source/item/item.test.ts

104 lines
3.4 KiB
TypeScript

import browser from "webextension-polyfill";
import {type TestContext, setup} from "@holllo/test";
import {type Value} from "@holllo/webextension-storage";
import {type Item, createItem, nextItem, nextItemId} from "./item.js";
const testText = "Test Item";
const testUrl = "https://example.org/";
/**
* Check all properties of an {@link Item}.
*
* @param item The {@link Item} to assert.
* @param test The {@link TestContext} for the assertions.
*/
function assertItem(item: Value<Item>, test: TestContext): void {
// Assert that itemKeyPrefix is used.
test.true(/^item-\d+$/.test(item.key), "item key regex");
// Assert that deserialization instantiates any classes.
test.true(item.value.dateAdded instanceof Date, "dateAdded is a Date");
// Assert that the expected values are indeed present.
test.true(item.value.id > 0, "id is set");
test.equals(item.value.text, testText, "text is set");
test.equals(item.value.url, testUrl, "url is set");
}
await setup(
"Item",
async (group) => {
const existingStorages: Array<Record<string, any>> = [];
group.beforeAll(async () => {
existingStorages.push(
await browser.storage.local.get(),
await browser.storage.sync.get(),
);
await browser.storage.local.clear();
await browser.storage.sync.clear();
});
group.afterAll(async () => {
await browser.storage.local.set(existingStorages[0]);
await browser.storage.sync.set(existingStorages[1]);
});
group.test("create & nextItem", async (test) => {
const testItem = await createItem(testText, testUrl);
assertItem(testItem, test);
await testItem.save();
// Make sure `nextItem()` returns an item.
let storedNext = await nextItem();
if (storedNext === undefined || storedNext.value === undefined) {
throw new Error("Expected an item");
}
// Assert that our first test item and the stored one are identical.
test.equals(storedNext.key, testItem.key, "id check");
assertItem(storedNext, test);
// Store all test items we create so we can remove them later on.
const items = [testItem];
// Create a bunch of test items and assert them all.
for (let index = 1; index < 10; index++) {
const next = await createItem(testText, testUrl);
test.equals(testItem.value.id + index, next.value.id, "id check");
assertItem(next, test);
items.push(next);
await next.save();
}
// Remove all test items.
await Promise.all(items.map(async (item) => item.remove()));
// After all items have been removed test that `nextItem` returns nothing.
// This test will fail if an item is left from development.
storedNext = await nextItem();
test.equals(storedNext, undefined, "next item is undefined");
});
group.test("nextItemId", async (test) => {
const testItem = await createItem(testText, testUrl);
assertItem(testItem, test);
await testItem.save();
const id = await nextItemId();
test.equals(typeof id, "number", "id is a number");
test.false(Number.isNaN(id), "id is not NaN");
test.true(id > 0, "id larger than 0");
test.equals(await nextItemId(), testItem.value.id + 1, "id check");
await testItem.remove();
});
},
{
// Run tests in series since we're using WebExtension storage to test stuff
// and don't want the ID checks to interfere with one another.
parallel: false,
},
);