From fc65190ef7b687650018cccfee2219bf00827f70 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 31 Oct 2021 15:30:22 +0900 Subject: feat: thread mute (#7930) * feat: thread mute * chore: fix comment * fix test * fix * refactor --- test/thread-mute.ts | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ test/utils.ts | 3 +- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 test/thread-mute.ts (limited to 'test') diff --git a/test/thread-mute.ts b/test/thread-mute.ts new file mode 100644 index 0000000000..95601cd903 --- /dev/null +++ b/test/thread-mute.ts @@ -0,0 +1,103 @@ +process.env.NODE_ENV = 'test'; + +import * as assert from 'assert'; +import * as childProcess from 'child_process'; +import { async, signup, request, post, react, connectStream, startServer, shutdownServer } from './utils'; + +describe('Note thread mute', () => { + let p: childProcess.ChildProcess; + + let alice: any; + let bob: any; + let carol: any; + + before(async () => { + p = await startServer(); + alice = await signup({ username: 'alice' }); + bob = await signup({ username: 'bob' }); + carol = await signup({ username: 'carol' }); + }); + + after(async () => { + await shutdownServer(p); + }); + + it('notes/mentions にミュートしているスレッドの投稿が含まれない', async(async () => { + const bobNote = await post(bob, { text: '@alice @carol root note' }); + const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' }); + + await request('/notes/thread-muting/create', { noteId: bobNote.id }, alice); + + const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' }); + const carolReplyWithoutMention = await post(carol, { replyId: aliceReply.id, text: 'child note' }); + + const res = await request('/notes/mentions', {}, alice); + + assert.strictEqual(res.status, 200); + assert.strictEqual(Array.isArray(res.body), true); + assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false); + assert.strictEqual(res.body.some((note: any) => note.id === carolReply.id), false); + assert.strictEqual(res.body.some((note: any) => note.id === carolReplyWithoutMention.id), false); + })); + + it('ミュートしているスレッドからメンションされても、hasUnreadMentions が true にならない', async(async () => { + // 状態リセット + await request('/i/read-all-unread-notes', {}, alice); + + const bobNote = await post(bob, { text: '@alice @carol root note' }); + + await request('/notes/thread-muting/create', { noteId: bobNote.id }, alice); + + const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' }); + + const res = await request('/i', {}, alice); + + assert.strictEqual(res.status, 200); + assert.strictEqual(res.body.hasUnreadMentions, false); + })); + + it('ミュートしているスレッドからメンションされても、ストリームに unreadMention イベントが流れてこない', () => new Promise(async done => { + // 状態リセット + await request('/i/read-all-unread-notes', {}, alice); + + const bobNote = await post(bob, { text: '@alice @carol root note' }); + + await request('/notes/thread-muting/create', { noteId: bobNote.id }, alice); + + let fired = false; + + const ws = await connectStream(alice, 'main', async ({ type, body }) => { + if (type === 'unreadMention') { + if (body === bobNote.id) return; + fired = true; + } + }); + + const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' }); + + setTimeout(() => { + assert.strictEqual(fired, false); + ws.close(); + done(); + }, 5000); + })); + + it('i/notifications にミュートしているスレッドの通知が含まれない', async(async () => { + const bobNote = await post(bob, { text: '@alice @carol root note' }); + const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' }); + + await request('/notes/thread-muting/create', { noteId: bobNote.id }, alice); + + const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' }); + const carolReplyWithoutMention = await post(carol, { replyId: aliceReply.id, text: 'child note' }); + + const res = await request('/i/notifications', {}, alice); + + assert.strictEqual(res.status, 200); + assert.strictEqual(Array.isArray(res.body), true); + assert.strictEqual(res.body.some((notification: any) => notification.note.id === carolReply.id), false); + assert.strictEqual(res.body.some((notification: any) => notification.note.id === carolReplyWithoutMention.id), false); + + // NOTE: bobの投稿はスレッドミュート前に行われたため通知に含まれていてもよい + })); +}); diff --git a/test/utils.ts b/test/utils.ts index 1a0c54463d..54bcf65ab1 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,5 +1,6 @@ import * as fs from 'fs'; import * as WebSocket from 'ws'; +import * as misskey from 'misskey-js'; import fetch from 'node-fetch'; const FormData = require('form-data'); import * as childProcess from 'child_process'; @@ -52,7 +53,7 @@ export const signup = async (params?: any): Promise => { return res.body; }; -export const post = async (user: any, params?: any): Promise => { +export const post = async (user: any, params?: misskey.Endpoints['notes/create']['req']): Promise => { const q = Object.assign({ text: 'test' }, params); -- cgit v1.2.3-freya