2023-05-31 06:09:18 +03:00
|
|
|
import path from 'node:path';
|
|
|
|
|
2023-09-17 23:26:06 +03:00
|
|
|
import { removeWithRetry } from '@affine-test/kit/utils/utils';
|
2023-05-31 06:09:18 +03:00
|
|
|
import fs from 'fs-extra';
|
|
|
|
import { v4 } from 'uuid';
|
|
|
|
import { afterEach, describe, expect, test, vi } from 'vitest';
|
|
|
|
|
|
|
|
const tmpDir = path.join(__dirname, 'tmp');
|
2023-06-13 05:01:43 +03:00
|
|
|
const appDataPath = path.join(tmpDir, 'app-data');
|
2023-05-31 06:09:18 +03:00
|
|
|
|
2023-10-19 06:14:30 +03:00
|
|
|
vi.doMock('@affine/electron/helper/db/ensure-db', () => ({
|
2023-05-31 06:09:18 +03:00
|
|
|
ensureSQLiteDB: async () => ({
|
|
|
|
destroy: () => {},
|
|
|
|
}),
|
|
|
|
}));
|
|
|
|
|
2023-10-19 06:14:30 +03:00
|
|
|
vi.doMock('@affine/electron/helper/main-rpc', () => ({
|
2023-06-13 05:01:43 +03:00
|
|
|
mainRPC: {
|
|
|
|
getPath: async () => appDataPath,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
2023-05-31 06:09:18 +03:00
|
|
|
afterEach(async () => {
|
2023-07-03 13:46:47 +03:00
|
|
|
await removeWithRetry(tmpDir);
|
2023-05-31 06:09:18 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('list workspaces', () => {
|
|
|
|
test('listWorkspaces (valid)', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { listWorkspaces } = await import(
|
|
|
|
'@affine/electron/helper/workspace/handlers'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
const meta = {
|
|
|
|
id: workspaceId,
|
|
|
|
};
|
|
|
|
await fs.ensureDir(workspacePath);
|
|
|
|
await fs.writeJSON(path.join(workspacePath, 'meta.json'), meta);
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspaces = await listWorkspaces();
|
2023-05-31 06:09:18 +03:00
|
|
|
expect(workspaces).toEqual([[workspaceId, meta]]);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('listWorkspaces (without meta json file)', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { listWorkspaces } = await import(
|
|
|
|
'@affine/electron/helper/workspace/handlers'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
await fs.ensureDir(workspacePath);
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspaces = await listWorkspaces();
|
2023-05-31 06:09:18 +03:00
|
|
|
expect(workspaces).toEqual([
|
|
|
|
[
|
|
|
|
workspaceId,
|
|
|
|
// meta file will be created automatically
|
|
|
|
{ id: workspaceId, mainDBPath: path.join(workspacePath, 'storage.db') },
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('delete workspace', () => {
|
|
|
|
test('deleteWorkspace', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { deleteWorkspace } = await import(
|
|
|
|
'@affine/electron/helper/workspace/handlers'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
await fs.ensureDir(workspacePath);
|
2023-06-13 05:01:43 +03:00
|
|
|
await deleteWorkspace(workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
expect(await fs.pathExists(workspacePath)).toBe(false);
|
2023-06-13 05:01:43 +03:00
|
|
|
// removed workspace will be moved to deleted-workspaces
|
2023-05-31 06:09:18 +03:00
|
|
|
expect(
|
|
|
|
await fs.pathExists(
|
2023-06-13 05:01:43 +03:00
|
|
|
path.join(appDataPath, 'deleted-workspaces', workspaceId)
|
2023-05-31 06:09:18 +03:00
|
|
|
)
|
|
|
|
).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('getWorkspaceMeta', () => {
|
|
|
|
test('can get meta', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { getWorkspaceMeta } = await import(
|
|
|
|
'@affine/electron/helper/workspace/meta'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
const meta = {
|
|
|
|
id: workspaceId,
|
|
|
|
};
|
|
|
|
await fs.ensureDir(workspacePath);
|
|
|
|
await fs.writeJSON(path.join(workspacePath, 'meta.json'), meta);
|
2023-06-13 05:01:43 +03:00
|
|
|
expect(await getWorkspaceMeta(workspaceId)).toEqual(meta);
|
2023-05-31 06:09:18 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
test('can create meta if not exists', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { getWorkspaceMeta } = await import(
|
|
|
|
'@affine/electron/helper/workspace/meta'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
await fs.ensureDir(workspacePath);
|
2023-06-13 05:01:43 +03:00
|
|
|
expect(await getWorkspaceMeta(workspaceId)).toEqual({
|
2023-05-31 06:09:18 +03:00
|
|
|
id: workspaceId,
|
|
|
|
mainDBPath: path.join(workspacePath, 'storage.db'),
|
|
|
|
});
|
|
|
|
expect(
|
|
|
|
await fs.pathExists(path.join(workspacePath, 'meta.json'))
|
|
|
|
).toBeTruthy();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('can migrate meta if db file is a link', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { getWorkspaceMeta } = await import(
|
|
|
|
'@affine/electron/helper/workspace/meta'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
await fs.ensureDir(workspacePath);
|
|
|
|
const sourcePath = path.join(tmpDir, 'source.db');
|
|
|
|
await fs.writeFile(sourcePath, 'test');
|
|
|
|
|
|
|
|
await fs.ensureSymlink(sourcePath, path.join(workspacePath, 'storage.db'));
|
|
|
|
|
2023-06-13 05:01:43 +03:00
|
|
|
expect(await getWorkspaceMeta(workspaceId)).toEqual({
|
2023-05-31 06:09:18 +03:00
|
|
|
id: workspaceId,
|
|
|
|
mainDBPath: path.join(workspacePath, 'storage.db'),
|
|
|
|
secondaryDBPath: sourcePath,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(
|
|
|
|
await fs.pathExists(path.join(workspacePath, 'meta.json'))
|
|
|
|
).toBeTruthy();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('storeWorkspaceMeta', async () => {
|
2023-10-19 06:14:30 +03:00
|
|
|
const { storeWorkspaceMeta } = await import(
|
|
|
|
'@affine/electron/helper/workspace/handlers'
|
|
|
|
);
|
2023-05-31 06:09:18 +03:00
|
|
|
const workspaceId = v4();
|
2023-06-13 05:01:43 +03:00
|
|
|
const workspacePath = path.join(appDataPath, 'workspaces', workspaceId);
|
2023-05-31 06:09:18 +03:00
|
|
|
await fs.ensureDir(workspacePath);
|
|
|
|
const meta = {
|
|
|
|
id: workspaceId,
|
|
|
|
mainDBPath: path.join(workspacePath, 'storage.db'),
|
|
|
|
};
|
2023-06-13 05:01:43 +03:00
|
|
|
await storeWorkspaceMeta(workspaceId, meta);
|
2023-05-31 06:09:18 +03:00
|
|
|
expect(await fs.readJSON(path.join(workspacePath, 'meta.json'))).toEqual(
|
|
|
|
meta
|
|
|
|
);
|
2023-06-13 05:01:43 +03:00
|
|
|
await storeWorkspaceMeta(workspaceId, {
|
2023-05-31 06:09:18 +03:00
|
|
|
secondaryDBPath: path.join(tmpDir, 'test.db'),
|
|
|
|
});
|
|
|
|
expect(await fs.readJSON(path.join(workspacePath, 'meta.json'))).toEqual({
|
|
|
|
...meta,
|
|
|
|
secondaryDBPath: path.join(tmpDir, 'test.db'),
|
|
|
|
});
|
|
|
|
});
|