mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-21 22:57:59 -04:00
add unit tests
This commit is contained in:
426
packages/insomnia/src/sync/vcs/__tests__/database.mock.ts
Normal file
426
packages/insomnia/src/sync/vcs/__tests__/database.mock.ts
Normal file
@@ -0,0 +1,426 @@
|
||||
import { database as db } from '../../../common/database';
|
||||
import * as models from '../../../models';
|
||||
import { Project } from '../../../models/project';
|
||||
import { Request } from '../../../models/request';
|
||||
import { RequestGroup } from '../../../models/request-group';
|
||||
import { Workspace } from '../../../models/workspace';
|
||||
import { WorkspaceMeta } from '../../../models/workspace-meta';
|
||||
|
||||
type MockModel = Partial<Project | Workspace | RequestGroup | Request | WorkspaceMeta>;
|
||||
const mocksWithoutParentIdProjects: Record<string, MockModel[]> = {
|
||||
[models.project.type]: [
|
||||
{
|
||||
_id: 'proj_1',
|
||||
name: 'Proj 1',
|
||||
parentId: null,
|
||||
remoteId: null,
|
||||
} as unknown as Project,
|
||||
{
|
||||
_id: 'proj_2',
|
||||
name: 'Proj 2',
|
||||
parentId: null,
|
||||
remoteId: null,
|
||||
} as unknown as Project,
|
||||
{
|
||||
_id: 'proj_3',
|
||||
name: 'Proj 3',
|
||||
parentId: null,
|
||||
remoteId: null,
|
||||
} as unknown as Project,
|
||||
],
|
||||
[models.workspace.type]: [
|
||||
{
|
||||
_id: 'wrk_1',
|
||||
name: 'Wrk 1',
|
||||
parentId: null,
|
||||
} as unknown as Workspace,
|
||||
{
|
||||
_id: 'wrk_2',
|
||||
name: 'Wrk 2',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
{
|
||||
_id: 'wrk_3',
|
||||
name: 'Wrk 3',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
{
|
||||
_id: 'wrk_4',
|
||||
name: 'Wrk 4',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
],
|
||||
[models.requestGroup.type]: [
|
||||
{
|
||||
_id: 'fld_1',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 1',
|
||||
},
|
||||
{
|
||||
_id: 'fld_2',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 2',
|
||||
},
|
||||
{
|
||||
_id: 'fld_3',
|
||||
parentId: 'fld_1',
|
||||
name: 'Fld 3',
|
||||
},
|
||||
],
|
||||
[models.request.type]: [
|
||||
{
|
||||
_id: 'req_1',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 1',
|
||||
},
|
||||
{
|
||||
_id: 'req_2',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 2',
|
||||
},
|
||||
{
|
||||
_id: 'req_3',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 3',
|
||||
},
|
||||
{
|
||||
_id: 'req_4',
|
||||
parentId: 'fld_3',
|
||||
name: 'Req 4',
|
||||
},
|
||||
{
|
||||
_id: 'req_5',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 5',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mocksHiddenWorkspaces: Record<string, MockModel[]> = {
|
||||
[models.project.type]: [
|
||||
{
|
||||
_id: 'proj_1',
|
||||
name: 'Proj 1',
|
||||
parentId: 'org_1',
|
||||
remoteId: 'team_1',
|
||||
},
|
||||
],
|
||||
[models.workspace.type]: [
|
||||
{
|
||||
_id: 'wrk_1',
|
||||
name: 'Wrk 1',
|
||||
parentId: 'proj_1',
|
||||
},
|
||||
{
|
||||
_id: 'wrk_2',
|
||||
name: 'Wrk 2',
|
||||
parentId: null,
|
||||
} as unknown as Workspace,
|
||||
{
|
||||
_id: 'wrk_3',
|
||||
name: 'Wrk 3',
|
||||
parentId: null,
|
||||
} as unknown as Workspace,
|
||||
{
|
||||
_id: 'wrk_4',
|
||||
name: 'Wrk 4',
|
||||
parentId: null,
|
||||
} as unknown as Workspace,
|
||||
],
|
||||
[models.requestGroup.type]: [
|
||||
{
|
||||
_id: 'fld_1',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 1',
|
||||
},
|
||||
{
|
||||
_id: 'fld_2',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 2',
|
||||
},
|
||||
{
|
||||
_id: 'fld_3',
|
||||
parentId: 'fld_1',
|
||||
name: 'Fld 3',
|
||||
},
|
||||
],
|
||||
[models.request.type]: [
|
||||
{
|
||||
_id: 'req_1',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 1',
|
||||
},
|
||||
{
|
||||
_id: 'req_2',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 2',
|
||||
},
|
||||
{
|
||||
_id: 'req_3',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 3',
|
||||
},
|
||||
{
|
||||
_id: 'req_4',
|
||||
parentId: 'fld_3',
|
||||
name: 'Req 4',
|
||||
},
|
||||
{
|
||||
_id: 'req_5',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 5',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mocksNoProblem: Record<string, MockModel[]> = {
|
||||
[models.project.type]: [
|
||||
{
|
||||
_id: 'proj_1',
|
||||
name: 'Proj 1',
|
||||
parentId: 'org_1',
|
||||
remoteId: null,
|
||||
},
|
||||
{
|
||||
_id: 'proj_2',
|
||||
name: 'Proj 2',
|
||||
parentId: 'org_2',
|
||||
remoteId: null,
|
||||
},
|
||||
{
|
||||
_id: 'proj_3',
|
||||
name: 'Proj 3',
|
||||
parentId: 'org_3',
|
||||
remoteId: 'team_proj_3',
|
||||
},
|
||||
],
|
||||
[models.workspace.type]: [
|
||||
{
|
||||
_id: 'wrk_1',
|
||||
name: 'Wrk 1',
|
||||
parentId: 'proj_1',
|
||||
},
|
||||
{
|
||||
_id: 'wrk_2',
|
||||
name: 'Wrk 2',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
],
|
||||
[models.requestGroup.type]: [
|
||||
{
|
||||
_id: 'fld_1',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 1',
|
||||
},
|
||||
{
|
||||
_id: 'fld_2',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 2',
|
||||
},
|
||||
{
|
||||
_id: 'fld_3',
|
||||
parentId: 'fld_1',
|
||||
name: 'Fld 3',
|
||||
},
|
||||
],
|
||||
[models.request.type]: [
|
||||
{
|
||||
_id: 'req_1',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 1',
|
||||
},
|
||||
{
|
||||
_id: 'req_2',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 2',
|
||||
},
|
||||
{
|
||||
_id: 'req_3',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 3',
|
||||
},
|
||||
{
|
||||
_id: 'req_4',
|
||||
parentId: 'fld_3',
|
||||
name: 'Req 4',
|
||||
},
|
||||
{
|
||||
_id: 'req_5',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 5',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mocksToBeRepaired: Record<string, MockModel[]> = {
|
||||
[models.project.type]: [
|
||||
{
|
||||
_id: 'proj_1',
|
||||
name: 'Proj 1',
|
||||
parentId: null,
|
||||
remoteId: 'team_1',
|
||||
} as unknown as Project,
|
||||
{
|
||||
_id: 'proj_2',
|
||||
name: 'Proj 2',
|
||||
parentId: null,
|
||||
remoteId: 'team_2',
|
||||
} as unknown as Project,
|
||||
{
|
||||
_id: 'proj_3',
|
||||
name: 'Proj 3',
|
||||
parentId: null,
|
||||
remoteId: null,
|
||||
} as unknown as Project,
|
||||
],
|
||||
[models.workspace.type]: [
|
||||
{
|
||||
_id: 'wrk_1',
|
||||
name: 'Wrk 1',
|
||||
parentId: null,
|
||||
} as unknown as Workspace,
|
||||
{
|
||||
_id: 'wrk_2',
|
||||
name: 'Wrk 2',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
{
|
||||
_id: 'wrk_3',
|
||||
name: 'Wrk 3',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
{
|
||||
_id: 'wrk_4',
|
||||
name: 'Wrk 4',
|
||||
parentId: 'proj_3',
|
||||
},
|
||||
],
|
||||
[models.requestGroup.type]: [
|
||||
{
|
||||
_id: 'fld_1',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 1',
|
||||
},
|
||||
{
|
||||
_id: 'fld_2',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Fld 2',
|
||||
},
|
||||
{
|
||||
_id: 'fld_3',
|
||||
parentId: 'fld_1',
|
||||
name: 'Fld 3',
|
||||
},
|
||||
],
|
||||
[models.request.type]: [
|
||||
{
|
||||
_id: 'req_1',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 1',
|
||||
},
|
||||
{
|
||||
_id: 'req_2',
|
||||
parentId: 'fld_1',
|
||||
name: 'Req 2',
|
||||
},
|
||||
{
|
||||
_id: 'req_3',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 3',
|
||||
},
|
||||
{
|
||||
_id: 'req_4',
|
||||
parentId: 'fld_3',
|
||||
name: 'Req 4',
|
||||
},
|
||||
{
|
||||
_id: 'req_5',
|
||||
parentId: 'wrk_1',
|
||||
name: 'Req 5',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockRemoteBackgroundCheck = {
|
||||
myWorkspaceId: 'org_my',
|
||||
remoteFileSnapshot: {
|
||||
'org_my': {
|
||||
ownedByMe: true,
|
||||
isPersonal: true,
|
||||
fileIdMap: {
|
||||
'wrk_1': 'team_1',
|
||||
'wrk_2': 'team_1',
|
||||
'wrk_3': 'team_2',
|
||||
'wrk_4': 'team_3',
|
||||
},
|
||||
projectIds: ['team_1', 'team_2', 'team_3', 'team_4', 'team_5'],
|
||||
},
|
||||
'org_1': {
|
||||
ownedByMe: false,
|
||||
isPersonal: false,
|
||||
fileIdMap: {},
|
||||
projectIds: [],
|
||||
},
|
||||
},
|
||||
byRemoteProjectId: new Map([
|
||||
['team_1', 'org_my'],
|
||||
['team_2', 'org_my'],
|
||||
['team_3', 'org_my'],
|
||||
['team_4', 'org_my'],
|
||||
['team_5', 'org_my'],
|
||||
['team_6', 'org_1'],
|
||||
]),
|
||||
byRemoteFileId: new Map([
|
||||
['wrk_1', {
|
||||
remoteOrgId: 'org_my',
|
||||
remoteProjectId: 'team_1',
|
||||
}],
|
||||
['wrk_2', {
|
||||
remoteOrgId: 'org_my',
|
||||
remoteProjectId: 'team_1',
|
||||
}],
|
||||
['wrk_3', {
|
||||
remoteOrgId: 'org_my',
|
||||
remoteProjectId: 'team_2',
|
||||
}],
|
||||
['wrk_4', {
|
||||
remoteOrgId: 'org_my',
|
||||
remoteProjectId: 'team_2',
|
||||
}],
|
||||
]),
|
||||
};
|
||||
|
||||
const mockRemoteBackgroundCheckMessedUp = {
|
||||
myWorkspaceId: 'org_my',
|
||||
remoteFileSnapshot: {
|
||||
'org_my': {
|
||||
ownedByMe: true,
|
||||
isPersonal: true,
|
||||
fileIdMap: {
|
||||
},
|
||||
projectIds: [],
|
||||
},
|
||||
'org_1': {
|
||||
ownedByMe: false,
|
||||
isPersonal: false,
|
||||
fileIdMap: {},
|
||||
projectIds: [],
|
||||
},
|
||||
},
|
||||
byRemoteProjectId: new Map(),
|
||||
byRemoteFileId: new Map(),
|
||||
};
|
||||
export function fakeDatabase(data: Record<string, MockModel[]>) {
|
||||
const promises: Promise<models.BaseModel>[] = [];
|
||||
for (const type of Object.keys(data)) {
|
||||
for (const doc of data[type]) {
|
||||
console.log(doc);
|
||||
// @ts-expect-error -- TSCONVERSION
|
||||
promises.push(db.insert<models.BaseModel>({ ...doc, type }));
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
export { mocksWithoutParentIdProjects, mocksHiddenWorkspaces, mocksNoProblem, mocksToBeRepaired };
|
||||
export { mockRemoteBackgroundCheck, mockRemoteBackgroundCheckMessedUp };
|
||||
@@ -1,73 +1,212 @@
|
||||
import { afterAll, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import { beforeEach, describe, expect, it } from '@jest/globals';
|
||||
|
||||
import { globalBeforeEach } from '../../../__jest__/before-each';
|
||||
import * as models from '../../../models';
|
||||
import MemoryDriver from '../../store/drivers/memory-driver';
|
||||
import { pushSnapshotOnInitialize } from '../initialize-backend-project';
|
||||
import { VCS } from '../vcs';
|
||||
import { _migrateToCloudSync, _migrateToLocalVault, _validateProjectsWithRemote, scanForMigration, shouldMigrate } from '../migrate-projects-into-organization';
|
||||
import { fakeDatabase, mockRemoteBackgroundCheck, mockRemoteBackgroundCheckMessedUp, mocksHiddenWorkspaces, mocksNoProblem, mocksToBeRepaired, mocksWithoutParentIdProjects } from './database.mock';
|
||||
|
||||
describe('migrate-projects-into-organizatino', () => {
|
||||
beforeEach(globalBeforeEach);
|
||||
console.log({
|
||||
_migrateToCloudSync, _migrateToLocalVault, _validateProjectsWithRemote,
|
||||
});
|
||||
describe('scanForMigration()', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
});
|
||||
it('should scan all the untracked projects and files (both files under projects and un parent project files)', async () => {
|
||||
await fakeDatabase(mocksWithoutParentIdProjects);
|
||||
|
||||
describe('pushSnapshotOnInitialize()', () => {
|
||||
const vcs = new VCS(new MemoryDriver());
|
||||
const result = await scanForMigration();
|
||||
console.log(result.filesByProject.size);
|
||||
expect(result.filesByProject.size).toBe(3);
|
||||
|
||||
const pushSpy = jest.spyOn(vcs, 'push');
|
||||
expect(result.filesByProject.has('wrk_2'));
|
||||
expect(result.filesByProject.has('wrk_3'));
|
||||
expect(result.filesByProject.has('wrk_4'));
|
||||
expect(result.filesNoProject.size).toBe(1);
|
||||
expect(result.filesNoProject.has('wrk_1'));
|
||||
expect(result.projects.size).toBe(3);
|
||||
expect(result.projects.has('proj_1'));
|
||||
expect(result.projects.has('proj_2'));
|
||||
expect(result.projects.has('proj_3'));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
it('should scan all the untracked files (only files)', async () => {
|
||||
await fakeDatabase(mocksHiddenWorkspaces);
|
||||
|
||||
afterAll(() => {
|
||||
pushSpy.mockClear();
|
||||
});
|
||||
const result = await scanForMigration();
|
||||
expect(result.filesByProject.size).toBe(0);
|
||||
expect(result.filesNoProject.size).toBe(3);
|
||||
expect(result.filesNoProject.has('wrk_2'));
|
||||
expect(result.filesNoProject.has('wrk_3'));
|
||||
expect(result.filesNoProject.has('wrk_4'));
|
||||
expect(result.projects.size).toBe(0);
|
||||
});
|
||||
|
||||
it('should not push if no active project', async () => {
|
||||
const project = await models.project.create({ remoteId: null });
|
||||
const workspace = await models.workspace.create({ parentId: project._id });
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id });
|
||||
vcs.clearBackendProject();
|
||||
it('should scan when there are no untracked projects and files', async () => {
|
||||
await fakeDatabase(mocksNoProblem);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
await expect(models.workspaceMeta.getByParentId(workspace._id)).resolves.toStrictEqual(workspaceMeta);
|
||||
});
|
||||
|
||||
it('should not push snapshot if not remote project', async () => {
|
||||
const project = await models.project.create({ remoteId: null });
|
||||
const workspace = await models.workspace.create({ parentId: project._id });
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
await expect(models.workspaceMeta.getByParentId(workspace._id)).resolves.toStrictEqual(workspaceMeta);
|
||||
});
|
||||
|
||||
it('should not push snapshot if workspace not in project', async () => {
|
||||
const project = await models.project.create({ remoteId: 'abc' });
|
||||
const anotherProject = await models.project.create({ remoteId: 'def' });
|
||||
const workspace = await models.workspace.create({ parentId: anotherProject._id });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should push snapshot if conditions are met', async () => {
|
||||
const project = await models.project.create({ remoteId: 'abc', parentId: 'team_abc' });
|
||||
const workspace = await models.workspace.create({ parentId: project._id });
|
||||
await models.workspaceMeta.create({ parentId: workspace._id, pushSnapshotOnInitialize: true });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).toHaveBeenCalledWith({ teamId: 'team_abc', teamProjectId: project.remoteId });
|
||||
const updatedMeta = await models.workspaceMeta.getByParentId(workspace._id);
|
||||
expect(updatedMeta?.pushSnapshotOnInitialize).toBe(false);
|
||||
});
|
||||
const result = await scanForMigration();
|
||||
expect(result.filesByProject.size).toBe(0);
|
||||
expect(result.filesNoProject.size).toBe(0);
|
||||
expect(result.projects.size).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('shouldMigrate()', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
});
|
||||
it('should return true with untracked projects and files (both files under projects and un parent project files)', async () => {
|
||||
await fakeDatabase(mocksWithoutParentIdProjects);
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const result = await shouldMigrate(queue);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return true with untracked files (only files)', async () => {
|
||||
await fakeDatabase(mocksHiddenWorkspaces);
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const result = await shouldMigrate(queue);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false with no untracked files', async () => {
|
||||
await fakeDatabase(mocksNoProblem);
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const result = await shouldMigrate(queue);
|
||||
expect(result).not.toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_migrateToCloudSync()', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
});
|
||||
|
||||
it('should fallback to local migration when there are no valid remote projects', async () => {
|
||||
await fakeDatabase(mocksWithoutParentIdProjects);
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const records = await _migrateToCloudSync(queue, mockRemoteBackgroundCheckMessedUp);
|
||||
|
||||
expect(records.filesForSync.length).toBe(0);
|
||||
expect(records.projects.size).toBe(3);
|
||||
expect(records.projects.has('proj_1')).toBeTruthy();
|
||||
expect(records.projects.has('proj_2')).toBeTruthy();
|
||||
expect(records.projects.has('proj_3')).toBeTruthy();
|
||||
const [proj1, proj2, proj3] = await Promise.all([
|
||||
models.project.getById(records.projects.get('proj_1')!),
|
||||
models.project.getById(records.projects.get('proj_2')!),
|
||||
models.project.getById(records.projects.get('proj_3')!),
|
||||
]);
|
||||
expect(proj1).toBeTruthy();
|
||||
expect(proj1!.remoteId).toBeNull();
|
||||
expect(proj2).toBeTruthy();
|
||||
expect(proj2!.remoteId).toBeNull();
|
||||
expect(proj3).toBeTruthy();
|
||||
expect(proj3!.remoteId).toBeNull();
|
||||
|
||||
expect(records.files.size).toBe(4);
|
||||
expect(records.files.has('wrk_1')).toBeTruthy();
|
||||
expect(records.files.has('wrk_2')).toBeTruthy(); // part of proj_3
|
||||
expect(records.files.has('wrk_3')).toBeTruthy(); // part of proj_3
|
||||
expect(records.files.has('wrk_4')).toBeTruthy(); // part of proj_3
|
||||
});
|
||||
|
||||
it('should repair projects with valid remote ids with personal workspace id if not linked correctly', async () => {
|
||||
await fakeDatabase(mocksToBeRepaired);
|
||||
|
||||
const beforeProj1 = await models.project.getById('proj_1');
|
||||
expect(beforeProj1!.parentId).toBeNull();
|
||||
|
||||
const beforeProj2 = await models.project.getById('proj_2');
|
||||
expect(beforeProj2!.parentId).toBeNull();
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const records = await _migrateToCloudSync(queue, mockRemoteBackgroundCheck);
|
||||
|
||||
expect(records.projects.size).toBe(1);
|
||||
expect(records.files.size).toBe(4); // => we've duplicated the files because they are not in correct linking between the local and remote
|
||||
|
||||
const repairedProj1 = await models.project.getById('proj_1');
|
||||
expect(repairedProj1!.parentId).toBe('org_my');
|
||||
|
||||
const repairedProj2 = await models.project.getById('proj_2');
|
||||
expect(repairedProj2!.parentId).toBe('org_my');
|
||||
|
||||
const [wrk1, wrk2, wrk3, wrk4] = await Promise.all([
|
||||
models.workspace.getById(records.files.get('wrk_1')!),
|
||||
models.workspace.getById(records.files.get('wrk_2')!),
|
||||
models.workspace.getById(records.files.get('wrk_3')!),
|
||||
models.workspace.getById(records.files.get('wrk_4')!),
|
||||
]);
|
||||
|
||||
expect(wrk1!.parentId).not.toBeNull(); // files without parent id (no project linking) => now corrected
|
||||
expect(wrk2!.parentId).not.toBe('proj_3'); // files with the parent id that does not exist in the cloud => duplicated and linked to the existing remote project
|
||||
expect(wrk3!.parentId).not.toBe('proj_3'); // files with the parent id that does not exist in the cloud => duplicated and linked to the existing remote project
|
||||
expect(wrk4!.parentId).not.toBe('proj_3'); // files with the parent id that does not exist in the cloud => duplicated and linked to the existing remote project
|
||||
|
||||
// these duplicated 4 files need to be synced now
|
||||
expect(records.filesForSync.length).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_migrateToLocalVault()', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
});
|
||||
|
||||
it('should duplicate all files and projects', async () => {
|
||||
await fakeDatabase(mocksWithoutParentIdProjects);
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const records = await _migrateToLocalVault(queue, mockRemoteBackgroundCheck);
|
||||
|
||||
// should never happen
|
||||
expect(records).not.toHaveProperty('filesForSync');
|
||||
expect(records.projects.size).toBe(3);
|
||||
expect(records.projects.has('proj_1')).toBeTruthy();
|
||||
expect(records.projects.has('proj_2')).toBeTruthy();
|
||||
expect(records.projects.has('proj_3')).toBeTruthy();
|
||||
expect(records.files.size).toBe(4);
|
||||
expect(records.files.has('wrk_1')).toBeTruthy();
|
||||
expect(records.files.has('wrk_2')).toBeTruthy(); // part of proj_3
|
||||
expect(records.files.has('wrk_3')).toBeTruthy(); // part of proj_3
|
||||
expect(records.files.has('wrk_4')).toBeTruthy(); // part of proj_3
|
||||
});
|
||||
|
||||
it('should link untracked files to a newly created local vault', async () => {
|
||||
await fakeDatabase(mocksHiddenWorkspaces);
|
||||
|
||||
const queue = await scanForMigration();
|
||||
const records = await _migrateToLocalVault(queue, mockRemoteBackgroundCheck);
|
||||
expect(records).not.toHaveProperty('filesForSync');
|
||||
expect(records.projects.size).toBe(0);
|
||||
expect(records.projects.has('proj_1')).not.toBeTruthy();
|
||||
expect(records.files.size).toBe(3);
|
||||
expect(records.files.has('wrk_1')).not.toBeTruthy(); // part of proj_1
|
||||
expect(records.files.has('wrk_2')).toBeTruthy();
|
||||
expect(records.files.has('wrk_3')).toBeTruthy();
|
||||
expect(records.files.has('wrk_4')).toBeTruthy();
|
||||
|
||||
const [wrk1, wrk2, wrk3, wrk4] = await Promise.all([
|
||||
models.workspace.getById('wrk_1'),
|
||||
models.workspace.getById(records.files.get('wrk_2')),
|
||||
models.workspace.getById(records.files.get('wrk_3')),
|
||||
models.workspace.getById(records.files.get('wrk_4')),
|
||||
]);
|
||||
|
||||
expect(wrk1).toMatchObject({});
|
||||
expect(wrk2).toBeTruthy();
|
||||
expect(wrk2?.parentId).not.toBeNull();
|
||||
|
||||
const { parentId: newVaultId } = wrk2!;
|
||||
expect(wrk3).toBeTruthy();
|
||||
expect(wrk3?.parentId).toEqual(newVaultId);
|
||||
expect(wrk4).toBeTruthy();
|
||||
expect(wrk4?.parentId).toEqual(newVaultId);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +49,8 @@ export const scanForMigration = async (): Promise<QueueForMigration> => {
|
||||
parentId: null,
|
||||
});
|
||||
|
||||
console.log({ legacyRemoteProjects });
|
||||
|
||||
for (const project of legacyRemoteProjects) {
|
||||
console.log('[migration] found legacy remote project', project);
|
||||
queueLocalProjects.add(project._id);
|
||||
@@ -68,6 +70,7 @@ export const scanForMigration = async (): Promise<QueueForMigration> => {
|
||||
_id: { $ne: models.project.SCRATCHPAD_PROJECT_ID },
|
||||
});
|
||||
|
||||
console.log({ localProjects });
|
||||
for (const project of localProjects) {
|
||||
console.log('[migration] found local project', project._id);
|
||||
queueLocalProjects.add(project._id);
|
||||
@@ -85,6 +88,8 @@ export const scanForMigration = async (): Promise<QueueForMigration> => {
|
||||
parentId: null,
|
||||
});
|
||||
|
||||
console.log({ untrackedFiles });
|
||||
|
||||
for (const file of untrackedFiles) {
|
||||
console.log('[migration] found an untracked file with no parents', file._id);
|
||||
queueLocalFilesNoProject.add(file._id);
|
||||
@@ -107,7 +112,7 @@ interface RemoteBackground {
|
||||
remoteProjectId: RemoteProjectId;
|
||||
}>;
|
||||
}
|
||||
const remoteBackgroundCheck = async (sessionId: string): Promise<RemoteBackground | null> => {
|
||||
export const remoteBackgroundCheck = async (sessionId: string): Promise<RemoteBackground | null> => {
|
||||
const response = await window.main.insomniaFetch<RemoteFileSnapshot | { error: string; message: string }>({
|
||||
method: 'GET',
|
||||
path: '/v1/user/file-snapshot',
|
||||
@@ -171,7 +176,8 @@ interface RecordsForMigration {
|
||||
projects: Map<string, string>;
|
||||
files: Map<string, string>;
|
||||
};
|
||||
const _migrateToLocalVault = async (queue: QueueForMigration, remoteBackground: RemoteBackground): Promise<RecordsForMigration> => {
|
||||
/** @private */
|
||||
export const _migrateToLocalVault = async (queue: QueueForMigration, remoteBackground: RemoteBackground): Promise<RecordsForMigration> => {
|
||||
const recordsForProjectMigration = new Map<string, string>();
|
||||
const recordsForFileMigration = new Map<string, string>();
|
||||
|
||||
@@ -232,7 +238,8 @@ const _migrateToLocalVault = async (queue: QueueForMigration, remoteBackground:
|
||||
};
|
||||
};
|
||||
|
||||
const _validateProjectsWithRemote = async (queue: QueueForMigration, remoteBackground: RemoteBackground) => {
|
||||
/** @private */
|
||||
export const _validateProjectsWithRemote = async (queue: QueueForMigration, remoteBackground: RemoteBackground) => {
|
||||
console.log('[migration] validating projects against the remote');
|
||||
const { myWorkspaceId } = remoteBackground;
|
||||
const myWorkspace = remoteBackground.remoteFileSnapshot[myWorkspaceId];
|
||||
@@ -303,7 +310,8 @@ const _validateProjectsWithRemote = async (queue: QueueForMigration, remoteBackg
|
||||
type RecordsForCloudMigration = RecordsForMigration & {
|
||||
filesForSync: Workspace[];
|
||||
};
|
||||
const _migrateToCloudSync = async (
|
||||
/** @private */
|
||||
export const _migrateToCloudSync = async (
|
||||
queue: QueueForMigration,
|
||||
remoteBackground: RemoteBackground,
|
||||
): Promise<RecordsForCloudMigration> => {
|
||||
@@ -330,6 +338,7 @@ const _migrateToCloudSync = async (
|
||||
for (const validProject of validProjects) {
|
||||
if (validProject.parentId !== myWorkspaceId) {
|
||||
console.log('[migration] repairing team-project to organization linking for local database');
|
||||
// TODO: update the array validProjects here
|
||||
await database.docUpdate<Project>(validProject, {
|
||||
parentId: myWorkspaceId,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user