mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-23 05:25:53 +08:00
feat(server): refactor mail queue (#15204)
This commit is contained in:
@@ -110,7 +110,7 @@ test('set and change password', async t => {
|
||||
const u1 = await app.signupV1(u1Email);
|
||||
await sendSetPasswordEmail(app, u1Email, '/password-change');
|
||||
|
||||
const setPasswordMail = app.mails.last('ChangePassword');
|
||||
const setPasswordMail = app.mails.last('SetPassword');
|
||||
const link = new URL(setPasswordMail.props.url);
|
||||
const setPasswordToken = link.searchParams.get('token');
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import {
|
||||
getCurrentUserQuery,
|
||||
getWorkspaceQuery,
|
||||
} from '@affine/graphql';
|
||||
import { WorkspaceMemberStatus } from '@prisma/client';
|
||||
|
||||
import { WorkspaceRole } from '../../../models';
|
||||
import { app, e2e, Mockers } from '../test';
|
||||
|
||||
const admin = await app.create(Mockers.User, {
|
||||
@@ -107,6 +109,31 @@ e2e('should ban account', async t => {
|
||||
t.is(banUser.disabled, true);
|
||||
});
|
||||
|
||||
e2e('should ban account with pending workspace invitation', async t => {
|
||||
const owner = await app.create(Mockers.User);
|
||||
const user = await app.create(Mockers.User);
|
||||
const workspace = await app.create(Mockers.Workspace, { owner });
|
||||
|
||||
await app.models.workspaceInvitation.set(
|
||||
workspace.id,
|
||||
user.id,
|
||||
WorkspaceRole.Collaborator,
|
||||
WorkspaceMemberStatus.Pending,
|
||||
{ inviterId: owner.id }
|
||||
);
|
||||
|
||||
await app.login(admin);
|
||||
|
||||
const { banUser } = await app.gql({
|
||||
query: disableUserMutation,
|
||||
variables: {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
t.is(banUser.disabled, true);
|
||||
});
|
||||
|
||||
e2e('should not login banned account', async t => {
|
||||
const user = await app.create(Mockers.User);
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@ import { interval, map, take, takeUntil } from 'rxjs';
|
||||
import Sinon from 'sinon';
|
||||
|
||||
import { Mailer } from '../../core/mail';
|
||||
import type { SendMailCommand } from '../../core/mail/types';
|
||||
import { MailName } from '../../mails';
|
||||
|
||||
export class MockMailer {
|
||||
send = Sinon.createStubInstance(Mailer).send.resolves(true);
|
||||
trySend(command: Jobs['notification.sendMail']) {
|
||||
skip = Sinon.createStubInstance(Mailer).skip.resolves(false);
|
||||
trySend(command: SendMailCommand) {
|
||||
return this.send(command, true);
|
||||
}
|
||||
|
||||
last<Mail extends MailName>(
|
||||
name: Mail
|
||||
): Extract<Jobs['notification.sendMail'], { name: Mail }> {
|
||||
last<Mail extends MailName>(name: Mail): SendMailCommand & { name: Mail } {
|
||||
const last = this.send.lastCall.args[0];
|
||||
|
||||
if (!last) {
|
||||
@@ -23,22 +23,26 @@ export class MockMailer {
|
||||
throw new Error(`Mail name mismatch: ${last.name} !== ${name}`);
|
||||
}
|
||||
|
||||
return last as any;
|
||||
return last as SendMailCommand & { name: Mail };
|
||||
}
|
||||
|
||||
waitFor<Mail extends MailName>(
|
||||
name: Mail,
|
||||
timeout: number = 1000
|
||||
): Promise<Extract<Jobs['notification.sendMail'], { name: Mail }>> {
|
||||
const { promise, reject, resolve } = Promise.withResolvers<any>();
|
||||
): Promise<SendMailCommand & { name: Mail }> {
|
||||
const { promise, reject, resolve } = Promise.withResolvers<
|
||||
SendMailCommand & { name: Mail }
|
||||
>();
|
||||
|
||||
interval(10)
|
||||
.pipe(
|
||||
take(Math.floor(timeout / 10)),
|
||||
takeUntil(promise),
|
||||
map(() => {
|
||||
const last = this.send.lastCall.args[0];
|
||||
return last.name === name ? last : undefined;
|
||||
const last = this.send.lastCall?.args[0];
|
||||
return last?.name === name
|
||||
? (last as SendMailCommand & { name: Mail })
|
||||
: undefined;
|
||||
})
|
||||
)
|
||||
.subscribe({
|
||||
|
||||
Reference in New Issue
Block a user