Add the migrations back using new tests.

This commit is contained in:
Bauke 2023-05-17 12:18:52 +02:00
parent 0ad7345a71
commit dfc42535f0
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
3 changed files with 174 additions and 0 deletions

View File

@ -0,0 +1,29 @@
import {setup} from "@holllo/test";
import {dataMigrations, type QueueItemPre030} from "./migrations.js";
import snapshots from "./snapshots.json";
const queueItemSample: QueueItemPre030 = {
added: new Date("2022-03-02T16:00:00Z"),
id: 1,
text: "Sample",
url: "https://example.org",
};
await setup("Migrations", async (group) => {
group.test("Snapshots", async (test) => {
let data: Record<string, any> = {
latestVersion: "0.1.0",
queue: [queueItemSample],
};
for (const [index, migration] of dataMigrations.entries()) {
data = (await migration.migrate(data)) as Record<string, any>;
test.equals(
JSON.stringify(data, null, 2),
JSON.stringify(snapshots[index], null, 2),
);
}
});
});

View File

@ -0,0 +1,115 @@
import browser from "webextension-polyfill";
import {migrate, type Migration} from "@holllo/migration-helper";
import {createValue} from "@holllo/webextension-storage";
import type {ItemKeyPrefix} from "../item/item.js";
/** The Queue Item type for versions `<0.3.0`. */
export type QueueItemPre030 = {
added: Date;
id: number;
text: string;
url: string;
};
/** The Queue Item type for versions `>=0.3.0 <1.0.0`. */
export type QueueItem030 = {
sortIndex: number;
} & QueueItemPre030;
/** The Queue Item type for versions `>=1.0.0`. */
export type QueueItem100 = {
dateAdded: Date;
id: number;
text: string | undefined;
url: string;
};
/** All migrations for Queue storage. */
export const dataMigrations: Array<Migration<string>> = [
{
version: "0.1.7",
async migrate(data: Record<string, any>) {
const migrated: Record<string, any> = {
version: "0.1.7",
};
const items = (data.queue as QueueItemPre030[]) ?? [];
for (const item of items) {
const key = `qi${item.id}`;
migrated[key] = item;
}
return migrated;
},
},
{
version: "0.3.0",
async migrate(data: Record<string, any>) {
const migrated: Record<string, any> = {
version: "0.3.0",
};
for (const [key, value] of Object.entries<QueueItemPre030>(data)) {
if (key.startsWith("qi")) {
const item: QueueItem030 = {
sortIndex: value.id,
...value,
};
migrated[key] = item;
}
}
return migrated;
},
},
{
version: "1.0.0",
async migrate(data: Record<string, any>) {
const migrated: Record<string, any> = {
version: "1.0.0",
};
for (const [key, value] of Object.entries<QueueItem030>(data)) {
if (key.startsWith("qi")) {
const item: QueueItem100 = {
dateAdded: new Date(value.added),
id: value.id,
text: value.text === "" ? undefined : value.text,
url: value.url,
};
const prefix: ItemKeyPrefix = "item-";
migrated[`${prefix}${item.id}`] = item;
}
}
return migrated;
},
},
];
/** Run the migrations and apply the result to storage. */
export async function runMigrations(): Promise<void> {
const manifest = browser.runtime.getManifest();
const version = await createValue<string>({
deserialize: (input) => input,
serialize: (input) => input,
key: "version",
storage: browser.storage.sync,
value: manifest.version,
});
if (manifest.version >= version.value) {
return;
}
const migrated = await migrate(
await browser.storage.sync.get(),
version.value,
dataMigrations,
);
await browser.storage.sync.clear();
await browser.storage.sync.set(migrated as Record<string, any>);
}

View File

@ -0,0 +1,30 @@
[
{
"version": "0.1.7",
"qi1": {
"added": "2022-03-02T16:00:00.000Z",
"id": 1,
"text": "Sample",
"url": "https://example.org"
}
},
{
"version": "0.3.0",
"qi1": {
"sortIndex": 1,
"added": "2022-03-02T16:00:00.000Z",
"id": 1,
"text": "Sample",
"url": "https://example.org"
}
},
{
"version": "1.0.0",
"item-1": {
"dateAdded": "2022-03-02T16:00:00.000Z",
"id": 1,
"text": "Sample",
"url": "https://example.org"
}
}
]