mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	test(backend): kill many any in backend test (partial) (#14054)
				
					
				
			* kill any on utils:api
* kill any on timeline test
* use optional chain to kill TS2532 on timeline test
変更前: 該当ノートが見つからなければundefinedに対するプロパティアクセスとしてテストがクラッシュ
変更後: 該当ノートが見つからなければoptional chainがundefinedとして評価されるが、strictEqualの右辺がnon-nullableなためアサーションに失敗しテストがクラッシュ
* kill `as any` for ApMfmService
* kill argument any for api-visibility
* kill argument any across a few tests
* do not return value that has yielded from `await`-ing `Promise<void>`
* force cast
* runtime non-null assertion to coerce
* rewrite `assert.notEqual(expr, null)` to `assert.ok(expr)`
こうすることでassertion type扱いになり、non-nullableになる
* change return type of `failedApiCall` to `void`
戻り値がどこにも使われていない
* split bindings for exports.ts
型が合わなくて文句を言ってくるので適切に分割
* runtime non-null assertion
* runtime non-null assertion
* 何故かうまく行かないので、とりあえずXORしてみる
* Revert "何故かうまく行かないので、とりあえずXORしてみる"
This reverts commit 48cf32c930924840d0892af92d71b9437acb5844.
* castAsErrorで安全ではないキャストを隠蔽
* 型アサーションの追加
* 型アサーションの追加
* 型アサーションの追加
* voidで値を返さない
* castAsError
* assert.ok => kill nullability
* もはや明示的な型の指定は必要ない
* castAsError
* castAsError
* 型アサーションの追加
* nullableを一旦抑止
* 変数を分離して型エラーを排除
* 不要なプロパティを削除する処理を隠蔽してanyを排除
* Repository type
* simple type
* assert.ok => kill nullability
* revert `as any` drop
reverts fe95c05b3f53266108128680d9358a3796844232 partialy
* test: fix invalid assertion
partially revert b99b7b5392d9d20c81dfee1346ba8b33ff9e1fbb
* test: 52d8a54fc7 により型が合うようになった部分の`as any`を除去
* format
* test: apply https://github.com/misskey-dev/misskey/pull/14054#discussion_r1672369526 (part 1)
* test: use non-null assertion to suppress too many error
* Update packages/backend/test/utils.ts
Co-authored-by: anatawa12 <anatawa12@icloud.com>
---------
Co-authored-by: anatawa12 <anatawa12@icloud.com>
			
			
This commit is contained in:
		
							parent
							
								
									7afa593d11
								
							
						
					
					
						commit
						31e82fc29a
					
				
					 16 changed files with 403 additions and 404 deletions
				
			
		| 
						 | 
				
			
			@ -25,7 +25,7 @@ export class ApMfmService {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public getNoteHtml(note: MiNote, apAppend?: string) {
 | 
			
		||||
	public getNoteHtml(note: Pick<MiNote, 'text' | 'mentionedRemoteUsers'>, apAppend?: string) {
 | 
			
		||||
		let noMisskeyContent = false;
 | 
			
		||||
		const srcMfm = (note.text ?? '') + (apAppend ?? '');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -206,7 +206,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			username,
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(usersShowResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(usersShowResponse.body.twoFactorEnabled, true);
 | 
			
		||||
		assert.strictEqual((usersShowResponse.body as unknown as { twoFactorEnabled: boolean }).twoFactorEnabled, true);
 | 
			
		||||
 | 
			
		||||
		const signinResponse = await api('signin', {
 | 
			
		||||
			...signinParam(),
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +248,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			keyName,
 | 
			
		||||
			credentialId,
 | 
			
		||||
			creationOptions: registerKeyResponse.body,
 | 
			
		||||
		}) as any, alice);
 | 
			
		||||
		} as any) as any, alice);
 | 
			
		||||
		assert.strictEqual(keyDoneResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(keyDoneResponse.body.id, credentialId.toString('base64url'));
 | 
			
		||||
		assert.strictEqual(keyDoneResponse.body.name, keyName);
 | 
			
		||||
| 
						 | 
				
			
			@ -257,22 +257,22 @@ describe('2要素認証', () => {
 | 
			
		|||
			username,
 | 
			
		||||
		});
 | 
			
		||||
		assert.strictEqual(usersShowResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(usersShowResponse.body.securityKeys, true);
 | 
			
		||||
		assert.strictEqual((usersShowResponse.body as unknown as { securityKeys: boolean }).securityKeys, true);
 | 
			
		||||
 | 
			
		||||
		const signinResponse = await api('signin', {
 | 
			
		||||
			...signinParam(),
 | 
			
		||||
		});
 | 
			
		||||
		assert.strictEqual(signinResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(signinResponse.body.i, undefined);
 | 
			
		||||
		assert.notEqual(signinResponse.body.challenge, undefined);
 | 
			
		||||
		assert.notEqual(signinResponse.body.allowCredentials, undefined);
 | 
			
		||||
		assert.strictEqual(signinResponse.body.allowCredentials[0].id, credentialId.toString('base64url'));
 | 
			
		||||
		assert.notEqual((signinResponse.body as unknown as { challenge: unknown | undefined }).challenge, undefined);
 | 
			
		||||
		assert.notEqual((signinResponse.body as unknown as { allowCredentials: unknown | undefined }).allowCredentials, undefined);
 | 
			
		||||
		assert.strictEqual((signinResponse.body as unknown as { allowCredentials: {id: string}[] }).allowCredentials[0].id, credentialId.toString('base64url'));
 | 
			
		||||
 | 
			
		||||
		const signinResponse2 = await api('signin', signinWithSecurityKeyParam({
 | 
			
		||||
			keyName,
 | 
			
		||||
			credentialId,
 | 
			
		||||
			requestOptions: signinResponse.body,
 | 
			
		||||
		}));
 | 
			
		||||
		} as any));
 | 
			
		||||
		assert.strictEqual(signinResponse2.status, 200);
 | 
			
		||||
		assert.notEqual(signinResponse2.body.i, undefined);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +307,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			keyName,
 | 
			
		||||
			credentialId,
 | 
			
		||||
			creationOptions: registerKeyResponse.body,
 | 
			
		||||
		}) as any, alice);
 | 
			
		||||
		} as any) as any, alice);
 | 
			
		||||
		assert.strictEqual(keyDoneResponse.status, 200);
 | 
			
		||||
 | 
			
		||||
		const passwordLessResponse = await api('i/2fa/password-less', {
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +319,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			username,
 | 
			
		||||
		});
 | 
			
		||||
		assert.strictEqual(usersShowResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(usersShowResponse.body.usePasswordLessLogin, true);
 | 
			
		||||
		assert.strictEqual((usersShowResponse.body as unknown as { usePasswordLessLogin: boolean }).usePasswordLessLogin, true);
 | 
			
		||||
 | 
			
		||||
		const signinResponse = await api('signin', {
 | 
			
		||||
			...signinParam(),
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +333,7 @@ describe('2要素認証', () => {
 | 
			
		|||
				keyName,
 | 
			
		||||
				credentialId,
 | 
			
		||||
				requestOptions: signinResponse.body,
 | 
			
		||||
			}),
 | 
			
		||||
			} as any),
 | 
			
		||||
			password: '',
 | 
			
		||||
		});
 | 
			
		||||
		assert.strictEqual(signinResponse2.status, 200);
 | 
			
		||||
| 
						 | 
				
			
			@ -370,7 +370,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			keyName,
 | 
			
		||||
			credentialId,
 | 
			
		||||
			creationOptions: registerKeyResponse.body,
 | 
			
		||||
		}) as any, alice);
 | 
			
		||||
		} as any) as any, alice);
 | 
			
		||||
		assert.strictEqual(keyDoneResponse.status, 200);
 | 
			
		||||
 | 
			
		||||
		const renamedKey = 'other-key';
 | 
			
		||||
| 
						 | 
				
			
			@ -383,6 +383,7 @@ describe('2要素認証', () => {
 | 
			
		|||
		const iResponse = await api('i', {
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(iResponse.status, 200);
 | 
			
		||||
		assert.ok(iResponse.body.securityKeysList);
 | 
			
		||||
		const securityKeys = iResponse.body.securityKeysList.filter((s: { id: string; }) => s.id === credentialId.toString('base64url'));
 | 
			
		||||
		assert.strictEqual(securityKeys.length, 1);
 | 
			
		||||
		assert.strictEqual(securityKeys[0].name, renamedKey);
 | 
			
		||||
| 
						 | 
				
			
			@ -419,13 +420,14 @@ describe('2要素認証', () => {
 | 
			
		|||
			keyName,
 | 
			
		||||
			credentialId,
 | 
			
		||||
			creationOptions: registerKeyResponse.body,
 | 
			
		||||
		}) as any, alice);
 | 
			
		||||
		} as any) as any, alice);
 | 
			
		||||
		assert.strictEqual(keyDoneResponse.status, 200);
 | 
			
		||||
 | 
			
		||||
		// テストの実行順によっては複数残ってるので全部消す
 | 
			
		||||
		const iResponse = await api('i', {
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(iResponse.status, 200);
 | 
			
		||||
		assert.ok(iResponse.body.securityKeysList);
 | 
			
		||||
		for (const key of iResponse.body.securityKeysList) {
 | 
			
		||||
			const removeKeyResponse = await api('i/2fa/remove-key', {
 | 
			
		||||
				token: otpToken(registerResponse.body.secret),
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +441,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			username,
 | 
			
		||||
		});
 | 
			
		||||
		assert.strictEqual(usersShowResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(usersShowResponse.body.securityKeys, false);
 | 
			
		||||
		assert.strictEqual((usersShowResponse.body as unknown as { securityKeys: boolean }).securityKeys, false);
 | 
			
		||||
 | 
			
		||||
		const signinResponse = await api('signin', {
 | 
			
		||||
			...signinParam(),
 | 
			
		||||
| 
						 | 
				
			
			@ -470,7 +472,7 @@ describe('2要素認証', () => {
 | 
			
		|||
			username,
 | 
			
		||||
		});
 | 
			
		||||
		assert.strictEqual(usersShowResponse.status, 200);
 | 
			
		||||
		assert.strictEqual(usersShowResponse.body.twoFactorEnabled, true);
 | 
			
		||||
		assert.strictEqual((usersShowResponse.body as unknown as { twoFactorEnabled: boolean }).twoFactorEnabled, true);
 | 
			
		||||
 | 
			
		||||
		const unregisterResponse = await api('i/2fa/unregister', {
 | 
			
		||||
			token: otpToken(registerResponse.body.secret),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -410,21 +410,21 @@ describe('API visibility', () => {
 | 
			
		|||
		test('[HTL] public-post が 自分が見れる', async () => {
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === pub.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === pub.id);
 | 
			
		||||
			assert.strictEqual(notes[0].text, 'x');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('[HTL] public-post が 非フォロワーから見れない', async () => {
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, other);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === pub.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === pub.id);
 | 
			
		||||
			assert.strictEqual(notes.length, 0);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('[HTL] followers-post が フォロワーから見れる', async () => {
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, follower);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === fol.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === fol.id);
 | 
			
		||||
			assert.strictEqual(notes[0].text, 'x');
 | 
			
		||||
		});
 | 
			
		||||
		//#endregion
 | 
			
		||||
| 
						 | 
				
			
			@ -433,21 +433,21 @@ describe('API visibility', () => {
 | 
			
		|||
		test('[replies] followers-reply が フォロワーから見れる', async () => {
 | 
			
		||||
			const res = await api('notes/replies', { noteId: tgt.id, limit: 100 }, follower);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === folR.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === folR.id);
 | 
			
		||||
			assert.strictEqual(notes[0].text, 'x');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('[replies] followers-reply が 非フォロワー (リプライ先ではない) から見れない', async () => {
 | 
			
		||||
			const res = await api('notes/replies', { noteId: tgt.id, limit: 100 }, other);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === folR.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === folR.id);
 | 
			
		||||
			assert.strictEqual(notes.length, 0);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('[replies] followers-reply が 非フォロワー (リプライ先である) から見れる', async () => {
 | 
			
		||||
			const res = await api('notes/replies', { noteId: tgt.id, limit: 100 }, target);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === folR.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === folR.id);
 | 
			
		||||
			assert.strictEqual(notes[0].text, 'x');
 | 
			
		||||
		});
 | 
			
		||||
		//#endregion
 | 
			
		||||
| 
						 | 
				
			
			@ -456,14 +456,14 @@ describe('API visibility', () => {
 | 
			
		|||
		test('[mentions] followers-reply が 非フォロワー (リプライ先である) から見れる', async () => {
 | 
			
		||||
			const res = await api('notes/mentions', { limit: 100 }, target);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === folR.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === folR.id);
 | 
			
		||||
			assert.strictEqual(notes[0].text, 'x');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('[mentions] followers-mention が 非フォロワー (メンション先である) から見れる', async () => {
 | 
			
		||||
			const res = await api('notes/mentions', { limit: 100 }, target);
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			const notes = res.body.filter((n: any) => n.id === folM.id);
 | 
			
		||||
			const notes = res.body.filter(n => n.id === folM.id);
 | 
			
		||||
			assert.strictEqual(notes[0].text, '@target x');
 | 
			
		||||
		});
 | 
			
		||||
		//#endregion
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
process.env.NODE_ENV = 'test';
 | 
			
		||||
 | 
			
		||||
import * as assert from 'assert';
 | 
			
		||||
import { api, post, signup } from '../utils.js';
 | 
			
		||||
import { api, castAsError, post, signup } from '../utils.js';
 | 
			
		||||
import type * as misskey from 'misskey-js';
 | 
			
		||||
 | 
			
		||||
describe('Block', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ describe('Block', () => {
 | 
			
		|||
		const res = await api('following/create', { userId: alice.id }, bob);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.id, 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('ブロックされているユーザーにリアクションできない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,8 @@ describe('Block', () => {
 | 
			
		|||
		const res = await api('notes/reactions/create', { noteId: note.id, reaction: '👍' }, bob);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.id, '20ef5475-9f38-4e4c-bd33-de6d979498ec');
 | 
			
		||||
		assert.ok(res.body);
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, '20ef5475-9f38-4e4c-bd33-de6d979498ec');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('ブロックされているユーザーに返信できない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +52,8 @@ describe('Block', () => {
 | 
			
		|||
		const res = await api('notes/create', { replyId: note.id, text: 'yo' }, bob);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
 | 
			
		||||
		assert.ok(res.body);
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('ブロックされているユーザーのノートをRenoteできない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +62,7 @@ describe('Block', () => {
 | 
			
		|||
		const res = await api('notes/create', { renoteId: note.id, text: 'yo' }, bob);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// TODO: ユーザーリストに入れられないテスト
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,14 +79,14 @@ describe('クリップ', () => {
 | 
			
		|||
	};
 | 
			
		||||
 | 
			
		||||
	const deleteClip = async (parameters: Misskey.entities.ClipsDeleteRequest, request: Partial<ApiRequest<'clips/delete'>> = {}): Promise<void> => {
 | 
			
		||||
		return await successfulApiCall({
 | 
			
		||||
		await successfulApiCall({
 | 
			
		||||
			endpoint: 'clips/delete',
 | 
			
		||||
			parameters,
 | 
			
		||||
			user: alice,
 | 
			
		||||
			...request,
 | 
			
		||||
		}, {
 | 
			
		||||
			status: 204,
 | 
			
		||||
		}) as any as void;
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const show = async (parameters: Misskey.entities.ClipsShowRequest, request: Partial<ApiRequest<'clips/show'>> = {}): Promise<Misskey.entities.Clip> => {
 | 
			
		||||
| 
						 | 
				
			
			@ -454,25 +454,25 @@ describe('クリップ', () => {
 | 
			
		|||
		let aliceClip: Misskey.entities.Clip;
 | 
			
		||||
 | 
			
		||||
		const favorite = async (parameters: Misskey.entities.ClipsFavoriteRequest, request: Partial<ApiRequest<'clips/favorite'>> = {}): Promise<void> => {
 | 
			
		||||
			return successfulApiCall({
 | 
			
		||||
			await successfulApiCall({
 | 
			
		||||
				endpoint: 'clips/favorite',
 | 
			
		||||
				parameters,
 | 
			
		||||
				user: alice,
 | 
			
		||||
				...request,
 | 
			
		||||
			}, {
 | 
			
		||||
				status: 204,
 | 
			
		||||
			}) as any as void;
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		const unfavorite = async (parameters: Misskey.entities.ClipsUnfavoriteRequest, request: Partial<ApiRequest<'clips/unfavorite'>> = {}): Promise<void> => {
 | 
			
		||||
			return successfulApiCall({
 | 
			
		||||
			await successfulApiCall({
 | 
			
		||||
				endpoint: 'clips/unfavorite',
 | 
			
		||||
				parameters,
 | 
			
		||||
				user: alice,
 | 
			
		||||
				...request,
 | 
			
		||||
			}, {
 | 
			
		||||
				status: 204,
 | 
			
		||||
			}) as any as void;
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		const myFavorites = async (request: Partial<ApiRequest<'clips/my-favorites'>> = {}): Promise<Misskey.entities.Clip[]> => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ import * as assert from 'assert';
 | 
			
		|||
// https://github.com/node-fetch/node-fetch/pull/1664
 | 
			
		||||
import { Blob } from 'node-fetch';
 | 
			
		||||
import { MiUser } from '@/models/_.js';
 | 
			
		||||
import { api, initTestDb, post, signup, simpleGet, uploadFile } from '../utils.js';
 | 
			
		||||
import { api, castAsError, initTestDb, post, signup, simpleGet, uploadFile } from '../utils.js';
 | 
			
		||||
import type * as misskey from 'misskey-js';
 | 
			
		||||
 | 
			
		||||
describe('Endpoints', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +164,7 @@ describe('Endpoints', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
 | 
			
		||||
			assert.strictEqual(res.body.id, alice.id);
 | 
			
		||||
			assert.strictEqual((res.body as unknown as { id: string }).id, alice.id);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('ユーザーが存在しなかったら怒る', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +285,8 @@ describe('Endpoints', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'CANNOT_REACT_TO_RENOTE');
 | 
			
		||||
			assert.ok(res.body);
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'CANNOT_REACT_TO_RENOTE');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('引用にリアクションできる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1063,7 +1064,7 @@ describe('Endpoints', () => {
 | 
			
		|||
				userId: bob.id,
 | 
			
		||||
			}, alice);
 | 
			
		||||
			assert.strictEqual(res1.status, 204);
 | 
			
		||||
			assert.strictEqual(res2.body?.memo, memo);
 | 
			
		||||
			assert.strictEqual((res2.body as unknown as { memo: string })?.memo, memo);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('自分に関するメモを更新できる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1078,7 +1079,7 @@ describe('Endpoints', () => {
 | 
			
		|||
				userId: alice.id,
 | 
			
		||||
			}, alice);
 | 
			
		||||
			assert.strictEqual(res1.status, 204);
 | 
			
		||||
			assert.strictEqual(res2.body?.memo, memo);
 | 
			
		||||
			assert.strictEqual((res2.body as unknown as { memo: string })?.memo, memo);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('メモを削除できる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1099,7 +1100,7 @@ describe('Endpoints', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			// memoには常に文字列かnullが入っている(5cac151)
 | 
			
		||||
			assert.strictEqual(res.body.memo, null);
 | 
			
		||||
			assert.strictEqual((res.body as unknown as { memo: string | null }).memo, null);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('メモは個人ごとに独立して保存される', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1126,8 +1127,8 @@ describe('Endpoints', () => {
 | 
			
		|||
				}, carol),
 | 
			
		||||
			]);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(resAlice.body.memo, memoAliceToBob);
 | 
			
		||||
			assert.strictEqual(resCarol.body.memo, memoCarolToBob);
 | 
			
		||||
			assert.strictEqual((resAlice.body as unknown as { memo: string }).memo, memoAliceToBob);
 | 
			
		||||
			assert.strictEqual((resCarol.body as unknown as { memo: string }).memo, memoCarolToBob);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,14 +61,14 @@ describe('export-clips', () => {
 | 
			
		|||
	});
 | 
			
		||||
 | 
			
		||||
	test('basic export', async () => {
 | 
			
		||||
		let res = await api('clips/create', {
 | 
			
		||||
		const res1 = await api('clips/create', {
 | 
			
		||||
			name: 'foo',
 | 
			
		||||
			description: 'bar',
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 200);
 | 
			
		||||
		assert.strictEqual(res1.status, 200);
 | 
			
		||||
 | 
			
		||||
		res = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		const res2 = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res2.status, 204);
 | 
			
		||||
 | 
			
		||||
		const exported = await pollFirstDriveFile();
 | 
			
		||||
		assert.strictEqual(exported[0].name, 'foo');
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ describe('export-clips', () => {
 | 
			
		|||
	});
 | 
			
		||||
 | 
			
		||||
	test('export with notes', async () => {
 | 
			
		||||
		let res = await api('clips/create', {
 | 
			
		||||
		const res = await api('clips/create', {
 | 
			
		||||
			name: 'foo',
 | 
			
		||||
			description: 'bar',
 | 
			
		||||
		}, alice);
 | 
			
		||||
| 
						 | 
				
			
			@ -96,15 +96,15 @@ describe('export-clips', () => {
 | 
			
		|||
		});
 | 
			
		||||
 | 
			
		||||
		for (const note of [note1, note2]) {
 | 
			
		||||
			res = await api('clips/add-note', {
 | 
			
		||||
			const res2 = await api('clips/add-note', {
 | 
			
		||||
				clipId: clip.id,
 | 
			
		||||
				noteId: note.id,
 | 
			
		||||
			}, alice);
 | 
			
		||||
			assert.strictEqual(res.status, 204);
 | 
			
		||||
			assert.strictEqual(res2.status, 204);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		res = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		const res3 = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res3.status, 204);
 | 
			
		||||
 | 
			
		||||
		const exported = await pollFirstDriveFile();
 | 
			
		||||
		assert.strictEqual(exported[0].name, 'foo');
 | 
			
		||||
| 
						 | 
				
			
			@ -116,19 +116,19 @@ describe('export-clips', () => {
 | 
			
		|||
	});
 | 
			
		||||
 | 
			
		||||
	test('multiple clips', async () => {
 | 
			
		||||
		let res = await api('clips/create', {
 | 
			
		||||
		const res1 = await api('clips/create', {
 | 
			
		||||
			name: 'kawaii',
 | 
			
		||||
			description: 'kawaii',
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 200);
 | 
			
		||||
		const clip1 = res.body;
 | 
			
		||||
		assert.strictEqual(res1.status, 200);
 | 
			
		||||
		const clip1 = res1.body;
 | 
			
		||||
 | 
			
		||||
		res = await api('clips/create', {
 | 
			
		||||
		const res2 = await api('clips/create', {
 | 
			
		||||
			name: 'yuri',
 | 
			
		||||
			description: 'yuri',
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 200);
 | 
			
		||||
		const clip2 = res.body;
 | 
			
		||||
		assert.strictEqual(res2.status, 200);
 | 
			
		||||
		const clip2 = res2.body;
 | 
			
		||||
 | 
			
		||||
		const note1 = await post(alice, {
 | 
			
		||||
			text: 'baz1',
 | 
			
		||||
| 
						 | 
				
			
			@ -138,20 +138,26 @@ describe('export-clips', () => {
 | 
			
		|||
			text: 'baz2',
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res = await api('clips/add-note', {
 | 
			
		||||
			clipId: clip1.id,
 | 
			
		||||
			noteId: note1.id,
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		{
 | 
			
		||||
			const res = await api('clips/add-note', {
 | 
			
		||||
				clipId: clip1.id,
 | 
			
		||||
				noteId: note1.id,
 | 
			
		||||
			}, alice);
 | 
			
		||||
			assert.strictEqual(res.status, 204);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		res = await api('clips/add-note', {
 | 
			
		||||
			clipId: clip2.id,
 | 
			
		||||
			noteId: note2.id,
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		{
 | 
			
		||||
			const res = await api('clips/add-note', {
 | 
			
		||||
				clipId: clip2.id,
 | 
			
		||||
				noteId: note2.id,
 | 
			
		||||
			}, alice);
 | 
			
		||||
			assert.strictEqual(res.status, 204);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		res = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		{
 | 
			
		||||
			const res = await api('i/export-clips', {}, alice);
 | 
			
		||||
			assert.strictEqual(res.status, 204);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const exported = await pollFirstDriveFile();
 | 
			
		||||
		assert.strictEqual(exported[0].name, 'kawaii');
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +169,7 @@ describe('export-clips', () => {
 | 
			
		|||
	});
 | 
			
		||||
 | 
			
		||||
	test('Clipping other user\'s note', async () => {
 | 
			
		||||
		let res = await api('clips/create', {
 | 
			
		||||
		const res = await api('clips/create', {
 | 
			
		||||
			name: 'kawaii',
 | 
			
		||||
			description: 'kawaii',
 | 
			
		||||
		}, alice);
 | 
			
		||||
| 
						 | 
				
			
			@ -175,14 +181,14 @@ describe('export-clips', () => {
 | 
			
		|||
			visibility: 'followers',
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res = await api('clips/add-note', {
 | 
			
		||||
		const res2 = await api('clips/add-note', {
 | 
			
		||||
			clipId: clip.id,
 | 
			
		||||
			noteId: note.id,
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		assert.strictEqual(res2.status, 204);
 | 
			
		||||
 | 
			
		||||
		res = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 204);
 | 
			
		||||
		const res3 = await api('i/export-clips', {}, alice);
 | 
			
		||||
		assert.strictEqual(res3.status, 204);
 | 
			
		||||
 | 
			
		||||
		const exported = await pollFirstDriveFile();
 | 
			
		||||
		assert.strictEqual(exported[0].name, 'kawaii');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,14 +13,14 @@ import { loadConfig } from '@/config.js';
 | 
			
		|||
import { MiRepository, MiUser, UsersRepository, miRepository } from '@/models/_.js';
 | 
			
		||||
import { secureRndstr } from '@/misc/secure-rndstr.js';
 | 
			
		||||
import { jobQueue } from '@/boot/common.js';
 | 
			
		||||
import { api, initTestDb, signup, successfulApiCall, uploadFile } from '../utils.js';
 | 
			
		||||
import { api, castAsError, initTestDb, signup, successfulApiCall, uploadFile } from '../utils.js';
 | 
			
		||||
import type * as misskey from 'misskey-js';
 | 
			
		||||
 | 
			
		||||
describe('Account Move', () => {
 | 
			
		||||
	let jq: INestApplicationContext;
 | 
			
		||||
	let url: URL;
 | 
			
		||||
 | 
			
		||||
	let root: any;
 | 
			
		||||
	let root: misskey.entities.SignupResponse;
 | 
			
		||||
	let alice: misskey.entities.SignupResponse;
 | 
			
		||||
	let bob: misskey.entities.SignupResponse;
 | 
			
		||||
	let carol: misskey.entities.SignupResponse;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +93,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Unable to add duplicated aliases to alsoKnownAs', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,8 +103,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'INVALID_PARAM');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, '3d81ceae-475f-4600-b2a8-2bc116157532');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'INVALID_PARAM');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '3d81ceae-475f-4600-b2a8-2bc116157532');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Unable to add itself', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -113,8 +113,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'FORBIDDEN_TO_SET_YOURSELF');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, '25c90186-4ab0-49c8-9bba-a1fa6c202ba4');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'FORBIDDEN_TO_SET_YOURSELF');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '25c90186-4ab0-49c8-9bba-a1fa6c202ba4');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Unable to add a nonexisting local account to alsoKnownAs', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,16 +123,16 @@ describe('Account Move', () => {
 | 
			
		|||
			}, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res1.status, 400);
 | 
			
		||||
			assert.strictEqual(res1.body.error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(res1.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
			assert.strictEqual(castAsError(res1.body).error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(castAsError(res1.body).error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
 | 
			
		||||
			const res2 = await api('i/update', {
 | 
			
		||||
				alsoKnownAs: ['@alice', 'nonexist'],
 | 
			
		||||
			}, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res2.status, 400);
 | 
			
		||||
			assert.strictEqual(res2.body.error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(res2.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
			assert.strictEqual(castAsError(res2.body).error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(castAsError(res2.body).error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Able to add two existing local account to alsoKnownAs', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -241,8 +241,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, root);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'NOT_ROOT_FORBIDDEN');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, '4362e8dc-731f-4ad8-a694-be2a88922a24');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'NOT_ROOT_FORBIDDEN');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '4362e8dc-731f-4ad8-a694-be2a88922a24');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Unable to move to a nonexisting local account', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -251,8 +251,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'NO_SUCH_USER');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Unable to move if alsoKnownAs is invalid', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -261,8 +261,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'DESTINATION_ACCOUNT_FORBIDS');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, 'b5c90186-4ab0-49c8-9bba-a1f766282ba4');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'DESTINATION_ACCOUNT_FORBIDS');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, 'b5c90186-4ab0-49c8-9bba-a1f766282ba4');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Relationships have been properly migrated', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -279,36 +279,44 @@ describe('Account Move', () => {
 | 
			
		|||
				userId: alice.id,
 | 
			
		||||
			}, alice);
 | 
			
		||||
			assert.strictEqual(aliceFollowings.status, 200);
 | 
			
		||||
			assert.ok(aliceFollowings);
 | 
			
		||||
			assert.strictEqual(aliceFollowings.body.length, 3);
 | 
			
		||||
 | 
			
		||||
			const carolFollowings = await api('users/following', {
 | 
			
		||||
				userId: carol.id,
 | 
			
		||||
			}, carol);
 | 
			
		||||
			assert.strictEqual(carolFollowings.status, 200);
 | 
			
		||||
			assert.ok(carolFollowings);
 | 
			
		||||
			assert.strictEqual(carolFollowings.body.length, 2);
 | 
			
		||||
			assert.strictEqual(carolFollowings.body[0].followeeId, bob.id);
 | 
			
		||||
			assert.strictEqual(carolFollowings.body[1].followeeId, alice.id);
 | 
			
		||||
 | 
			
		||||
			const blockings = await api('blocking/list', {}, dave);
 | 
			
		||||
			assert.strictEqual(blockings.status, 200);
 | 
			
		||||
			assert.ok(blockings);
 | 
			
		||||
			assert.strictEqual(blockings.body.length, 2);
 | 
			
		||||
			assert.strictEqual(blockings.body[0].blockeeId, bob.id);
 | 
			
		||||
			assert.strictEqual(blockings.body[1].blockeeId, alice.id);
 | 
			
		||||
 | 
			
		||||
			const mutings = await api('mute/list', {}, dave);
 | 
			
		||||
			assert.strictEqual(mutings.status, 200);
 | 
			
		||||
			assert.ok(mutings);
 | 
			
		||||
			assert.strictEqual(mutings.body.length, 2);
 | 
			
		||||
			assert.strictEqual(mutings.body[0].muteeId, bob.id);
 | 
			
		||||
			assert.strictEqual(mutings.body[1].muteeId, alice.id);
 | 
			
		||||
 | 
			
		||||
			const rootLists = await api('users/lists/list', {}, root);
 | 
			
		||||
			assert.strictEqual(rootLists.status, 200);
 | 
			
		||||
			assert.ok(rootLists);
 | 
			
		||||
			assert.ok(rootLists.body[0].userIds);
 | 
			
		||||
			assert.strictEqual(rootLists.body[0].userIds.length, 2);
 | 
			
		||||
			assert.ok(rootLists.body[0].userIds.find((id: string) => id === bob.id));
 | 
			
		||||
			assert.ok(rootLists.body[0].userIds.find((id: string) => id === alice.id));
 | 
			
		||||
 | 
			
		||||
			const eveLists = await api('users/lists/list', {}, eve);
 | 
			
		||||
			assert.strictEqual(eveLists.status, 200);
 | 
			
		||||
			assert.ok(eveLists);
 | 
			
		||||
			assert.ok(eveLists.body[0].userIds);
 | 
			
		||||
			assert.strictEqual(eveLists.body[0].userIds.length, 1);
 | 
			
		||||
			assert.ok(eveLists.body[0].userIds.find((id: string) => id === bob.id));
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			@ -347,8 +355,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'DESTINATION_ACCOUNT_FORBIDS');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, 'b5c90186-4ab0-49c8-9bba-a1f766282ba4');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'DESTINATION_ACCOUNT_FORBIDS');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, 'b5c90186-4ab0-49c8-9bba-a1f766282ba4');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Follow and follower counts are properly adjusted', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -419,8 +427,9 @@ describe('Account Move', () => {
 | 
			
		|||
		] as const)('Prohibit access after moving: %s', async (endpoint) => {
 | 
			
		||||
			const res = await api(endpoint, {}, alice);
 | 
			
		||||
			assert.strictEqual(res.status, 403);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
			assert.ok(res.body);
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Prohibit access after moving: /antennas/update', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -438,16 +447,19 @@ describe('Account Move', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 403);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
			assert.ok(res.body);
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Prohibit access after moving: /drive/files/create', async () => {
 | 
			
		||||
			// FIXME: 一旦逃げておく
 | 
			
		||||
			const res = await uploadFile(alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 403);
 | 
			
		||||
			assert.strictEqual((res.body! as any as { error: misskey.api.APIError }).error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual((res.body! as any as { error: misskey.api.APIError }).error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
			assert.ok(res.body);
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('Prohibit updating alsoKnownAs after moving', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -456,8 +468,8 @@ describe('Account Move', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 403);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(res.body.error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'YOUR_ACCOUNT_MOVED');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,8 +47,8 @@ describe('Mute', () => {
 | 
			
		|||
 | 
			
		||||
		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 === carolNote.id), false);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('ミュートしているユーザーからメンションされても、hasUnreadMentions が true にならない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -92,9 +92,9 @@ describe('Mute', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('タイムラインにミュートしているユーザーの投稿のRenoteが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -108,9 +108,9 @@ describe('Mute', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,8 +124,8 @@ describe('Mute', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのリプライが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -138,8 +138,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのリプライが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -152,8 +152,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからの引用リノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -166,8 +166,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのリノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -180,8 +180,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのフォロー通知が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -193,8 +193,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
 | 
			
		||||
			await api('following/delete', { userId: alice.id }, bob);
 | 
			
		||||
			await api('following/delete', { userId: alice.id }, carol);
 | 
			
		||||
| 
						 | 
				
			
			@ -210,8 +210,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
 | 
			
		||||
			await api('following/delete', { userId: alice.id }, bob);
 | 
			
		||||
			await api('following/delete', { userId: alice.id }, carol);
 | 
			
		||||
| 
						 | 
				
			
			@ -228,8 +228,8 @@ describe('Mute', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
		test('通知にミュートしているユーザーからのリプライが含まれない', async () => {
 | 
			
		||||
			const aliceNote = await post(alice, { text: 'hi' });
 | 
			
		||||
| 
						 | 
				
			
			@ -241,8 +241,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのリプライが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -255,8 +255,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからの引用リノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -269,8 +269,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのリノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -283,8 +283,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('通知にミュートしているユーザーからのフォロー通知が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -296,8 +296,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
 | 
			
		||||
			await api('following/delete', { userId: alice.id }, bob);
 | 
			
		||||
			await api('following/delete', { userId: alice.id }, carol);
 | 
			
		||||
| 
						 | 
				
			
			@ -313,8 +313,8 @@ describe('Mute', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === bob.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(notification => 'userId' in notification && notification.userId === carol.id), false);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,16 +3,18 @@
 | 
			
		|||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import type { Repository } from "typeorm";
 | 
			
		||||
 | 
			
		||||
process.env.NODE_ENV = 'test';
 | 
			
		||||
 | 
			
		||||
import * as assert from 'assert';
 | 
			
		||||
import { MiNote } from '@/models/Note.js';
 | 
			
		||||
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
 | 
			
		||||
import { api, initTestDb, post, role, signup, uploadFile, uploadUrl } from '../utils.js';
 | 
			
		||||
import { api, castAsError, initTestDb, post, role, signup, uploadFile, uploadUrl } from '../utils.js';
 | 
			
		||||
import type * as misskey from 'misskey-js';
 | 
			
		||||
 | 
			
		||||
describe('Note', () => {
 | 
			
		||||
	let Notes: any;
 | 
			
		||||
	let Notes: Repository<MiNote>;
 | 
			
		||||
 | 
			
		||||
	let root: misskey.entities.SignupResponse;
 | 
			
		||||
	let alice: misskey.entities.SignupResponse;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +63,8 @@ describe('Note', () => {
 | 
			
		|||
		}, alice);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.code, 'NO_SUCH_FILE');
 | 
			
		||||
		assert.strictEqual(res.body.error.id, 'b6992544-63e7-67f0-fa7f-32444b1b5306');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.code, 'NO_SUCH_FILE');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, 'b6992544-63e7-67f0-fa7f-32444b1b5306');
 | 
			
		||||
	}, 1000 * 10);
 | 
			
		||||
 | 
			
		||||
	test('存在しないファイルで怒られる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -72,8 +74,8 @@ describe('Note', () => {
 | 
			
		|||
		}, alice);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.code, 'NO_SUCH_FILE');
 | 
			
		||||
		assert.strictEqual(res.body.error.id, 'b6992544-63e7-67f0-fa7f-32444b1b5306');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.code, 'NO_SUCH_FILE');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, 'b6992544-63e7-67f0-fa7f-32444b1b5306');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('不正なファイルIDで怒られる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,8 +83,8 @@ describe('Note', () => {
 | 
			
		|||
			fileIds: ['kyoppie'],
 | 
			
		||||
		}, alice);
 | 
			
		||||
		assert.strictEqual(res.status, 400);
 | 
			
		||||
		assert.strictEqual(res.body.error.code, 'NO_SUCH_FILE');
 | 
			
		||||
		assert.strictEqual(res.body.error.id, 'b6992544-63e7-67f0-fa7f-32444b1b5306');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.code, 'NO_SUCH_FILE');
 | 
			
		||||
		assert.strictEqual(castAsError(res.body).error.id, 'b6992544-63e7-67f0-fa7f-32444b1b5306');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('返信できる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -101,6 +103,7 @@ describe('Note', () => {
 | 
			
		|||
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.text, alicePost.text);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.replyId, alicePost.replyId);
 | 
			
		||||
		assert.ok(res.body.createdNote.reply);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.reply.text, bobPost.text);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +121,7 @@ describe('Note', () => {
 | 
			
		|||
		assert.strictEqual(res.status, 200);
 | 
			
		||||
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.renoteId, alicePost.renoteId);
 | 
			
		||||
		assert.ok(res.body.createdNote.renote);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.renote.text, bobPost.text);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -137,6 +141,7 @@ describe('Note', () => {
 | 
			
		|||
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.text, alicePost.text);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.renoteId, alicePost.renoteId);
 | 
			
		||||
		assert.ok(res.body.createdNote.renote);
 | 
			
		||||
		assert.strictEqual(res.body.createdNote.renote.text, bobPost.text);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +223,7 @@ describe('Note', () => {
 | 
			
		|||
		}, bob);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(bobReply.status, 400);
 | 
			
		||||
		assert.strictEqual(bobReply.body.error.code, 'CANNOT_REPLY_TO_AN_INVISIBLE_NOTE');
 | 
			
		||||
		assert.strictEqual(castAsError(bobReply.body).error.code, 'CANNOT_REPLY_TO_AN_INVISIBLE_NOTE');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('visibility: specifiedなノートに対してvisibility: specifiedで返信できる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +261,7 @@ describe('Note', () => {
 | 
			
		|||
		}, bob);
 | 
			
		||||
 | 
			
		||||
		assert.strictEqual(bobReply.status, 400);
 | 
			
		||||
		assert.strictEqual(bobReply.body.error.code, 'CANNOT_REPLY_TO_SPECIFIED_VISIBILITY_NOTE_WITH_EXTENDED_VISIBILITY');
 | 
			
		||||
		assert.strictEqual(castAsError(bobReply.body).error.code, 'CANNOT_REPLY_TO_SPECIFIED_VISIBILITY_NOTE_WITH_EXTENDED_VISIBILITY');
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('文字数ぎりぎりで怒られない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -333,6 +338,7 @@ describe('Note', () => {
 | 
			
		|||
		assert.strictEqual(res.body.createdNote.text, post.text);
 | 
			
		||||
 | 
			
		||||
		const noteDoc = await Notes.findOneBy({ id: res.body.createdNote.id });
 | 
			
		||||
		assert.ok(noteDoc);
 | 
			
		||||
		assert.deepStrictEqual(noteDoc.mentions, [bob.id]);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -345,6 +351,7 @@ describe('Note', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
 | 
			
		||||
			assert.ok(res.body.createdNote.files);
 | 
			
		||||
			assert.strictEqual(res.body.createdNote.files.length, 1);
 | 
			
		||||
			assert.strictEqual(res.body.createdNote.files[0].id, file.body!.id);
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			@ -363,8 +370,9 @@ describe('Note', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			const myNote = res.body.find((note: { id: string; files: { id: string }[] }) => note.id === createdNote.body.createdNote.id);
 | 
			
		||||
			assert.notEqual(myNote, null);
 | 
			
		||||
			const myNote = res.body.find(note => note.id === createdNote.body.createdNote.id);
 | 
			
		||||
			assert.ok(myNote);
 | 
			
		||||
			assert.ok(myNote.files);
 | 
			
		||||
			assert.strictEqual(myNote.files.length, 1);
 | 
			
		||||
			assert.strictEqual(myNote.files[0].id, file.body!.id);
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			@ -389,7 +397,9 @@ describe('Note', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			const myNote = res.body.find((note: { id: string }) => note.id === renoted.body.createdNote.id);
 | 
			
		||||
			assert.notEqual(myNote, null);
 | 
			
		||||
			assert.ok(myNote);
 | 
			
		||||
			assert.ok(myNote.renote);
 | 
			
		||||
			assert.ok(myNote.renote.files);
 | 
			
		||||
			assert.strictEqual(myNote.renote.files.length, 1);
 | 
			
		||||
			assert.strictEqual(myNote.renote.files[0].id, file.body!.id);
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			@ -415,7 +425,9 @@ describe('Note', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			const myNote = res.body.find((note: { id: string }) => note.id === reply.body.createdNote.id);
 | 
			
		||||
			assert.notEqual(myNote, null);
 | 
			
		||||
			assert.ok(myNote);
 | 
			
		||||
			assert.ok(myNote.reply);
 | 
			
		||||
			assert.ok(myNote.reply.files);
 | 
			
		||||
			assert.strictEqual(myNote.reply.files.length, 1);
 | 
			
		||||
			assert.strictEqual(myNote.reply.files[0].id, file.body!.id);
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			@ -446,7 +458,10 @@ describe('Note', () => {
 | 
			
		|||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
			assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
			const myNote = res.body.find((note: { id: string }) => note.id === renoted.body.createdNote.id);
 | 
			
		||||
			assert.notEqual(myNote, null);
 | 
			
		||||
			assert.ok(myNote);
 | 
			
		||||
			assert.ok(myNote.renote);
 | 
			
		||||
			assert.ok(myNote.renote.reply);
 | 
			
		||||
			assert.ok(myNote.renote.reply.files);
 | 
			
		||||
			assert.strictEqual(myNote.renote.reply.files.length, 1);
 | 
			
		||||
			assert.strictEqual(myNote.renote.reply.files[0].id, file.body!.id);
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			@ -474,7 +489,7 @@ describe('Note', () => {
 | 
			
		|||
						priority: 0,
 | 
			
		||||
						value: true,
 | 
			
		||||
					},
 | 
			
		||||
				} as any,
 | 
			
		||||
				},
 | 
			
		||||
			}, root);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
| 
						 | 
				
			
			@ -498,7 +513,7 @@ describe('Note', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(liftnsfw.status, 400);
 | 
			
		||||
			assert.strictEqual(liftnsfw.body.error.code, 'RESTRICTED_BY_ROLE');
 | 
			
		||||
			assert.strictEqual(castAsError(liftnsfw.body).error.code, 'RESTRICTED_BY_ROLE');
 | 
			
		||||
 | 
			
		||||
			const oldaddnsfw = await api('drive/files/update', {
 | 
			
		||||
				fileId: file.body!.id,
 | 
			
		||||
| 
						 | 
				
			
			@ -710,7 +725,7 @@ describe('Note', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(note1.status, 400);
 | 
			
		||||
			assert.strictEqual(note1.body.error.code, 'CONTAINS_PROHIBITED_WORDS');
 | 
			
		||||
			assert.strictEqual(castAsError(note1.body).error.code, 'CONTAINS_PROHIBITED_WORDS');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('禁止ワードを含む投稿はエラーになる (正規表現)', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -727,7 +742,7 @@ describe('Note', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(note2.status, 400);
 | 
			
		||||
			assert.strictEqual(note2.body.error.code, 'CONTAINS_PROHIBITED_WORDS');
 | 
			
		||||
			assert.strictEqual(castAsError(note2.body).error.code, 'CONTAINS_PROHIBITED_WORDS');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('禁止ワードを含む投稿はエラーになる (スペースアンド)', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -744,7 +759,7 @@ describe('Note', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(note2.status, 400);
 | 
			
		||||
			assert.strictEqual(note2.body.error.code, 'CONTAINS_PROHIBITED_WORDS');
 | 
			
		||||
			assert.strictEqual(castAsError(note2.body).error.code, 'CONTAINS_PROHIBITED_WORDS');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('禁止ワードを含んでるリモートノートもエラーになる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -786,7 +801,7 @@ describe('Note', () => {
 | 
			
		|||
						priority: 1,
 | 
			
		||||
						value: 0,
 | 
			
		||||
					},
 | 
			
		||||
				} as any,
 | 
			
		||||
				},
 | 
			
		||||
			}, root);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
| 
						 | 
				
			
			@ -807,7 +822,7 @@ describe('Note', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(note.status, 400);
 | 
			
		||||
			assert.strictEqual(note.body.error.code, 'CONTAINS_TOO_MANY_MENTIONS');
 | 
			
		||||
			assert.strictEqual(castAsError(note.body).error.code, 'CONTAINS_TOO_MANY_MENTIONS');
 | 
			
		||||
 | 
			
		||||
			await api('admin/roles/unassign', {
 | 
			
		||||
				userId: alice.id,
 | 
			
		||||
| 
						 | 
				
			
			@ -840,7 +855,7 @@ describe('Note', () => {
 | 
			
		|||
						priority: 1,
 | 
			
		||||
						value: 0,
 | 
			
		||||
					},
 | 
			
		||||
				} as any,
 | 
			
		||||
				},
 | 
			
		||||
			}, root);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
| 
						 | 
				
			
			@ -863,7 +878,7 @@ describe('Note', () => {
 | 
			
		|||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(note.status, 400);
 | 
			
		||||
			assert.strictEqual(note.body.error.code, 'CONTAINS_TOO_MANY_MENTIONS');
 | 
			
		||||
			assert.strictEqual(castAsError(note.body).error.code, 'CONTAINS_TOO_MANY_MENTIONS');
 | 
			
		||||
 | 
			
		||||
			await api('admin/roles/unassign', {
 | 
			
		||||
				userId: alice.id,
 | 
			
		||||
| 
						 | 
				
			
			@ -896,7 +911,7 @@ describe('Note', () => {
 | 
			
		|||
						priority: 1,
 | 
			
		||||
						value: 1,
 | 
			
		||||
					},
 | 
			
		||||
				} as any,
 | 
			
		||||
				},
 | 
			
		||||
			}, root);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 200);
 | 
			
		||||
| 
						 | 
				
			
			@ -951,6 +966,7 @@ describe('Note', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(deleteOneRes.status, 204);
 | 
			
		||||
			let mainNote = await Notes.findOneBy({ id: mainNoteRes.body.createdNote.id });
 | 
			
		||||
			assert.ok(mainNote);
 | 
			
		||||
			assert.strictEqual(mainNote.repliesCount, 1);
 | 
			
		||||
 | 
			
		||||
			const deleteTwoRes = await api('notes/delete', {
 | 
			
		||||
| 
						 | 
				
			
			@ -959,6 +975,7 @@ describe('Note', () => {
 | 
			
		|||
 | 
			
		||||
			assert.strictEqual(deleteTwoRes.status, 204);
 | 
			
		||||
			mainNote = await Notes.findOneBy({ id: mainNoteRes.body.createdNote.id });
 | 
			
		||||
			assert.ok(mainNote);
 | 
			
		||||
			assert.strictEqual(mainNote.repliesCount, 0);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			@ -980,7 +997,7 @@ describe('Note', () => {
 | 
			
		|||
				}, alice);
 | 
			
		||||
 | 
			
		||||
				assert.strictEqual(res.status, 400);
 | 
			
		||||
				assert.strictEqual(res.body.error.code, 'UNAVAILABLE');
 | 
			
		||||
				assert.strictEqual(castAsError(res.body).error.code, 'UNAVAILABLE');
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			afterAll(async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -992,7 +1009,7 @@ describe('Note', () => {
 | 
			
		|||
			const res = await api('notes/translate', { noteId: 'foo', targetLang: 'ja' }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'NO_SUCH_NOTE');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'NO_SUCH_NOTE');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('不可視なノートは翻訳できない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1000,7 +1017,7 @@ describe('Note', () => {
 | 
			
		|||
			const bobTranslateAttempt = await api('notes/translate', { noteId: aliceNote.id, targetLang: 'ja' }, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(bobTranslateAttempt.status, 400);
 | 
			
		||||
			assert.strictEqual(bobTranslateAttempt.body.error.code, 'CANNOT_TRANSLATE_INVISIBLE_NOTE');
 | 
			
		||||
			assert.strictEqual(castAsError(bobTranslateAttempt.body).error.code, 'CANNOT_TRANSLATE_INVISIBLE_NOTE');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('text: null なノートを翻訳すると空のレスポンスが返ってくる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1016,7 +1033,7 @@ describe('Note', () => {
 | 
			
		|||
 | 
			
		||||
			// NOTE: デフォルトでは登録されていないので落ちる
 | 
			
		||||
			assert.strictEqual(res.status, 400);
 | 
			
		||||
			assert.strictEqual(res.body.error.code, 'UNAVAILABLE');
 | 
			
		||||
			assert.strictEqual(castAsError(res.body).error.code, 'UNAVAILABLE');
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,9 +42,9 @@ describe('Renote Mute', () => {
 | 
			
		|||
 | 
			
		||||
		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);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolRenote.id), false);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('タイムラインにリノートミュートしているユーザーの引用が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +59,9 @@ describe('Renote Mute', () => {
 | 
			
		|||
 | 
			
		||||
		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);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolRenote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// #12956
 | 
			
		||||
| 
						 | 
				
			
			@ -76,8 +76,8 @@ describe('Renote Mute', () => {
 | 
			
		|||
 | 
			
		||||
		assert.strictEqual(res.status, 200);
 | 
			
		||||
		assert.strictEqual(Array.isArray(res.body), true);
 | 
			
		||||
		assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some((note: any) => note.id === bobRenote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === bobRenote.id), true);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('ストリームにリノートミュートしているユーザーのリノートが流れない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,9 +33,9 @@ describe('Note thread mute', () => {
 | 
			
		|||
 | 
			
		||||
		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);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolReply.id), false);
 | 
			
		||||
		assert.strictEqual(res.body.some(note => note.id === carolReplyWithoutMention.id), false);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	test('ミュートしているスレッドからメンションされても、hasUnreadMentions が true にならない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +93,8 @@ describe('Note thread mute', () => {
 | 
			
		|||
 | 
			
		||||
		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);
 | 
			
		||||
		assert.strictEqual(res.body.some(notification => 'note' in notification && notification.note.id === carolReply.id), false);
 | 
			
		||||
		assert.strictEqual(res.body.some(notification => 'note' in notification && notification.note.id === carolReplyWithoutMention.id), false);
 | 
			
		||||
 | 
			
		||||
		// NOTE: bobの投稿はスレッドミュート前に行われたため通知に含まれていてもよい
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,8 +37,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === aliceNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーのノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -53,8 +53,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーの visibility: followers なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -69,9 +69,9 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === bobNote.id)?.text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でフォローしているユーザーの他人への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -86,8 +86,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーの他人への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,8 +103,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーの他人へのDM返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -120,8 +120,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーの他人の visibility: followers な投稿への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -137,8 +137,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーの行った別のフォローしているユーザーの visibility: followers な投稿への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -156,9 +156,9 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === carolNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === carolNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーの行った別のフォローしているユーザーの投稿への visibility: specified な返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -175,8 +175,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でフォローしているユーザーのそのユーザー自身への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -191,8 +191,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -207,8 +207,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, 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);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('自分の他人への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -221,8 +221,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーの他人の投稿のリノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -237,8 +237,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withRenotes: false] フォローしているユーザーの他人の投稿のリノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -255,8 +255,8 @@ describe('Timelines', () => {
 | 
			
		|||
				withRenotes: false,
 | 
			
		||||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withRenotes: false] フォローしているユーザーの他人の投稿の引用が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -273,8 +273,8 @@ describe('Timelines', () => {
 | 
			
		|||
				withRenotes: false,
 | 
			
		||||
			}, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーの他人への visibility: specified なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -288,7 +288,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーが行ったミュートしているユーザーのリノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -304,8 +304,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーが行ったミュートしているユーザーの投稿への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -322,8 +322,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているリモートユーザーのノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -338,7 +338,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているリモートユーザーの visibility: home なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +353,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withFiles: true] フォローしているユーザーのファイル付きノートのみ含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -374,10 +374,10 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100, withFiles: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote2.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote2.id), false);
 | 
			
		||||
		}, 1000 * 10);
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーのチャンネル投稿が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -392,7 +392,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('自分の visibility: specified なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -404,8 +404,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === aliceNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーの自身を visibleUserIds に指定した visibility: specified なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -419,8 +419,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === bobNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしていないユーザーの自身を visibleUserIds に指定した visibility: specified なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -432,7 +432,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーの自身を visibleUserIds に指定していない visibility: specified なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -446,7 +446,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしていないユーザーからの visibility: specified なノートに返信したときの自身のノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -459,8 +459,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'ok');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === aliceNote.id)?.text, 'ok');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		/* TODO
 | 
			
		||||
| 
						 | 
				
			
			@ -474,8 +474,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'ok');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === bobNote.id).text, 'ok');
 | 
			
		||||
		});
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -490,7 +490,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -505,8 +505,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('他人の他人への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -519,8 +519,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('他人のその人自身への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -533,8 +533,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('チャンネル投稿が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -547,7 +547,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リモートユーザーのノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -559,7 +559,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// 含まれても良いと思うけど実装が面倒なので含まれない
 | 
			
		||||
| 
						 | 
				
			
			@ -575,8 +575,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('ミュートしているユーザーのノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -591,8 +591,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーが行ったミュートしているユーザーのリノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -608,8 +608,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でフォローしているユーザーが行ったミュートしているユーザーの投稿への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -626,8 +626,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -642,8 +642,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, 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);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withReplies: true] 他人の他人への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -656,7 +656,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100, withReplies: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -670,8 +670,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100, withFiles: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		}, 1000 * 10);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -685,7 +685,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('ローカルユーザーの visibility: home なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -697,7 +697,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているローカルユーザーの visibility: home なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -711,7 +711,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -726,8 +726,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, 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);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('他人の他人への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -740,8 +740,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === carolNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リモートユーザーのノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -753,7 +753,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/local-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているリモートユーザーのノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -768,7 +768,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているリモートユーザーの visibility: home なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -783,7 +783,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withReplies: true] 他人の他人への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -796,7 +796,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100, withReplies: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -810,8 +810,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/hybrid-timeline', { limit: 100, withFiles: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		}, 1000 * 10);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -828,7 +828,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているフォローしていないユーザーの visibility: home なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -843,7 +843,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているフォローしていないユーザーの visibility: followers なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -858,7 +858,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているフォローしていないユーザーの他人への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -874,7 +874,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているフォローしていないユーザーのユーザー自身への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -890,8 +890,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でリスインしているフォローしていないユーザーからの自分への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -908,7 +908,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: false でリスインしているフォローしていないユーザーの他人への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -925,7 +925,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('withReplies: true でリスインしているフォローしていないユーザーの他人への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -942,7 +942,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているフォローしているユーザーの visibility: home なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -958,7 +958,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているフォローしているユーザーの visibility: followers なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -974,8 +974,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === bobNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしている自分の visibility: followers なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -990,8 +990,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === aliceNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているユーザーのチャンネルノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1007,7 +1007,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withFiles: true] リスインしているユーザーのファイル付きノートのみ含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1023,8 +1023,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id, withFiles: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		}, 1000 * 10);
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1039,8 +1039,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === bobNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('リスインしているユーザーの自身宛てではない visibility: specified なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1056,7 +1056,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,7 +1070,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしていないユーザーの visibility: followers なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1082,7 +1082,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('フォローしているユーザーの visibility: followers なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1096,8 +1096,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === bobNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('自身の visibility: followers なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1109,8 +1109,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: alice.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.find(note => note.id === aliceNote.id)?.text, 'hi');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('チャンネル投稿が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1123,7 +1123,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withReplies: false] 他人への返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1137,8 +1137,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withReplies: true] 他人への返信が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1152,8 +1152,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withReplies: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withReplies: true] 他人への visibility: specified な返信が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1167,8 +1167,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withReplies: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1182,8 +1182,8 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withFiles: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
		}, 1000 * 10);
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1196,7 +1196,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withChannelNotes: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withChannelNotes: true] 他人が取得した場合センシティブチャンネル投稿が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1209,7 +1209,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withChannelNotes: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('[withChannelNotes: true] 自分が取得した場合センシティブチャンネル投稿が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1222,7 +1222,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withChannelNotes: true }, bob);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('ミュートしているユーザーに関連する投稿が含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1237,7 +1237,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('ミュートしていても userId に指定したユーザーの投稿が含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1253,9 +1253,9 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote3.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote1.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote3.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('自身の visibility: specified なノートが含まれる', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1267,7 +1267,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: alice.id, withReplies: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test.concurrent('visibleUserIds に指定されてない visibility: specified なノートが含まれない', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1279,7 +1279,7 @@ describe('Timelines', () => {
 | 
			
		|||
 | 
			
		||||
			const res = await api('users/notes', { userId: bob.id, withReplies: true }, alice);
 | 
			
		||||
 | 
			
		||||
			assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
 | 
			
		||||
			assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		/** @see https://github.com/misskey-dev/misskey/issues/14000 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,10 +23,10 @@ describe('ApMfmService', () => {
 | 
			
		|||
 | 
			
		||||
	describe('getNoteHtml', () => {
 | 
			
		||||
		test('Do not provide _misskey_content for simple text', () => {
 | 
			
		||||
			const note: MiNote = {
 | 
			
		||||
			const note = {
 | 
			
		||||
				text: 'テキスト #タグ @mention 🍊 :emoji: https://example.com',
 | 
			
		||||
				mentionedRemoteUsers: '[]',
 | 
			
		||||
			} as any;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			const { content, noMisskeyContent } = apMfmService.getNoteHtml(note);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -35,10 +35,10 @@ describe('ApMfmService', () => {
 | 
			
		|||
		});
 | 
			
		||||
 | 
			
		||||
		test('Provide _misskey_content for MFM', () => {
 | 
			
		||||
			const note: MiNote = {
 | 
			
		||||
			const note = {
 | 
			
		||||
				text: '$[tada foo]',
 | 
			
		||||
				mentionedRemoteUsers: '[]',
 | 
			
		||||
			} as any;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			const { content, noMisskeyContent } = apMfmService.getNoteHtml(note);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ import { ModuleMocker } from 'jest-mock';
 | 
			
		|||
import { Test } from '@nestjs/testing';
 | 
			
		||||
import { afterAll, beforeAll, describe, test } from '@jest/globals';
 | 
			
		||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
			
		||||
import { FileInfoService } from '@/core/FileInfoService.js';
 | 
			
		||||
import { FileInfo, FileInfoService } from '@/core/FileInfoService.js';
 | 
			
		||||
//import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { AiService } from '@/core/AiService.js';
 | 
			
		||||
import { LoggerService } from '@/core/LoggerService.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +28,15 @@ const moduleMocker = new ModuleMocker(global);
 | 
			
		|||
describe('FileInfoService', () => {
 | 
			
		||||
	let app: TestingModule;
 | 
			
		||||
	let fileInfoService: FileInfoService;
 | 
			
		||||
	const strip = (fileInfo: FileInfo): Omit<Partial<FileInfo>, 'warnings' | 'blurhash' | 'sensitive' | 'porn'> => {
 | 
			
		||||
		const fi: Partial<FileInfo> = fileInfo;
 | 
			
		||||
		delete fi.warnings;
 | 
			
		||||
		delete fi.sensitive;
 | 
			
		||||
		delete fi.blurhash;
 | 
			
		||||
		delete fi.porn;
 | 
			
		||||
		
 | 
			
		||||
		return fi;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	beforeAll(async () => {
 | 
			
		||||
		app = await Test.createTestingModule({
 | 
			
		||||
| 
						 | 
				
			
			@ -63,11 +72,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
	test('Empty file', async () => {
 | 
			
		||||
		const path = `${resources}/emptyfile`;
 | 
			
		||||
		const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
		delete info.warnings;
 | 
			
		||||
		delete info.blurhash;
 | 
			
		||||
		delete info.sensitive;
 | 
			
		||||
		delete info.porn;
 | 
			
		||||
		const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
		assert.deepStrictEqual(info, {
 | 
			
		||||
			size: 0,
 | 
			
		||||
			md5: 'd41d8cd98f00b204e9800998ecf8427e',
 | 
			
		||||
| 
						 | 
				
			
			@ -84,11 +89,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
	describe('IMAGE', () => {
 | 
			
		||||
		test('Generic JPEG', async () => {
 | 
			
		||||
			const path = `${resources}/192.jpg`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 5131,
 | 
			
		||||
				md5: '8c9ed0677dd2b8f9f7472c3af247e5e3',
 | 
			
		||||
| 
						 | 
				
			
			@ -104,11 +105,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('Generic APNG', async () => {
 | 
			
		||||
			const path = `${resources}/anime.png`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 1868,
 | 
			
		||||
				md5: '08189c607bea3b952704676bb3c979e0',
 | 
			
		||||
| 
						 | 
				
			
			@ -124,11 +121,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('Generic AGIF', async () => {
 | 
			
		||||
			const path = `${resources}/anime.gif`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 2248,
 | 
			
		||||
				md5: '32c47a11555675d9267aee1a86571e7e',
 | 
			
		||||
| 
						 | 
				
			
			@ -144,11 +137,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('PNG with alpha', async () => {
 | 
			
		||||
			const path = `${resources}/with-alpha.png`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 3772,
 | 
			
		||||
				md5: 'f73535c3e1e27508885b69b10cf6e991',
 | 
			
		||||
| 
						 | 
				
			
			@ -164,11 +153,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('Generic SVG', async () => {
 | 
			
		||||
			const path = `${resources}/image.svg`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 505,
 | 
			
		||||
				md5: 'b6f52b4b021e7b92cdd04509c7267965',
 | 
			
		||||
| 
						 | 
				
			
			@ -185,11 +170,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
		test('SVG with XML definition', async () => {
 | 
			
		||||
			// https://github.com/misskey-dev/misskey/issues/4413
 | 
			
		||||
			const path = `${resources}/with-xml-def.svg`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 544,
 | 
			
		||||
				md5: '4b7a346cde9ccbeb267e812567e33397',
 | 
			
		||||
| 
						 | 
				
			
			@ -205,11 +186,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('Dimension limit', async () => {
 | 
			
		||||
			const path = `${resources}/25000x25000.png`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 75933,
 | 
			
		||||
				md5: '268c5dde99e17cf8fe09f1ab3f97df56',
 | 
			
		||||
| 
						 | 
				
			
			@ -225,11 +202,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('Rotate JPEG', async () => {
 | 
			
		||||
			const path = `${resources}/rotate.jpg`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			assert.deepStrictEqual(info, {
 | 
			
		||||
				size: 12624,
 | 
			
		||||
				md5: '68d5b2d8d1d1acbbce99203e3ec3857e',
 | 
			
		||||
| 
						 | 
				
			
			@ -247,11 +220,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
	describe('AUDIO', () => {
 | 
			
		||||
		test('MP3', async () => {
 | 
			
		||||
			const path = `${resources}/kick_gaba7.mp3`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			delete info.width;
 | 
			
		||||
			delete info.height;
 | 
			
		||||
			delete info.orientation;
 | 
			
		||||
| 
						 | 
				
			
			@ -267,11 +236,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('WAV', async () => {
 | 
			
		||||
			const path = `${resources}/kick_gaba7.wav`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			delete info.width;
 | 
			
		||||
			delete info.height;
 | 
			
		||||
			delete info.orientation;
 | 
			
		||||
| 
						 | 
				
			
			@ -287,11 +252,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('AAC', async () => {
 | 
			
		||||
			const path = `${resources}/kick_gaba7.aac`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			delete info.width;
 | 
			
		||||
			delete info.height;
 | 
			
		||||
			delete info.orientation;
 | 
			
		||||
| 
						 | 
				
			
			@ -307,11 +268,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('FLAC', async () => {
 | 
			
		||||
			const path = `${resources}/kick_gaba7.flac`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			delete info.width;
 | 
			
		||||
			delete info.height;
 | 
			
		||||
			delete info.orientation;
 | 
			
		||||
| 
						 | 
				
			
			@ -327,11 +284,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('MPEG-4 AUDIO (M4A)', async () => {
 | 
			
		||||
			const path = `${resources}/kick_gaba7.m4a`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			delete info.width;
 | 
			
		||||
			delete info.height;
 | 
			
		||||
			delete info.orientation;
 | 
			
		||||
| 
						 | 
				
			
			@ -347,11 +300,7 @@ describe('FileInfoService', () => {
 | 
			
		|||
 | 
			
		||||
		test('WEBM AUDIO', async () => {
 | 
			
		||||
			const path = `${resources}/kick_gaba7.webm`;
 | 
			
		||||
			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
 | 
			
		||||
			delete info.warnings;
 | 
			
		||||
			delete info.blurhash;
 | 
			
		||||
			delete info.sensitive;
 | 
			
		||||
			delete info.porn;
 | 
			
		||||
			const info = strip(await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }));
 | 
			
		||||
			delete info.width;
 | 
			
		||||
			delete info.height;
 | 
			
		||||
			delete info.orientation;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ import { entities } from '../src/postgres.js';
 | 
			
		|||
import { loadConfig } from '../src/config.js';
 | 
			
		||||
import type * as misskey from 'misskey-js';
 | 
			
		||||
import { type Response } from 'node-fetch';
 | 
			
		||||
import { ApiError } from "@/server/api/error.js";
 | 
			
		||||
 | 
			
		||||
export { server as startServer, jobQueue as startJobQueue } from '@/boot/common.js';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,27 +49,28 @@ export const successfulApiCall = async <E extends keyof misskey.Endpoints, P ext
 | 
			
		|||
	const res = await api(endpoint, parameters, user);
 | 
			
		||||
	const status = assertion.status ?? (res.body == null ? 204 : 200);
 | 
			
		||||
	assert.strictEqual(res.status, status, inspect(res.body, { depth: 5, colors: true }));
 | 
			
		||||
	return res.body;
 | 
			
		||||
 | 
			
		||||
	return res.body as misskey.api.SwitchCaseResponseType<E, P>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const failedApiCall = async <T, E extends keyof misskey.Endpoints, P extends misskey.Endpoints[E]['req']>(request: ApiRequest<E, P>, assertion: {
 | 
			
		||||
export const failedApiCall = async <E extends keyof misskey.Endpoints, P extends misskey.Endpoints[E]['req']>(request: ApiRequest<E, P>, assertion: {
 | 
			
		||||
	status: number,
 | 
			
		||||
	code: string,
 | 
			
		||||
	id: string
 | 
			
		||||
}): Promise<T> => {
 | 
			
		||||
}): Promise<void> => {
 | 
			
		||||
	const { endpoint, parameters, user } = request;
 | 
			
		||||
	const { status, code, id } = assertion;
 | 
			
		||||
	const res = await api(endpoint, parameters, user);
 | 
			
		||||
	assert.strictEqual(res.status, status, inspect(res.body));
 | 
			
		||||
	assert.strictEqual(res.body.error.code, code, inspect(res.body));
 | 
			
		||||
	assert.strictEqual(res.body.error.id, id, inspect(res.body));
 | 
			
		||||
	return res.body;
 | 
			
		||||
	assert.ok(res.body);
 | 
			
		||||
	assert.strictEqual(castAsError(res.body as any).error.code, code, inspect(res.body));
 | 
			
		||||
	assert.strictEqual(castAsError(res.body as any).error.id, id, inspect(res.body));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const api = async <E extends keyof misskey.Endpoints>(path: E, params: misskey.Endpoints[E]['req'], me?: UserToken): Promise<{
 | 
			
		||||
export const api = async <E extends keyof misskey.Endpoints, P extends misskey.Endpoints[E]['req']>(path: E, params: P, me?: UserToken): Promise<{
 | 
			
		||||
	status: number,
 | 
			
		||||
	headers: Headers,
 | 
			
		||||
	body: any
 | 
			
		||||
	body: misskey.api.SwitchCaseResponseType<E, P>
 | 
			
		||||
}> => {
 | 
			
		||||
	const bodyAuth: Record<string, string> = {};
 | 
			
		||||
	const headers: Record<string, string> = {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,13 +91,14 @@ export const api = async <E extends keyof misskey.Endpoints>(path: E, params: mi
 | 
			
		|||
	});
 | 
			
		||||
 | 
			
		||||
	const body = res.headers.get('content-type') === 'application/json; charset=utf-8'
 | 
			
		||||
		? await res.json()
 | 
			
		||||
		? await res.json() as misskey.api.SwitchCaseResponseType<E, P>
 | 
			
		||||
		: null;
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		status: res.status,
 | 
			
		||||
		headers: res.headers,
 | 
			
		||||
		body,
 | 
			
		||||
		// FIXME: removing this non-null assertion: requires better typing around empty response.
 | 
			
		||||
		body: body!,
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +144,8 @@ export const post = async (user: UserToken, params: misskey.Endpoints['notes/cre
 | 
			
		|||
 | 
			
		||||
	const res = await api('notes/create', q, user);
 | 
			
		||||
 | 
			
		||||
	return res.body ? res.body.createdNote : null;
 | 
			
		||||
	// FIXME: the return type should reflect this fact.
 | 
			
		||||
	return (res.body ? res.body.createdNote : null)!;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const createAppToken = async (user: UserToken, permissions: (typeof misskey.permissions)[number][]) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -635,3 +639,9 @@ export async function sendEnvResetRequest() {
 | 
			
		|||
		throw new Error('server env update failed.');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 与えられた値を強制的にエラーとみなす。この関数は型安全性を破壊するため、異常系のアサーション以外で用いられるべきではない。
 | 
			
		||||
// FIXME(misskey-js): misskey-jsがエラー情報を公開するようになったらこの関数を廃止する
 | 
			
		||||
export function castAsError(obj: Record<string, unknown>): { error: ApiError } {
 | 
			
		||||
	return obj as { error: ApiError };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue