diff --git a/src/migrations/migration.service.spec.ts b/src/migrations/migration.service.spec.ts index b7ec09378803f8ce99fa428ea2593ef361207ee5..850480717dff11793f01c8873425e2a9f419f400 100644 --- a/src/migrations/migration.service.spec.ts +++ b/src/migrations/migration.service.spec.ts @@ -8,12 +8,28 @@ import { MIGRATION_RESULT_COMPLETE, MIGRATION_RESULT_FAILED, } from './migration.data' +import { Client, QueryResult } from 'cozy-client' +import { Notes, ReleaseNotes } from 'models/releaseNotes.model' +import { Schema } from 'models/schema.models' const migrateSpy = jest.spyOn(Migrate, 'migrate') describe('Migration service', () => { - const ms = new MigrationService(mockClient) - - it('should run migrations', () => { + const ms = new MigrationService(mockClient, jest.fn()) + const releaseNotes: Notes = { + title: '', + description: '', + } + beforeEach(() => { + migrateSpy.mockClear() + }) + it('should run migrations', async () => { + const schema: Schema = { _id: '1', version: 0 } + const mockQueryResult: QueryResult<Schema[]> = { + data: [schema], + bookmark: '', + next: false, + skip: 0, + } const migrations: Migration[] = [ { baseSchemaVersion: 0, @@ -21,7 +37,8 @@ describe('Migration service', () => { appVersion: '1.2.4', description: 'Removing mailToken from profil', docTypes: PROFILE_DOCTYPE, - run: (docs: any[]): Profile[] => { + releaseNotes: releaseNotes, + run: async (client: Client, docs: any[]): Promise<Profile[]> => { return docs.map(doc => { if (doc.mailToken) { delete doc.mailToken @@ -31,11 +48,19 @@ describe('Migration service', () => { }, }, ] - ms.runMigrations(migrations) + mockClient.query.mockResolvedValue(mockQueryResult) + await ms.runMigrations(migrations) expect(migrateSpy).toBeCalledTimes(1) }) - it('should run migrations with one fail', () => { + it('should run migrations with one fail', async () => { + const schema: Schema = { _id: '1', version: 0 } + const mockQueryResult: QueryResult<Schema[]> = { + data: [schema], + bookmark: '', + next: false, + skip: 0, + } const migrations: Migration[] = [ { baseSchemaVersion: 0, @@ -43,7 +68,8 @@ describe('Migration service', () => { appVersion: '1.2.4', description: 'Removing mailToken from profil', docTypes: PROFILE_DOCTYPE, - run: (docs: any[]): Profile[] => { + releaseNotes: releaseNotes, + run: async (client: Client, docs: any[]): Promise<Profile[]> => { return [] }, }, @@ -53,12 +79,20 @@ describe('Migration service', () => { errors: [], } const migrateSpyOneFail = migrateSpy.mockResolvedValueOnce(result) - ms.runMigrations(migrations) + mockClient.query.mockResolvedValue(mockQueryResult) + + await ms.runMigrations(migrations) expect(migrateSpyOneFail).toBeCalledTimes(2) }) - it('should not run migrations with two fail', () => { - migrateSpy.mockClear() + it('should not run migrations with two fail', async () => { + const schema: Schema = { _id: '1', version: 0 } + const mockQueryResult: QueryResult<Schema[]> = { + data: [schema], + bookmark: '', + next: false, + skip: 0, + } const migrations: Migration[] = [ { baseSchemaVersion: 0, @@ -66,7 +100,8 @@ describe('Migration service', () => { appVersion: '1.2.4', description: 'Removing mailToken from profil', docTypes: PROFILE_DOCTYPE, - run: (docs: any[]): Profile[] => { + releaseNotes: releaseNotes, + run: async (client: Client, docs: any[]): Promise<Profile[]> => { return [] }, }, @@ -75,17 +110,28 @@ describe('Migration service', () => { type: MIGRATION_RESULT_FAILED, errors: [], } + mockClient.query.mockResolvedValue(mockQueryResult) const migrateSpyTwoFailsKo = jest .spyOn(Migrate, 'migrate') .mockResolvedValueOnce(result) .mockResolvedValueOnce(result) - ms.runMigrations(migrations) - expect(migrateSpyTwoFailsKo).toBeCalledTimes(1) - expect(migrateSpy).toBeCalledTimes(1) + try { + await ms.runMigrations(migrations) + expect(migrateSpyTwoFailsKo).toBeCalledTimes(1) + expect(migrateSpy).toBeCalledTimes(1) + } catch (error) { + expect(error).toEqual(new Error()) + } }) - it('should run migrations with two fail', () => { - migrateSpy.mockClear() + it('should skip migrations if schema number is up to date', async () => { + const schema: Schema = { _id: '1', version: 1 } + const mockQueryResult: QueryResult<Schema[]> = { + data: [schema], + bookmark: '', + next: false, + skip: 0, + } const migrations: Migration[] = [ { baseSchemaVersion: 0, @@ -93,25 +139,53 @@ describe('Migration service', () => { appVersion: '1.2.4', description: 'Removing mailToken from profil', docTypes: PROFILE_DOCTYPE, - run: (docs: any[]): Profile[] => { + releaseNotes: releaseNotes, + run: async (client: Client, docs: any[]): Promise<Profile[]> => { return [] }, }, ] - const result: MigrationResult = { - type: MIGRATION_RESULT_FAILED, - errors: [], - } - const resultOk: MigrationResult = { - type: MIGRATION_RESULT_COMPLETE, - errors: [], + mockClient.query.mockResolvedValue(mockQueryResult) + + await ms.runMigrations(migrations) + expect(migrateSpy).toBeCalledTimes(0) + }) + it('should run 2 migrations properly from a fresh instance and dont show releasenotes', async () => { + const schema: Schema = { _id: '1', version: 0 } + const mockQueryResult: QueryResult<Schema[]> = { + data: [schema], + bookmark: '', + next: false, + skip: 0, } - const migrateSpyTwoFails = jest - .spyOn(Migrate, 'migrate') - .mockResolvedValueOnce(result) - .mockResolvedValueOnce(resultOk) - ms.runMigrations(migrations) - expect(migrateSpyTwoFails).toBeCalledTimes(1) - expect(migrateSpy).toBeCalledTimes(1) + const migrations: Migration[] = [ + { + baseSchemaVersion: 0, + targetSchemaVersion: 1, + appVersion: '1.2.4', + description: 'Removing mailToken from profil', + docTypes: PROFILE_DOCTYPE, + releaseNotes: releaseNotes, + run: async (client: Client, docs: any[]): Promise<Profile[]> => { + return [] + }, + }, + { + baseSchemaVersion: 1, + targetSchemaVersion: 2, + appVersion: '1.2.4', + description: 'Removing mailToken from profil', + docTypes: PROFILE_DOCTYPE, + releaseNotes: releaseNotes, + run: async (client: Client, docs: any[]): Promise<Profile[]> => { + return [] + }, + }, + ] + mockClient.query.mockResolvedValue(mockQueryResult) + + const res = await ms.runMigrations(migrations) + expect(migrateSpy).toBeCalledTimes(2) + expect(res.show).toBeFalsy() }) }) diff --git a/src/migrations/migration.service.ts b/src/migrations/migration.service.ts index c282caf1559595d98bc28191357be548465feb9b..0ede26effbcc62ae082c685bf34e01da1b581ef5 100644 --- a/src/migrations/migration.service.ts +++ b/src/migrations/migration.service.ts @@ -50,14 +50,13 @@ export class MigrationService { } const currentVersion = await this.currentSchemaVersion(this._client) const targetVersion = migrations[migrations.length - 1].targetSchemaVersion - console.log('CURRENT VERSION', currentVersion) - console.log('CURRENT targetVersion', targetVersion) + // Prevent Migration service to run every migration if not needed if (currentVersion != targetVersion) { const startMigrationIndex = migrations.length - (targetVersion - currentVersion) const migrationsToRun = migrations.splice(startMigrationIndex) - console.log('migrationsToRun', migrationsToRun) + for (const migration of migrationsToRun) { // First attempt const migrationResult: MigrationResult = await migrate( diff --git a/src/services/initialization.service.spec.ts b/src/services/initialization.service.spec.ts index e782eedb8fc165277f36494c357ee67a8b2e6e61..ba4cc353721c95b0bd7e5c48075a534591007763 100644 --- a/src/services/initialization.service.spec.ts +++ b/src/services/initialization.service.spec.ts @@ -175,39 +175,6 @@ describe('Initialization service', () => { mockClient.create.mockClear() }) - describe('initIndex method', () => { - beforeEach(() => { - mockCreateIndexKonnector.mockClear() - mockCreateIndexAccount.mockClear() - }) - it('should return true when all indexes created', async () => { - const mockQueryResult: QueryResult<boolean> = { - data: true, - bookmark: '', - next: false, - skip: 0, - } - mockClient.query.mockResolvedValueOnce(mockQueryResult) - mockCreateIndexKonnector.mockResolvedValueOnce(mockQueryResult) - mockCreateIndexAccount.mockResolvedValueOnce(mockQueryResult) - await expect(initializationService.initIndex()).resolves.toBe(true) - }) - it('should throw error when an index is not created', async () => { - const mockQueryResult: QueryResult<boolean> = { - data: true, - bookmark: '', - next: false, - skip: 0, - } - mockClient.query.mockResolvedValueOnce(mockQueryResult) - mockCreateIndexKonnector.mockRejectedValueOnce(new Error()) - mockCreateIndexAccount.mockResolvedValueOnce(mockQueryResult) - await expect(initializationService.initIndex()).rejects.toThrow( - new Error() - ) - }) - }) - describe('initProfile method', () => { beforeEach(() => { mockGetProfile.mockClear()