Skip to content

Commit f60335c

Browse files
fix(backend): Webhook Test一致性
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
1 parent 1bc4f40 commit f60335c

File tree

7 files changed

+42
-24
lines changed

7 files changed

+42
-24
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/712)
4646
- Fix: FTT無効時にユーザーリストタイムラインが使用できない問題を修正
4747
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/709)
48+
- Fix: User Webhookテスト機能のMock Payloadを修正
4849

4950
### Misskey.js
5051
- Fix: Stream初期化時、別途WebSocketを指定する場合の型定義を修正

packages/backend/src/core/QueueService.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { randomUUID } from 'node:crypto';
77
import { Inject, Injectable } from '@nestjs/common';
88
import type { IActivity } from '@/core/activitypub/type.js';
99
import type { MiDriveFile } from '@/models/DriveFile.js';
10-
import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js';
10+
import type { MiWebhook, WebhookEventTypes, webhookEventTypes } from '@/models/Webhook.js';
1111
import type { MiSystemWebhook, SystemWebhookEventType } from '@/models/SystemWebhook.js';
1212
import type { Config } from '@/config.js';
1313
import { DI } from '@/di-symbols.js';
@@ -35,6 +35,7 @@ import type {
3535
} from './QueueModule.js';
3636
import type httpSignature from '@peertube/http-signature';
3737
import type * as Bull from 'bullmq';
38+
import { type UserWebhookPayload } from './UserWebhookService.js';
3839

3940
@Injectable()
4041
export class QueueService {
@@ -471,7 +472,7 @@ export class QueueService {
471472
public userWebhookDeliver(
472473
webhook: MiWebhook,
473474
type: typeof webhookEventTypes[number],
474-
content: unknown,
475+
content: UserWebhookPayload<WebhookEventTypes>,
475476
opts?: { attempts?: number },
476477
) {
477478
const data: UserWebhookDeliverJobData = {

packages/backend/src/core/UserWebhookService.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@
66
import { Inject, Injectable } from '@nestjs/common';
77
import * as Redis from 'ioredis';
88
import { type WebhooksRepository } from '@/models/_.js';
9-
import { MiWebhook } from '@/models/Webhook.js';
9+
import { MiWebhook, WebhookEventTypes } from '@/models/Webhook.js';
1010
import { DI } from '@/di-symbols.js';
1111
import { bindThis } from '@/decorators.js';
1212
import { GlobalEvents } from '@/core/GlobalEventService.js';
1313
import type { OnApplicationShutdown } from '@nestjs/common';
14+
import type { Packed } from '@/misc/json-schema.js';
15+
16+
export type UserWebhookPayload<T extends WebhookEventTypes> =
17+
T extends 'note' | 'reply' | 'renote' |'mention' ? {
18+
note: Packed<'Note'>,
19+
} :
20+
T extends 'follow' | 'followed' | 'unfollow' ? {
21+
user: Packed<'User'>,
22+
} : never;
1423

1524
@Injectable()
1625
export class UserWebhookService implements OnApplicationShutdown {

packages/backend/src/core/WebhookTestService.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWeb
1010
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
1111
import { Packed } from '@/misc/json-schema.js';
1212
import { type WebhookEventTypes } from '@/models/Webhook.js';
13-
import { UserWebhookService } from '@/core/UserWebhookService.js';
13+
import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
1414
import { QueueService } from '@/core/QueueService.js';
1515
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
1616

@@ -306,10 +306,10 @@ export class WebhookTestService {
306306
* - 送信対象イベント(on)に関する設定
307307
*/
308308
@bindThis
309-
public async testUserWebhook(
309+
public async testUserWebhook<T extends WebhookEventTypes>(
310310
params: {
311311
webhookId: MiWebhook['id'],
312-
type: WebhookEventTypes,
312+
type: T,
313313
override?: Partial<Omit<MiWebhook, 'id'>>,
314314
},
315315
sender: MiUser | null,
@@ -321,7 +321,7 @@ export class WebhookTestService {
321321
}
322322

323323
const webhook = webhooks[0];
324-
const send = (contents: unknown) => {
324+
const send = <U extends WebhookEventTypes>(contents: UserWebhookPayload<U>) => {
325325
const merged = {
326326
...webhook,
327327
...params.override,
@@ -361,33 +361,40 @@ export class WebhookTestService {
361361

362362
switch (params.type) {
363363
case 'note': {
364-
send(toPackedNote(dummyNote1));
364+
send({ note: toPackedNote(dummyNote1) });
365365
break;
366366
}
367367
case 'reply': {
368-
send(toPackedNote(dummyReply1));
368+
send({ note: toPackedNote(dummyReply1) });
369369
break;
370370
}
371371
case 'renote': {
372-
send(toPackedNote(dummyRenote1));
372+
send({ note: toPackedNote(dummyRenote1) });
373373
break;
374374
}
375375
case 'mention': {
376-
send(toPackedNote(dummyMention1));
376+
send({ note: toPackedNote(dummyMention1) });
377377
break;
378378
}
379379
case 'follow': {
380-
send(toPackedUserDetailedNotMe(dummyUser1));
380+
send({ user: toPackedUserDetailedNotMe(dummyUser1) });
381381
break;
382382
}
383383
case 'followed': {
384-
send(toPackedUserLite(dummyUser2));
384+
send({ user: toPackedUserDetailedNotMe(dummyUser2) });
385385
break;
386386
}
387387
case 'unfollow': {
388-
send(toPackedUserDetailedNotMe(dummyUser3));
388+
send({ user: toPackedUserDetailedNotMe(dummyUser3) });
389389
break;
390390
}
391+
// まだ実装されていない (#9485)
392+
case 'reaction': return;
393+
default: {
394+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
395+
const _exhaustiveAssertion: never = params.type;
396+
return;
397+
}
391398
}
392399
}
393400

packages/backend/test/unit/WebhookTestService.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import { Test, TestingModule } from '@nestjs/testing';
88
import { beforeAll, describe, jest } from '@jest/globals';
99
import { WebhookTestService } from '@/core/WebhookTestService.js';
10-
import { UserWebhookService } from '@/core/UserWebhookService.js';
10+
import { UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
1111
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
1212
import { GlobalModule } from '@/GlobalModule.js';
1313
import { MiSystemWebhook, MiUser, MiWebhook, UserProfilesRepository, UsersRepository } from '@/models/_.js';
@@ -122,7 +122,7 @@ describe('WebhookTestService', () => {
122122
const calls = queueService.userWebhookDeliver.mock.calls[0];
123123
expect((calls[0] as any).id).toBe('dummy-webhook');
124124
expect(calls[1]).toBe('note');
125-
expect((calls[2] as any).id).toBe('dummy-note-1');
125+
expect((calls[2] as UserWebhookPayload<'note'>).note.id).toBe('dummy-note-1');
126126
});
127127

128128
test('reply', async () => {
@@ -131,7 +131,7 @@ describe('WebhookTestService', () => {
131131
const calls = queueService.userWebhookDeliver.mock.calls[0];
132132
expect((calls[0] as any).id).toBe('dummy-webhook');
133133
expect(calls[1]).toBe('reply');
134-
expect((calls[2] as any).id).toBe('dummy-reply-1');
134+
expect((calls[2] as UserWebhookPayload<'reply'>).note.id).toBe('dummy-reply-1');
135135
});
136136

137137
test('renote', async () => {
@@ -140,7 +140,7 @@ describe('WebhookTestService', () => {
140140
const calls = queueService.userWebhookDeliver.mock.calls[0];
141141
expect((calls[0] as any).id).toBe('dummy-webhook');
142142
expect(calls[1]).toBe('renote');
143-
expect((calls[2] as any).id).toBe('dummy-renote-1');
143+
expect((calls[2] as UserWebhookPayload<'renote'>).note.id).toBe('dummy-renote-1');
144144
});
145145

146146
test('mention', async () => {
@@ -149,7 +149,7 @@ describe('WebhookTestService', () => {
149149
const calls = queueService.userWebhookDeliver.mock.calls[0];
150150
expect((calls[0] as any).id).toBe('dummy-webhook');
151151
expect(calls[1]).toBe('mention');
152-
expect((calls[2] as any).id).toBe('dummy-mention-1');
152+
expect((calls[2] as UserWebhookPayload<'mention'>).note.id).toBe('dummy-mention-1');
153153
});
154154

155155
test('follow', async () => {
@@ -158,7 +158,7 @@ describe('WebhookTestService', () => {
158158
const calls = queueService.userWebhookDeliver.mock.calls[0];
159159
expect((calls[0] as any).id).toBe('dummy-webhook');
160160
expect(calls[1]).toBe('follow');
161-
expect((calls[2] as any).id).toBe('dummy-user-1');
161+
expect((calls[2] as UserWebhookPayload<'follow'>).user.id).toBe('dummy-user-1');
162162
});
163163

164164
test('followed', async () => {
@@ -167,7 +167,7 @@ describe('WebhookTestService', () => {
167167
const calls = queueService.userWebhookDeliver.mock.calls[0];
168168
expect((calls[0] as any).id).toBe('dummy-webhook');
169169
expect(calls[1]).toBe('followed');
170-
expect((calls[2] as any).id).toBe('dummy-user-2');
170+
expect((calls[2] as UserWebhookPayload<'followed'>).user.id).toBe('dummy-user-2');
171171
});
172172

173173
test('unfollow', async () => {
@@ -176,7 +176,7 @@ describe('WebhookTestService', () => {
176176
const calls = queueService.userWebhookDeliver.mock.calls[0];
177177
expect((calls[0] as any).id).toBe('dummy-webhook');
178178
expect(calls[1]).toBe('unfollow');
179-
expect((calls[2] as any).id).toBe('dummy-user-3');
179+
expect((calls[2] as UserWebhookPayload<'unfollow'>).user.id).toBe('dummy-user-3');
180180
});
181181

182182
describe('NoSuchWebhookError', () => {

packages/frontend/src/pages/settings/webhook.edit.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
4444
<MkButton transparent :class="$style.testButton" :disabled="!(active && event_renote)" @click="test('renote')"><i class="ti ti-send"></i></MkButton>
4545
</div>
4646
<div :class="$style.switchBox">
47-
<MkSwitch v-model="event_reaction">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
47+
<MkSwitch v-model="event_reaction" :disabled="true">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
4848
<MkButton transparent :class="$style.testButton" :disabled="!(active && event_reaction)" @click="test('reaction')"><i class="ti ti-send"></i></MkButton>
4949
</div>
5050
<div :class="$style.switchBox">

packages/frontend/src/pages/settings/webhook.new.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
2727
<MkSwitch v-model="event_note">{{ i18n.ts._webhookSettings._events.note }}</MkSwitch>
2828
<MkSwitch v-model="event_reply">{{ i18n.ts._webhookSettings._events.reply }}</MkSwitch>
2929
<MkSwitch v-model="event_renote">{{ i18n.ts._webhookSettings._events.renote }}</MkSwitch>
30-
<MkSwitch v-model="event_reaction">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
30+
<MkSwitch v-model="event_reaction" :disabled="true">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
3131
<MkSwitch v-model="event_mention">{{ i18n.ts._webhookSettings._events.mention }}</MkSwitch>
3232
</div>
3333
</FormSection>

0 commit comments

Comments
 (0)