feat: Per-user renote mute (#10249)

* feat: per-user renote muting

From FoundKey/c414f24a2c https://akkoma.dev/FoundKeyGang/FoundKey

* Update ja-JP.yml

* Delete renote-muting.ts

* rename

* fix ids

* lint

* fix

* Update CHANGELOG.md

* リノートをミュートしたユーザー一覧を見れるように

* 🎨

* add test

* fix test

---------

Co-authored-by: Hélène <pleroma-dev@helene.moe>
This commit is contained in:
syuilo
2023-03-08 08:56:09 +09:00
committed by GitHub
parent 8bf6911d4b
commit 4c2f7c64cc
43 changed files with 683 additions and 26 deletions

View File

@@ -70,9 +70,9 @@ describe('Block', () => {
// TODO: ユーザーリストから除外されるテスト
test('タイムライン(LTL)にブロックされているユーザーの投稿が含まれない', async () => {
const aliceNote = await post(alice);
const bobNote = await post(bob);
const carolNote = await post(carol);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi' });
const carolNote = await post(carol, { text: 'hi' });
const res = await api('/notes/local-timeline', {}, bob);

View File

@@ -206,7 +206,7 @@ describe('Endpoints', () => {
describe('notes/reactions/create', () => {
test('リアクションできる', async () => {
const bobPost = await post(bob);
const bobPost = await post(bob, { text: 'hi' });
const res = await api('/notes/reactions/create', {
noteId: bobPost.id,
@@ -224,7 +224,7 @@ describe('Endpoints', () => {
});
test('自分の投稿にもリアクションできる', async () => {
const myPost = await post(alice);
const myPost = await post(alice, { text: 'hi' });
const res = await api('/notes/reactions/create', {
noteId: myPost.id,
@@ -235,7 +235,7 @@ describe('Endpoints', () => {
});
test('二重にリアクションすると上書きされる', async () => {
const bobPost = await post(bob);
const bobPost = await post(bob, { text: 'hi' });
await api('/notes/reactions/create', {
noteId: bobPost.id,

View File

@@ -76,9 +76,9 @@ describe('Mute', () => {
describe('Timeline', () => {
test('タイムラインにミュートしているユーザーの投稿が含まれない', async () => {
const aliceNote = await post(alice);
const bobNote = await post(bob);
const carolNote = await post(carol);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi' });
const carolNote = await post(carol, { text: 'hi' });
const res = await api('/notes/local-timeline', {}, alice);
@@ -90,8 +90,8 @@ describe('Mute', () => {
});
test('タイムラインにミュートしているユーザーの投稿のRenoteが含まれない', async () => {
const aliceNote = await post(alice);
const carolNote = await post(carol);
const aliceNote = await post(alice, { text: 'hi' });
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, {
renoteId: carolNote.id,
});
@@ -108,7 +108,7 @@ describe('Mute', () => {
describe('Notification', () => {
test('通知にミュートしているユーザーの通知が含まれない(リアクション)', async () => {
const aliceNote = await post(alice);
const aliceNote = await post(alice, { text: 'hi' });
await react(bob, aliceNote, 'like');
await react(carol, aliceNote, 'like');

View File

@@ -0,0 +1,85 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { signup, api, post, react, startServer, waitFire } from '../utils.js';
import type { INestApplicationContext } from '@nestjs/common';
describe('Renote Mute', () => {
let p: INestApplicationContext;
// alice mutes carol
let alice: any;
let bob: any;
let carol: any;
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
}, 1000 * 60 * 2);
afterAll(async () => {
await p.close();
});
test('ミュート作成', async () => {
const res = await api('/renote-mute/create', {
userId: carol.id,
}, alice);
assert.strictEqual(res.status, 204);
});
test('タイムラインにリノートミュートしているユーザーのリノートが含まれない', async () => {
const bobNote = await post(bob, { text: 'hi' });
const carolRenote = await post(carol, { renoteId: bobNote.id });
const carolNote = await post(carol, { text: 'hi' });
const res = await api('/notes/local-timeline', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolRenote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
});
test('タイムラインにリノートミュートしているユーザーの引用が含まれる', async () => {
const bobNote = await post(bob, { text: 'hi' });
const carolRenote = await post(carol, { renoteId: bobNote.id, text: 'kore' });
const carolNote = await post(carol, { text: 'hi' });
const res = await api('/notes/local-timeline', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolRenote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
});
test('ストリームにリノートミュートしているユーザーのリノートが流れない', async () => {
const bobNote = await post(bob, { text: 'hi' });
const fired = await waitFire(
alice, 'localTimeline',
() => api('notes/create', { renoteId: bobNote.id }, carol),
msg => msg.type === 'note' && msg.body.userId === carol.id,
);
assert.strictEqual(fired, false);
});
test('ストリームにリノートミュートしているユーザーの引用が流れる', async () => {
const bobNote = await post(bob, { text: 'hi' });
const fired = await waitFire(
alice, 'localTimeline',
() => api('notes/create', { renoteId: bobNote.id, text: 'kore' }, carol),
msg => msg.type === 'note' && msg.body.userId === carol.id,
);
assert.strictEqual(fired, true);
});
});