Files
8bitworkshop/test/unit/teststorage.ts
T

124 lines
6.3 KiB
TypeScript

import assert from "assert";
import { describe, it } from "mocha";
import {
StorageManagerLike, detectBrowserKind, formatStorageSize, getPersistAdvice,
getPersistStatusMessage, getQuotaExceededMessage, getStorageEstimate,
getStorageStatus, isPersistSupported, requestPersistentStorage
} from "../../src/ide/storage";
function mockStorage(opts: {
persisted?: boolean, persist?: boolean | Error, usage?: number, quota?: number, noEstimate?: boolean
}): StorageManagerLike & { persistCalls: number } {
var mock: any = {
persistCalls: 0,
persisted: async () => !!opts.persisted,
persist: async () => {
mock.persistCalls++;
if (opts.persist instanceof Error) throw opts.persist;
return !!opts.persist;
}
};
if (!opts.noEstimate)
mock.estimate = async () => ({ usage: opts.usage, quota: opts.quota });
return mock;
}
describe('persistent storage helpers', function () {
it('detects missing StorageManager', async function () {
assert.strictEqual(isPersistSupported(null), false);
var status = await requestPersistentStorage(null);
assert.deepStrictEqual(status, { supported: false, persisted: false, granted: false, usage: undefined, quota: undefined });
});
it('does not re-request when already persisted', async function () {
var mock = mockStorage({ persisted: true, usage: 1024, quota: 2048 });
var status = await requestPersistentStorage(mock);
assert.strictEqual(status.persisted, true);
assert.strictEqual(status.granted, false);
assert.strictEqual(mock.persistCalls, 0, "should not call persist() when already granted");
});
it('requests persistence when not yet granted', async function () {
var mock = mockStorage({ persisted: false, persist: true });
var status = await requestPersistentStorage(mock);
assert.strictEqual(status.persisted, true);
assert.strictEqual(status.granted, true);
assert.strictEqual(mock.persistCalls, 1);
});
it('treats a denial as a normal result', async function () {
var mock = mockStorage({ persisted: false, persist: false });
var status = await requestPersistentStorage(mock);
assert.strictEqual(status.supported, true);
assert.strictEqual(status.persisted, false);
assert.strictEqual(status.granted, false);
});
it('survives persist() throwing (Safari, iframes)', async function () {
var mock = mockStorage({ persisted: false, persist: new Error("SecurityError") });
var status = await requestPersistentStorage(mock);
assert.strictEqual(status.persisted, false);
assert.strictEqual(status.granted, false);
});
it('survives a missing or failing estimate()', async function () {
assert.deepStrictEqual(await getStorageEstimate(mockStorage({ noEstimate: true })), {});
var broken: any = { persist: async () => true, estimate: async () => { throw new Error("nope"); } };
assert.deepStrictEqual(await getStorageEstimate(broken), {});
var status = await getStorageStatus(broken);
assert.strictEqual(status.supported, true);
assert.strictEqual(status.persisted, false); // no persisted() method
});
it('reports usage from estimate()', async function () {
var status = await getStorageStatus(mockStorage({ persisted: true, usage: 1500000, quota: 2000000000 }));
assert.strictEqual(status.usage, 1500000);
assert.strictEqual(status.quota, 2000000000);
});
it('formats sizes', function () {
assert.strictEqual(formatStorageSize(0), "0 bytes");
assert.strictEqual(formatStorageSize(512), "512 bytes");
assert.strictEqual(formatStorageSize(1536), "1.5 KB");
assert.strictEqual(formatStorageSize(1024 * 1024 * 3), "3.0 MB");
assert.strictEqual(formatStorageSize(undefined), "?");
});
it('detects browser families for advice', function () {
assert.strictEqual(detectBrowserKind("Mozilla/5.0 (Macintosh) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0 Safari/537.36"), 'chromium');
assert.strictEqual(detectBrowserKind("Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 Chrome/120.0 Safari/537.36 Edg/120.0"), 'chromium');
assert.strictEqual(detectBrowserKind("Mozilla/5.0 (X11; Linux) Gecko/20100101 Firefox/122.0"), 'firefox');
assert.strictEqual(detectBrowserKind("Mozilla/5.0 (Macintosh) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15"), 'safari');
assert.strictEqual(detectBrowserKind(""), 'other');
// each family gets non-empty, distinct advice
var advice = ['chromium', 'firefox', 'safari', 'other'].map((k: any) => getPersistAdvice(k));
advice.forEach(a => assert.ok(a.length > 0));
assert.strictEqual(new Set(advice).size, 4);
});
it('explains each outcome without calling it an error', function () {
var denied = getPersistStatusMessage({ supported: true, persisted: false, usage: 1024, quota: 4096 }, true);
assert.ok(/has not granted/.test(denied));
assert.ok(/Download All Changes/.test(denied), "should suggest a backup");
assert.ok(/1.0 KB of the 4.0 KB/.test(denied), "should report usage");
var granted = getPersistStatusMessage({ supported: true, persisted: true, granted: true }, true);
assert.ok(/just granted/.test(granted));
var already = getPersistStatusMessage({ supported: true, persisted: true, granted: false }, false);
assert.ok(/already/.test(already));
var unsupported = getPersistStatusMessage({ supported: false, persisted: false }, true);
assert.ok(/doesn't support/.test(unsupported));
});
it('tells the user what to do when the quota is full', function () {
var msg = getQuotaExceededMessage({ supported: true, persisted: false, usage: 100, quota: 200 });
assert.ok(/ran out of space/.test(msg));
assert.ok(/Download All Changes/.test(msg));
assert.ok(msg.indexOf(getPersistAdvice()) >= 0, "should include advice when not persisted");
var persisted = getQuotaExceededMessage({ supported: true, persisted: true, usage: 100, quota: 200 });
assert.ok(persisted.indexOf(getPersistAdvice()) < 0, "no persist advice when already persisted");
});
});