mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 02:42:25 +08:00
test(server): use mocker (#12435)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Tests** - Refactored test setup for the database-backed document reader to improve modularity and clarity. - Simplified database initialization and cleanup in tests. - Updated mocks and assertions to align with the new test structure. - Maintained existing test coverage and logic. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,67 +1,54 @@
|
|||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { mock } from 'node:test';
|
import { mock } from 'node:test';
|
||||||
|
|
||||||
import { User, Workspace } from '@prisma/client';
|
import test from 'ava';
|
||||||
import ava, { TestFn } from 'ava';
|
|
||||||
import { applyUpdate, Doc as YDoc } from 'yjs';
|
import { applyUpdate, Doc as YDoc } from 'yjs';
|
||||||
|
|
||||||
import { createTestingApp, type TestingApp } from '../../../__tests__/utils';
|
import { createModule } from '../../../__tests__/create-module';
|
||||||
|
import { Mockers } from '../../../__tests__/mocks';
|
||||||
import { Models } from '../../../models';
|
import { Models } from '../../../models';
|
||||||
import { WorkspaceBlobStorage } from '../../storage/wrappers/blob';
|
import { DocReader, DocStorageModule, PgWorkspaceDocStorageAdapter } from '..';
|
||||||
import { DocReader, PgWorkspaceDocStorageAdapter } from '..';
|
|
||||||
import { DatabaseDocReader } from '../reader';
|
import { DatabaseDocReader } from '../reader';
|
||||||
|
|
||||||
const test = ava as TestFn<{
|
const module = await createModule({
|
||||||
models: Models;
|
imports: [DocStorageModule],
|
||||||
app: TestingApp;
|
|
||||||
docReader: DocReader;
|
|
||||||
adapter: PgWorkspaceDocStorageAdapter;
|
|
||||||
blobStorage: WorkspaceBlobStorage;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
test.before(async t => {
|
|
||||||
const app = await createTestingApp();
|
|
||||||
|
|
||||||
t.context.models = app.get(Models);
|
|
||||||
t.context.docReader = app.get(DocReader);
|
|
||||||
t.context.adapter = app.get(PgWorkspaceDocStorageAdapter);
|
|
||||||
t.context.blobStorage = app.get(WorkspaceBlobStorage);
|
|
||||||
t.context.app = app;
|
|
||||||
});
|
});
|
||||||
|
const docReader = module.get(DocReader);
|
||||||
|
const adapter = module.get(PgWorkspaceDocStorageAdapter);
|
||||||
|
const models = module.get(Models);
|
||||||
|
|
||||||
let user: User;
|
const user = await module.create(Mockers.User);
|
||||||
let workspace: Workspace;
|
|
||||||
|
|
||||||
test.beforeEach(async t => {
|
|
||||||
await t.context.app.initTestingDB();
|
|
||||||
user = await t.context.models.user.create({
|
|
||||||
email: 'test@affine.pro',
|
|
||||||
});
|
|
||||||
workspace = await t.context.models.workspace.create(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
test.afterEach.always(() => {
|
test.afterEach.always(() => {
|
||||||
mock.reset();
|
mock.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
test.after.always(async t => {
|
test.after.always(async () => {
|
||||||
await t.context.app.close();
|
await module.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should be database reader', async t => {
|
||||||
|
t.true(docReader instanceof DatabaseDocReader);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return null when doc not found', async t => {
|
test('should return null when doc not found', async t => {
|
||||||
const { docReader } = t.context;
|
const workspace = await module.create(Mockers.Workspace, {
|
||||||
|
owner: user,
|
||||||
|
});
|
||||||
|
|
||||||
const docId = randomUUID();
|
const docId = randomUUID();
|
||||||
const doc = await docReader.getDoc(workspace.id, docId);
|
const doc = await docReader.getDoc(workspace.id, docId);
|
||||||
t.is(doc, null);
|
t.is(doc, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return doc when found', async t => {
|
test('should return doc when found', async t => {
|
||||||
const { docReader } = t.context;
|
const workspace = await module.create(Mockers.Workspace, {
|
||||||
t.true(docReader instanceof DatabaseDocReader);
|
owner: user,
|
||||||
|
});
|
||||||
|
|
||||||
const docId = randomUUID();
|
const docId = randomUUID();
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
await t.context.models.doc.createUpdates([
|
await models.doc.createUpdates([
|
||||||
{
|
{
|
||||||
spaceId: workspace.id,
|
spaceId: workspace.id,
|
||||||
docId,
|
docId,
|
||||||
@@ -79,7 +66,10 @@ test('should return doc when found', async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should return doc diff', async t => {
|
test('should return doc diff', async t => {
|
||||||
const { docReader } = t.context;
|
const workspace = await module.create(Mockers.Workspace, {
|
||||||
|
owner: user,
|
||||||
|
});
|
||||||
|
|
||||||
const docId = randomUUID();
|
const docId = randomUUID();
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
let updates: Buffer[] = [];
|
let updates: Buffer[] = [];
|
||||||
@@ -94,7 +84,7 @@ test('should return doc diff', async t => {
|
|||||||
text.insert(5, ' ');
|
text.insert(5, ' ');
|
||||||
text.insert(11, '!');
|
text.insert(11, '!');
|
||||||
|
|
||||||
await t.context.models.doc.createUpdates(
|
await models.doc.createUpdates(
|
||||||
updates.map((update, index) => ({
|
updates.map((update, index) => ({
|
||||||
spaceId: workspace.id,
|
spaceId: workspace.id,
|
||||||
docId,
|
docId,
|
||||||
@@ -108,6 +98,7 @@ test('should return doc diff', async t => {
|
|||||||
|
|
||||||
const doc2 = new YDoc();
|
const doc2 = new YDoc();
|
||||||
const diff = await docReader.getDocDiff(workspace.id, docId);
|
const diff = await docReader.getDocDiff(workspace.id, docId);
|
||||||
|
|
||||||
t.truthy(diff);
|
t.truthy(diff);
|
||||||
t.truthy(diff!.missing);
|
t.truthy(diff!.missing);
|
||||||
t.truthy(diff!.state);
|
t.truthy(diff!.state);
|
||||||
@@ -116,6 +107,7 @@ test('should return doc diff', async t => {
|
|||||||
|
|
||||||
// nothing changed
|
// nothing changed
|
||||||
const diff2 = await docReader.getDocDiff(workspace.id, docId, diff!.state);
|
const diff2 = await docReader.getDocDiff(workspace.id, docId, diff!.state);
|
||||||
|
|
||||||
t.truthy(diff2);
|
t.truthy(diff2);
|
||||||
t.truthy(diff2!.missing);
|
t.truthy(diff2!.missing);
|
||||||
t.deepEqual(diff2!.missing, new Uint8Array([0, 0]));
|
t.deepEqual(diff2!.missing, new Uint8Array([0, 0]));
|
||||||
@@ -125,7 +117,7 @@ test('should return doc diff', async t => {
|
|||||||
|
|
||||||
// add new content on doc1
|
// add new content on doc1
|
||||||
text.insert(12, '@');
|
text.insert(12, '@');
|
||||||
await t.context.models.doc.createUpdates(
|
await models.doc.createUpdates(
|
||||||
updates.map((update, index) => ({
|
updates.map((update, index) => ({
|
||||||
spaceId: workspace.id,
|
spaceId: workspace.id,
|
||||||
docId,
|
docId,
|
||||||
@@ -136,6 +128,7 @@ test('should return doc diff', async t => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const diff3 = await docReader.getDocDiff(workspace.id, docId, diff2!.state);
|
const diff3 = await docReader.getDocDiff(workspace.id, docId, diff2!.state);
|
||||||
|
|
||||||
t.truthy(diff3);
|
t.truthy(diff3);
|
||||||
t.truthy(diff3!.missing);
|
t.truthy(diff3!.missing);
|
||||||
t.truthy(diff3!.state);
|
t.truthy(diff3!.state);
|
||||||
@@ -144,8 +137,11 @@ test('should return doc diff', async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should get doc content', async t => {
|
test('should get doc content', async t => {
|
||||||
|
const workspace = await module.create(Mockers.Workspace, {
|
||||||
|
owner: user,
|
||||||
|
});
|
||||||
|
|
||||||
const docId = randomUUID();
|
const docId = randomUUID();
|
||||||
const { docReader } = t.context;
|
|
||||||
|
|
||||||
const doc = new YDoc();
|
const doc = new YDoc();
|
||||||
const text = doc.getText('content');
|
const text = doc.getText('content');
|
||||||
@@ -159,16 +155,19 @@ test('should get doc content', async t => {
|
|||||||
text.insert(5, 'world');
|
text.insert(5, 'world');
|
||||||
text.insert(5, ' ');
|
text.insert(5, ' ');
|
||||||
|
|
||||||
await t.context.adapter.pushDocUpdates(workspace.id, docId, updates, user.id);
|
await adapter.pushDocUpdates(workspace.id, docId, updates, user.id);
|
||||||
|
|
||||||
const docContent = await docReader.getDocContent(workspace.id, docId);
|
const docContent = await docReader.getDocContent(workspace.id, docId);
|
||||||
|
|
||||||
// TODO(@fengmk2): should create a test ydoc with blocks
|
// TODO(@fengmk2): should create a test ydoc with blocks
|
||||||
t.is(docContent, null);
|
t.is(docContent, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should get workspace content with default avatar', async t => {
|
test('should get workspace content with default avatar', async t => {
|
||||||
const { docReader } = t.context;
|
const workspace = await module.create(Mockers.Workspace, {
|
||||||
t.true(docReader instanceof DatabaseDocReader);
|
owner: user,
|
||||||
|
name: '',
|
||||||
|
});
|
||||||
|
|
||||||
const doc = new YDoc();
|
const doc = new YDoc();
|
||||||
const text = doc.getText('content');
|
const text = doc.getText('content');
|
||||||
@@ -182,12 +181,7 @@ test('should get workspace content with default avatar', async t => {
|
|||||||
text.insert(5, 'world');
|
text.insert(5, 'world');
|
||||||
text.insert(5, ' ');
|
text.insert(5, ' ');
|
||||||
|
|
||||||
await t.context.adapter.pushDocUpdates(
|
await adapter.pushDocUpdates(workspace.id, workspace.id, updates, user.id);
|
||||||
workspace.id,
|
|
||||||
workspace.id,
|
|
||||||
updates,
|
|
||||||
user.id
|
|
||||||
);
|
|
||||||
|
|
||||||
mock.method(docReader, 'parseWorkspaceContent', () => ({
|
mock.method(docReader, 'parseWorkspaceContent', () => ({
|
||||||
name: 'Test Workspace',
|
name: 'Test Workspace',
|
||||||
@@ -195,6 +189,7 @@ test('should get workspace content with default avatar', async t => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const workspaceContent = await docReader.getWorkspaceContent(workspace.id);
|
const workspaceContent = await docReader.getWorkspaceContent(workspace.id);
|
||||||
|
|
||||||
t.truthy(workspaceContent);
|
t.truthy(workspaceContent);
|
||||||
t.deepEqual(workspaceContent, {
|
t.deepEqual(workspaceContent, {
|
||||||
id: workspace.id,
|
id: workspace.id,
|
||||||
@@ -205,8 +200,10 @@ test('should get workspace content with default avatar', async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should get workspace content with custom avatar', async t => {
|
test('should get workspace content with custom avatar', async t => {
|
||||||
const { docReader, blobStorage } = t.context;
|
const workspace = await module.create(Mockers.Workspace, {
|
||||||
t.true(docReader instanceof DatabaseDocReader);
|
owner: user,
|
||||||
|
name: '',
|
||||||
|
});
|
||||||
|
|
||||||
const doc = new YDoc();
|
const doc = new YDoc();
|
||||||
const text = doc.getText('content');
|
const text = doc.getText('content');
|
||||||
@@ -220,19 +217,9 @@ test('should get workspace content with custom avatar', async t => {
|
|||||||
text.insert(5, 'world');
|
text.insert(5, 'world');
|
||||||
text.insert(5, ' ');
|
text.insert(5, ' ');
|
||||||
|
|
||||||
await t.context.adapter.pushDocUpdates(
|
await adapter.pushDocUpdates(workspace.id, workspace.id, updates, user.id);
|
||||||
workspace.id,
|
|
||||||
workspace.id,
|
|
||||||
updates,
|
|
||||||
user.id
|
|
||||||
);
|
|
||||||
|
|
||||||
const avatarKey = randomUUID();
|
const avatarKey = randomUUID();
|
||||||
await blobStorage.put(
|
|
||||||
workspace.id,
|
|
||||||
avatarKey,
|
|
||||||
Buffer.from('mock avatar image data here')
|
|
||||||
);
|
|
||||||
|
|
||||||
mock.method(docReader, 'parseWorkspaceContent', () => ({
|
mock.method(docReader, 'parseWorkspaceContent', () => ({
|
||||||
name: 'Test Workspace',
|
name: 'Test Workspace',
|
||||||
@@ -240,6 +227,7 @@ test('should get workspace content with custom avatar', async t => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const workspaceContent = await docReader.getWorkspaceContent(workspace.id);
|
const workspaceContent = await docReader.getWorkspaceContent(workspace.id);
|
||||||
|
|
||||||
t.truthy(workspaceContent);
|
t.truthy(workspaceContent);
|
||||||
t.deepEqual(workspaceContent, {
|
t.deepEqual(workspaceContent, {
|
||||||
id: workspace.id,
|
id: workspace.id,
|
||||||
@@ -247,17 +235,20 @@ test('should get workspace content with custom avatar', async t => {
|
|||||||
avatarKey,
|
avatarKey,
|
||||||
avatarUrl: `http://localhost:3010/api/workspaces/${workspace.id}/blobs/${avatarKey}`,
|
avatarUrl: `http://localhost:3010/api/workspaces/${workspace.id}/blobs/${avatarKey}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
// should save to database
|
// should save to database
|
||||||
const workspace2 = await t.context.models.workspace.get(workspace.id);
|
const workspace2 = await models.workspace.get(workspace.id);
|
||||||
|
|
||||||
t.truthy(workspace2);
|
t.truthy(workspace2);
|
||||||
t.is(workspace2!.name, 'Test Workspace');
|
t.is(workspace2!.name, 'Test Workspace');
|
||||||
t.is(workspace2!.avatarKey, avatarKey);
|
t.is(workspace2!.avatarKey, avatarKey);
|
||||||
|
|
||||||
// read from database
|
// read from database
|
||||||
await t.context.models.workspace.update(workspace.id, {
|
await models.workspace.update(workspace.id, {
|
||||||
name: 'Test Workspace 2',
|
name: 'Test Workspace 2',
|
||||||
});
|
});
|
||||||
const workspaceContent2 = await docReader.getWorkspaceContent(workspace.id);
|
const workspaceContent2 = await docReader.getWorkspaceContent(workspace.id);
|
||||||
|
|
||||||
t.truthy(workspaceContent2);
|
t.truthy(workspaceContent2);
|
||||||
t.deepEqual(workspaceContent2, {
|
t.deepEqual(workspaceContent2, {
|
||||||
id: workspace.id,
|
id: workspace.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user