From 433d46e57f127ae7b3dc3715e9363790425eeabf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?=
 <46447427+samunohito@users.noreply.github.com>
Date: Fri, 22 Dec 2023 09:06:13 +0900
Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E3=83=86=E3=82=B9=E3=83=88?=
 =?UTF-8?q?=E3=81=8C=E6=AD=BB=E3=82=93=E3=81=A7=E3=81=84=E3=82=8B=E3=81=AE?=
 =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3=20(#12738)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix test

* fix test

* fix test

* fix test

* fix test
---
 packages/backend/src/core/UserListService.ts | 13 ++++++++++---
 packages/backend/test/e2e/timelines.ts       | 15 +++++++--------
 packages/backend/test/unit/RoleService.ts    | 20 +++++++++++++++++---
 3 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts
index 832b715d97..b6e4e1e884 100644
--- a/packages/backend/src/core/UserListService.ts
+++ b/packages/backend/src/core/UserListService.ts
@@ -3,8 +3,9 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
+import { Inject, Injectable, OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
 import * as Redis from 'ioredis';
+import { ModuleRef } from '@nestjs/core';
 import type { UserListMembershipsRepository } from '@/models/_.js';
 import type { MiUser } from '@/models/User.js';
 import type { MiUserList } from '@/models/UserList.js';
@@ -21,12 +22,15 @@ import { RedisKVCache } from '@/misc/cache.js';
 import { RoleService } from '@/core/RoleService.js';
 
 @Injectable()
-export class UserListService implements OnApplicationShutdown {
+export class UserListService implements OnApplicationShutdown, OnModuleInit {
 	public static TooManyUsersError = class extends Error {};
 
 	public membersCache: RedisKVCache<Set<string>>;
+	private roleService: RoleService;
 
 	constructor(
+		private moduleRef: ModuleRef,
+
 		@Inject(DI.redis)
 		private redisClient: Redis.Redis,
 
@@ -38,7 +42,6 @@ export class UserListService implements OnApplicationShutdown {
 
 		private userEntityService: UserEntityService,
 		private idService: IdService,
-		private roleService: RoleService,
 		private globalEventService: GlobalEventService,
 		private proxyAccountService: ProxyAccountService,
 		private queueService: QueueService,
@@ -54,6 +57,10 @@ export class UserListService implements OnApplicationShutdown {
 		this.redisForSub.on('message', this.onMessage);
 	}
 
+	async onModuleInit() {
+		this.roleService = this.moduleRef.get(RoleService.name);
+	}
+
 	@bindThis
 	private async onMessage(_: string, data: string): Promise<void> {
 		const obj = JSON.parse(data);
diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts
index 73c446444b..cb9558b416 100644
--- a/packages/backend/test/e2e/timelines.ts
+++ b/packages/backend/test/e2e/timelines.ts
@@ -10,9 +10,8 @@ process.env.NODE_ENV = 'test';
 process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING = 'true';
 
 import * as assert from 'assert';
-import { signup, api, post, react, startServer, waitFire, sleep, uploadUrl, randomString } from '../utils.js';
+import { api, post, randomString, signup, sleep, startServer, uploadUrl } from '../utils.js';
 import type { INestApplicationContext } from '@nestjs/common';
-import type * as misskey from 'misskey-js';
 
 function genHost() {
 	return randomString() + '.example.com';
@@ -366,8 +365,8 @@ describe('Timelines', () => {
 			await api('/following/create', { userId: bob.id }, alice);
 			await sleep(1000);
 			const [bobFile, carolFile] = await Promise.all([
-				uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'),
-				uploadUrl(carol, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'),
+				uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'),
+				uploadUrl(carol, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'),
 			]);
 			const bobNote1 = await post(bob, { text: 'hi' });
 			const bobNote2 = await post(bob, { fileIds: [bobFile.id] });
@@ -666,7 +665,7 @@ describe('Timelines', () => {
 		test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
 			const [alice, bob] = await Promise.all([signup(), signup()]);
 
-			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png');
+			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
 			const bobNote1 = await post(bob, { text: 'hi' });
 			const bobNote2 = await post(bob, { fileIds: [file.id] });
 
@@ -804,7 +803,7 @@ describe('Timelines', () => {
 		test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
 			const [alice, bob] = await Promise.all([signup(), signup()]);
 
-			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png');
+			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
 			const bobNote1 = await post(bob, { text: 'hi' });
 			const bobNote2 = await post(bob, { fileIds: [file.id] });
 
@@ -999,7 +998,7 @@ describe('Timelines', () => {
 
 			const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
 			await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
-			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png');
+			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
 			const bobNote1 = await post(bob, { text: 'hi' });
 			const bobNote2 = await post(bob, { fileIds: [file.id] });
 
@@ -1158,7 +1157,7 @@ describe('Timelines', () => {
 		test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
 			const [alice, bob] = await Promise.all([signup(), signup()]);
 
-			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png');
+			const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
 			const bobNote1 = await post(bob, { text: 'hi' });
 			const bobNote2 = await post(bob, { fileIds: [file.id] });
 
diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts
index 99c6912116..9879eb8e3e 100644
--- a/packages/backend/test/unit/RoleService.ts
+++ b/packages/backend/test/unit/RoleService.ts
@@ -73,13 +73,21 @@ describe('RoleService', () => {
 				CacheService,
 				IdService,
 				GlobalEventService,
+				{
+					provide: NotificationService,
+					useFactory: () => ({
+						createNotification: jest.fn(),
+					}),
+				},
+				{
+					provide: NotificationService.name,
+					useExisting: NotificationService,
+				},
 			],
 		})
 			.useMocker((token) => {
 				if (token === MetaService) {
 					return { fetch: jest.fn() };
-				} else if (token === NotificationService) {
-					return { createNotification: jest.fn() };
 				}
 				if (typeof token === 'function') {
 					const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
@@ -98,6 +106,8 @@ describe('RoleService', () => {
 
 		metaService = app.get<MetaService>(MetaService) as jest.Mocked<MetaService>;
 		notificationService = app.get<NotificationService>(NotificationService) as jest.Mocked<NotificationService>;
+
+		await roleService.onModuleInit();
 	});
 
 	afterEach(async () => {
@@ -284,10 +294,12 @@ describe('RoleService', () => {
 			const user = await createUser();
 			const role = await createRole({
 				isPublic: true,
+				name: 'a',
 			});
 
 			await roleService.assign(user.id, role.id);
 
+			clock.uninstall();
 			await sleep(100);
 
 			const assignments = await roleAssignmentsRepository.find({
@@ -301,7 +313,7 @@ describe('RoleService', () => {
 			expect(notificationService.createNotification).toHaveBeenCalled();
 			expect(notificationService.createNotification.mock.lastCall![0]).toBe(user.id);
 			expect(notificationService.createNotification.mock.lastCall![1]).toBe('roleAssigned');
-			expect(notificationService.createNotification.mock.lastCall![2]).toBe({
+			expect(notificationService.createNotification.mock.lastCall![2]).toEqual({
 				roleId: role.id,
 			});
 		});
@@ -310,10 +322,12 @@ describe('RoleService', () => {
 			const user = await createUser();
 			const role = await createRole({
 				isPublic: false,
+				name: 'a',
 			});
 
 			await roleService.assign(user.id, role.id);
 
+			clock.uninstall();
 			await sleep(100);
 
 			const assignments = await roleAssignmentsRepository.find({