mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-25 20:12:13 +03:00
test: remove deprecated test (#2880)
This commit is contained in:
parent
78b74d5b15
commit
26ac56e163
@ -1,484 +0,0 @@
|
||||
/**
|
||||
* @vitest-environment happy-dom
|
||||
*/
|
||||
import 'fake-indexeddb/auto';
|
||||
|
||||
import { readFile } from 'node:fs/promises';
|
||||
|
||||
import { MessageCode } from '@affine/env/constant';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import {
|
||||
createWorkspaceResponseSchema,
|
||||
usageResponseSchema,
|
||||
} from '@affine/env/workspace/legacy-cloud';
|
||||
import user1 from '@affine-test/fixtures/built-in-user1.json';
|
||||
import user2 from '@affine-test/fixtures/built-in-user2.json';
|
||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import type { Page, PageMeta } from '@blocksuite/store';
|
||||
import { Workspace } from '@blocksuite/store';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { WebSocket } from 'ws';
|
||||
import { applyUpdate } from 'yjs';
|
||||
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
import { createUserApis, createWorkspaceApis, RequestError } from '../api';
|
||||
import { createStatusApis } from '../api/status';
|
||||
import { KeckProvider } from '../keck';
|
||||
import {
|
||||
createAffineAuth,
|
||||
getLoginStorage,
|
||||
loginResponseSchema,
|
||||
setLoginStorage,
|
||||
} from '../login';
|
||||
|
||||
declare module '@blocksuite/store' {
|
||||
interface PageMeta {
|
||||
isPublic?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
globalThis.WebSocket = WebSocket;
|
||||
|
||||
let workspaceApis: ReturnType<typeof createWorkspaceApis>;
|
||||
let userApis: ReturnType<typeof createUserApis>;
|
||||
let affineAuth: ReturnType<typeof createAffineAuth>;
|
||||
let statusApis: ReturnType<typeof createStatusApis>;
|
||||
|
||||
async function initPage(page: Page) {
|
||||
await page.waitForLoaded();
|
||||
// Add page block and surface block at root level
|
||||
const pageBlockId = page.addBlock('affine:page', {
|
||||
title: new page.Text(''),
|
||||
});
|
||||
page.addBlock('affine:surface', {}, pageBlockId);
|
||||
const frameId = page.addBlock('affine:note', {}, pageBlockId);
|
||||
page.addBlock('affine:paragraph', {}, frameId);
|
||||
page.resetHistory();
|
||||
return {
|
||||
pageBlockId,
|
||||
frameId,
|
||||
} as const;
|
||||
}
|
||||
|
||||
const mockUser = {
|
||||
name: faker.name.fullName(),
|
||||
email: faker.internet.email(),
|
||||
password: faker.internet.password(),
|
||||
};
|
||||
|
||||
async function waitForConnected(provider: KeckProvider) {
|
||||
return new Promise<void>(resolve => {
|
||||
provider.once('status', ({ status }: any) => {
|
||||
expect(status).toBe('connected');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
// create a new user for each test, so that each test can be run independently
|
||||
mockUser.name = faker.name.fullName();
|
||||
mockUser.email = faker.internet.email();
|
||||
mockUser.password = faker.internet.password();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
affineAuth = createAffineAuth('http://127.0.0.1:3000/');
|
||||
userApis = createUserApis('http://127.0.0.1:3000/');
|
||||
workspaceApis = createWorkspaceApis('http://127.0.0.1:3000/');
|
||||
statusApis = createStatusApis('http://127.0.0.1:3000/');
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
expect(await statusApis.healthz(), 'health check').toBe(true);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
const data = await fetch('http://127.0.0.1:3000/api/user/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: 'DebugCreateUser',
|
||||
...mockUser,
|
||||
}),
|
||||
}).then(r => r.json());
|
||||
setLoginStorage(data);
|
||||
loginResponseSchema.parse(data);
|
||||
});
|
||||
|
||||
declare global {
|
||||
interface DocumentEventMap {
|
||||
'affine-error': CustomEvent<{
|
||||
code: (typeof MessageCode)[keyof typeof MessageCode];
|
||||
}>;
|
||||
}
|
||||
}
|
||||
|
||||
async function createWorkspace(
|
||||
workspaceApi: typeof workspaceApis,
|
||||
callback?: (workspace: Workspace) => Promise<void>
|
||||
): Promise<string> {
|
||||
const workspace = createEmptyBlockSuiteWorkspace(
|
||||
faker.datatype.uuid(),
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
if (callback) {
|
||||
await callback(workspace);
|
||||
}
|
||||
const binary = Workspace.Y.encodeStateAsUpdate(workspace.doc);
|
||||
const data = await workspaceApi.createWorkspace(binary);
|
||||
createWorkspaceResponseSchema.parse(data);
|
||||
return data.id;
|
||||
}
|
||||
|
||||
describe('api', () => {
|
||||
test('built-in mock user', async () => {
|
||||
const data = await fetch('http://127.0.0.1:3000/api/user/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: 'DebugLoginUser',
|
||||
email: user1.email,
|
||||
password: user1.password,
|
||||
}),
|
||||
}).then(r => r.json());
|
||||
loginResponseSchema.parse(data);
|
||||
const data2 = await fetch('http://127.0.0.1:3000/api/user/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: 'DebugLoginUser',
|
||||
email: user2.email,
|
||||
password: user2.password,
|
||||
}),
|
||||
}).then(r => r.json());
|
||||
loginResponseSchema.parse(data2);
|
||||
});
|
||||
|
||||
test('failed', async () => {
|
||||
workspaceApis = createWorkspaceApis('http://127.0.0.1:10086/404/');
|
||||
const listener = vi.fn(
|
||||
(
|
||||
e: CustomEvent<{
|
||||
code: (typeof MessageCode)[keyof typeof MessageCode];
|
||||
}>
|
||||
) => {
|
||||
expect(e.detail.code).toBe(MessageCode.loadListFailed);
|
||||
}
|
||||
);
|
||||
|
||||
document.addEventListener('affine-error', listener);
|
||||
expect(listener).toBeCalledTimes(0);
|
||||
await workspaceApis.getWorkspaces().catch(e => {
|
||||
expect(e).toBeInstanceOf(RequestError);
|
||||
});
|
||||
expect(listener).toBeCalledTimes(1);
|
||||
document.removeEventListener('affine-error', listener);
|
||||
});
|
||||
|
||||
test('no permission', async () => {
|
||||
await workspaceApis.downloadWorkspace('not-exist').catch(e => {
|
||||
expect(e).toBeInstanceOf(RequestError);
|
||||
expect(e.code).toBe(MessageCode.noPermission);
|
||||
});
|
||||
});
|
||||
|
||||
test('blob too large', async () => {
|
||||
await workspaceApis
|
||||
.uploadBlob('test', new ArrayBuffer(1024 * 1024 * 1024 + 1), 'image/png')
|
||||
.catch(e => {
|
||||
expect(e).toBeInstanceOf(RequestError);
|
||||
expect(e.code).toBe(MessageCode.blobTooLarge);
|
||||
});
|
||||
});
|
||||
|
||||
test('refresh token', async () => {
|
||||
const storage = getLoginStorage();
|
||||
assertExists(storage);
|
||||
loginResponseSchema.parse(await affineAuth.refreshToken(storage));
|
||||
});
|
||||
|
||||
test(
|
||||
'create workspace',
|
||||
async () => {
|
||||
const id = await createWorkspace(workspaceApis);
|
||||
expect(id).toBeTypeOf('string');
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
}
|
||||
);
|
||||
|
||||
test(
|
||||
'delete workspace',
|
||||
async () => {
|
||||
const id = await createWorkspace(workspaceApis);
|
||||
const response = await workspaceApis.deleteWorkspace({
|
||||
id,
|
||||
});
|
||||
expect(response).toBe(true);
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
}
|
||||
);
|
||||
|
||||
test('get workspaces', async () => {
|
||||
const id = await createWorkspace(workspaceApis);
|
||||
const response = await workspaceApis.getWorkspaces();
|
||||
expect(response).toBeInstanceOf(Array);
|
||||
expect(response.length).toBe(1);
|
||||
expect(response[0].id).toBe(id);
|
||||
});
|
||||
|
||||
test(
|
||||
'blob',
|
||||
async () => {
|
||||
const workspace = new Workspace({
|
||||
id: 'test',
|
||||
});
|
||||
const path = require.resolve('@affine-test/fixtures/smile.png');
|
||||
const imageBuffer = await readFile(path);
|
||||
const binary = Workspace.Y.encodeStateAsUpdate(workspace.doc);
|
||||
const data = await workspaceApis.createWorkspace(binary);
|
||||
createWorkspaceResponseSchema.parse(data);
|
||||
const workspaceId = data.id;
|
||||
const blobId = await workspaceApis.uploadBlob(
|
||||
workspaceId,
|
||||
imageBuffer,
|
||||
'image/png'
|
||||
);
|
||||
expect(blobId).toBeTypeOf('string');
|
||||
const arrayBuffer = await workspaceApis.getBlob(workspaceId, blobId);
|
||||
expect(arrayBuffer).toBeInstanceOf(ArrayBuffer);
|
||||
expect(arrayBuffer.byteLength).toEqual(imageBuffer.byteLength);
|
||||
expect(Buffer.from(arrayBuffer)).toEqual(imageBuffer);
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
}
|
||||
);
|
||||
|
||||
test(
|
||||
'workspace binary',
|
||||
async () => {
|
||||
const id = await createWorkspace(workspaceApis);
|
||||
await workspaceApis.updateWorkspace({
|
||||
id,
|
||||
public: true,
|
||||
});
|
||||
const binary = await workspaceApis.downloadWorkspace(id, false);
|
||||
const publicBinary = await workspaceApis.downloadWorkspace(id, true);
|
||||
expect(binary).toBeInstanceOf(ArrayBuffer);
|
||||
expect(publicBinary).toBeInstanceOf(ArrayBuffer);
|
||||
expect(binary).toEqual(publicBinary);
|
||||
expect(binary.byteLength).toEqual(publicBinary.byteLength);
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
}
|
||||
);
|
||||
|
||||
test.fails('workspace page binary', async () => {
|
||||
const id = await createWorkspace(workspaceApis, async workspace => {
|
||||
{
|
||||
const page = workspace.createPage('page0');
|
||||
const { frameId } = await initPage(page);
|
||||
page.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new page.Text('This is page0'),
|
||||
},
|
||||
frameId
|
||||
);
|
||||
}
|
||||
{
|
||||
const page = workspace.createPage('page1');
|
||||
const { frameId } = await initPage(page);
|
||||
page.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new page.Text('This is page1'),
|
||||
},
|
||||
frameId
|
||||
);
|
||||
}
|
||||
});
|
||||
await workspaceApis.updateWorkspace({
|
||||
id,
|
||||
public: true,
|
||||
});
|
||||
let originalPage0Json: any = null;
|
||||
let originalPage1Json: any = null;
|
||||
{
|
||||
const binary = await workspaceApis.downloadWorkspace(id, false);
|
||||
const workspace = new Workspace({
|
||||
id: faker.datatype.uuid(),
|
||||
})
|
||||
.register(AffineSchemas)
|
||||
.register(__unstableSchemas);
|
||||
applyUpdate(workspace.doc, new Uint8Array(binary));
|
||||
const page0 = workspace.getPage('page0') as Page;
|
||||
const page1 = workspace.getPage('page1') as Page;
|
||||
expect(page0).not.toBeUndefined();
|
||||
expect(page1).not.toBeUndefined();
|
||||
originalPage0Json = workspace.doc.share.get(page0.prefixedId)?.toJSON();
|
||||
originalPage1Json = workspace.doc.share.get(page1.prefixedId)?.toJSON();
|
||||
}
|
||||
{
|
||||
const workspace = new Workspace({
|
||||
id: faker.datatype.uuid(),
|
||||
})
|
||||
.register(AffineSchemas)
|
||||
.register(__unstableSchemas);
|
||||
const binary = await workspaceApis.downloadPublicWorkspacePage(
|
||||
id,
|
||||
'page0'
|
||||
);
|
||||
applyUpdate(workspace.doc, new Uint8Array(binary));
|
||||
const page0 = workspace.getPage('page0') as Page;
|
||||
expect(page0).not.toBeNull();
|
||||
expect(workspace.getPage('page1')).toBeNull();
|
||||
expect(workspace.doc.share.get(page0.prefixedId)?.toJSON()).toEqual(
|
||||
originalPage0Json
|
||||
);
|
||||
}
|
||||
{
|
||||
const workspace = new Workspace({
|
||||
id: faker.datatype.uuid(),
|
||||
})
|
||||
.register(AffineSchemas)
|
||||
.register(__unstableSchemas);
|
||||
const binary = await workspaceApis.downloadPublicWorkspacePage(
|
||||
id,
|
||||
'page1'
|
||||
);
|
||||
applyUpdate(workspace.doc, new Uint8Array(binary));
|
||||
const page1 = workspace.getPage('page1') as Page;
|
||||
expect(workspace.getPage('page0')).toBeNull();
|
||||
expect(page1).not.toBeNull();
|
||||
expect(workspace.doc.share.get(page1.prefixedId)?.toJSON()).toEqual(
|
||||
originalPage1Json
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test(
|
||||
'usage',
|
||||
async () => {
|
||||
const usageResponse = await userApis.getUsage();
|
||||
usageResponseSchema.parse(usageResponse);
|
||||
const id = await createWorkspace(workspaceApis);
|
||||
const path = require.resolve('@affine-test/fixtures/smile.png');
|
||||
const imageBuffer = await readFile(path);
|
||||
const blobId = await workspaceApis.uploadBlob(
|
||||
id,
|
||||
imageBuffer,
|
||||
'image/png'
|
||||
);
|
||||
const buffer = await workspaceApis.getBlob(id, blobId);
|
||||
expect(buffer.byteLength).toEqual(imageBuffer.byteLength);
|
||||
const newUsageResponse = await userApis.getUsage();
|
||||
usageResponseSchema.parse(newUsageResponse);
|
||||
expect(usageResponse.blob_usage.usage).not.equals(
|
||||
newUsageResponse.blob_usage.usage
|
||||
);
|
||||
expect(newUsageResponse.blob_usage.usage).equals(96);
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
}
|
||||
);
|
||||
|
||||
test.fails(
|
||||
'public page',
|
||||
async () => {
|
||||
const id = await createWorkspace(workspaceApis, async workspace => {
|
||||
const page = workspace.createPage('page0');
|
||||
const { frameId } = await initPage(page);
|
||||
page.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new page.Text('This is page0'),
|
||||
},
|
||||
frameId
|
||||
);
|
||||
});
|
||||
const binary = await workspaceApis.downloadWorkspace(id, false);
|
||||
const workspace = createEmptyBlockSuiteWorkspace(
|
||||
id,
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
Workspace.Y.applyUpdate(workspace.doc, new Uint8Array(binary));
|
||||
const workspace2 = createEmptyBlockSuiteWorkspace(
|
||||
id,
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
{
|
||||
const wsUrl = `ws://127.0.0.1:3000/api/sync/`;
|
||||
const provider = new KeckProvider(wsUrl, workspace.id, workspace.doc, {
|
||||
params: { token: getLoginStorage()?.token },
|
||||
awareness: workspace.awarenessStore.awareness,
|
||||
connect: false,
|
||||
});
|
||||
const provider2 = new KeckProvider(
|
||||
wsUrl,
|
||||
workspace2.id,
|
||||
workspace2.doc,
|
||||
{
|
||||
params: { token: getLoginStorage()?.token },
|
||||
awareness: workspace2.awarenessStore.awareness,
|
||||
connect: false,
|
||||
}
|
||||
);
|
||||
|
||||
provider.connect();
|
||||
provider2.connect();
|
||||
|
||||
await Promise.all([
|
||||
await waitForConnected(provider),
|
||||
await waitForConnected(provider2),
|
||||
]);
|
||||
const pageId = 'page0';
|
||||
const page = workspace.getPage(pageId) as Page;
|
||||
expect(page).not.toBeNull();
|
||||
expect(page).not.toBeUndefined();
|
||||
workspace.setPageMeta(pageId, {
|
||||
isPublic: true,
|
||||
});
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
const page2 = workspace2.getPage(pageId) as Page;
|
||||
expect(page2).not.toBeNull();
|
||||
const meta = workspace2.meta.getPageMeta(pageId) as PageMeta;
|
||||
expect(meta.isPublic).toBe(true);
|
||||
|
||||
const binary = await workspaceApis.downloadPublicWorkspacePage(
|
||||
id,
|
||||
pageId
|
||||
);
|
||||
const publicWorkspace = createEmptyBlockSuiteWorkspace(
|
||||
id,
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
Workspace.Y.applyUpdate(publicWorkspace.doc, new Uint8Array(binary));
|
||||
const publicPage = publicWorkspace.getPage(pageId) as Page;
|
||||
expect(publicPage).not.toBeNull();
|
||||
}
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
retry: 3,
|
||||
}
|
||||
);
|
||||
});
|
@ -1,20 +0,0 @@
|
||||
import { getDefaultStore } from 'jotai';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { currentAffineUserAtom } from '../atom';
|
||||
|
||||
describe('atom', () => {
|
||||
test('currentAffineUserAtom', () => {
|
||||
const store = getDefaultStore();
|
||||
const mock = {
|
||||
created_at: 0,
|
||||
exp: 0,
|
||||
email: '',
|
||||
id: '',
|
||||
name: '',
|
||||
avatar_url: '',
|
||||
};
|
||||
store.set(currentAffineUserAtom, mock);
|
||||
expect(store.get(currentAffineUserAtom)).toEqual(mock);
|
||||
});
|
||||
});
|
@ -1,45 +0,0 @@
|
||||
/**
|
||||
* @vitest-environment happy-dom
|
||||
*/
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import type { AccessTokenMessage } from '../login';
|
||||
import {
|
||||
getLoginStorage,
|
||||
isExpired,
|
||||
setLoginStorage,
|
||||
STORAGE_KEY,
|
||||
} from '../login';
|
||||
|
||||
describe('storage', () => {
|
||||
test('should work', () => {
|
||||
setLoginStorage({
|
||||
token: '1',
|
||||
refresh: '2',
|
||||
});
|
||||
const data = localStorage.getItem(STORAGE_KEY);
|
||||
expect(data).toBe('{"token":"1","refresh":"2"}');
|
||||
const login = getLoginStorage();
|
||||
expect(login).toEqual({
|
||||
token: '1',
|
||||
refresh: '2',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('utils', () => {
|
||||
test('isExpired', async () => {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
expect(isExpired({ exp: now + 1 } as AccessTokenMessage, 0)).toBeFalsy();
|
||||
const promise = new Promise<void>(resolve => {
|
||||
setTimeout(() => {
|
||||
expect(
|
||||
isExpired({ exp: now + 1 } as AccessTokenMessage, 0)
|
||||
).toBeTruthy();
|
||||
resolve();
|
||||
}, 2000);
|
||||
});
|
||||
expect(isExpired({ exp: now - 1 } as AccessTokenMessage, 0)).toBeTruthy();
|
||||
await promise;
|
||||
});
|
||||
});
|
@ -1,184 +0,0 @@
|
||||
/**
|
||||
* @vitest-environment happy-dom
|
||||
*/
|
||||
import 'fake-indexeddb/auto';
|
||||
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import type { Workspace } from '@affine/env/workspace/legacy-cloud';
|
||||
import { PermissionType } from '@affine/env/workspace/legacy-cloud';
|
||||
import user1 from '@affine-test/fixtures/built-in-user1.json';
|
||||
import user2 from '@affine-test/fixtures/built-in-user2.json';
|
||||
import type { ParagraphBlockModel } from '@blocksuite/blocks/models';
|
||||
import type { Page, Text } from '@blocksuite/store';
|
||||
import { uuidv4, Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { WebSocket } from 'ws';
|
||||
|
||||
import type { LoginResponse } from '../../affine/login';
|
||||
import { loginResponseSchema } from '../../affine/login';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
import { createWorkspaceApis } from '../api';
|
||||
import { KeckProvider } from '../keck';
|
||||
|
||||
declare module '@blocksuite/store' {
|
||||
interface PageMeta {
|
||||
foo: string;
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
globalThis.WebSocket = WebSocket;
|
||||
|
||||
const currentTokenRef = {
|
||||
current: null as LoginResponse | null,
|
||||
};
|
||||
|
||||
vi.stubGlobal('localStorage', {
|
||||
getItem: () => JSON.stringify(currentTokenRef.current),
|
||||
setItem: () => null,
|
||||
});
|
||||
|
||||
let workspaceApis: ReturnType<typeof createWorkspaceApis>;
|
||||
|
||||
let user1Token: LoginResponse;
|
||||
let user2Token: LoginResponse;
|
||||
|
||||
beforeEach(() => {
|
||||
workspaceApis = createWorkspaceApis('http://127.0.0.1:3000/');
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
const data = await fetch('http://127.0.0.1:3000/api/user/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: 'DebugLoginUser',
|
||||
email: user1.email,
|
||||
password: user1.password,
|
||||
}),
|
||||
}).then(r => r.json());
|
||||
loginResponseSchema.parse(data);
|
||||
user1Token = data;
|
||||
const data2 = await fetch('http://127.0.0.1:3000/api/user/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: 'DebugLoginUser',
|
||||
email: user2.email,
|
||||
password: user2.password,
|
||||
}),
|
||||
}).then(r => r.json());
|
||||
loginResponseSchema.parse(data2);
|
||||
user2Token = data2;
|
||||
});
|
||||
|
||||
const wsUrl = `ws://127.0.0.1:3000/api/sync/`;
|
||||
|
||||
describe('ydoc sync', () => {
|
||||
test(
|
||||
'page',
|
||||
async () => {
|
||||
currentTokenRef.current = user1Token;
|
||||
const list = await workspaceApis.getWorkspaces();
|
||||
const root = list.find(
|
||||
workspace => workspace.permission === PermissionType.Owner
|
||||
) as Workspace;
|
||||
expect(root).toBeDefined();
|
||||
const binary = await workspaceApis.downloadWorkspace(root.id);
|
||||
const workspace1 = createEmptyBlockSuiteWorkspace(
|
||||
root.id,
|
||||
WorkspaceFlavour.AFFINE,
|
||||
{
|
||||
workspaceApis,
|
||||
}
|
||||
);
|
||||
const workspace2 = createEmptyBlockSuiteWorkspace(
|
||||
root.id,
|
||||
WorkspaceFlavour.AFFINE,
|
||||
{
|
||||
workspaceApis,
|
||||
}
|
||||
);
|
||||
BlockSuiteWorkspace.Y.applyUpdate(workspace1.doc, new Uint8Array(binary));
|
||||
BlockSuiteWorkspace.Y.applyUpdate(workspace2.doc, new Uint8Array(binary));
|
||||
const provider1 = new KeckProvider(wsUrl, workspace1.id, workspace1.doc, {
|
||||
params: { token: user1Token.token },
|
||||
awareness: workspace1.awarenessStore.awareness,
|
||||
// @ts-expect-error
|
||||
disableBc: true,
|
||||
connect: false,
|
||||
});
|
||||
|
||||
const provider2 = new KeckProvider(wsUrl, workspace2.id, workspace2.doc, {
|
||||
params: { token: user2Token.token },
|
||||
awareness: workspace2.awarenessStore.awareness,
|
||||
// @ts-expect-error
|
||||
disableBc: true,
|
||||
connect: false,
|
||||
});
|
||||
|
||||
provider1.connect();
|
||||
provider2.connect();
|
||||
|
||||
function waitForConnected(provider: KeckProvider) {
|
||||
return new Promise<void>(resolve => {
|
||||
provider.once('status', ({ status }: any) => {
|
||||
expect(status).toBe('connected');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
waitForConnected(provider1),
|
||||
waitForConnected(provider2),
|
||||
]);
|
||||
|
||||
const pageId = uuidv4();
|
||||
const page1 = workspace1.createPage({ id: pageId });
|
||||
await page1.waitForLoaded();
|
||||
const pageBlockId = page1.addBlock('affine:page', {
|
||||
title: new page1.Text(''),
|
||||
});
|
||||
page1.addBlock('affine:surface', {}, pageBlockId);
|
||||
const frameId = page1.addBlock('affine:note', {}, pageBlockId);
|
||||
const paragraphId = page1.addBlock('affine:paragraph', {}, frameId);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
expect(workspace2.getPage(pageId)).toBeDefined();
|
||||
expect(workspace2.doc.getMap(`space:${pageId}`).toJSON()).toEqual(
|
||||
workspace1.doc.getMap(`space:${pageId}`).toJSON()
|
||||
);
|
||||
const page2 = workspace2.getPage(pageId) as Page;
|
||||
await page2.waitForLoaded();
|
||||
page1.updateBlock(
|
||||
page1.getBlockById(paragraphId) as ParagraphBlockModel,
|
||||
{
|
||||
text: new page1.Text('hello world'),
|
||||
}
|
||||
);
|
||||
workspace1.meta.setPageMeta(pageId, {
|
||||
foo: 'bar',
|
||||
});
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
const pageMeta = workspace2.meta.getPageMeta(pageId);
|
||||
expect(pageMeta).toBeDefined();
|
||||
expect(pageMeta?.foo).toBe('bar');
|
||||
const paragraph2 = page2.getBlockById(paragraphId) as ParagraphBlockModel;
|
||||
const text = paragraph2.text as Text;
|
||||
expect(text.toString()).toEqual(
|
||||
page1.getBlockById(paragraphId)?.text?.toString()
|
||||
);
|
||||
|
||||
provider1.disconnect();
|
||||
provider2.disconnect();
|
||||
},
|
||||
{
|
||||
timeout: 30000,
|
||||
retry: 3,
|
||||
}
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue
Block a user