From c525ca24fd4c07ae5b91a6e8db54e4c985ff6769 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Thu, 22 May 2025 04:25:20 +0000 Subject: [PATCH] test(server): use mocker (#12435) ## 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. --- .../__tests__/reader-from-database.spec.ts | 121 ++++++++---------- 1 file changed, 56 insertions(+), 65 deletions(-) diff --git a/packages/backend/server/src/core/doc/__tests__/reader-from-database.spec.ts b/packages/backend/server/src/core/doc/__tests__/reader-from-database.spec.ts index 1554d93130..eb4de37ef6 100644 --- a/packages/backend/server/src/core/doc/__tests__/reader-from-database.spec.ts +++ b/packages/backend/server/src/core/doc/__tests__/reader-from-database.spec.ts @@ -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,