2023-09-05 11:01:45 +03:00
|
|
|
import { randomUUID } from 'node:crypto';
|
2023-08-29 13:07:05 +03:00
|
|
|
|
|
|
|
import type { INestApplication } from '@nestjs/common';
|
2023-09-05 11:01:45 +03:00
|
|
|
import { hashSync } from '@node-rs/argon2';
|
2023-09-29 06:02:26 +03:00
|
|
|
import { type User } from '@prisma/client';
|
|
|
|
import ava, { type TestFn } from 'ava';
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-15 10:34:14 +03:00
|
|
|
import { AppModule } from '../src/app';
|
|
|
|
import { MailService } from '../src/modules/auth/mailer';
|
2024-01-10 10:28:46 +03:00
|
|
|
import { FeatureKind, FeatureManagementService } from '../src/modules/features';
|
|
|
|
import { Quotas } from '../src/modules/quota';
|
2023-09-15 10:34:14 +03:00
|
|
|
import { PrismaService } from '../src/prisma';
|
2024-01-11 09:40:55 +03:00
|
|
|
import {
|
|
|
|
createTestingApp,
|
|
|
|
createWorkspace,
|
|
|
|
getInviteInfo,
|
|
|
|
inviteUser,
|
|
|
|
signUp,
|
|
|
|
} from './utils';
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-05 11:01:45 +03:00
|
|
|
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]) };
|
|
|
|
},
|
|
|
|
},
|
2023-11-06 06:49:39 +03:00
|
|
|
get workspaceUserPermission() {
|
2023-09-05 11:01:45 +03:00
|
|
|
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 };
|
|
|
|
},
|
2023-11-06 06:49:39 +03:00
|
|
|
async workspaceUserPermission() {
|
2023-09-05 11:01:45 +03:00
|
|
|
return {
|
|
|
|
id: randomUUID(),
|
|
|
|
createdAt: new Date(),
|
|
|
|
};
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
2024-01-10 10:28:46 +03:00
|
|
|
get features() {
|
|
|
|
return {
|
|
|
|
async findFirst() {
|
|
|
|
return {
|
|
|
|
id: 1,
|
|
|
|
type: FeatureKind.Quota,
|
|
|
|
feature: Quotas[0].feature,
|
|
|
|
configs: Quotas[0].configs,
|
|
|
|
version: Quotas[0].version,
|
|
|
|
createdAt: new Date(),
|
|
|
|
};
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
get userFeatures() {
|
|
|
|
return {
|
|
|
|
async findFirst() {
|
|
|
|
return {
|
|
|
|
createdAt: new Date(),
|
|
|
|
featureId: 1,
|
|
|
|
reason: '',
|
|
|
|
expiredAt: null,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
2023-09-05 11:01:45 +03:00
|
|
|
};
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-15 10:34:14 +03:00
|
|
|
const test = ava as TestFn<{
|
|
|
|
app: INestApplication;
|
|
|
|
mail: MailService;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
test.beforeEach(async t => {
|
2024-01-11 09:40:55 +03:00
|
|
|
const { module, app } = await createTestingApp({
|
2023-09-01 22:41:29 +03:00
|
|
|
imports: [AppModule],
|
2024-01-11 09:40:55 +03:00
|
|
|
tapModule: module => {
|
|
|
|
module
|
|
|
|
.overrideProvider(PrismaService)
|
|
|
|
.useValue(FakePrisma)
|
|
|
|
.overrideProvider(FeatureManagementService)
|
|
|
|
.useValue({
|
|
|
|
hasWorkspaceFeature() {
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-15 10:34:14 +03:00
|
|
|
const mail = module.get(MailService);
|
|
|
|
t.context.app = app;
|
|
|
|
t.context.mail = mail;
|
2023-09-01 22:41:29 +03:00
|
|
|
});
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-15 10:34:14 +03:00
|
|
|
test.afterEach.always(async t => {
|
|
|
|
await t.context.app.close();
|
2023-09-01 22:41:29 +03:00
|
|
|
});
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-01 22:41:29 +03:00
|
|
|
test('should send invite email', async t => {
|
2023-09-15 10:34:14 +03:00
|
|
|
const { mail, app } = t.context;
|
2023-09-01 22:41:29 +03:00
|
|
|
if (mail.hasConfigured()) {
|
|
|
|
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
|
|
|
|
const u2 = await signUp(app, 'u2', 'u2@affine.pro', '1');
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-01 22:41:29 +03:00
|
|
|
const workspace = await createWorkspace(app, u1.token.token);
|
|
|
|
const inviteId = await inviteUser(
|
|
|
|
app,
|
|
|
|
u1.token.token,
|
|
|
|
workspace.id,
|
|
|
|
u2.email,
|
|
|
|
'Admin'
|
|
|
|
);
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-01 22:41:29 +03:00
|
|
|
const inviteInfo = await getInviteInfo(app, u1.token.token, inviteId);
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-01 22:41:29 +03:00
|
|
|
const resp = await mail.sendInviteEmail(
|
|
|
|
'production@toeverything.info',
|
|
|
|
inviteId,
|
|
|
|
{
|
|
|
|
workspace: {
|
|
|
|
id: inviteInfo.workspace.id,
|
|
|
|
name: inviteInfo.workspace.name,
|
|
|
|
avatar: '',
|
|
|
|
},
|
|
|
|
user: {
|
|
|
|
avatar: inviteInfo.user?.avatarUrl || '',
|
|
|
|
name: inviteInfo.user?.name || '',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
);
|
2023-08-29 13:07:05 +03:00
|
|
|
|
2023-09-15 10:34:14 +03:00
|
|
|
t.is(resp.accepted.length, 1, 'failed to send invite email');
|
2023-09-01 22:41:29 +03:00
|
|
|
}
|
|
|
|
t.pass();
|
2023-08-29 13:07:05 +03:00
|
|
|
});
|