refactor: SystemWebhook/UserWebhookの配信処理呼び出し部分の改善 (#15035)
* UserWebhook側の対処 * SystemWebhook側の対処 * fix test
This commit is contained in:
@@ -3,13 +3,14 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { jest } from '@jest/globals';
|
||||
import { describe, jest } from '@jest/globals';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { randomString } from '../utils.js';
|
||||
import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js';
|
||||
import {
|
||||
AbuseReportNotificationRecipientRepository,
|
||||
MiAbuseReportNotificationRecipient,
|
||||
MiAbuseUserReport,
|
||||
MiSystemWebhook,
|
||||
MiUser,
|
||||
SystemWebhooksRepository,
|
||||
@@ -112,7 +113,10 @@ describe('AbuseReportNotificationService', () => {
|
||||
provide: SystemWebhookService, useFactory: () => ({ enqueueSystemWebhook: jest.fn() }),
|
||||
},
|
||||
{
|
||||
provide: UserEntityService, useFactory: () => ({ pack: (v: any) => v }),
|
||||
provide: UserEntityService, useFactory: () => ({
|
||||
pack: (v: any) => Promise.resolve(v),
|
||||
packMany: (v: any) => Promise.resolve(v),
|
||||
}),
|
||||
},
|
||||
{
|
||||
provide: EmailService, useFactory: () => ({ sendEmail: jest.fn() }),
|
||||
@@ -344,4 +348,46 @@ describe('AbuseReportNotificationService', () => {
|
||||
expect(recipients).toEqual([recipient3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('notifySystemWebhook', () => {
|
||||
test('非アクティブな通報通知はWebhook送信から除外される', async () => {
|
||||
const recipient1 = await createRecipient({
|
||||
method: 'webhook',
|
||||
systemWebhookId: systemWebhook1.id,
|
||||
isActive: true,
|
||||
});
|
||||
const recipient2 = await createRecipient({
|
||||
method: 'webhook',
|
||||
systemWebhookId: systemWebhook2.id,
|
||||
isActive: false,
|
||||
});
|
||||
|
||||
const reports: MiAbuseUserReport[] = [
|
||||
{
|
||||
id: idService.gen(),
|
||||
targetUserId: alice.id,
|
||||
targetUser: alice,
|
||||
reporterId: bob.id,
|
||||
reporter: bob,
|
||||
assigneeId: null,
|
||||
assignee: null,
|
||||
resolved: false,
|
||||
forwarded: false,
|
||||
comment: 'test',
|
||||
moderationNote: '',
|
||||
resolvedAs: null,
|
||||
targetUserHost: null,
|
||||
reporterHost: null,
|
||||
},
|
||||
];
|
||||
|
||||
await service.notifySystemWebhook(reports, 'abuseReport');
|
||||
|
||||
// 実際に除外されるかはSystemWebhookService側で確認する.
|
||||
// ここでは非アクティブな通報通知を除外設定できているかを確認する
|
||||
expect(webhookService.enqueueSystemWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(webhookService.enqueueSystemWebhook.mock.calls[0][0]).toBe('abuseReport');
|
||||
expect(webhookService.enqueueSystemWebhook.mock.calls[0][2]).toEqual({ excludes: [systemWebhook2.id] });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -314,9 +314,10 @@ describe('SystemWebhookService', () => {
|
||||
isActive: true,
|
||||
on: ['abuseReport'],
|
||||
});
|
||||
await service.enqueueSystemWebhook(webhook.id, 'abuseReport', { foo: 'bar' } as any);
|
||||
await service.enqueueSystemWebhook('abuseReport', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.systemWebhookDeliver).toHaveBeenCalled();
|
||||
expect(queueService.systemWebhookDeliver).toHaveBeenCalledTimes(1);
|
||||
expect(queueService.systemWebhookDeliver.mock.calls[0][0] as MiSystemWebhook).toEqual(webhook);
|
||||
});
|
||||
|
||||
test('非アクティブなWebhookはキューに追加されない', async () => {
|
||||
@@ -324,7 +325,7 @@ describe('SystemWebhookService', () => {
|
||||
isActive: false,
|
||||
on: ['abuseReport'],
|
||||
});
|
||||
await service.enqueueSystemWebhook(webhook.id, 'abuseReport', { foo: 'bar' } as any);
|
||||
await service.enqueueSystemWebhook('abuseReport', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.systemWebhookDeliver).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -338,11 +339,49 @@ describe('SystemWebhookService', () => {
|
||||
isActive: true,
|
||||
on: ['abuseReportResolved'],
|
||||
});
|
||||
await service.enqueueSystemWebhook(webhook1.id, 'abuseReport', { foo: 'bar' } as any);
|
||||
await service.enqueueSystemWebhook(webhook2.id, 'abuseReport', { foo: 'bar' } as any);
|
||||
await service.enqueueSystemWebhook('abuseReport', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.systemWebhookDeliver).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('混在した時、有効かつ許可されたイベント種別のみ', async () => {
|
||||
const webhook1 = await createWebhook({
|
||||
isActive: true,
|
||||
on: ['abuseReport'],
|
||||
});
|
||||
const webhook2 = await createWebhook({
|
||||
isActive: true,
|
||||
on: ['abuseReportResolved'],
|
||||
});
|
||||
const webhook3 = await createWebhook({
|
||||
isActive: false,
|
||||
on: ['abuseReport'],
|
||||
});
|
||||
const webhook4 = await createWebhook({
|
||||
isActive: false,
|
||||
on: ['abuseReportResolved'],
|
||||
});
|
||||
await service.enqueueSystemWebhook('abuseReport', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.systemWebhookDeliver).toHaveBeenCalledTimes(1);
|
||||
expect(queueService.systemWebhookDeliver.mock.calls[0][0] as MiSystemWebhook).toEqual(webhook1);
|
||||
});
|
||||
|
||||
test('除外指定した場合は送信されない', async () => {
|
||||
const webhook1 = await createWebhook({
|
||||
isActive: true,
|
||||
on: ['abuseReport'],
|
||||
});
|
||||
const webhook2 = await createWebhook({
|
||||
isActive: true,
|
||||
on: ['abuseReport'],
|
||||
});
|
||||
|
||||
await service.enqueueSystemWebhook('abuseReport', { foo: 'bar' } as any, { excludes: [webhook2.id] });
|
||||
|
||||
expect(queueService.systemWebhookDeliver).toHaveBeenCalledTimes(1);
|
||||
expect(queueService.systemWebhookDeliver.mock.calls[0][0] as MiSystemWebhook).toEqual(webhook1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchActiveSystemWebhooks', () => {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
@@ -71,7 +70,7 @@ describe('UserWebhookService', () => {
|
||||
LoggerService,
|
||||
GlobalEventService,
|
||||
{
|
||||
provide: QueueService, useFactory: () => ({ systemWebhookDeliver: jest.fn() }),
|
||||
provide: QueueService, useFactory: () => ({ userWebhookDeliver: jest.fn() }),
|
||||
},
|
||||
],
|
||||
})
|
||||
@@ -242,4 +241,92 @@ describe('UserWebhookService', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('アプリを毎回作り直す必要があるグループ', () => {
|
||||
beforeEach(async () => {
|
||||
await beforeAllImpl();
|
||||
await beforeEachImpl();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await afterEachImpl();
|
||||
await afterAllImpl();
|
||||
});
|
||||
|
||||
describe('enqueueUserWebhook', () => {
|
||||
test('キューに追加成功', async () => {
|
||||
const webhook = await createWebhook({
|
||||
active: true,
|
||||
on: ['note'],
|
||||
});
|
||||
await service.enqueueUserWebhook(webhook.userId, 'note', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.userWebhookDeliver).toHaveBeenCalledTimes(1);
|
||||
expect(queueService.userWebhookDeliver.mock.calls[0][0] as MiWebhook).toEqual(webhook);
|
||||
});
|
||||
|
||||
test('非アクティブなWebhookはキューに追加されない', async () => {
|
||||
const webhook = await createWebhook({
|
||||
active: false,
|
||||
on: ['note'],
|
||||
});
|
||||
await service.enqueueUserWebhook(webhook.userId, 'note', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.userWebhookDeliver).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('未許可のイベント種別が渡された場合はWebhookはキューに追加されない', async () => {
|
||||
const webhook1 = await createWebhook({
|
||||
active: true,
|
||||
on: [],
|
||||
});
|
||||
const webhook2 = await createWebhook({
|
||||
active: true,
|
||||
on: ['note'],
|
||||
});
|
||||
await service.enqueueUserWebhook(webhook1.userId, 'renote', { foo: 'bar' } as any);
|
||||
await service.enqueueUserWebhook(webhook2.userId, 'renote', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.userWebhookDeliver).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('ユーザIDが異なるWebhookはキューに追加されない', async () => {
|
||||
const webhook = await createWebhook({
|
||||
active: true,
|
||||
on: ['note'],
|
||||
});
|
||||
await service.enqueueUserWebhook(idService.gen(), 'note', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.userWebhookDeliver).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('混在した時、有効かつ許可されたイベント種別のみ', async () => {
|
||||
const userId = root.id;
|
||||
const webhook1 = await createWebhook({
|
||||
userId,
|
||||
active: true,
|
||||
on: ['note'],
|
||||
});
|
||||
const webhook2 = await createWebhook({
|
||||
userId,
|
||||
active: true,
|
||||
on: ['renote'],
|
||||
});
|
||||
const webhook3 = await createWebhook({
|
||||
userId,
|
||||
active: false,
|
||||
on: ['note'],
|
||||
});
|
||||
const webhook4 = await createWebhook({
|
||||
userId,
|
||||
active: false,
|
||||
on: ['renote'],
|
||||
});
|
||||
await service.enqueueUserWebhook(userId, 'note', { foo: 'bar' } as any);
|
||||
|
||||
expect(queueService.userWebhookDeliver).toHaveBeenCalledTimes(1);
|
||||
expect(queueService.userWebhookDeliver.mock.calls[0][0] as MiWebhook).toEqual(webhook1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -18,6 +18,7 @@ import { QueueLoggerService } from '@/queue/QueueLoggerService.js';
|
||||
import { EmailService } from '@/core/EmailService.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
import { AnnouncementService } from '@/core/AnnouncementService.js';
|
||||
import { SystemWebhookEventType } from '@/models/SystemWebhook.js';
|
||||
|
||||
const baseDate = new Date(Date.UTC(2000, 11, 15, 12, 0, 0));
|
||||
|
||||
@@ -334,9 +335,10 @@ describe('CheckModeratorsActivityProcessorService', () => {
|
||||
mockModeratorRole([user1]);
|
||||
await service.notifyInactiveModeratorsWarning({ time: 1, asDays: 0, asHours: 0 });
|
||||
|
||||
expect(systemWebhookService.enqueueSystemWebhook).toHaveBeenCalledTimes(2);
|
||||
expect(systemWebhookService.enqueueSystemWebhook.mock.calls[0][0]).toEqual(systemWebhook1);
|
||||
expect(systemWebhookService.enqueueSystemWebhook.mock.calls[1][0]).toEqual(systemWebhook2);
|
||||
// typeとactiveによる絞り込みが機能しているかはSystemWebhookServiceのテストで確認する.
|
||||
// ここでは呼び出されているか、typeが正しいかのみを確認する
|
||||
expect(systemWebhookService.enqueueSystemWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(systemWebhookService.enqueueSystemWebhook.mock.calls[0][0] as SystemWebhookEventType).toEqual('inactiveModeratorsWarning');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -372,8 +374,10 @@ describe('CheckModeratorsActivityProcessorService', () => {
|
||||
mockModeratorRole([user1]);
|
||||
await service.notifyChangeToInvitationOnly();
|
||||
|
||||
// typeとactiveによる絞り込みが機能しているかはSystemWebhookServiceのテストで確認する.
|
||||
// ここでは呼び出されているか、typeが正しいかのみを確認する
|
||||
expect(systemWebhookService.enqueueSystemWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(systemWebhookService.enqueueSystemWebhook.mock.calls[0][0]).toEqual(systemWebhook2);
|
||||
expect(systemWebhookService.enqueueSystemWebhook.mock.calls[0][0] as SystemWebhookEventType).toEqual('inactiveModeratorsInvitationOnlyChanged');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user