Skip to content

Commit

Permalink
fix(backend): フォローしているユーザーからの自分の投稿への返信がタイムラインに含まれない問題を修正
Browse files Browse the repository at this point in the history
  • Loading branch information
syuilo committed Oct 10, 2023
1 parent 26b7112 commit 1f0c27e
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
-->

## 2023.10.1
### Server
- Fix: フォローしているユーザーからの自分の投稿への返信がタイムラインに含まれない問題を修正

## 2023.10.0
### NOTE
- 2023.9.2で導入されたノート編集機能はクオリティの高い実装が困難であることが判明したため撤回されました
Expand Down
8 changes: 4 additions & 4 deletions packages/backend/src/core/NoteCreateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,8 +868,8 @@ export class NoteCreateService implements OnApplicationShutdown {
// 基本的にvisibleUserIdsには自身のidが含まれている前提であること
if (note.visibility === 'specified' && !note.visibleUserIds.some(v => v === following.followerId)) continue;

// 自分自身以外への返信
if (note.replyId && note.replyUserId !== note.userId) {
// 「自分自身への返信 or そのフォロワーへの返信」のどちらでもない場合
if (note.replyId && !(note.replyUserId === note.userId || note.replyUserId === following.followerId)) {
if (!following.withReplies) continue;
}

Expand All @@ -886,8 +886,8 @@ export class NoteCreateService implements OnApplicationShutdown {
!note.visibleUserIds.some(v => v === userListMembership.userListUserId)
) continue;

// 自分自身以外への返信
if (note.replyId && note.replyUserId !== note.userId) {
// 「自分自身への返信 or そのリストの作成者への返信」のどちらでもない場合
if (note.replyId && !(note.replyUserId === note.userId || note.replyUserId === userListMembership.userListUserId)) {
if (!userListMembership.withReplies) continue;
}

Expand Down
66 changes: 66 additions & 0 deletions packages/backend/test/e2e/timelines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,22 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
});

test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);

await api('/following/create', { userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });

await waitForPushToTl();

const res = await api('/notes/timeline', {}, alice);

assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});

test.concurrent('自分の他人への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);

Expand Down Expand Up @@ -589,6 +605,24 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
});

/* 実装が面倒
test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
await api('/following/create', { userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });
await waitForPushToTl();
const res = await api('/notes/local-timeline', {}, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
*/

test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);

Expand Down Expand Up @@ -644,6 +678,22 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});

test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);

await api('/following/create', { userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });

await waitForPushToTl();

const res = await api('/notes/hybrid-timeline', {}, alice);

assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});

test.concurrent('リモートユーザーのノートが含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);

Expand Down Expand Up @@ -779,6 +829,22 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
});

test.concurrent('withReplies: false でリスインしているフォローしていないユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);

const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });

await waitForPushToTl();

const res = await api('/notes/user-list-timeline', { listId: list.id, withReplies: false }, alice);

assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});

test.concurrent('withReplies: true でリスインしているフォローしていないユーザーの他人への返信が含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);

Expand Down

0 comments on commit 1f0c27e

Please sign in to comment.