bitwarden-estensione-browser/libs/common/src/platform/services/migration-runner.spec.ts

103 lines
3.2 KiB
TypeScript

import { mock } from "jest-mock-extended";
import { awaitAsync } from "../../../spec";
import { CURRENT_VERSION } from "../../state-migrations";
import { MigrationBuilder } from "../../state-migrations/migration-builder";
import { LogService } from "../abstractions/log.service";
import { AbstractStorageService } from "../abstractions/storage.service";
import { MigrationBuilderService } from "./migration-builder.service";
import { MigrationRunner } from "./migration-runner";
describe("MigrationRunner", () => {
const storage = mock<AbstractStorageService>();
const logService = mock<LogService>();
const migrationBuilderService = mock<MigrationBuilderService>();
const mockMigrationBuilder = mock<MigrationBuilder>();
migrationBuilderService.build.mockReturnValue(mockMigrationBuilder);
const sut = new MigrationRunner(storage, logService, migrationBuilderService);
describe("migrate", () => {
it("should not run migrations if state is empty", async () => {
storage.get.mockReturnValueOnce(null);
await sut.run();
expect(migrationBuilderService.build).not.toHaveBeenCalled();
});
it("should set to current version if state is empty", async () => {
storage.get.mockReturnValueOnce(null);
await sut.run();
expect(storage.save).toHaveBeenCalledWith("stateVersion", CURRENT_VERSION);
});
it("should run migration if there is a stateVersion", async () => {
storage.get.mockResolvedValueOnce(12);
await sut.run();
expect(mockMigrationBuilder.migrate).toHaveBeenCalled();
});
});
describe("waitForCompletion", () => {
it("should wait until stateVersion is current before completing", async () => {
let stateVersion: number | null = null;
storage.get.mockImplementation((key) => {
if (key === "stateVersion") {
return Promise.resolve(stateVersion);
}
});
let promiseCompleted = false;
const completionPromise = sut.waitForCompletion().then(() => (promiseCompleted = true));
await awaitAsync(10);
expect(promiseCompleted).toBe(false);
stateVersion = CURRENT_VERSION;
await completionPromise;
});
// Skipped for CI since this test takes a while to complete, remove `.skip` to test
it.skip(
"will complete after 8 second step wait if migrations still aren't complete",
async () => {
storage.get.mockImplementation((key) => {
if (key === "stateVersion") {
return Promise.resolve(null);
}
});
let promiseCompleted = false;
void sut.waitForCompletion().then(() => (promiseCompleted = true));
await awaitAsync(2 + 4 + 8 + 16);
expect(promiseCompleted).toBe(false);
await awaitAsync(32 + 64 + 128 + 256);
expect(promiseCompleted).toBe(false);
await awaitAsync(512 + 1024 + 2048 + 4096);
expect(promiseCompleted).toBe(false);
const SKEW = 20;
await awaitAsync(8192 + SKEW);
expect(promiseCompleted).toBe(true);
},
// Have to combine all the steps into the timeout to get this to run
2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024 + 2048 + 4096 + 8192 + 100,
);
});
});