[PM-7766] Add `clientType` to MigrationHelper (#8945)
* Add `clientType` to MigrationHelper * PM-7766 - Fix migration builder tests to take new clientType into account. Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * PM-7766 - Add client type to migration builder tests. * PM-7766 - Fix migration-helper.spec tests. * PM-7766 - Fix migrator.spec.ts --------- Co-authored-by: Jared Snider <jsnider@bitwarden.com>
This commit is contained in:
parent
42f1f965af
commit
3caa6cb635
|
@ -71,6 +71,7 @@ import {
|
||||||
} from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
} from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
@ -520,6 +521,7 @@ export default class MainBackground {
|
||||||
this.storageService,
|
this.storageService,
|
||||||
this.logService,
|
this.logService,
|
||||||
new MigrationBuilderService(),
|
new MigrationBuilderService(),
|
||||||
|
ClientType.Browser,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.stateService = new DefaultBrowserStateService(
|
this.stateService = new DefaultBrowserStateService(
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
|
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
|
||||||
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ export async function migrationRunnerFactory(
|
||||||
await diskStorageServiceFactory(cache, opts),
|
await diskStorageServiceFactory(cache, opts),
|
||||||
await logServiceFactory(cache, opts),
|
await logServiceFactory(cache, opts),
|
||||||
new MigrationBuilderService(),
|
new MigrationBuilderService(),
|
||||||
|
ClientType.Browser,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
SYSTEM_THEME_OBSERVABLE,
|
SYSTEM_THEME_OBSERVABLE,
|
||||||
SafeInjectionToken,
|
SafeInjectionToken,
|
||||||
INTRAPROCESS_MESSAGING_SUBJECT,
|
INTRAPROCESS_MESSAGING_SUBJECT,
|
||||||
|
CLIENT_TYPE,
|
||||||
} from "@bitwarden/angular/services/injection-tokens";
|
} from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
||||||
import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common";
|
import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
|
@ -45,6 +46,7 @@ import {
|
||||||
UserNotificationSettingsServiceAbstraction,
|
UserNotificationSettingsServiceAbstraction,
|
||||||
} from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
} from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
|
@ -558,6 +560,10 @@ const safeProviders: SafeProvider[] = [
|
||||||
OBSERVABLE_LARGE_OBJECT_MEMORY_STORAGE,
|
OBSERVABLE_LARGE_OBJECT_MEMORY_STORAGE,
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
safeProvider({
|
||||||
|
provide: CLIENT_TYPE,
|
||||||
|
useValue: ClientType.Browser,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -344,6 +344,7 @@ export class Main {
|
||||||
this.storageService,
|
this.storageService,
|
||||||
this.logService,
|
this.logService,
|
||||||
new MigrationBuilderService(),
|
new MigrationBuilderService(),
|
||||||
|
ClientType.Cli,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.stateService = new StateService(
|
this.stateService = new StateService(
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
SafeInjectionToken,
|
SafeInjectionToken,
|
||||||
STATE_FACTORY,
|
STATE_FACTORY,
|
||||||
INTRAPROCESS_MESSAGING_SUBJECT,
|
INTRAPROCESS_MESSAGING_SUBJECT,
|
||||||
|
CLIENT_TYPE,
|
||||||
} from "@bitwarden/angular/services/injection-tokens";
|
} from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
||||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
|
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
|
||||||
|
@ -25,6 +26,7 @@ import { KdfConfigService as KdfConfigServiceAbstraction } from "@bitwarden/comm
|
||||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
|
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
|
@ -275,6 +277,10 @@ const safeProviders: SafeProvider[] = [
|
||||||
useClass: NativeMessagingManifestService,
|
useClass: NativeMessagingManifestService,
|
||||||
deps: [],
|
deps: [],
|
||||||
}),
|
}),
|
||||||
|
safeProvider({
|
||||||
|
provide: CLIENT_TYPE,
|
||||||
|
useValue: ClientType.Desktop,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Subject, firstValueFrom } from "rxjs";
|
||||||
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
|
@ -190,6 +191,7 @@ export class Main {
|
||||||
this.storageService,
|
this.storageService,
|
||||||
this.logService,
|
this.logService,
|
||||||
new MigrationBuilderService(),
|
new MigrationBuilderService(),
|
||||||
|
ClientType.Desktop,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: this state service will have access to on disk storage, but not in memory storage.
|
// TODO: this state service will have access to on disk storage, but not in memory storage.
|
||||||
|
|
|
@ -13,10 +13,12 @@ import {
|
||||||
OBSERVABLE_DISK_LOCAL_STORAGE,
|
OBSERVABLE_DISK_LOCAL_STORAGE,
|
||||||
WINDOW,
|
WINDOW,
|
||||||
SafeInjectionToken,
|
SafeInjectionToken,
|
||||||
|
CLIENT_TYPE,
|
||||||
} from "@bitwarden/angular/services/injection-tokens";
|
} from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
||||||
import { ModalService as ModalServiceAbstraction } from "@bitwarden/angular/services/modal.service";
|
import { ModalService as ModalServiceAbstraction } from "@bitwarden/angular/services/modal.service";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -157,6 +159,10 @@ const safeProviders: SafeProvider[] = [
|
||||||
new DefaultThemeStateService(globalStateProvider, ThemeType.Light),
|
new DefaultThemeStateService(globalStateProvider, ThemeType.Light),
|
||||||
deps: [GlobalStateProvider],
|
deps: [GlobalStateProvider],
|
||||||
}),
|
}),
|
||||||
|
safeProvider({
|
||||||
|
provide: CLIENT_TYPE,
|
||||||
|
useValue: ClientType.Web,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
|
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
@ -14,7 +15,7 @@ export class WebMigrationRunner extends MigrationRunner {
|
||||||
migrationBuilderService: MigrationBuilderService,
|
migrationBuilderService: MigrationBuilderService,
|
||||||
private diskLocalStorage: WindowStorageService,
|
private diskLocalStorage: WindowStorageService,
|
||||||
) {
|
) {
|
||||||
super(diskStorage, logService, migrationBuilderService);
|
super(diskStorage, logService, migrationBuilderService, ClientType.Web);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async run(): Promise<void> {
|
override async run(): Promise<void> {
|
||||||
|
@ -46,7 +47,7 @@ class WebMigrationHelper extends MigrationHelper {
|
||||||
storageService: WindowStorageService,
|
storageService: WindowStorageService,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
) {
|
) {
|
||||||
super(currentVersion, storageService, logService, "web-disk-local");
|
super(currentVersion, storageService, logService, "web-disk-local", ClientType.Web);
|
||||||
this.diskLocalStorageService = storageService;
|
this.diskLocalStorageService = storageService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { InjectionToken } from "@angular/core";
|
import { InjectionToken } from "@angular/core";
|
||||||
import { Observable, Subject } from "rxjs";
|
import { Observable, Subject } from "rxjs";
|
||||||
|
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import {
|
import {
|
||||||
AbstractMemoryStorageService,
|
AbstractMemoryStorageService,
|
||||||
AbstractStorageService,
|
AbstractStorageService,
|
||||||
|
@ -52,3 +53,4 @@ export const SYSTEM_THEME_OBSERVABLE = new SafeInjectionToken<Observable<ThemeTy
|
||||||
export const INTRAPROCESS_MESSAGING_SUBJECT = new SafeInjectionToken<Subject<Message<object>>>(
|
export const INTRAPROCESS_MESSAGING_SUBJECT = new SafeInjectionToken<Subject<Message<object>>>(
|
||||||
"INTRAPROCESS_MESSAGING_SUBJECT",
|
"INTRAPROCESS_MESSAGING_SUBJECT",
|
||||||
);
|
);
|
||||||
|
export const CLIENT_TYPE = new SafeInjectionToken<ClientType>("CLIENT_TYPE");
|
||||||
|
|
|
@ -276,6 +276,7 @@ import {
|
||||||
SYSTEM_THEME_OBSERVABLE,
|
SYSTEM_THEME_OBSERVABLE,
|
||||||
WINDOW,
|
WINDOW,
|
||||||
INTRAPROCESS_MESSAGING_SUBJECT,
|
INTRAPROCESS_MESSAGING_SUBJECT,
|
||||||
|
CLIENT_TYPE,
|
||||||
} from "./injection-tokens";
|
} from "./injection-tokens";
|
||||||
import { ModalService } from "./modal.service";
|
import { ModalService } from "./modal.service";
|
||||||
|
|
||||||
|
@ -1099,7 +1100,7 @@ const safeProviders: SafeProvider[] = [
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: MigrationRunner,
|
provide: MigrationRunner,
|
||||||
useClass: MigrationRunner,
|
useClass: MigrationRunner,
|
||||||
deps: [AbstractStorageService, LogService, MigrationBuilderService],
|
deps: [AbstractStorageService, LogService, MigrationBuilderService, CLIENT_TYPE],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: MigrationBuilderService,
|
provide: MigrationBuilderService,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { mock } from "jest-mock-extended";
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
import { FakeStorageService } from "../../../spec/fake-storage.service";
|
import { FakeStorageService } from "../../../spec/fake-storage.service";
|
||||||
|
import { ClientType } from "../../enums";
|
||||||
import { MigrationHelper } from "../../state-migrations/migration-helper";
|
import { MigrationHelper } from "../../state-migrations/migration-helper";
|
||||||
|
|
||||||
import { MigrationBuilderService } from "./migration-builder.service";
|
import { MigrationBuilderService } from "./migration-builder.service";
|
||||||
|
@ -66,25 +67,38 @@ describe("MigrationBuilderService", () => {
|
||||||
global: {},
|
global: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
it.each([
|
const startingStates = [
|
||||||
noAccounts,
|
{ data: noAccounts, description: "No Accounts" },
|
||||||
nullAndUndefinedAccounts,
|
{ data: nullAndUndefinedAccounts, description: "Null and Undefined Accounts" },
|
||||||
emptyAccountObject,
|
{ data: emptyAccountObject, description: "Empty Account Object" },
|
||||||
nullCommonAccountProperties,
|
{ data: nullCommonAccountProperties, description: "Null Common Account Properties" },
|
||||||
emptyCommonAccountProperties,
|
{ data: emptyCommonAccountProperties, description: "Empty Common Account Properties" },
|
||||||
nullGlobal,
|
{ data: nullGlobal, description: "Null Global" },
|
||||||
undefinedGlobal,
|
{ data: undefinedGlobal, description: "Undefined Global" },
|
||||||
emptyGlobalObject,
|
{ data: emptyGlobalObject, description: "Empty Global Object" },
|
||||||
])("should not produce migrations that throw when given data: %s", async (startingState) => {
|
];
|
||||||
const sut = new MigrationBuilderService();
|
|
||||||
|
|
||||||
const helper = new MigrationHelper(
|
const clientTypes = Object.values(ClientType);
|
||||||
startingStateVersion,
|
|
||||||
new FakeStorageService(startingState),
|
|
||||||
mock(),
|
|
||||||
"general",
|
|
||||||
);
|
|
||||||
|
|
||||||
await sut.build().migrate(helper);
|
// Generate all possible test cases
|
||||||
});
|
const testCases = startingStates.flatMap((startingState) =>
|
||||||
|
clientTypes.map((clientType) => ({ startingState, clientType })),
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(testCases)(
|
||||||
|
"should not produce migrations that throw when given $startingState.description for client $clientType",
|
||||||
|
async ({ startingState, clientType }) => {
|
||||||
|
const sut = new MigrationBuilderService();
|
||||||
|
|
||||||
|
const helper = new MigrationHelper(
|
||||||
|
startingStateVersion,
|
||||||
|
new FakeStorageService(startingState),
|
||||||
|
mock(),
|
||||||
|
"general",
|
||||||
|
clientType,
|
||||||
|
);
|
||||||
|
|
||||||
|
await sut.build().migrate(helper);
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { mock } from "jest-mock-extended";
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
import { awaitAsync } from "../../../spec";
|
import { awaitAsync } from "../../../spec";
|
||||||
|
import { ClientType } from "../../enums";
|
||||||
import { CURRENT_VERSION } from "../../state-migrations";
|
import { CURRENT_VERSION } from "../../state-migrations";
|
||||||
import { MigrationBuilder } from "../../state-migrations/migration-builder";
|
import { MigrationBuilder } from "../../state-migrations/migration-builder";
|
||||||
import { LogService } from "../abstractions/log.service";
|
import { LogService } from "../abstractions/log.service";
|
||||||
|
@ -17,7 +18,7 @@ describe("MigrationRunner", () => {
|
||||||
|
|
||||||
migrationBuilderService.build.mockReturnValue(mockMigrationBuilder);
|
migrationBuilderService.build.mockReturnValue(mockMigrationBuilder);
|
||||||
|
|
||||||
const sut = new MigrationRunner(storage, logService, migrationBuilderService);
|
const sut = new MigrationRunner(storage, logService, migrationBuilderService, ClientType.Web);
|
||||||
|
|
||||||
describe("migrate", () => {
|
describe("migrate", () => {
|
||||||
it("should not run migrations if state is empty", async () => {
|
it("should not run migrations if state is empty", async () => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ClientType } from "../../enums";
|
||||||
import { waitForMigrations } from "../../state-migrations";
|
import { waitForMigrations } from "../../state-migrations";
|
||||||
import { CURRENT_VERSION, currentVersion } from "../../state-migrations/migrate";
|
import { CURRENT_VERSION, currentVersion } from "../../state-migrations/migrate";
|
||||||
import { MigrationHelper } from "../../state-migrations/migration-helper";
|
import { MigrationHelper } from "../../state-migrations/migration-helper";
|
||||||
|
@ -11,6 +12,7 @@ export class MigrationRunner {
|
||||||
protected diskStorage: AbstractStorageService,
|
protected diskStorage: AbstractStorageService,
|
||||||
protected logService: LogService,
|
protected logService: LogService,
|
||||||
protected migrationBuilderService: MigrationBuilderService,
|
protected migrationBuilderService: MigrationBuilderService,
|
||||||
|
private clientType: ClientType,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async run(): Promise<void> {
|
async run(): Promise<void> {
|
||||||
|
@ -19,6 +21,7 @@ export class MigrationRunner {
|
||||||
this.diskStorage,
|
this.diskStorage,
|
||||||
this.logService,
|
this.logService,
|
||||||
"general",
|
"general",
|
||||||
|
this.clientType,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (migrationHelper.currentVersion < 0) {
|
if (migrationHelper.currentVersion < 0) {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { mock } from "jest-mock-extended";
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-restricted-paths
|
||||||
|
import { ClientType } from "../enums";
|
||||||
|
|
||||||
import { MigrationBuilder } from "./migration-builder";
|
import { MigrationBuilder } from "./migration-builder";
|
||||||
import { MigrationHelper } from "./migration-helper";
|
import { MigrationHelper } from "./migration-helper";
|
||||||
import { Migrator } from "./migrator";
|
import { Migrator } from "./migrator";
|
||||||
|
@ -72,65 +75,69 @@ describe("MigrationBuilder", () => {
|
||||||
expect(migrations[1]).toMatchObject({ migrator: expect.any(TestMigrator), direction: "down" });
|
expect(migrations[1]).toMatchObject({ migrator: expect.any(TestMigrator), direction: "down" });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("migrate", () => {
|
const clientTypes = Object.values(ClientType);
|
||||||
let migrator: TestMigrator;
|
|
||||||
let rollback_migrator: TestMigrator;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
describe.each(clientTypes)("for client %s", (clientType) => {
|
||||||
sut = sut.with(TestMigrator, 0, 1).rollback(TestMigrator, 1, 0);
|
describe("migrate", () => {
|
||||||
migrator = (sut as any).migrations[0].migrator;
|
let migrator: TestMigrator;
|
||||||
rollback_migrator = (sut as any).migrations[1].migrator;
|
let rollback_migrator: TestMigrator;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
sut = sut.with(TestMigrator, 0, 1).rollback(TestMigrator, 1, 0);
|
||||||
|
migrator = (sut as any).migrations[0].migrator;
|
||||||
|
rollback_migrator = (sut as any).migrations[1].migrator;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should migrate", async () => {
|
||||||
|
const helper = new MigrationHelper(0, mock(), mock(), "general", clientType);
|
||||||
|
const spy = jest.spyOn(migrator, "migrate");
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(spy).toBeCalledWith(helper);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should rollback", async () => {
|
||||||
|
const helper = new MigrationHelper(1, mock(), mock(), "general", clientType);
|
||||||
|
const spy = jest.spyOn(rollback_migrator, "rollback");
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(spy).toBeCalledWith(helper);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should update version on migrate", async () => {
|
||||||
|
const helper = new MigrationHelper(0, mock(), mock(), "general", clientType);
|
||||||
|
const spy = jest.spyOn(migrator, "updateVersion");
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(spy).toBeCalledWith(helper, "up");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should update version on rollback", async () => {
|
||||||
|
const helper = new MigrationHelper(1, mock(), mock(), "general", clientType);
|
||||||
|
const spy = jest.spyOn(rollback_migrator, "updateVersion");
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(spy).toBeCalledWith(helper, "down");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not run the migrator if the current version does not match the from version", async () => {
|
||||||
|
const helper = new MigrationHelper(3, mock(), mock(), "general", clientType);
|
||||||
|
const migrate = jest.spyOn(migrator, "migrate");
|
||||||
|
const rollback = jest.spyOn(rollback_migrator, "rollback");
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(migrate).not.toBeCalled();
|
||||||
|
expect(rollback).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not update version if the current version does not match the from version", async () => {
|
||||||
|
const helper = new MigrationHelper(3, mock(), mock(), "general", clientType);
|
||||||
|
const migrate = jest.spyOn(migrator, "updateVersion");
|
||||||
|
const rollback = jest.spyOn(rollback_migrator, "updateVersion");
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(migrate).not.toBeCalled();
|
||||||
|
expect(rollback).not.toBeCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should migrate", async () => {
|
it("should be able to call instance methods", async () => {
|
||||||
const helper = new MigrationHelper(0, mock(), mock(), "general");
|
const helper = new MigrationHelper(0, mock(), mock(), "general", clientType);
|
||||||
const spy = jest.spyOn(migrator, "migrate");
|
await sut.with(TestMigratorWithInstanceMethod, 0, 1).migrate(helper);
|
||||||
await sut.migrate(helper);
|
|
||||||
expect(spy).toBeCalledWith(helper);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should rollback", async () => {
|
|
||||||
const helper = new MigrationHelper(1, mock(), mock(), "general");
|
|
||||||
const spy = jest.spyOn(rollback_migrator, "rollback");
|
|
||||||
await sut.migrate(helper);
|
|
||||||
expect(spy).toBeCalledWith(helper);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should update version on migrate", async () => {
|
|
||||||
const helper = new MigrationHelper(0, mock(), mock(), "general");
|
|
||||||
const spy = jest.spyOn(migrator, "updateVersion");
|
|
||||||
await sut.migrate(helper);
|
|
||||||
expect(spy).toBeCalledWith(helper, "up");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should update version on rollback", async () => {
|
|
||||||
const helper = new MigrationHelper(1, mock(), mock(), "general");
|
|
||||||
const spy = jest.spyOn(rollback_migrator, "updateVersion");
|
|
||||||
await sut.migrate(helper);
|
|
||||||
expect(spy).toBeCalledWith(helper, "down");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not run the migrator if the current version does not match the from version", async () => {
|
|
||||||
const helper = new MigrationHelper(3, mock(), mock(), "general");
|
|
||||||
const migrate = jest.spyOn(migrator, "migrate");
|
|
||||||
const rollback = jest.spyOn(rollback_migrator, "rollback");
|
|
||||||
await sut.migrate(helper);
|
|
||||||
expect(migrate).not.toBeCalled();
|
|
||||||
expect(rollback).not.toBeCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not update version if the current version does not match the from version", async () => {
|
|
||||||
const helper = new MigrationHelper(3, mock(), mock(), "general");
|
|
||||||
const migrate = jest.spyOn(migrator, "updateVersion");
|
|
||||||
const rollback = jest.spyOn(rollback_migrator, "updateVersion");
|
|
||||||
await sut.migrate(helper);
|
|
||||||
expect(migrate).not.toBeCalled();
|
|
||||||
expect(rollback).not.toBeCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should be able to call instance methods", async () => {
|
|
||||||
const helper = new MigrationHelper(0, mock(), mock(), "general");
|
|
||||||
await sut.with(TestMigratorWithInstanceMethod, 0, 1).migrate(helper);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { MockProxy, mock } from "jest-mock-extended";
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
||||||
import { FakeStorageService } from "../../spec/fake-storage.service";
|
import { FakeStorageService } from "../../spec/fake-storage.service";
|
||||||
|
// eslint-disable-next-line import/no-restricted-paths -- Needed client type enum
|
||||||
|
import { ClientType } from "../enums";
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
||||||
import { LogService } from "../platform/abstractions/log.service";
|
import { LogService } from "../platform/abstractions/log.service";
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
|
||||||
|
@ -32,116 +34,129 @@ describe("RemoveLegacyEtmKeyMigrator", () => {
|
||||||
let logService: MockProxy<LogService>;
|
let logService: MockProxy<LogService>;
|
||||||
let sut: MigrationHelper;
|
let sut: MigrationHelper;
|
||||||
|
|
||||||
beforeEach(() => {
|
const clientTypes = Object.values(ClientType);
|
||||||
logService = mock();
|
|
||||||
storage = mock();
|
|
||||||
storage.get.mockImplementation((key) => (exampleJSON as any)[key]);
|
|
||||||
|
|
||||||
sut = new MigrationHelper(0, storage, logService, "general");
|
describe.each(clientTypes)("for client %s", (clientType) => {
|
||||||
});
|
beforeEach(() => {
|
||||||
|
logService = mock();
|
||||||
|
storage = mock();
|
||||||
|
storage.get.mockImplementation((key) => (exampleJSON as any)[key]);
|
||||||
|
|
||||||
describe("get", () => {
|
sut = new MigrationHelper(0, storage, logService, "general", clientType);
|
||||||
it("should delegate to storage.get", async () => {
|
|
||||||
await sut.get("key");
|
|
||||||
expect(storage.get).toHaveBeenCalledWith("key");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("set", () => {
|
|
||||||
it("should delegate to storage.save", async () => {
|
|
||||||
await sut.set("key", "value");
|
|
||||||
expect(storage.save).toHaveBeenCalledWith("key", "value");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("getAccounts", () => {
|
|
||||||
it("should return all accounts", async () => {
|
|
||||||
const accounts = await sut.getAccounts();
|
|
||||||
expect(accounts).toEqual([
|
|
||||||
{ userId: "c493ed01-4e08-4e88-abc7-332f380ca760", account: { otherStuff: "otherStuff1" } },
|
|
||||||
{ userId: "23e61a5f-2ece-4f5e-b499-f0bc489482a9", account: { otherStuff: "otherStuff2" } },
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle missing authenticatedAccounts", async () => {
|
describe("get", () => {
|
||||||
storage.get.mockImplementation((key) =>
|
it("should delegate to storage.get", async () => {
|
||||||
key === "authenticatedAccounts" ? undefined : (exampleJSON as any)[key],
|
await sut.get("key");
|
||||||
);
|
expect(storage.get).toHaveBeenCalledWith("key");
|
||||||
const accounts = await sut.getAccounts();
|
|
||||||
expect(accounts).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("getFromGlobal", () => {
|
|
||||||
it("should return the correct value", async () => {
|
|
||||||
sut.currentVersion = 9;
|
|
||||||
const value = await sut.getFromGlobal({
|
|
||||||
stateDefinition: { name: "serviceName" },
|
|
||||||
key: "key",
|
|
||||||
});
|
});
|
||||||
expect(value).toEqual("global_serviceName_key");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw if the current version is less than 9", () => {
|
describe("set", () => {
|
||||||
expect(() =>
|
it("should delegate to storage.save", async () => {
|
||||||
sut.getFromGlobal({ stateDefinition: { name: "serviceName" }, key: "key" }),
|
await sut.set("key", "value");
|
||||||
).toThrowError("No key builder should be used for versions prior to 9.");
|
expect(storage.save).toHaveBeenCalledWith("key", "value");
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe("setToGlobal", () => {
|
|
||||||
it("should set the correct value", async () => {
|
|
||||||
sut.currentVersion = 9;
|
|
||||||
await sut.setToGlobal({ stateDefinition: { name: "serviceName" }, key: "key" }, "new_value");
|
|
||||||
expect(storage.save).toHaveBeenCalledWith("global_serviceName_key", "new_value");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw if the current version is less than 9", () => {
|
describe("getAccounts", () => {
|
||||||
expect(() =>
|
it("should return all accounts", async () => {
|
||||||
sut.setToGlobal(
|
const accounts = await sut.getAccounts();
|
||||||
|
expect(accounts).toEqual([
|
||||||
|
{
|
||||||
|
userId: "c493ed01-4e08-4e88-abc7-332f380ca760",
|
||||||
|
account: { otherStuff: "otherStuff1" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userId: "23e61a5f-2ece-4f5e-b499-f0bc489482a9",
|
||||||
|
account: { otherStuff: "otherStuff2" },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle missing authenticatedAccounts", async () => {
|
||||||
|
storage.get.mockImplementation((key) =>
|
||||||
|
key === "authenticatedAccounts" ? undefined : (exampleJSON as any)[key],
|
||||||
|
);
|
||||||
|
const accounts = await sut.getAccounts();
|
||||||
|
expect(accounts).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getFromGlobal", () => {
|
||||||
|
it("should return the correct value", async () => {
|
||||||
|
sut.currentVersion = 9;
|
||||||
|
const value = await sut.getFromGlobal({
|
||||||
|
stateDefinition: { name: "serviceName" },
|
||||||
|
key: "key",
|
||||||
|
});
|
||||||
|
expect(value).toEqual("global_serviceName_key");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw if the current version is less than 9", () => {
|
||||||
|
expect(() =>
|
||||||
|
sut.getFromGlobal({ stateDefinition: { name: "serviceName" }, key: "key" }),
|
||||||
|
).toThrowError("No key builder should be used for versions prior to 9.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("setToGlobal", () => {
|
||||||
|
it("should set the correct value", async () => {
|
||||||
|
sut.currentVersion = 9;
|
||||||
|
await sut.setToGlobal(
|
||||||
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
||||||
"global_serviceName_key",
|
"new_value",
|
||||||
),
|
);
|
||||||
).toThrowError("No key builder should be used for versions prior to 9.");
|
expect(storage.save).toHaveBeenCalledWith("global_serviceName_key", "new_value");
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
it("should throw if the current version is less than 9", () => {
|
||||||
describe("getFromUser", () => {
|
expect(() =>
|
||||||
it("should return the correct value", async () => {
|
sut.setToGlobal(
|
||||||
sut.currentVersion = 9;
|
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
||||||
const value = await sut.getFromUser("userId", {
|
"global_serviceName_key",
|
||||||
stateDefinition: { name: "serviceName" },
|
),
|
||||||
key: "key",
|
).toThrowError("No key builder should be used for versions prior to 9.");
|
||||||
});
|
});
|
||||||
expect(value).toEqual("user_userId_serviceName_key");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw if the current version is less than 9", () => {
|
describe("getFromUser", () => {
|
||||||
expect(() =>
|
it("should return the correct value", async () => {
|
||||||
sut.getFromUser("userId", { stateDefinition: { name: "serviceName" }, key: "key" }),
|
sut.currentVersion = 9;
|
||||||
).toThrowError("No key builder should be used for versions prior to 9.");
|
const value = await sut.getFromUser("userId", {
|
||||||
});
|
stateDefinition: { name: "serviceName" },
|
||||||
});
|
key: "key",
|
||||||
|
});
|
||||||
|
expect(value).toEqual("user_userId_serviceName_key");
|
||||||
|
});
|
||||||
|
|
||||||
describe("setToUser", () => {
|
it("should throw if the current version is less than 9", () => {
|
||||||
it("should set the correct value", async () => {
|
expect(() =>
|
||||||
sut.currentVersion = 9;
|
sut.getFromUser("userId", { stateDefinition: { name: "serviceName" }, key: "key" }),
|
||||||
await sut.setToUser(
|
).toThrowError("No key builder should be used for versions prior to 9.");
|
||||||
"userId",
|
});
|
||||||
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
|
||||||
"new_value",
|
|
||||||
);
|
|
||||||
expect(storage.save).toHaveBeenCalledWith("user_userId_serviceName_key", "new_value");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw if the current version is less than 9", () => {
|
describe("setToUser", () => {
|
||||||
expect(() =>
|
it("should set the correct value", async () => {
|
||||||
sut.setToUser(
|
sut.currentVersion = 9;
|
||||||
|
await sut.setToUser(
|
||||||
"userId",
|
"userId",
|
||||||
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
||||||
"new_value",
|
"new_value",
|
||||||
),
|
);
|
||||||
).toThrowError("No key builder should be used for versions prior to 9.");
|
expect(storage.save).toHaveBeenCalledWith("user_userId_serviceName_key", "new_value");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw if the current version is less than 9", () => {
|
||||||
|
expect(() =>
|
||||||
|
sut.setToUser(
|
||||||
|
"userId",
|
||||||
|
{ stateDefinition: { name: "serviceName" }, key: "key" },
|
||||||
|
"new_value",
|
||||||
|
),
|
||||||
|
).toThrowError("No key builder should be used for versions prior to 9.");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -151,6 +166,7 @@ export function mockMigrationHelper(
|
||||||
storageJson: any,
|
storageJson: any,
|
||||||
stateVersion = 0,
|
stateVersion = 0,
|
||||||
type: MigrationHelperType = "general",
|
type: MigrationHelperType = "general",
|
||||||
|
clientType: ClientType = ClientType.Web,
|
||||||
): MockProxy<MigrationHelper> {
|
): MockProxy<MigrationHelper> {
|
||||||
const logService: MockProxy<LogService> = mock();
|
const logService: MockProxy<LogService> = mock();
|
||||||
const storage: MockProxy<AbstractStorageService> = mock();
|
const storage: MockProxy<AbstractStorageService> = mock();
|
||||||
|
@ -158,7 +174,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, type);
|
const helper = new MigrationHelper(stateVersion, storage, logService, type, clientType);
|
||||||
|
|
||||||
const mockHelper = mock<MigrationHelper>();
|
const mockHelper = mock<MigrationHelper>();
|
||||||
mockHelper.get.mockImplementation((key) => helper.get(key));
|
mockHelper.get.mockImplementation((key) => helper.get(key));
|
||||||
|
@ -295,7 +311,13 @@ 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(), "general");
|
const helper = new MigrationHelper(
|
||||||
|
migrator.fromVersion,
|
||||||
|
fakeStorageService,
|
||||||
|
mock(),
|
||||||
|
"general",
|
||||||
|
ClientType.Web,
|
||||||
|
);
|
||||||
|
|
||||||
// Run their migrations
|
// Run their migrations
|
||||||
if (direction === "rollback") {
|
if (direction === "rollback") {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to provide client type to migrations
|
||||||
|
import { ClientType } from "../enums";
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
||||||
import { LogService } from "../platform/abstractions/log.service";
|
import { LogService } from "../platform/abstractions/log.service";
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
|
||||||
|
@ -17,6 +19,7 @@ export class MigrationHelper {
|
||||||
private storageService: AbstractStorageService,
|
private storageService: AbstractStorageService,
|
||||||
public logService: LogService,
|
public logService: LogService,
|
||||||
type: MigrationHelperType,
|
type: MigrationHelperType,
|
||||||
|
public clientType: ClientType,
|
||||||
) {
|
) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-restricted-paths -- Needed client type enum
|
||||||
|
import { ClientType } from "../enums";
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
|
||||||
import { LogService } from "../platform/abstractions/log.service";
|
import { LogService } from "../platform/abstractions/log.service";
|
||||||
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
|
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
|
||||||
|
@ -23,52 +25,56 @@ describe("migrator default methods", () => {
|
||||||
let helper: MigrationHelper;
|
let helper: MigrationHelper;
|
||||||
let sut: TestMigrator;
|
let sut: TestMigrator;
|
||||||
|
|
||||||
beforeEach(() => {
|
const clientTypes = Object.values(ClientType);
|
||||||
storage = mock();
|
|
||||||
logService = mock();
|
|
||||||
helper = new MigrationHelper(0, storage, logService, "general");
|
|
||||||
sut = new TestMigrator(0, 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("shouldMigrate", () => {
|
describe.each(clientTypes)("for client %s", (clientType) => {
|
||||||
describe("up", () => {
|
beforeEach(() => {
|
||||||
it("should return true if the current version equals the from version", async () => {
|
storage = mock();
|
||||||
expect(await sut.shouldMigrate(helper, "up")).toBe(true);
|
logService = mock();
|
||||||
|
helper = new MigrationHelper(0, storage, logService, "general", clientType);
|
||||||
|
sut = new TestMigrator(0, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("shouldMigrate", () => {
|
||||||
|
describe("up", () => {
|
||||||
|
it("should return true if the current version equals the from version", async () => {
|
||||||
|
expect(await sut.shouldMigrate(helper, "up")).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false if the current version does not equal the from version", async () => {
|
||||||
|
helper.currentVersion = 1;
|
||||||
|
expect(await sut.shouldMigrate(helper, "up")).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false if the current version does not equal the from version", async () => {
|
describe("down", () => {
|
||||||
helper.currentVersion = 1;
|
it("should return true if the current version equals the to version", async () => {
|
||||||
expect(await sut.shouldMigrate(helper, "up")).toBe(false);
|
helper.currentVersion = 1;
|
||||||
|
expect(await sut.shouldMigrate(helper, "down")).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false if the current version does not equal the to version", async () => {
|
||||||
|
expect(await sut.shouldMigrate(helper, "down")).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("down", () => {
|
describe("updateVersion", () => {
|
||||||
it("should return true if the current version equals the to version", async () => {
|
describe("up", () => {
|
||||||
helper.currentVersion = 1;
|
it("should update the version", async () => {
|
||||||
expect(await sut.shouldMigrate(helper, "down")).toBe(true);
|
await sut.updateVersion(helper, "up");
|
||||||
|
expect(storage.save).toBeCalledWith("stateVersion", 1);
|
||||||
|
expect(helper.currentVersion).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false if the current version does not equal the to version", async () => {
|
describe("down", () => {
|
||||||
expect(await sut.shouldMigrate(helper, "down")).toBe(false);
|
it("should update the version", async () => {
|
||||||
});
|
helper.currentVersion = 1;
|
||||||
});
|
await sut.updateVersion(helper, "down");
|
||||||
});
|
expect(storage.save).toBeCalledWith("stateVersion", 0);
|
||||||
|
expect(helper.currentVersion).toBe(0);
|
||||||
describe("updateVersion", () => {
|
});
|
||||||
describe("up", () => {
|
|
||||||
it("should update the version", async () => {
|
|
||||||
await sut.updateVersion(helper, "up");
|
|
||||||
expect(storage.save).toBeCalledWith("stateVersion", 1);
|
|
||||||
expect(helper.currentVersion).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("down", () => {
|
|
||||||
it("should update the version", async () => {
|
|
||||||
helper.currentVersion = 1;
|
|
||||||
await sut.updateVersion(helper, "down");
|
|
||||||
expect(storage.save).toBeCalledWith("stateVersion", 0);
|
|
||||||
expect(helper.currentVersion).toBe(0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue