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:
fengmk2
2025-05-22 04:25:20 +00:00
parent 573c2faf76
commit c525ca24fd

View File

@@ -1,67 +1,54 @@
import { randomUUID } from 'node:crypto';
import { mock } from 'node:test';
import { User, Workspace } from '@prisma/client';
import ava, { TestFn } from 'ava';
import test from 'ava';
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 { WorkspaceBlobStorage } from '../../storage/wrappers/blob';
import { DocReader, PgWorkspaceDocStorageAdapter } from '..';
import { DocReader, DocStorageModule, PgWorkspaceDocStorageAdapter } from '..';
import { DatabaseDocReader } from '../reader';
const test = ava as TestFn<{
models: Models;
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 module = await createModule({
imports: [DocStorageModule],
});
const docReader = module.get(DocReader);
const adapter = module.get(PgWorkspaceDocStorageAdapter);
const models = module.get(Models);
let user: 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);
});
const user = await module.create(Mockers.User);
test.afterEach.always(() => {
mock.reset();
});
test.after.always(async t => {
await t.context.app.close();
test.after.always(async () => {
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 => {
const { docReader } = t.context;
const workspace = await module.create(Mockers.Workspace, {
owner: user,
});
const docId = randomUUID();
const doc = await docReader.getDoc(workspace.id, docId);
t.is(doc, null);
});
test('should return doc when found', async t => {
const { docReader } = t.context;
t.true(docReader instanceof DatabaseDocReader);
const workspace = await module.create(Mockers.Workspace, {
owner: user,
});
const docId = randomUUID();
const timestamp = Date.now();
await t.context.models.doc.createUpdates([
await models.doc.createUpdates([
{
spaceId: workspace.id,
docId,
@@ -79,7 +66,10 @@ test('should return doc when found', 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 timestamp = Date.now();
let updates: Buffer[] = [];
@@ -94,7 +84,7 @@ test('should return doc diff', async t => {
text.insert(5, ' ');
text.insert(11, '!');
await t.context.models.doc.createUpdates(
await models.doc.createUpdates(
updates.map((update, index) => ({
spaceId: workspace.id,
docId,
@@ -108,6 +98,7 @@ test('should return doc diff', async t => {
const doc2 = new YDoc();
const diff = await docReader.getDocDiff(workspace.id, docId);
t.truthy(diff);
t.truthy(diff!.missing);
t.truthy(diff!.state);
@@ -116,6 +107,7 @@ test('should return doc diff', async t => {
// nothing changed
const diff2 = await docReader.getDocDiff(workspace.id, docId, diff!.state);
t.truthy(diff2);
t.truthy(diff2!.missing);
t.deepEqual(diff2!.missing, new Uint8Array([0, 0]));
@@ -125,7 +117,7 @@ test('should return doc diff', async t => {
// add new content on doc1
text.insert(12, '@');
await t.context.models.doc.createUpdates(
await models.doc.createUpdates(
updates.map((update, index) => ({
spaceId: workspace.id,
docId,
@@ -136,6 +128,7 @@ test('should return doc diff', async t => {
);
const diff3 = await docReader.getDocDiff(workspace.id, docId, diff2!.state);
t.truthy(diff3);
t.truthy(diff3!.missing);
t.truthy(diff3!.state);
@@ -144,8 +137,11 @@ test('should return doc diff', async t => {
});
test('should get doc content', async t => {
const workspace = await module.create(Mockers.Workspace, {
owner: user,
});
const docId = randomUUID();
const { docReader } = t.context;
const doc = new YDoc();
const text = doc.getText('content');
@@ -159,16 +155,19 @@ test('should get doc content', async t => {
text.insert(5, 'world');
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);
// TODO(@fengmk2): should create a test ydoc with blocks
t.is(docContent, null);
});
test('should get workspace content with default avatar', async t => {
const { docReader } = t.context;
t.true(docReader instanceof DatabaseDocReader);
const workspace = await module.create(Mockers.Workspace, {
owner: user,
name: '',
});
const doc = new YDoc();
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, ' ');
await t.context.adapter.pushDocUpdates(
workspace.id,
workspace.id,
updates,
user.id
);
await adapter.pushDocUpdates(workspace.id, workspace.id, updates, user.id);
mock.method(docReader, 'parseWorkspaceContent', () => ({
name: 'Test Workspace',
@@ -195,6 +189,7 @@ test('should get workspace content with default avatar', async t => {
}));
const workspaceContent = await docReader.getWorkspaceContent(workspace.id);
t.truthy(workspaceContent);
t.deepEqual(workspaceContent, {
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 => {
const { docReader, blobStorage } = t.context;
t.true(docReader instanceof DatabaseDocReader);
const workspace = await module.create(Mockers.Workspace, {
owner: user,
name: '',
});
const doc = new YDoc();
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, ' ');
await t.context.adapter.pushDocUpdates(
workspace.id,
workspace.id,
updates,
user.id
);
await adapter.pushDocUpdates(workspace.id, workspace.id, updates, user.id);
const avatarKey = randomUUID();
await blobStorage.put(
workspace.id,
avatarKey,
Buffer.from('mock avatar image data here')
);
mock.method(docReader, 'parseWorkspaceContent', () => ({
name: 'Test Workspace',
@@ -240,6 +227,7 @@ test('should get workspace content with custom avatar', async t => {
}));
const workspaceContent = await docReader.getWorkspaceContent(workspace.id);
t.truthy(workspaceContent);
t.deepEqual(workspaceContent, {
id: workspace.id,
@@ -247,17 +235,20 @@ test('should get workspace content with custom avatar', async t => {
avatarKey,
avatarUrl: `http://localhost:3010/api/workspaces/${workspace.id}/blobs/${avatarKey}`,
});
// 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.is(workspace2!.name, 'Test Workspace');
t.is(workspace2!.avatarKey, avatarKey);
// read from database
await t.context.models.workspace.update(workspace.id, {
await models.workspace.update(workspace.id, {
name: 'Test Workspace 2',
});
const workspaceContent2 = await docReader.getWorkspaceContent(workspace.id);
t.truthy(workspaceContent2);
t.deepEqual(workspaceContent2, {
id: workspace.id,