From dfa5fefa7f75b82acd664d7747f84b5e27176a3a Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 5 Sep 2023 01:01:45 -0700 Subject: [PATCH] test(server): use mock PrismaService in tests (#4101) --- apps/server/src/tests/app.e2e.ts | 67 ++++++++----- apps/server/src/tests/auth.spec.ts | 23 ++--- apps/server/src/tests/config.spec.ts | 5 +- apps/server/src/tests/doc.spec.ts | 34 +++---- apps/server/src/tests/mailer.spec.ts | 97 ++++++++++++++++--- .../src/tests/prometheus-metrics.spec.ts | 16 ++- apps/server/src/tests/session.spec.ts | 9 +- apps/server/src/tests/user.spec.ts | 20 ++-- apps/server/src/tests/workspace-blobs.spec.ts | 22 ++--- .../server/src/tests/workspace-invite.spec.ts | 35 +++---- apps/server/src/tests/workspace.spec.ts | 76 +++++++-------- 11 files changed, 228 insertions(+), 176 deletions(-) diff --git a/apps/server/src/tests/app.e2e.ts b/apps/server/src/tests/app.e2e.ts index 4232eb4b1c..c592cad9f8 100644 --- a/apps/server/src/tests/app.e2e.ts +++ b/apps/server/src/tests/app.e2e.ts @@ -1,10 +1,11 @@ -import { equal, ok } from 'node:assert'; +import { ok } from 'node:assert'; +import { randomUUID } from 'node:crypto'; import { Transformer } from '@napi-rs/image'; import type { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; -import { hash } from '@node-rs/argon2'; -import { PrismaClient } from '@prisma/client'; +import { hashSync } from '@node-rs/argon2'; +import { User } from '@prisma/client'; import test from 'ava'; import { Express } from 'express'; // @ts-expect-error graphql-upload is not typed @@ -12,30 +13,46 @@ import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs'; import request from 'supertest'; import { AppModule } from '../app'; +import { PrismaService } from '../prisma/service'; const gql = '/graphql'; let app: INestApplication; -// cleanup database before each test -test.beforeEach(async () => { - const client = new PrismaClient(); - await client.$connect(); - await client.user.deleteMany({}); - await client.user.create({ - data: { - name: 'Alex Yang', - email: 'alex.yang@example.org', - password: await hash('123456'), - }, - }); - await client.$disconnect(); -}); +class FakePrisma { + fakeUser: User = { + id: randomUUID(), + name: 'Alex Yang', + avatarUrl: '', + email: 'alex.yang@example.org', + password: hashSync('123456'), + emailVerified: new Date(), + createdAt: new Date(), + }; + 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(); + }, + }; + } +} test.beforeEach(async () => { const module = await Test.createTestingModule({ imports: [AppModule], - }).compile(); + }) + .overrideProvider(PrismaService) + .useClass(FakePrisma) + .compile(); app = module.createNestApplication({ cors: true, bodyParser: true, @@ -53,8 +70,8 @@ test.afterEach(async () => { await app.close(); }); -test('should init app', async () => { - ok(typeof app === 'object'); +test('should init app', async t => { + t.is(typeof app, 'object'); await request(app.getHttpServer()) .post(gql) .send({ @@ -80,11 +97,11 @@ test('should init app', async () => { }) .expect(200) .expect(res => { - ok(res.body.data.__typename === 'Query'); + t.is(res.body.data.__typename, 'Query'); }); }); -test('should find default user', async () => { +test('should find default user', async t => { const { token } = await createToken(app); await request(app.getHttpServer()) .post(gql) @@ -101,11 +118,11 @@ test('should find default user', async () => { }) .expect(200) .expect(res => { - equal(res.body.data.user.email, 'alex.yang@example.org'); + t.is(res.body.data.user.email, 'alex.yang@example.org'); }); }); -test('should be able to upload avatar', async () => { +test('should be able to upload avatar', async t => { const { token, id } = await createToken(app); const png = await Transformer.fromRgbaPixels( Buffer.alloc(400 * 400 * 4).fill(255), @@ -136,7 +153,7 @@ test('should be able to upload avatar', async () => { .attach('0', png, 'avatar.png') .expect(200) .expect(res => { - equal(res.body.data.uploadAvatar.id, id); + t.is(res.body.data.uploadAvatar.id, id); }); }); diff --git a/apps/server/src/tests/auth.spec.ts b/apps/server/src/tests/auth.spec.ts index 7215b5f19c..ff18272978 100644 --- a/apps/server/src/tests/auth.spec.ts +++ b/apps/server/src/tests/auth.spec.ts @@ -1,6 +1,4 @@ /// -import { equal } from 'node:assert'; - import { Test, TestingModule } from '@nestjs/testing'; import { PrismaClient } from '@prisma/client'; import test from 'ava'; @@ -69,20 +67,19 @@ test('should be able to verify', async t => { { const token = await auth.sign(user); const claim = await auth.verify(token); - equal(claim.id, '1'); - equal(claim.name, 'Alex Yang'); - equal(claim.email, 'alexyang@example.org'); - equal(claim.emailVerified?.toISOString(), date.toISOString()); - equal(claim.createdAt.toISOString(), date.toISOString()); + t.is(claim.id, '1'); + t.is(claim.name, 'Alex Yang'); + t.is(claim.email, 'alexyang@example.org'); + t.is(claim.emailVerified?.toISOString(), date.toISOString()); + t.is(claim.createdAt.toISOString(), date.toISOString()); } { const token = await auth.refresh(user); const claim = await auth.verify(token); - equal(claim.id, '1'); - equal(claim.name, 'Alex Yang'); - equal(claim.email, 'alexyang@example.org'); - equal(claim.emailVerified?.toISOString(), date.toISOString()); - equal(claim.createdAt.toISOString(), date.toISOString()); + t.is(claim.id, '1'); + t.is(claim.name, 'Alex Yang'); + t.is(claim.email, 'alexyang@example.org'); + t.is(claim.emailVerified?.toISOString(), date.toISOString()); + t.is(claim.createdAt.toISOString(), date.toISOString()); } - t.pass(); }); diff --git a/apps/server/src/tests/config.spec.ts b/apps/server/src/tests/config.spec.ts index ddc76573d8..c8a1b1885e 100644 --- a/apps/server/src/tests/config.spec.ts +++ b/apps/server/src/tests/config.spec.ts @@ -1,5 +1,3 @@ -import { ok } from 'node:assert'; - import { Test } from '@nestjs/testing'; import test from 'ava'; @@ -28,6 +26,5 @@ test('should be able to override config', async t => { }).compile(); const config = module.get(Config); - ok(config.host, 'testing'); - t.pass(); + t.is(config.host, 'testing'); }); diff --git a/apps/server/src/tests/doc.spec.ts b/apps/server/src/tests/doc.spec.ts index bcf339677d..39826f7e65 100644 --- a/apps/server/src/tests/doc.spec.ts +++ b/apps/server/src/tests/doc.spec.ts @@ -1,4 +1,3 @@ -import { deepEqual, equal, ok } from 'node:assert'; import { mock } from 'node:test'; import { INestApplication } from '@nestjs/common'; @@ -54,10 +53,9 @@ test('should setup update poll interval', async t => { await m.createNestApplication().init(); - equal(fake.mock.callCount(), 1); + t.is(fake.mock.callCount(), 1); // @ts-expect-error private member - ok(manager.job); - t.pass(); + t.truthy(manager.job); }); test('should be able to stop poll', async t => { @@ -66,10 +64,9 @@ test('should be able to stop poll', async t => { await app.close(); - equal(fake.mock.callCount(), 1); + t.is(fake.mock.callCount(), 1); // @ts-expect-error private member - equal(manager.job, null); - t.pass(); + t.is(manager.job, null); }); test('should poll when intervel due', async t => { @@ -84,22 +81,21 @@ test('should poll when intervel due', async t => { }); timer.tick(interval); - equal(fake.mock.callCount(), 1); + t.is(fake.mock.callCount(), 1); // busy timer.tick(interval); // @ts-expect-error private member - equal(manager.busy, true); - equal(fake.mock.callCount(), 1); + t.is(manager.busy, true); + t.is(fake.mock.callCount(), 1); resolve(); await timer.tickAsync(1); // @ts-expect-error private member - equal(manager.busy, false); + t.is(manager.busy, false); timer.tick(interval); - equal(fake.mock.callCount(), 2); - t.pass(); + t.is(fake.mock.callCount(), 2); }); test('should merge update when intervel due', async t => { @@ -135,7 +131,10 @@ test('should merge update when intervel due', async t => { await manager.apply(); - deepEqual(await manager.getLatestUpdate(ws.id, '1'), update); + t.deepEqual( + (await manager.getLatestUpdate(ws.id, '1'))?.toString('hex'), + Buffer.from(update.buffer).toString('hex') + ); let appendUpdate = Buffer.from([]); doc.on('update', update => { @@ -153,9 +152,8 @@ test('should merge update when intervel due', async t => { await manager.apply(); - deepEqual( - await manager.getLatestUpdate(ws.id, '1'), - encodeStateAsUpdate(doc) + t.deepEqual( + (await manager.getLatestUpdate(ws.id, '1'))?.toString('hex'), + Buffer.from(encodeStateAsUpdate(doc)).toString('hex') ); - t.pass(); }); diff --git a/apps/server/src/tests/mailer.spec.ts b/apps/server/src/tests/mailer.spec.ts index 87e76526a4..a507017209 100644 --- a/apps/server/src/tests/mailer.spec.ts +++ b/apps/server/src/tests/mailer.spec.ts @@ -1,36 +1,107 @@ import { ok } from 'node:assert'; +import { randomUUID } from 'node:crypto'; import type { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; -import { PrismaClient } from '@prisma/client'; +import { hashSync } from '@node-rs/argon2'; +import { User } from '@prisma/client'; import test from 'ava'; // @ts-expect-error graphql-upload is not typed import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs'; import { AppModule } from '../app'; import { MailService } from '../modules/auth/mailer'; +import { PrismaService } from '../prisma'; import { createWorkspace, getInviteInfo, inviteUser, signUp } from './utils'; let app: INestApplication; -const client = new PrismaClient(); - let mail: MailService; -// 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(); -}); +const FakePrisma = { + fakeUser: { + id: randomUUID(), + name: 'Alex Yang', + avatarUrl: '', + email: 'alex.yang@example.org', + password: hashSync('123456'), + emailVerified: new Date(), + createdAt: new Date(), + } satisfies User, + + get user() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const prisma = this; + return { + async findFirst() { + return null; + }, + async create({ data }: any) { + return { + ...prisma.fakeUser, + ...data, + }; + }, + async findUnique() { + return prisma.fakeUser; + }, + }; + }, + get workspace() { + return { + id: randomUUID(), + async create({ data }: any) { + return { + id: this.id, + public: data.public ?? false, + createdAt: new Date(), + }; + }, + }; + }, + snapshot: { + id: randomUUID(), + async create() {}, + async findFirstOrThrow() { + return { id: this.id, blob: Buffer.from([0, 0]) }; + }, + }, + get userWorkspacePermission() { + return { + id: randomUUID(), + prisma: this, + async count() { + return 1; + }, + async create() { + return { id: this.id }; + }, + async findUniqueOrThrow() { + return { id: this.id, workspaceId: this.prisma.workspace.id }; + }, + async findFirst() { + return { id: this.id }; + }, + async findFirstOrThrow() { + return { id: this.id, user: this.prisma.fakeUser }; + }, + async userWorkspacePermission() { + return { + id: randomUUID(), + createdAt: new Date(), + }; + }, + }; + }, +}; test.beforeEach(async () => { const module = await Test.createTestingModule({ imports: [AppModule], - }).compile(); + }) + .overrideProvider(PrismaService) + .useValue(FakePrisma) + .compile(); app = module.createNestApplication(); app.use( graphqlUploadExpress({ diff --git a/apps/server/src/tests/prometheus-metrics.spec.ts b/apps/server/src/tests/prometheus-metrics.spec.ts index 59a069dbb8..b9daf8ac5d 100644 --- a/apps/server/src/tests/prometheus-metrics.spec.ts +++ b/apps/server/src/tests/prometheus-metrics.spec.ts @@ -1,5 +1,3 @@ -import { ok } from 'node:assert'; - import { Test, TestingModule } from '@nestjs/testing'; import test from 'ava'; import { register } from 'prom-client'; @@ -27,10 +25,10 @@ test('should be able to increment counter', async t => { metrics.socketIOEventCounter(1, { event: 'client-handshake' }); const socketIOCounterMetric = await register.getSingleMetric('socket_io_counter'); - ok(socketIOCounterMetric); + t.truthy(socketIOCounterMetric); - ok( - JSON.stringify((await socketIOCounterMetric.get()).values) === + t.truthy( + JSON.stringify((await socketIOCounterMetric!.get()).values) === '[{"value":1,"labels":{"event":"client-handshake"}}]' ); t.pass(); @@ -58,20 +56,20 @@ test('should be able to timer', async t => { } const socketIOTimerMetric = register.getSingleMetric('socket_io_timer'); - ok(socketIOTimerMetric); + t.truthy(socketIOTimerMetric); - const observations = (await socketIOTimerMetric.get()).values; + const observations = (await socketIOTimerMetric!.get()).values; for (const observation of observations) { if ( observation.labels.event === 'client-handshake' && 'quantile' in observation.labels ) { - ok( + t.truthy( observation.value >= minimum / 1000, 'observation.value should be greater than minimum' ); - ok( + t.truthy( observation.value <= maximum / 1000, 'observation.value should be less than maximum' ); diff --git a/apps/server/src/tests/session.spec.ts b/apps/server/src/tests/session.spec.ts index aed6380540..26bbbd0376 100644 --- a/apps/server/src/tests/session.spec.ts +++ b/apps/server/src/tests/session.spec.ts @@ -1,5 +1,4 @@ /// -import { equal } from 'node:assert'; import { Test, TestingModule } from '@nestjs/testing'; import { PrismaClient } from '@prisma/client'; @@ -31,14 +30,12 @@ test.afterEach(async () => { test('should be able to set session', async t => { await session.set('test', 'value'); - equal(await session.get('test'), 'value'); - t.pass(); + t.is(await session.get('test'), 'value'); }); test('should be expired by ttl', async t => { await session.set('test', 'value', 100); - equal(await session.get('test'), 'value'); + t.is(await session.get('test'), 'value'); await new Promise(resolve => setTimeout(resolve, 500)); - equal(await session.get('test'), undefined); - t.pass(); + t.is(await session.get('test'), undefined); }); diff --git a/apps/server/src/tests/user.spec.ts b/apps/server/src/tests/user.spec.ts index 5883aa368d..ad91a9fff6 100644 --- a/apps/server/src/tests/user.spec.ts +++ b/apps/server/src/tests/user.spec.ts @@ -1,5 +1,3 @@ -import { ok, rejects } from 'node:assert'; - import type { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { PrismaClient } from '@prisma/client'; @@ -41,20 +39,18 @@ test.afterEach(async () => { test('should register a user', async t => { const user = await signUp(app, 'u1', 'u1@affine.pro', '123456'); - ok(typeof user.id === 'string', 'user.id is not a string'); - ok(user.name === 'u1', 'user.name is not valid'); - ok(user.email === 'u1@affine.pro', 'user.email is not valid'); - t.pass(); + t.is(typeof user.id, 'string', 'user.id is not a string'); + t.is(user.name, 'u1', 'user.name is not valid'); + t.is(user.email, 'u1@affine.pro', 'user.email is not valid'); }); test('should get current user', async t => { const user = await signUp(app, 'u1', 'u1@affine.pro', '123456'); const currUser = await currentUser(app, user.token.token); - ok(currUser.id === user.id, 'user.id is not valid'); - ok(currUser.name === user.name, 'user.name is not valid'); - ok(currUser.email === user.email, 'user.email is not valid'); - ok(currUser.hasPassword, 'currUser.hasPassword is not valid'); - t.pass(); + t.is(currUser.id, user.id, 'user.id is not valid'); + t.is(currUser.name, user.name, 'user.name is not valid'); + t.is(currUser.email, user.email, 'user.email is not valid'); + t.true(currUser.hasPassword, 'currUser.hasPassword is not valid'); }); test('should be able to delete user', async t => { @@ -72,6 +68,6 @@ test('should be able to delete user', async t => { `, }) .expect(200); - await rejects(currentUser(app, user.token.token)); + await t.throwsAsync(() => currentUser(app, user.token.token)); t.pass(); }); diff --git a/apps/server/src/tests/workspace-blobs.spec.ts b/apps/server/src/tests/workspace-blobs.spec.ts index e552150491..dbcb436922 100644 --- a/apps/server/src/tests/workspace-blobs.spec.ts +++ b/apps/server/src/tests/workspace-blobs.spec.ts @@ -1,5 +1,3 @@ -import { deepEqual, ok } from 'node:assert'; - import type { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { PrismaClient } from '@prisma/client'; @@ -67,15 +65,14 @@ test('should set blobs', async t => { .auth(u1.token.token, { type: 'bearer' }) .buffer(); - deepEqual(response1.body, buffer1, 'failed to get blob'); + t.deepEqual(response1.body, buffer1, 'failed to get blob'); const response2 = await request(server) .get(`/api/workspaces/${workspace.id}/blobs/${hash2}`) .auth(u1.token.token, { type: 'bearer' }) .buffer(); - deepEqual(response2.body, buffer2, 'failed to get blob'); - t.pass(); + t.deepEqual(response2.body, buffer2, 'failed to get blob'); }); test('should list blobs', async t => { @@ -83,7 +80,7 @@ test('should list blobs', async t => { const workspace = await createWorkspace(app, u1.token.token); const blobs = await listBlobs(app, u1.token.token, workspace.id); - ok(blobs.length === 0, 'failed to list blobs'); + t.is(blobs.length, 0, 'failed to list blobs'); const buffer1 = Buffer.from([0, 0]); const hash1 = await setBlob(app, u1.token.token, workspace.id, buffer1); @@ -91,10 +88,9 @@ test('should list blobs', async t => { const hash2 = await setBlob(app, u1.token.token, workspace.id, buffer2); const ret = await listBlobs(app, u1.token.token, workspace.id); - ok(ret.length === 2, 'failed to list blobs'); - ok(ret[0] === hash1, 'failed to list blobs'); - ok(ret[1] === hash2, 'failed to list blobs'); - t.pass(); + t.is(ret.length, 2, 'failed to list blobs'); + t.is(ret[0], hash1, 'failed to list blobs'); + t.is(ret[1], hash2, 'failed to list blobs'); }); test('should calc blobs size', async t => { @@ -108,8 +104,7 @@ test('should calc blobs size', async t => { await setBlob(app, u1.token.token, workspace.id, buffer2); const size = await collectBlobSizes(app, u1.token.token, workspace.id); - ok(size === 4, 'failed to collect blob sizes'); - t.pass(); + t.is(size, 4, 'failed to collect blob sizes'); }); test('should calc all blobs size', async t => { @@ -130,6 +125,5 @@ test('should calc all blobs size', async t => { await setBlob(app, u1.token.token, workspace2.id, buffer4); const size = await collectAllBlobSizes(app, u1.token.token); - ok(size === 8, 'failed to collect all blob sizes'); - t.pass(); + t.is(size, 8, 'failed to collect all blob sizes'); }); diff --git a/apps/server/src/tests/workspace-invite.spec.ts b/apps/server/src/tests/workspace-invite.spec.ts index 32506bc74a..7bf71ca17e 100644 --- a/apps/server/src/tests/workspace-invite.spec.ts +++ b/apps/server/src/tests/workspace-invite.spec.ts @@ -1,5 +1,3 @@ -import { ok } from 'node:assert'; - import type { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { PrismaClient } from '@prisma/client'; @@ -72,8 +70,7 @@ test('should invite a user', async t => { u2.email, 'Admin' ); - ok(!!invite, 'failed to invite user'); - t.pass(); + t.truthy(invite, 'failed to invite user'); }); test('should accept an invite', async t => { @@ -84,13 +81,13 @@ test('should accept an invite', async t => { await inviteUser(app, u1.token.token, workspace.id, u2.email, 'Admin'); const accept = await acceptInvite(app, u2.token.token, workspace.id); - ok(accept === true, 'failed to accept invite'); + t.is(accept, true, 'failed to accept invite'); const currWorkspace = await getWorkspace(app, u1.token.token, workspace.id); const currMember = currWorkspace.members.find(u => u.email === u2.email); - ok(currMember !== undefined, 'failed to invite user'); - ok(currMember.id === u2.id, 'failed to invite user'); - ok(!currMember.accepted, 'failed to invite user'); + t.not(currMember, undefined, 'failed to invite user'); + t.is(currMember!.id, u2.id, 'failed to invite user'); + t.true(!currMember!.accepted, 'failed to invite user'); t.pass(); }); @@ -103,8 +100,7 @@ test('should leave a workspace', async t => { await acceptInvite(app, u2.token.token, workspace.id); const leave = await leaveWorkspace(app, u2.token.token, workspace.id); - ok(leave === true, 'failed to leave workspace'); - t.pass(); + t.true(leave, 'failed to leave workspace'); }); test('should revoke a user', async t => { @@ -115,11 +111,10 @@ test('should revoke a user', async t => { await inviteUser(app, u1.token.token, workspace.id, u2.email, 'Admin'); const currWorkspace = await getWorkspace(app, u1.token.token, workspace.id); - ok(currWorkspace.members.length === 2, 'failed to invite user'); + t.is(currWorkspace.members.length, 2, 'failed to invite user'); const revoke = await revokeUser(app, u1.token.token, workspace.id, u2.id); - ok(revoke === true, 'failed to revoke user'); - t.pass(); + t.true(revoke, 'failed to revoke user'); }); test('should create user if not exist', async t => { @@ -130,9 +125,8 @@ test('should create user if not exist', async t => { await inviteUser(app, u1.token.token, workspace.id, 'u2@affine.pro', 'Admin'); const user = await auth.getUserByEmail('u2@affine.pro'); - ok(user !== undefined, 'failed to create user'); - ok(user?.name === 'Unnamed', 'failed to create user'); - t.pass(); + t.not(user, undefined, 'failed to create user'); + t.is(user?.name, 'Unnamed', 'failed to create user'); }); test('should invite a user by link', async t => { @@ -150,7 +144,7 @@ test('should invite a user by link', async t => { ); const accept = await acceptInviteById(app, workspace.id, invite); - ok(accept === true, 'failed to accept invite'); + t.true(accept, 'failed to accept invite'); const invite1 = await inviteUser( app, @@ -160,13 +154,12 @@ test('should invite a user by link', async t => { 'Admin' ); - ok(invite === invite1, 'repeat the invitation must return same id'); + t.is(invite, invite1, 'repeat the invitation must return same id'); const currWorkspace = await getWorkspace(app, u1.token.token, workspace.id); const currMember = currWorkspace.members.find(u => u.email === u2.email); - ok(currMember !== undefined, 'failed to invite user'); - ok(currMember.inviteId === invite, 'failed to check invite id'); - t.pass(); + t.not(currMember, undefined, 'failed to invite user'); + t.is(currMember?.inviteId, invite, 'failed to check invite id'); }); test('should send invite email', async t => { diff --git a/apps/server/src/tests/workspace.spec.ts b/apps/server/src/tests/workspace.spec.ts index 500c3ce045..c40989d6cc 100644 --- a/apps/server/src/tests/workspace.spec.ts +++ b/apps/server/src/tests/workspace.spec.ts @@ -1,5 +1,3 @@ -import { deepEqual, ok, rejects } from 'node:assert'; - import type { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { PrismaClient } from '@prisma/client'; @@ -56,9 +54,9 @@ test.afterEach(async () => { test('should register a user', async t => { const user = await signUp(app, 'u1', 'u1@affine.pro', '123456'); - t.true(typeof user.id === 'string', 'user.id is not a string'); - t.true(user.name === 'u1', 'user.name is not valid'); - t.true(user.email === 'u1@affine.pro', 'user.email is not valid'); + t.is(typeof user.id, 'string', 'user.id is not a string'); + t.is(user.name, 'u1', 'user.name is not valid'); + t.is(user.email, 'u1@affine.pro', 'user.email is not valid'); }); test.skip('should be throttled at call signUp', async t => { @@ -69,17 +67,15 @@ test.skip('should be throttled at call signUp', async t => { // throttles are applied to each endpoint separately await currentUser(app, token); } - await rejects(signUp(app, 'u11', 'u11@affine.pro', '11')); - await rejects(currentUser(app, token)); - t.pass(); + await t.throwsAsync(() => signUp(app, 'u11', 'u11@affine.pro', '11')); + await t.throwsAsync(() => currentUser(app, token)); }); test('should create a workspace', async t => { const user = await signUp(app, 'u1', 'u1@affine.pro', '1'); const workspace = await createWorkspace(app, user.token.token); - ok(typeof workspace.id === 'string', 'workspace.id is not a string'); - t.pass(); + t.is(typeof workspace.id, 'string', 'workspace.id is not a string'); }); test('should can publish workspace', async t => { @@ -92,7 +88,7 @@ test('should can publish workspace', async t => { workspace.id, true ); - ok(isPublic === true, 'failed to publish workspace'); + t.true(isPublic, 'failed to publish workspace'); const isPrivate = await updateWorkspace( app, @@ -100,28 +96,20 @@ test('should can publish workspace', async t => { workspace.id, false ); - ok(isPrivate === false, 'failed to unpublish workspace'); - t.pass(); + t.false(isPrivate, 'failed to unpublish workspace'); }); test('should can read published workspace', async t => { const user = await signUp(app, 'u1', 'u1@affine.pro', '1'); const workspace = await createWorkspace(app, user.token.token); - await rejects( - getPublicWorkspace(app, 'not_exists_ws'), - 'must not get not exists workspace' - ); - await rejects( - getPublicWorkspace(app, workspace.id), - 'must not get private workspace' - ); + await t.throwsAsync(() => getPublicWorkspace(app, 'not_exists_ws')); + await t.throwsAsync(() => getPublicWorkspace(app, workspace.id)); await updateWorkspace(app, user.token.token, workspace.id, true); const publicWorkspace = await getPublicWorkspace(app, workspace.id); - ok(publicWorkspace.id === workspace.id, 'failed to get public workspace'); - t.pass(); + t.is(publicWorkspace.id, workspace.id, 'failed to get public workspace'); }); test('should share a page', async t => { @@ -131,46 +119,46 @@ test('should share a page', async t => { const workspace = await createWorkspace(app, u1.token.token); const share = await sharePage(app, u1.token.token, workspace.id, 'page1'); - t.true(share === true, 'failed to share page'); + t.true(share, 'failed to share page'); const pages = await getWorkspaceSharedPages( app, u1.token.token, workspace.id ); - t.true(pages.length === 1, 'failed to get shared pages'); - t.true(pages[0] === 'page1', 'failed to get shared page: page1'); + t.is(pages.length, 1, 'failed to get shared pages'); + t.is(pages[0], 'page1', 'failed to get shared page: page1'); const msg1 = await sharePage(app, u2.token.token, workspace.id, 'page2'); - t.true(msg1 === 'Permission denied', 'unauthorized user can share page'); + t.is(msg1, 'Permission denied', 'unauthorized user can share page'); const msg2 = await revokePage(app, u2.token.token, 'not_exists_ws', 'page2'); - t.true(msg2 === 'Permission denied', 'unauthorized user can share page'); + t.is(msg2, 'Permission denied', 'unauthorized user can share page'); await inviteUser(app, u1.token.token, workspace.id, u2.email, 'Admin'); await acceptInvite(app, u2.token.token, workspace.id); const invited = await sharePage(app, u2.token.token, workspace.id, 'page2'); - t.true(invited === true, 'failed to share page'); + t.true(invited, 'failed to share page'); const revoke = await revokePage(app, u1.token.token, workspace.id, 'page1'); - t.true(revoke === true, 'failed to revoke page'); + t.true(revoke, 'failed to revoke page'); const pages2 = await getWorkspaceSharedPages( app, u1.token.token, workspace.id ); - t.true(pages2.length === 1, 'failed to get shared pages'); - t.true(pages2[0] === 'page2', 'failed to get shared page: page2'); + t.is(pages2.length, 1, 'failed to get shared pages'); + t.is(pages2[0], 'page2', 'failed to get shared page: page2'); const msg3 = await revokePage(app, u1.token.token, workspace.id, 'page3'); - t.true(msg3 === false, 'can revoke non-exists page'); + t.false(msg3, 'can revoke non-exists page'); const msg4 = await revokePage(app, u1.token.token, workspace.id, 'page2'); - t.true(msg4 === true, 'failed to revoke page'); + t.true(msg4, 'failed to revoke page'); const page3 = await getWorkspaceSharedPages( app, u1.token.token, workspace.id ); - t.true(page3.length === 0, 'failed to get shared pages'); + t.is(page3.length, 0, 'failed to get shared pages'); }); test('should can get workspace doc', async t => { @@ -184,7 +172,11 @@ test('should can get workspace doc', async t => { .expect(200) .type('application/octet-stream'); - deepEqual(res1.body, Buffer.from([0, 0]), 'failed to get doc with u1 token'); + t.deepEqual( + res1.body, + Buffer.from([0, 0]), + 'failed to get doc with u1 token' + ); await request(app.getHttpServer()) .get(`/api/workspaces/${workspace.id}/docs/${workspace.id}`) @@ -207,8 +199,11 @@ test('should can get workspace doc', async t => { .expect(200) .type('application/octet-stream'); - deepEqual(res2.body, Buffer.from([0, 0]), 'failed to get doc with u2 token'); - t.pass(); + t.deepEqual( + res2.body, + Buffer.from([0, 0]), + 'failed to get doc with u2 token' + ); }); test('should be able to get public workspace doc', async t => { @@ -222,13 +217,12 @@ test('should be able to get public workspace doc', async t => { true ); - ok(isPublic === true, 'failed to publish workspace'); + t.true(isPublic, 'failed to publish workspace'); const res = await request(app.getHttpServer()) .get(`/api/workspaces/${workspace.id}/docs/${workspace.id}`) .expect(200) .type('application/octet-stream'); - deepEqual(res.body, Buffer.from([0, 0]), 'failed to get public doc'); - t.pass(); + t.deepEqual(res.body, Buffer.from([0, 0]), 'failed to get public doc'); });