test: add local provider test

This commit is contained in:
alt0 2023-01-09 00:48:54 +08:00
parent 055b63382b
commit e1e1d0c964
24 changed files with 565 additions and 1506 deletions

View File

@ -1,19 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
projects: ['<rootDir>/packages/app'],
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
// '^.+\\.[tj]sx?$' to process js/ts with `ts-jest`
// '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest`
'^.+\\.tsx?$': [
'ts-jest',
{
useESM: true,
},
],
},
};

View File

@ -14,7 +14,8 @@
"test": "playwright test",
"test:dc": "pnpm --filter @affine/datacenter test",
"test:e2e:codegen": "npx playwright codegen http://localhost:8080",
"test:unit": "jest",
"test:unit": "vitest run",
"test:unit:watch": "vitest",
"postinstall": "husky install",
"notify": "node --experimental-modules scripts/notify.mjs",
"check:ci": "pnpm lint & pnpm test"
@ -24,24 +25,23 @@
"*.{ts,tsx,js,jsx}": "npx eslint --cache --fix"
},
"devDependencies": {
"@jest/globals": "^29.3.1",
"@changesets/cli": "^2.26.0",
"@playwright/test": "^1.29.1",
"@typescript-eslint/eslint-plugin": "^5.47.0",
"@typescript-eslint/parser": "^5.47.0",
"@types/eslint": "^8.4.10",
"@types/node": "^18.11.17",
"@typescript-eslint/eslint-plugin": "^5.47.0",
"@typescript-eslint/parser": "^5.47.0",
"eslint": "^8.30.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"fake-indexeddb": "4.0.1",
"got": "^12.5.3",
"jest": "^29.3.1",
"prettier": "^2.7.1",
"ts-jest": "^29.0.3",
"typescript": "^4.9.3",
"lint-staged": "^13.1.0",
"husky": "^8.0.2",
"@changesets/cli": "^2.26.0"
"lint-staged": "^13.1.0",
"prettier": "^2.7.1",
"typescript": "^4.9.3",
"vitest": "^0.26.3"
},
"eslintConfig": {
"root": true,

View File

@ -1,4 +1,4 @@
import { describe, test, expect } from '@jest/globals';
import { describe, test, expect } from 'vitest';
import { printer } from './../printer';
const chalk = require('chalk');
describe('printer', () => {

View File

@ -1,4 +1,4 @@
import { describe, test, expect } from '@jest/globals';
import { describe, test, expect } from 'vitest';
import { isMobile } from '../get-is-mobile';
describe('get-is-mobile', () => {

View File

@ -28,8 +28,18 @@ export class DataCenter {
static async init(debug: boolean): Promise<DataCenter> {
const dc = new DataCenter(debug);
// TODO: switch different provider
dc.registerProvider(new LocalProvider());
dc.registerProvider(new AffineProvider());
dc.registerProvider(
new LocalProvider({
logger: dc._logger,
workspaces: dc._workspaces.createScope(),
})
);
dc.registerProvider(
new AffineProvider({
logger: dc._logger,
workspaces: dc._workspaces.createScope(),
})
);
return dc;
}
@ -42,11 +52,7 @@ export class DataCenter {
if (!this._defaultProvider) {
this._defaultProvider = provider;
}
// inject data in provider
provider.inject({
logger: this._logger,
workspaces: this._workspaces.createScope(),
});
provider.init();
this.providerMap.set(provider.id, provider);
}

View File

@ -11,6 +11,7 @@ import {
updateWorkspace,
} from './apis/workspace';
import { BaseProvider } from '../base';
import type { ProviderConstructorParams } from '../base';
import { User, Workspace as WS, WorkspaceMeta } from '../../types';
import { Workspace } from '@blocksuite/store';
import { BlockSchema } from '@blocksuite/blocks/models';
@ -32,8 +33,8 @@ export class AffineProvider extends BaseProvider {
private _wsMap: Map<string, WebsocketProvider> = new Map();
private _idbMap: Map<string, IndexedDBProvider> = new Map();
constructor() {
super();
constructor(params: ProviderConstructorParams) {
super(params);
}
override async init() {

View File

@ -2,20 +2,23 @@ import { BlobStorage, Workspace } from '@blocksuite/store';
import { Logger, User, Workspace as WS, WorkspaceMeta } from '../types';
import type { WorkspacesScope } from '../workspaces';
const defaultLogger = () => {
return;
};
export interface ProviderConstructorParams {
logger?: Logger;
workspaces: WorkspacesScope;
}
export class BaseProvider {
public readonly id: string = 'base';
protected _workspaces!: WorkspacesScope;
protected _logger!: Logger;
protected _blobs!: BlobStorage;
public inject({
logger,
workspaces,
}: {
logger: Logger;
workspaces: WorkspacesScope;
}) {
this._logger = logger;
public constructor({ logger, workspaces }: ProviderConstructorParams) {
this._logger = (logger || defaultLogger) as Logger;
this._workspaces = workspaces;
}

View File

@ -0,0 +1,49 @@
import { describe, test, expect } from 'vitest';
import { Workspaces } from '../../workspaces';
import { LocalProvider } from './local';
import 'fake-indexeddb/auto';
describe('local provider', () => {
const workspaces = new Workspaces();
const provider = new LocalProvider({
workspaces: workspaces.createScope(),
});
const workspaceName = 'workspace-test';
let workspaceId: string | undefined;
test('create workspace', async () => {
const w = await provider.createWorkspace({
name: workspaceName,
avatar: 'avatar-url-test',
});
workspaceId = w?.room;
expect(workspaces.workspaces.length).toEqual(1);
expect(workspaces.workspaces[0].name).toEqual(workspaceName);
});
test('workspace list cache', async () => {
const workspaces1 = new Workspaces();
const provider1 = new LocalProvider({
workspaces: workspaces1.createScope(),
});
await provider1.loadWorkspaces();
expect(workspaces1.workspaces.length).toEqual(1);
expect(workspaces1.workspaces[0].name).toEqual(workspaceName);
expect(workspaces1.workspaces[0].id).toEqual(workspaceId);
});
test('update workspace', async () => {
await provider.updateWorkspaceMeta(workspaceId!, {
name: '1111',
});
expect(workspaces.workspaces[0].name).toEqual('1111');
});
test('delete workspace', async () => {
expect(workspaces.workspaces.length).toEqual(1);
await provider.deleteWorkspace(workspaces.workspaces[0].id);
expect(workspaces.workspaces.length).toEqual(0);
});
});

View File

@ -1,4 +1,5 @@
import { BaseProvider } from '../base';
import type { ProviderConstructorParams } from '../base';
import { varStorage as storage } from 'lib0/storage';
import { Workspace as WS, WorkspaceMeta } from '../../types';
import { Workspace, uuidv4 } from '@blocksuite/store';
@ -12,8 +13,8 @@ export class LocalProvider extends BaseProvider {
public id = 'local';
private _idbMap: Map<string, IndexedDBProvider> = new Map();
constructor() {
super();
constructor(params: ProviderConstructorParams) {
super(params);
this.loadWorkspaces();
}

View File

@ -1,4 +1,4 @@
import { getLogger } from 'src';
import { getLogger } from '../logger';
export type Workspace = {
name: string;

View File

@ -20,7 +20,7 @@ export class Workspaces extends Observable<'change'> {
private _workspacesMap = new Map<string, Workspace>();
get workspaces(): Workspace[] {
return Object.values(this._workspacesMap);
return Array.from(this._workspacesMap.values());
}
find(workspaceId: string) {

View File

@ -1,15 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Auth', () => {
test('sign in', async () => {});
test('sign out', async () => {});
test('isLogin', async () => {});
test('getUserInfo', async () => {});
});

View File

@ -1,15 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Collaborate', () => {
test('collaborate editor content', async () => {});
test('collaborate workspace name', async () => {});
test('collaborate workspace avatar', async () => {});
test('collaborate workspace list', async () => {});
});

View File

@ -1,17 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Permission', () => {
test('get the public of workspace', async () => {});
test('make workspace public', async () => {});
test('make workspace private', async () => {});
test('un-login user open the public workspace ', async () => {});
test('un-login user open the private workspace ', async () => {});
});

View File

@ -1,15 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Share', () => {
test('add(invite) member by email', async () => {});
test('accept invite member link', async () => {});
test('members list', async () => {});
test('delete member', async () => {});
});

View File

@ -1,23 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Sync', () => {
test('get cloud the sync flag of workspace', async () => {});
test('enable [cloud sync feature]', async () => {});
test('close [cloud sync feature]', async () => {});
test('editor cloud storage', async () => {});
test('cloud sync is in-progress', async () => {});
test('cloud sync is completed', async () => {});
test('cloud sync is error', async () => {});
test('cloud storage is right', async () => {});
});

View File

@ -1,13 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Attachment', () => {
test('upload blob', async () => {});
test('get blob', async () => {});
test('remove blob', async () => {});
});

View File

@ -1,11 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Import/Export Workspace', () => {
test('import workspace', async () => {});
test('export workspace', async () => {});
});

View File

@ -1,47 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Init Data Center', () => {
test('init', async () => {
// const dataCenter = await getDataCenter();
// expect(dataCenter).toBeTruthy();
// await dataCenter.clear();
// const workspace = await dataCenter.load('test1');
// expect(workspace).toBeTruthy();
});
test('init singleton', async () => {
// // data center is singleton
// const [dc1, dc2] = await Promise.all([getDataCenter(), getDataCenter()]);
// expect(dc1).toEqual(dc2);
// // load same workspace will get same instance
// const [ws1, ws2] = await Promise.all([
// dc1.load('test1'),
// dc2.load('test1'),
// ]);
// expect(ws1).toEqual(ws2);
});
test('should init error with unknown provider', async () => {
// const dc = await getDataCenter();
// await dc.clear();
// // load workspace with unknown provider will throw error
// test.fail();
// await dc.load('test2', { providerId: 'not exist provider' });
});
test.skip('init affine provider', async () => {
// const dataCenter = await getDataCenter();
// await dataCenter.clear();
// // load workspace with affine provider
// // TODO: set constant token for testing
// const workspace = await dataCenter.load('6', {
// providerId: 'affine',
// config: { token: 'YOUR_TOKEN' },
// });
// expect(workspace).toBeTruthy();
});
});

View File

@ -1,23 +0,0 @@
import assert from 'assert';
import { test, expect } from '@playwright/test';
import { getDataCenter, waitOnce } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Search', () => {
test('search result', async () => {
// const dc = await getDataCenter();
// const workspace = await dc.load('test');
// assert(workspace);
// workspace.createPage('test');
// await waitOnce(workspace.signals.pageAdded);
// const page = workspace.getPage('test');
// assert(page);
// const text = new page.Text(page, 'hello world');
// const blockId = page.addBlock({ flavour: 'affine:paragraph', text });
// expect(workspace.search('hello')).toStrictEqual(
// new Map([[blockId, 'test']])
// );
});
});

View File

@ -1,64 +0,0 @@
import { test, expect } from '@playwright/test';
import { getDataCenter } from '../utils.js';
import 'fake-indexeddb/auto';
test.describe('Workspace', () => {
test('create', async () => {});
test('load', async () => {});
test('get workspace name', async () => {});
test('set workspace name', async () => {});
test('get workspace avatar', async () => {});
test('set workspace avatar', async () => {});
test('list', async () => {
// const dataCenter = await getDataCenter();
// await dataCenter.clear();
// await Promise.all([
// dataCenter.load('test3'),
// dataCenter.load('test4'),
// dataCenter.load('test5'),
// dataCenter.load('test6'),
// ]);
// expect(await dataCenter.list()).toStrictEqual({
// test3: { local: true },
// test4: { local: true },
// test5: { local: true },
// test6: { local: true },
// });
// await dataCenter.reload('test3', { providerId: 'affine' });
// expect(await dataCenter.list()).toStrictEqual({
// test3: { affine: true },
// test4: { local: true },
// test5: { local: true },
// test6: { local: true },
// });
});
test('destroy', async () => {
// const dataCenter = await getDataCenter();
// await dataCenter.clear();
// // return new workspace if origin workspace is destroyed
// const ws1 = await dataCenter.load('test7');
// await dataCenter.destroy('test7');
// const ws2 = await dataCenter.load('test7');
// expect(ws1 !== ws2).toBeTruthy();
// // return new workspace if workspace is reload
// const ws3 = await dataCenter.load('test8');
// const ws4 = await dataCenter.reload('test8', { providerId: 'affine' });
// expect(ws3 !== ws4).toBeTruthy();
});
test('remove', async () => {
// const dataCenter = await getDataCenter();
// await dataCenter.clear();
// // remove workspace will remove workspace data
// await Promise.all([dataCenter.load('test9'), dataCenter.load('test10')]);
// await dataCenter.delete('test9');
// expect(await dataCenter.list()).toStrictEqual({ test10: { local: true } });
});
});

View File

@ -1,9 +0,0 @@
import { Signal } from '@blocksuite/store';
export const getDataCenter = async () => {
const dataCenter = await import('../src/index.js');
return await dataCenter.getDataCenter(false);
};
export const waitOnce = <T>(signal: Signal<T>) =>
new Promise<T>(resolve => signal.once(val => resolve(val)));

1667
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

7
vitest.config.ts Normal file
View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
include: ['packages/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
});