mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
[PM-6965] Add type
Property to MigrationHelper
(#8411)
* Add `type` Property to `MigrationHelper` * Fix Tests * Make `type` parameter required * Fix mockHelper.type * Remove `readonly` from `type`
This commit is contained in:
parent
8639f494f3
commit
908d3d165e
@ -46,7 +46,7 @@ class WebMigrationHelper extends MigrationHelper {
|
|||||||
storageService: WindowStorageService,
|
storageService: WindowStorageService,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
) {
|
) {
|
||||||
super(currentVersion, storageService, logService);
|
super(currentVersion, storageService, logService, "web-disk-local");
|
||||||
this.diskLocalStorageService = storageService;
|
this.diskLocalStorageService = storageService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ describe("MigrationBuilderService", () => {
|
|||||||
startingStateVersion,
|
startingStateVersion,
|
||||||
new FakeStorageService(startingState),
|
new FakeStorageService(startingState),
|
||||||
mock(),
|
mock(),
|
||||||
|
"general",
|
||||||
);
|
);
|
||||||
|
|
||||||
await sut.build().migrate(helper);
|
await sut.build().migrate(helper);
|
||||||
|
@ -18,6 +18,7 @@ export class MigrationRunner {
|
|||||||
await currentVersion(this.diskStorage, this.logService),
|
await currentVersion(this.diskStorage, this.logService),
|
||||||
this.diskStorage,
|
this.diskStorage,
|
||||||
this.logService,
|
this.logService,
|
||||||
|
"general",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (migrationHelper.currentVersion < 0) {
|
if (migrationHelper.currentVersion < 0) {
|
||||||
|
@ -83,35 +83,35 @@ describe("MigrationBuilder", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should migrate", async () => {
|
it("should migrate", async () => {
|
||||||
const helper = new MigrationHelper(0, mock(), mock());
|
const helper = new MigrationHelper(0, mock(), mock(), "general");
|
||||||
const spy = jest.spyOn(migrator, "migrate");
|
const spy = jest.spyOn(migrator, "migrate");
|
||||||
await sut.migrate(helper);
|
await sut.migrate(helper);
|
||||||
expect(spy).toBeCalledWith(helper);
|
expect(spy).toBeCalledWith(helper);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should rollback", async () => {
|
it("should rollback", async () => {
|
||||||
const helper = new MigrationHelper(1, mock(), mock());
|
const helper = new MigrationHelper(1, mock(), mock(), "general");
|
||||||
const spy = jest.spyOn(rollback_migrator, "rollback");
|
const spy = jest.spyOn(rollback_migrator, "rollback");
|
||||||
await sut.migrate(helper);
|
await sut.migrate(helper);
|
||||||
expect(spy).toBeCalledWith(helper);
|
expect(spy).toBeCalledWith(helper);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should update version on migrate", async () => {
|
it("should update version on migrate", async () => {
|
||||||
const helper = new MigrationHelper(0, mock(), mock());
|
const helper = new MigrationHelper(0, mock(), mock(), "general");
|
||||||
const spy = jest.spyOn(migrator, "updateVersion");
|
const spy = jest.spyOn(migrator, "updateVersion");
|
||||||
await sut.migrate(helper);
|
await sut.migrate(helper);
|
||||||
expect(spy).toBeCalledWith(helper, "up");
|
expect(spy).toBeCalledWith(helper, "up");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should update version on rollback", async () => {
|
it("should update version on rollback", async () => {
|
||||||
const helper = new MigrationHelper(1, mock(), mock());
|
const helper = new MigrationHelper(1, mock(), mock(), "general");
|
||||||
const spy = jest.spyOn(rollback_migrator, "updateVersion");
|
const spy = jest.spyOn(rollback_migrator, "updateVersion");
|
||||||
await sut.migrate(helper);
|
await sut.migrate(helper);
|
||||||
expect(spy).toBeCalledWith(helper, "down");
|
expect(spy).toBeCalledWith(helper, "down");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not run the migrator if the current version does not match the from version", async () => {
|
it("should not run the migrator if the current version does not match the from version", async () => {
|
||||||
const helper = new MigrationHelper(3, mock(), mock());
|
const helper = new MigrationHelper(3, mock(), mock(), "general");
|
||||||
const migrate = jest.spyOn(migrator, "migrate");
|
const migrate = jest.spyOn(migrator, "migrate");
|
||||||
const rollback = jest.spyOn(rollback_migrator, "rollback");
|
const rollback = jest.spyOn(rollback_migrator, "rollback");
|
||||||
await sut.migrate(helper);
|
await sut.migrate(helper);
|
||||||
@ -120,7 +120,7 @@ describe("MigrationBuilder", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should not update version if the current version does not match the from version", async () => {
|
it("should not update version if the current version does not match the from version", async () => {
|
||||||
const helper = new MigrationHelper(3, mock(), mock());
|
const helper = new MigrationHelper(3, mock(), mock(), "general");
|
||||||
const migrate = jest.spyOn(migrator, "updateVersion");
|
const migrate = jest.spyOn(migrator, "updateVersion");
|
||||||
const rollback = jest.spyOn(rollback_migrator, "updateVersion");
|
const rollback = jest.spyOn(rollback_migrator, "updateVersion");
|
||||||
await sut.migrate(helper);
|
await sut.migrate(helper);
|
||||||
@ -130,7 +130,7 @@ describe("MigrationBuilder", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should be able to call instance methods", async () => {
|
it("should be able to call instance methods", async () => {
|
||||||
const helper = new MigrationHelper(0, mock(), mock());
|
const helper = new MigrationHelper(0, mock(), mock(), "general");
|
||||||
await sut.with(TestMigratorWithInstanceMethod, 0, 1).migrate(helper);
|
await sut.with(TestMigratorWithInstanceMethod, 0, 1).migrate(helper);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@ import { AbstractStorageService } from "../platform/abstractions/storage.service
|
|||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to generate unique strings for injection
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to generate unique strings for injection
|
||||||
import { Utils } from "../platform/misc/utils";
|
import { Utils } from "../platform/misc/utils";
|
||||||
|
|
||||||
import { MigrationHelper } from "./migration-helper";
|
import { MigrationHelper, MigrationHelperType } from "./migration-helper";
|
||||||
import { Migrator } from "./migrator";
|
import { Migrator } from "./migrator";
|
||||||
|
|
||||||
const exampleJSON = {
|
const exampleJSON = {
|
||||||
@ -37,7 +37,7 @@ describe("RemoveLegacyEtmKeyMigrator", () => {
|
|||||||
storage = mock();
|
storage = mock();
|
||||||
storage.get.mockImplementation((key) => (exampleJSON as any)[key]);
|
storage.get.mockImplementation((key) => (exampleJSON as any)[key]);
|
||||||
|
|
||||||
sut = new MigrationHelper(0, storage, logService);
|
sut = new MigrationHelper(0, storage, logService, "general");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("get", () => {
|
describe("get", () => {
|
||||||
@ -150,6 +150,7 @@ describe("RemoveLegacyEtmKeyMigrator", () => {
|
|||||||
export function mockMigrationHelper(
|
export function mockMigrationHelper(
|
||||||
storageJson: any,
|
storageJson: any,
|
||||||
stateVersion = 0,
|
stateVersion = 0,
|
||||||
|
type: MigrationHelperType = "general",
|
||||||
): MockProxy<MigrationHelper> {
|
): MockProxy<MigrationHelper> {
|
||||||
const logService: MockProxy<LogService> = mock();
|
const logService: MockProxy<LogService> = mock();
|
||||||
const storage: MockProxy<AbstractStorageService> = mock();
|
const storage: MockProxy<AbstractStorageService> = mock();
|
||||||
@ -157,7 +158,7 @@ export function mockMigrationHelper(
|
|||||||
storage.save.mockImplementation(async (key, value) => {
|
storage.save.mockImplementation(async (key, value) => {
|
||||||
(storageJson as any)[key] = value;
|
(storageJson as any)[key] = value;
|
||||||
});
|
});
|
||||||
const helper = new MigrationHelper(stateVersion, storage, logService);
|
const helper = new MigrationHelper(stateVersion, storage, logService, type);
|
||||||
|
|
||||||
const mockHelper = mock<MigrationHelper>();
|
const mockHelper = mock<MigrationHelper>();
|
||||||
mockHelper.get.mockImplementation((key) => helper.get(key));
|
mockHelper.get.mockImplementation((key) => helper.get(key));
|
||||||
@ -175,6 +176,9 @@ export function mockMigrationHelper(
|
|||||||
helper.setToUser(userId, keyDefinition, value),
|
helper.setToUser(userId, keyDefinition, value),
|
||||||
);
|
);
|
||||||
mockHelper.getAccounts.mockImplementation(() => helper.getAccounts());
|
mockHelper.getAccounts.mockImplementation(() => helper.getAccounts());
|
||||||
|
|
||||||
|
mockHelper.type = helper.type;
|
||||||
|
|
||||||
return mockHelper;
|
return mockHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +295,7 @@ export async function runMigrator<
|
|||||||
const allInjectedData = injectData(initalData, []);
|
const allInjectedData = injectData(initalData, []);
|
||||||
|
|
||||||
const fakeStorageService = new FakeStorageService(initalData);
|
const fakeStorageService = new FakeStorageService(initalData);
|
||||||
const helper = new MigrationHelper(migrator.fromVersion, fakeStorageService, mock());
|
const helper = new MigrationHelper(migrator.fromVersion, fakeStorageService, mock(), "general");
|
||||||
|
|
||||||
// Run their migrations
|
// Run their migrations
|
||||||
if (direction === "rollback") {
|
if (direction === "rollback") {
|
||||||
|
@ -9,12 +9,29 @@ export type KeyDefinitionLike = {
|
|||||||
key: string;
|
key: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MigrationHelperType = "general" | "web-disk-local";
|
||||||
|
|
||||||
export class MigrationHelper {
|
export class MigrationHelper {
|
||||||
constructor(
|
constructor(
|
||||||
public currentVersion: number,
|
public currentVersion: number,
|
||||||
private storageService: AbstractStorageService,
|
private storageService: AbstractStorageService,
|
||||||
public logService: LogService,
|
public logService: LogService,
|
||||||
) {}
|
type: MigrationHelperType,
|
||||||
|
) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On some clients, migrations are ran multiple times without direct action from the migration writer.
|
||||||
|
*
|
||||||
|
* All clients will run through migrations at least once, this run is referred to as `"general"`. If a migration is
|
||||||
|
* ran more than that single time, they will get a unique name if that the write can make conditional logic based on which
|
||||||
|
* migration run this is.
|
||||||
|
*
|
||||||
|
* @remarks The preferrable way of writing migrations is ALWAYS to be defensive and reflect on the data you are given back. This
|
||||||
|
* should really only be used when reflecting on the data given isn't enough.
|
||||||
|
*/
|
||||||
|
type: MigrationHelperType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a value from the storage service at the given key.
|
* Gets a value from the storage service at the given key.
|
||||||
|
@ -26,7 +26,7 @@ describe("migrator default methods", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
storage = mock();
|
storage = mock();
|
||||||
logService = mock();
|
logService = mock();
|
||||||
helper = new MigrationHelper(0, storage, logService);
|
helper = new MigrationHelper(0, storage, logService, "general");
|
||||||
sut = new TestMigrator(0, 1);
|
sut = new TestMigrator(0, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user