mirror of
https://github.com/bitwarden/browser
synced 2025-12-20 10:13:31 +00:00
[PM-6172] Run localStorage migrations for web (#7900)
* Create MigrationRunner - Create MigrationRunner Service for running migrations in StateService - Create web override so that migrations also run against `localStorage` * Fix Web StateService * Fix WebMigrationRunner * Fix CLI * Fix ElectronStateService * Update Comment * More Common Scenarios
This commit is contained in:
102
libs/common/src/platform/services/migration-runner.spec.ts
Normal file
102
libs/common/src/platform/services/migration-runner.spec.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
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,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user