test(server): make server testing utils (#5544)

This commit is contained in:
liuyi
2024-01-11 06:40:55 +00:00
parent 9253e522aa
commit 12fdb18a80
20 changed files with 238 additions and 451 deletions

View File

@@ -3,17 +3,16 @@ import { randomUUID } from 'node:crypto';
import { Transformer } from '@napi-rs/image';
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { hashSync } from '@node-rs/argon2';
import { type User } from '@prisma/client';
import ava, { type TestFn } from 'ava';
import type { Express } from 'express';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import request from 'supertest';
import { AppModule } from '../src/app';
import { FeatureManagementService } from '../src/modules/features';
import { PrismaService } from '../src/prisma/service';
import { createTestingApp } from './utils';
const gql = '/graphql';
@@ -49,25 +48,18 @@ class FakePrisma {
}
test.beforeEach(async t => {
const module = await Test.createTestingModule({
const { app } = await createTestingApp({
imports: [AppModule],
})
.overrideProvider(PrismaService)
.useClass(FakePrisma)
.overrideProvider(FeatureManagementService)
.useValue({ canEarlyAccess: () => true })
.compile();
t.context.app = module.createNestApplication({
cors: true,
bodyParser: true,
tapModule(builder) {
builder
.overrideProvider(PrismaService)
.useClass(FakePrisma)
.overrideProvider(FeatureManagementService)
.useValue({ canEarlyAccess: () => true });
},
});
t.context.app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await t.context.app.init();
t.context.app = app;
});
test.afterEach.always(async t => {

View File

@@ -3,19 +3,13 @@ import {
getLatestMailMessage,
} from '@affine-test/kit/utils/cloud';
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import ava, { type TestFn } from 'ava';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import { AppModule } from '../src/app';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { MailService } from '../src/modules/auth/mailer';
import { AuthService } from '../src/modules/auth/service';
import {
changeEmail,
createWorkspace,
initFeatureConfigs,
createTestingApp,
sendChangeEmail,
sendVerifyChangeEmail,
signUp,
@@ -23,44 +17,20 @@ import {
const test = ava as TestFn<{
app: INestApplication;
client: PrismaClient;
auth: AuthService;
mail: MailService;
}>;
test.beforeEach(async t => {
const client = new PrismaClient();
t.context.client = client;
await client.$connect();
await client.user.deleteMany({});
await client.snapshot.deleteMany({});
await client.update.deleteMany({});
await client.workspace.deleteMany({});
await client.$disconnect();
const module = await Test.createTestingModule({
imports: [AppModule],
providers: [RevertCommand, RunCommand],
}).compile();
const app = module.createNestApplication();
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await app.init();
const auth = module.get(AuthService);
const mail = module.get(MailService);
const { app } = await createTestingApp();
const auth = app.get(AuthService);
const mail = app.get(MailService);
t.context.app = app;
t.context.auth = auth;
t.context.mail = mail;
// init features
await initFeatureConfigs(module);
});
test.afterEach(async t => {
test.afterEach.always(async t => {
await t.context.app.close();
});
@@ -73,8 +43,6 @@ test('change email', async t => {
const u1 = await signUp(app, 'u1', u1Email, '1');
await createWorkspace(app, u1.token.token);
const primitiveMailCount = await getCurrentMailMessageCount();
await sendChangeEmail(app, u1.token.token, u1Email, 'affine.pro');

View File

@@ -1,34 +1,19 @@
/// <reference types="../src/global.d.ts" />
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import { TestingModule } from '@nestjs/testing';
import test from 'ava';
import { CacheModule } from '../src/cache';
import { ConfigModule } from '../src/config';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { GqlModule } from '../src/graphql.module';
import { AuthModule } from '../src/modules/auth';
import { AuthResolver } from '../src/modules/auth/resolver';
import { AuthService } from '../src/modules/auth/service';
import { PrismaModule } from '../src/prisma';
import { mintChallengeResponse, verifyChallengeResponse } from '../src/storage';
import { RateLimiterModule } from '../src/throttler';
import { initFeatureConfigs } from './utils';
import { createTestingModule } from './utils';
let authService: AuthService;
let authResolver: AuthResolver;
let module: TestingModule;
// cleanup database before each test
test.beforeEach(async () => {
const client = new PrismaClient();
await client.$connect();
await client.user.deleteMany({});
await client.$disconnect();
});
test.beforeEach(async () => {
module = await Test.createTestingModule({
module = await createTestingModule({
imports: [
ConfigModule.forRoot({
auth: {
@@ -39,20 +24,11 @@ test.beforeEach(async () => {
host: 'example.org',
https: true,
}),
PrismaModule,
CacheModule,
GqlModule,
AuthModule,
RateLimiterModule,
RevertCommand,
RunCommand,
],
}).compile();
});
authService = module.get(AuthService);
authResolver = module.get(AuthResolver);
// init features
await initFeatureConfigs(module);
});
test.afterEach.always(async () => {

View File

@@ -1,9 +1,7 @@
import { mock } from 'node:test';
import type { INestApplication } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { TestingModule } from '@nestjs/testing';
import test from 'ava';
import { register } from 'prom-client';
import * as Sinon from 'sinon';
import {
applyUpdate,
@@ -12,37 +10,19 @@ import {
encodeStateAsUpdate,
} from 'yjs';
import { CacheModule } from '../src/cache';
import { Config, ConfigModule } from '../src/config';
import {
collectMigrations,
RevertCommand,
RunCommand,
} from '../src/data/commands/run';
import { EventModule } from '../src/event';
import { Config } from '../src/config';
import { DocManager, DocModule } from '../src/modules/doc';
import { QuotaModule } from '../src/modules/quota';
import { StorageModule } from '../src/modules/storage';
import { PrismaModule, PrismaService } from '../src/prisma';
import { flushDB } from './utils';
import { PrismaService } from '../src/prisma';
import { createTestingModule, initTestingDB } from './utils';
const createModule = () => {
return Test.createTestingModule({
imports: [
PrismaModule,
CacheModule,
EventModule,
QuotaModule,
StorageModule,
ConfigModule.forRoot(),
DocModule,
RevertCommand,
RunCommand,
],
}).compile();
return createTestingModule({
imports: [QuotaModule, StorageModule, DocModule],
});
};
let app: INestApplication;
let m: TestingModule;
let timer: Sinon.SinonFakeTimers;
@@ -51,44 +31,34 @@ test.beforeEach(async () => {
timer = Sinon.useFakeTimers({
toFake: ['setInterval'],
});
await flushDB();
m = await createModule();
app = m.createNestApplication();
app.enableShutdownHooks();
await app.init();
// init features
const run = m.get(RunCommand);
const revert = m.get(RevertCommand);
const migrations = await collectMigrations();
await Promise.allSettled(migrations.map(m => revert.run([m.name])));
await run.run();
await m.init();
await initTestingDB(m.get(PrismaService));
});
test.afterEach.always(async () => {
await app.close();
await m.close();
timer.restore();
});
test('should setup update poll interval', async t => {
register.clear();
const m = await createModule();
const manager = m.get(DocManager);
const fake = mock.method(manager, 'setup');
await m.createNestApplication().init();
await m.init();
t.is(fake.mock.callCount(), 1);
// @ts-expect-error private member
t.truthy(manager.job);
m.close();
});
test('should be able to stop poll', async t => {
const manager = m.get(DocManager);
const fake = mock.method(manager, 'destroy');
await app.close();
await m.close();
t.is(fake.mock.callCount(), 1);
// @ts-expect-error private member

View File

@@ -1,14 +1,9 @@
/// <reference types="../src/global.d.ts" />
import { Injectable } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import { INestApplication, Injectable } from '@nestjs/common';
import ava, { type TestFn } from 'ava';
import { CacheModule } from '../src/cache';
import { ConfigModule } from '../src/config';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { AuthModule } from '../src/modules/auth';
import { AuthService } from '../src/modules/auth/service';
import {
FeatureManagementService,
@@ -19,9 +14,8 @@ import {
import { UserType } from '../src/modules/users/types';
import { WorkspaceResolver } from '../src/modules/workspaces/resolvers';
import { Permission } from '../src/modules/workspaces/types';
import { PrismaModule, PrismaService } from '../src/prisma';
import { RateLimiterModule } from '../src/throttler';
import { initFeatureConfigs } from './utils';
import { PrismaService } from '../src/prisma';
import { createTestingApp } from './utils';
@Injectable()
class WorkspaceResolverMock {
@@ -53,20 +47,11 @@ const test = ava as TestFn<{
feature: FeatureService;
workspace: WorkspaceResolver;
management: FeatureManagementService;
app: TestingModule;
app: INestApplication;
}>;
// cleanup database before each test
test.beforeEach(async () => {
const client = new PrismaClient();
await client.$connect();
await client.user.deleteMany({});
await client.workspace.deleteMany({});
await client.$disconnect();
});
test.beforeEach(async t => {
const module = await Test.createTestingModule({
const { app } = await createTestingApp({
imports: [
ConfigModule.forRoot({
auth: {
@@ -80,28 +65,21 @@ test.beforeEach(async t => {
earlyAccessPreview: true,
},
}),
PrismaModule,
CacheModule,
AuthModule,
FeatureModule,
RateLimiterModule,
RevertCommand,
RunCommand,
],
providers: [WorkspaceResolver],
})
.overrideProvider(WorkspaceResolver)
.useClass(WorkspaceResolverMock)
.compile();
tapModule: module => {
module
.overrideProvider(WorkspaceResolver)
.useClass(WorkspaceResolverMock);
},
});
t.context.app = module;
t.context.auth = module.get(AuthService);
t.context.feature = module.get(FeatureService);
t.context.workspace = module.get(WorkspaceResolver);
t.context.management = module.get(FeatureManagementService);
// init features
await initFeatureConfigs(module);
t.context.app = app;
t.context.auth = app.get(AuthService);
t.context.feature = app.get(FeatureService);
t.context.workspace = app.get(WorkspaceResolver);
t.context.management = app.get(FeatureManagementService);
});
test.afterEach.always(async t => {

View File

@@ -1,40 +1,26 @@
import { INestApplication } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import { Test, TestingModule } from '@nestjs/testing';
import { TestingModule } from '@nestjs/testing';
import type { Snapshot } from '@prisma/client';
import test from 'ava';
import * as Sinon from 'sinon';
import { ConfigModule } from '../src/config';
import { EventModule, type EventPayload } from '../src/event';
import { type EventPayload } from '../src/event';
import { DocHistoryManager } from '../src/modules/doc';
import { QuotaModule } from '../src/modules/quota';
import { StorageModule } from '../src/modules/storage';
import { PrismaModule, PrismaService } from '../src/prisma';
import { flushDB } from './utils';
import { PrismaService } from '../src/prisma';
import { createTestingModule } from './utils';
let app: INestApplication;
let m: TestingModule;
let manager: DocHistoryManager;
let db: PrismaService;
// cleanup database before each test
test.beforeEach(async () => {
await flushDB();
m = await Test.createTestingModule({
imports: [
PrismaModule,
QuotaModule,
EventModule,
StorageModule,
ScheduleModule.forRoot(),
ConfigModule.forRoot(),
],
m = await createTestingModule({
imports: [StorageModule, QuotaModule],
providers: [DocHistoryManager],
}).compile();
});
app = m.createNestApplication();
await app.init();
manager = m.get(DocHistoryManager);
Sinon.stub(manager, 'getExpiredDateFromNow').resolves(
new Date(Date.now() + 1000)
@@ -42,8 +28,7 @@ test.beforeEach(async () => {
db = m.get(PrismaService);
});
test.afterEach(async () => {
await app.close();
test.afterEach.always(async () => {
await m.close();
Sinon.restore();
});

View File

@@ -6,19 +6,13 @@ import {
getCurrentMailMessageCount,
getLatestMailMessage,
} from '@affine-test/kit/utils/cloud';
import { Test, TestingModule } from '@nestjs/testing';
import { TestingModule } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import ava, { type TestFn } from 'ava';
import { CacheModule } from '../src/cache';
import { ConfigModule } from '../src/config';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { GqlModule } from '../src/graphql.module';
import { AuthModule } from '../src/modules/auth';
import { AuthService } from '../src/modules/auth/service';
import { PrismaModule } from '../src/prisma';
import { RateLimiterModule } from '../src/throttler';
import { initFeatureConfigs } from './utils';
import { createTestingModule } from './utils';
const test = ava as TestFn<{
auth: AuthService;
@@ -34,7 +28,7 @@ test.beforeEach(async () => {
});
test.beforeEach(async t => {
t.context.module = await Test.createTestingModule({
t.context.module = await createTestingModule({
imports: [
ConfigModule.forRoot({
auth: {
@@ -43,18 +37,9 @@ test.beforeEach(async t => {
leeway: 1,
},
}),
PrismaModule,
GqlModule,
AuthModule,
CacheModule,
RateLimiterModule,
],
providers: [RevertCommand, RunCommand],
}).compile();
});
t.context.auth = t.context.module.get(AuthService);
// init features
await initFeatureConfigs(t.context.module);
});
test.afterEach.always(async t => {

View File

@@ -1,18 +1,22 @@
import { randomUUID } from 'node:crypto';
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { hashSync } from '@node-rs/argon2';
import { type User } from '@prisma/client';
import ava, { type TestFn } from 'ava';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import { AppModule } from '../src/app';
import { MailService } from '../src/modules/auth/mailer';
import { FeatureKind, FeatureManagementService } from '../src/modules/features';
import { Quotas } from '../src/modules/quota';
import { PrismaService } from '../src/prisma';
import { createWorkspace, getInviteInfo, inviteUser, signUp } from './utils';
import {
createTestingApp,
createWorkspace,
getInviteInfo,
inviteUser,
signUp,
} from './utils';
const FakePrisma = {
fakeUser: {
@@ -123,26 +127,20 @@ const test = ava as TestFn<{
}>;
test.beforeEach(async t => {
const module = await Test.createTestingModule({
const { module, app } = await createTestingApp({
imports: [AppModule],
})
.overrideProvider(PrismaService)
.useValue(FakePrisma)
.overrideProvider(FeatureManagementService)
.useValue({
hasWorkspaceFeature() {
return false;
},
})
.compile();
const app = module.createNestApplication();
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await app.init();
tapModule: module => {
module
.overrideProvider(PrismaService)
.useValue(FakePrisma)
.overrideProvider(FeatureManagementService)
.useValue({
hasWorkspaceFeature() {
return false;
},
});
},
});
const mail = module.get(MailService);
t.context.app = app;

View File

@@ -1,14 +1,8 @@
/// <reference types="../src/global.d.ts" />
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import { TestingModule } from '@nestjs/testing';
import ava, { type TestFn } from 'ava';
import { CacheModule } from '../src/cache';
import { ConfigModule } from '../src/config';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { EventModule } from '../src/event';
import { AuthModule } from '../src/modules/auth';
import { AuthService } from '../src/modules/auth/service';
import {
QuotaManagementService,
@@ -18,64 +12,32 @@ import {
QuotaType,
} from '../src/modules/quota';
import { StorageModule } from '../src/modules/storage';
import { PrismaModule } from '../src/prisma';
import { RateLimiterModule } from '../src/throttler';
import { initFeatureConfigs } from './utils';
import { createTestingModule } from './utils';
const test = ava as TestFn<{
auth: AuthService;
quota: QuotaService;
storageQuota: QuotaManagementService;
app: TestingModule;
module: TestingModule;
}>;
// cleanup database before each test
test.beforeEach(async () => {
const client = new PrismaClient();
await client.$connect();
await client.user.deleteMany({});
await client.$disconnect();
});
test.beforeEach(async t => {
const module = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
auth: {
accessTokenExpiresIn: 1,
refreshTokenExpiresIn: 1,
leeway: 1,
},
host: 'example.org',
https: true,
}),
PrismaModule,
CacheModule,
AuthModule,
EventModule,
QuotaModule,
StorageModule,
RateLimiterModule,
RevertCommand,
RunCommand,
],
}).compile();
const module = await createTestingModule({
imports: [StorageModule, QuotaModule],
});
const quota = module.get(QuotaService);
const storageQuota = module.get(QuotaManagementService);
const auth = module.get(AuthService);
t.context.app = module;
t.context.module = module;
t.context.quota = quota;
t.context.storageQuota = storageQuota;
t.context.auth = auth;
// init features
await initFeatureConfigs(module);
});
test.afterEach.always(async t => {
await t.context.app.close();
await t.context.module.close();
});
test('should be able to set quota', async t => {

View File

@@ -1,19 +1,20 @@
/// <reference types="../src/global.d.ts" />
import { Test, TestingModule } from '@nestjs/testing';
import { TestingModule } from '@nestjs/testing';
import ava, { type TestFn } from 'ava';
import { CacheModule } from '../src/cache';
import { ConfigModule } from '../src/config';
import { SessionModule, SessionService } from '../src/session';
import { createTestingModule } from './utils';
const test = ava as TestFn<{
session: SessionService;
app: TestingModule;
module: TestingModule;
}>;
test.beforeEach(async t => {
const module = await Test.createTestingModule({
const module = await createTestingModule({
imports: [
ConfigModule.forRoot({
redis: {
@@ -23,14 +24,14 @@ test.beforeEach(async t => {
CacheModule,
SessionModule,
],
}).compile();
});
const session = module.get(SessionService);
t.context.app = module;
t.context.module = module;
t.context.session = session;
});
test.afterEach.always(async t => {
await t.context.app.close();
await t.context.module.close();
});
test('should be able to set session', async t => {

View File

@@ -1,40 +1,17 @@
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import test from 'ava';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import request from 'supertest';
import { AppModule } from '../src/app';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { currentUser, initFeatureConfigs, signUp } from './utils';
import { createTestingApp, currentUser, signUp } from './utils';
let app: INestApplication;
// cleanup database before each test
test.beforeEach(async () => {
const client = new PrismaClient();
await client.$connect();
await client.user.deleteMany({});
await client.$disconnect();
});
test.beforeEach(async () => {
const module = await Test.createTestingModule({
const { app: testApp } = await createTestingApp({
imports: [AppModule],
providers: [RevertCommand, RunCommand],
}).compile();
app = module.createNestApplication();
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await app.init();
// init features
await initFeatureConfigs(module);
});
app = testApp;
});
test.afterEach.always(async () => {

View File

@@ -1,14 +1,14 @@
import { randomUUID } from 'node:crypto';
import { INestApplication, ModuleMetadata } from '@nestjs/common';
import { Query, Resolver } from '@nestjs/graphql';
import { Test, TestingModuleBuilder } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import { TestingModule } from '@nestjs/testing';
import { hashSync } from '@node-rs/argon2';
import { PrismaClient, type User } from '@prisma/client';
import { AppModule, FunctionalityModules } from '../../src/app';
import { UserFeaturesInit1698652531198 } from '../../src/data/migrations/1698652531198-user-features-init';
import { GqlModule } from '../../src/graphql.module';
import { RevertCommand, RunCommand } from '../../src/data/commands/run';
export async function flushDB() {
const client = new PrismaClient();
await client.$connect();
async function flushDB(client: PrismaClient) {
const result: { tablename: string }[] =
await client.$queryRaw`SELECT tablename
FROM pg_catalog.pg_tables
@@ -22,41 +22,99 @@ export async function flushDB() {
.filter(name => !name.includes('migrations'))
.join(', ')}`
);
await client.$disconnect();
}
export class FakePrisma {
fakeUser: User = {
id: randomUUID(),
name: 'Alex Yang',
avatarUrl: '',
email: 'alex.yang@example.org',
password: hashSync('123456'),
emailVerified: new Date(),
createdAt: new Date(),
};
async function initFeatureConfigs(db: PrismaClient) {
await UserFeaturesInit1698652531198.up(db);
}
get user() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const prisma = this;
return {
async findFirst() {
return prisma.fakeUser;
},
async findUnique() {
return this.findFirst();
},
async update() {
return this.findFirst();
},
};
export async function initTestingDB(db: PrismaClient) {
await flushDB(db);
await initFeatureConfigs(db);
}
interface TestingModuleMeatdata extends ModuleMetadata {
tapModule?(m: TestingModuleBuilder): void;
tapApp?(app: INestApplication): void;
}
function dedupeModules(modules: NonNullable<ModuleMetadata['imports']>) {
const map = new Map();
modules.forEach(m => {
if ('module' in m) {
map.set(m.module, m);
} else {
map.set(m, m);
}
});
return Array.from(map.values());
}
@Resolver(() => String)
class MockResolver {
@Query(() => String)
hello() {
return 'hello world';
}
}
export async function initFeatureConfigs(module: TestingModule) {
const run = module.get(RunCommand);
const revert = module.get(RevertCommand);
await Promise.allSettled([revert.run(['UserFeaturesInit1698652531198'])]);
await run.runOne('UserFeaturesInit1698652531198');
export async function createTestingModule(
moduleDef: TestingModuleMeatdata = {}
) {
// setting up
let imports = moduleDef.imports ?? [];
imports =
imports[0] === AppModule
? [AppModule]
: dedupeModules([...FunctionalityModules, GqlModule, ...imports]);
const builder = Test.createTestingModule({
imports,
providers: [MockResolver, ...(moduleDef.providers ?? [])],
controllers: moduleDef.controllers,
});
if (moduleDef.tapModule) {
moduleDef.tapModule(builder);
}
const m = await builder.compile();
const prisma = m.get(PrismaClient);
if (prisma instanceof PrismaClient) {
await flushDB(prisma);
await initFeatureConfigs(prisma);
}
return m;
}
export async function createTestingApp(moduleDef: TestingModuleMeatdata = {}) {
const m = await createTestingModule(moduleDef);
const app = m.createNestApplication({
cors: true,
bodyParser: true,
rawBody: true,
});
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
if (moduleDef.tapApp) {
moduleDef.tapApp(app);
}
await app.init();
return {
module: m,
app,
};
}

View File

@@ -1,19 +1,15 @@
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import test from 'ava';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import request from 'supertest';
import { AppModule } from '../src/app';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { QuotaService, QuotaType } from '../src/modules/quota';
import {
checkBlobSize,
collectAllBlobSizes,
createTestingApp,
createWorkspace,
getWorkspaceBlobsSize,
initFeatureConfigs,
listBlobs,
setBlob,
signUp,
@@ -22,36 +18,13 @@ import {
let app: INestApplication;
let quota: QuotaService;
const client = new PrismaClient();
// cleanup database before each test
test.beforeEach(async () => {
await client.$connect();
await client.user.deleteMany({});
await client.snapshot.deleteMany({});
await client.update.deleteMany({});
await client.workspace.deleteMany({});
await client.$disconnect();
});
test.beforeEach(async () => {
const module = await Test.createTestingModule({
const { app: testApp } = await createTestingApp({
imports: [AppModule],
providers: [RevertCommand, RunCommand],
}).compile();
app = module.createNestApplication();
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
quota = module.get(QuotaService);
});
// init features
await initFeatureConfigs(module);
await app.init();
app = testApp;
quota = app.get(QuotaService);
});
test.afterEach.always(async () => {

View File

@@ -3,20 +3,18 @@ import {
getLatestMailMessage,
} from '@affine-test/kit/utils/cloud';
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import ava, { type TestFn } from 'ava';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import { AppModule } from '../src/app';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { MailService } from '../src/modules/auth/mailer';
import { AuthService } from '../src/modules/auth/service';
import { PrismaService } from '../src/prisma';
import {
acceptInviteById,
createTestingApp,
createWorkspace,
getWorkspace,
initFeatureConfigs,
inviteUser,
leaveWorkspace,
revokeUser,
@@ -31,36 +29,13 @@ const test = ava as TestFn<{
}>;
test.beforeEach(async t => {
const client = new PrismaClient();
t.context.client = client;
await client.$connect();
await client.user.deleteMany({});
await client.snapshot.deleteMany({});
await client.update.deleteMany({});
await client.workspace.deleteMany({});
await client.$disconnect();
const module = await Test.createTestingModule({
const { app } = await createTestingApp({
imports: [AppModule],
providers: [RevertCommand, RunCommand],
}).compile();
const app = module.createNestApplication();
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await app.init();
const auth = module.get(AuthService);
const mail = module.get(MailService);
});
t.context.app = app;
t.context.auth = auth;
t.context.mail = mail;
// init features
await initFeatureConfigs(module);
t.context.client = app.get(PrismaService);
t.context.auth = app.get(AuthService);
t.context.mail = app.get(MailService);
});
test.afterEach.always(async t => {

View File

@@ -1,19 +1,17 @@
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import ava, { type TestFn } from 'ava';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import request from 'supertest';
import { AppModule } from '../src/app';
import { RevertCommand, RunCommand } from '../src/data/commands/run';
import { PrismaService } from '../src/prisma';
import {
acceptInviteById,
createTestingApp,
createWorkspace,
currentUser,
getPublicWorkspace,
getWorkspacePublicPages,
initFeatureConfigs,
inviteUser,
publishPage,
revokePublicPage,
@@ -27,30 +25,12 @@ const test = ava as TestFn<{
}>;
test.beforeEach(async t => {
const client = new PrismaClient();
await client.$connect();
await client.user.deleteMany({});
await client.update.deleteMany({});
await client.snapshot.deleteMany({});
await client.workspace.deleteMany({});
await client.$disconnect();
const module = await Test.createTestingModule({
const { app } = await createTestingApp({
imports: [AppModule],
providers: [RevertCommand, RunCommand],
}).compile();
const app = module.createNestApplication();
app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await app.init();
t.context.client = client;
t.context.app = app;
});
// init features
await initFeatureConfigs(module);
t.context.client = app.get(PrismaService);
t.context.app = app;
});
test.afterEach.always(async t => {