diff --git a/packages/backend/test/unit/AnnouncementService.ts b/packages/backend/test/unit/AnnouncementService.ts index 8f61d91ba9..55924b5609 100644 --- a/packages/backend/test/unit/AnnouncementService.ts +++ b/packages/backend/test/unit/AnnouncementService.ts @@ -85,6 +85,7 @@ describe('AnnouncementService', () => { }) .compile(); + await app.init(); app.enableShutdownHooks(); announcementService = app.get(AnnouncementService); diff --git a/packages/backend/test/unit/DriveService.ts b/packages/backend/test/unit/DriveService.ts index 7234da2e36..79e99c7583 100644 --- a/packages/backend/test/unit/DriveService.ts +++ b/packages/backend/test/unit/DriveService.ts @@ -23,6 +23,7 @@ describe('DriveService', () => { imports: [GlobalModule, CoreModule], providers: [DriveService], }).compile(); + await app.init(); app.enableShutdownHooks(); driveService = app.get(DriveService); }); diff --git a/packages/backend/test/unit/FetchInstanceMetadataService.ts b/packages/backend/test/unit/FetchInstanceMetadataService.ts index 34200899d4..5652f84e88 100644 --- a/packages/backend/test/unit/FetchInstanceMetadataService.ts +++ b/packages/backend/test/unit/FetchInstanceMetadataService.ts @@ -58,6 +58,7 @@ describe('FetchInstanceMetadataService', () => { }}) .compile(); + await app.init(); app.enableShutdownHooks(); fetchInstanceMetadataService = app.get(FetchInstanceMetadataService); diff --git a/packages/backend/test/unit/FileInfoService.ts b/packages/backend/test/unit/FileInfoService.ts index de0b31488c..6bf69a23da 100644 --- a/packages/backend/test/unit/FileInfoService.ts +++ b/packages/backend/test/unit/FileInfoService.ts @@ -50,6 +50,7 @@ describe('FileInfoService', () => { }) .compile(); + await app.init(); app.enableShutdownHooks(); fileInfoService = app.get(FileInfoService); diff --git a/packages/backend/test/unit/MetaService.ts b/packages/backend/test/unit/MetaService.ts index ab30f48283..98c269ecd0 100644 --- a/packages/backend/test/unit/MetaService.ts +++ b/packages/backend/test/unit/MetaService.ts @@ -28,6 +28,7 @@ describe('MetaService', () => { ], }).compile(); + await app.init(); app.enableShutdownHooks(); metaService = app.get(MetaService, { strict: false }); diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts index bb8e6981d5..594f39455d 100644 --- a/packages/backend/test/unit/MfmService.ts +++ b/packages/backend/test/unit/MfmService.ts @@ -18,6 +18,7 @@ describe('MfmService', () => { const app = await Test.createTestingModule({ imports: [GlobalModule, CoreModule], }).compile(); + await app.init(); mfmService = app.get(MfmService); }); diff --git a/packages/backend/test/unit/NoteCreateService.ts b/packages/backend/test/unit/NoteCreateService.ts new file mode 100644 index 0000000000..d6d1867601 --- /dev/null +++ b/packages/backend/test/unit/NoteCreateService.ts @@ -0,0 +1,143 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +process.env.NODE_ENV = 'test'; + +import { jest } from '@jest/globals'; +import { ModuleMocker } from 'jest-mock'; +import { Test } from '@nestjs/testing'; +import * as Redis from 'ioredis'; +import { GlobalModule } from '@/GlobalModule.js'; +import type { UsersRepository, MiUser, NotesRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; +import { genAidx } from '@/misc/id/aidx.js'; +import { CacheService } from '@/core/CacheService.js'; +import { IdService } from '@/core/IdService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; +import { NoteCreateService } from '@/core/NoteCreateService.js'; +import { CoreModule } from '@/core/CoreModule.js'; +import { MetaService } from '@/core/MetaService.js'; +import { RoleService } from '@/core/RoleService.js'; +import NotesChart from '@/core/chart/charts/notes.js'; +import PerUserNotesChart from '@/core/chart/charts/per-user-notes.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { HashtagService } from '@/core/HashtagService.js'; +import { AntennaService } from '@/core/AntennaService.js'; +import ActiveUsersChart from '@/core/chart/charts/active-users.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; +import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js'; +import { UtilityService } from '@/core/UtilityService.js'; +import { sleep } from '../utils.js'; +import type { TestingModule } from '@nestjs/testing'; +import type { MockFunctionMetadata } from 'jest-mock'; + +const moduleMocker = new ModuleMocker(global); + +describe('NoteCreateService', () => { + let app: TestingModule; + let noteCreateService: NoteCreateService; + let usersRepository: UsersRepository; + let notesRepository: NotesRepository; + let globalEventService: jest.Mocked; + let redisForTimelines: jest.Mocked; + + function createUser(data: Partial = {}) { + const un = secureRndstr(16); + return usersRepository.insert({ + id: genAidx(new Date()), + createdAt: new Date(), + username: un, + usernameLower: un, + ...data, + }) + .then(x => usersRepository.findOneByOrFail(x.identifiers[0])); + } + + beforeEach(async () => { + app = await Test.createTestingModule({ + imports: [ + GlobalModule, + //CoreModule, + ], + providers: [ + UtilityService, + MetaService, + CacheService, + IdService, + RoleService, + NotesChart, + PerUserNotesChart, + ActiveUsersChart, + UserEntityService, + NoteEntityService, + HashtagService, + AntennaService, + NoteCreateService, + ], + }) + .useMocker((token) => { + if (token === GlobalEventService) { + return { + publishNotesStream: jest.fn(), + publishMainStream: jest.fn(), + }; + } else if (token === DI.redisForTimelines) { + return { + xadd: jest.fn(), + }; + } else if (typeof token === 'function') { + const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata; + const Mock = moduleMocker.generateFromMetadata(mockMetadata); + return new Mock(); + } + }) + .compile(); + + await app.init(); + app.enableShutdownHooks(); + + noteCreateService = app.get(NoteCreateService); + usersRepository = app.get(DI.usersRepository); + globalEventService = app.get(GlobalEventService) as jest.Mocked; + redisForTimelines = app.get(DI.redisForTimelines) as jest.Mocked; + }); + + afterEach(async () => { + await Promise.all([ + app.get(DI.metasRepository).delete({}), + usersRepository.delete({}), + notesRepository.delete({}), + ]); + + await app.close(); + }); + + describe('create', () => { + test('text', async () => { + const me = await createUser(); + const follower = await createUser(); + await app.get(DI.followingsRepository).insert({ + id: genAidx(new Date()), + followerId: follower.id, + followeeId: me.id, + createdAt: new Date(), + }); + const result = await noteCreateService.create(me, { + text: 'Hello, Misskey!', + }); + + expect(result.text).toBe('Hello, Misskey!'); + + await sleep(100); + + expect(globalEventService.publishNotesStream).toHaveBeenCalled(); + expect(globalEventService.publishNotesStream.mock.lastCall![0].id).toBe(result.id); + expect(redisForTimelines.xadd).toHaveBeenCalled(); + expect(redisForTimelines.xadd.mock.calls.some(call => call[0] === `homeTimeline:${follower.id}`)).toBe(true); + }); + }); +}); + diff --git a/packages/backend/test/unit/ReactionService.ts b/packages/backend/test/unit/ReactionService.ts index 7b5bf7d0a0..8ee2c17449 100644 --- a/packages/backend/test/unit/ReactionService.ts +++ b/packages/backend/test/unit/ReactionService.ts @@ -17,6 +17,7 @@ describe('ReactionService', () => { const app = await Test.createTestingModule({ imports: [GlobalModule, CoreModule], }).compile(); + await app.init(); reactionService = app.get(ReactionService); }); diff --git a/packages/backend/test/unit/RelayService.ts b/packages/backend/test/unit/RelayService.ts index f780a25388..e43e102bb9 100644 --- a/packages/backend/test/unit/RelayService.ts +++ b/packages/backend/test/unit/RelayService.ts @@ -54,6 +54,7 @@ describe('RelayService', () => { }) .compile(); + await app.init(); app.enableShutdownHooks(); relayService = app.get(RelayService); diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts index c6a14702ae..3a2de024fb 100644 --- a/packages/backend/test/unit/RoleService.ts +++ b/packages/backend/test/unit/RoleService.ts @@ -87,6 +87,7 @@ describe('RoleService', () => { }) .compile(); + await app.init(); app.enableShutdownHooks(); roleService = app.get(RoleService); diff --git a/packages/backend/test/unit/S3Service.ts b/packages/backend/test/unit/S3Service.ts index c1eafc96b7..7a650fc1b5 100644 --- a/packages/backend/test/unit/S3Service.ts +++ b/packages/backend/test/unit/S3Service.ts @@ -24,6 +24,7 @@ describe('S3Service', () => { imports: [GlobalModule, CoreModule], providers: [S3Service], }).compile(); + await app.init(); app.enableShutdownHooks(); s3Service = app.get(S3Service); });