/* * SPDX-FileCopyrightText: syuilo and misskey-project * SPDX-License-Identifier: AGPL-3.0-only */ /* eslint-disable */ import { afterEach, beforeEach, describe, expect } from '@jest/globals'; import { Test, TestingModule } from '@nestjs/testing'; import { GlobalModule } from '@/GlobalModule.js'; import { CoreModule } from '@/core/CoreModule.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { IdService } from '@/core/IdService.js'; import { type ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, MiChannel, MiChannelFollowing, MiDriveFile, MiUser, UserProfilesRepository, UsersRepository, } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { ChannelFollowingService } from "@/core/ChannelFollowingService.js"; import { MiLocalUser } from "@/models/User.js"; describe('ChannelFollowingService', () => { let app: TestingModule; let service: ChannelFollowingService; let channelsRepository: ChannelsRepository; let channelFollowingsRepository: ChannelFollowingsRepository; let usersRepository: UsersRepository; let userProfilesRepository: UserProfilesRepository; let driveFilesRepository: DriveFilesRepository; let idService: IdService; let alice: MiLocalUser; let bob: MiLocalUser; let channel1: MiChannel; let channel2: MiChannel; let channel3: MiChannel; let driveFile1: MiDriveFile; let driveFile2: MiDriveFile; async function createUser(data: Partial = {}) { const user = await usersRepository .insert({ id: idService.gen(), username: 'username', usernameLower: 'username', ...data, }) .then(x => usersRepository.findOneByOrFail(x.identifiers[0])); await userProfilesRepository.insert({ userId: user.id, }); return user; } async function createChannel(data: Partial = {}) { return await channelsRepository .insert({ id: idService.gen(), ...data, }) .then(x => channelsRepository.findOneByOrFail(x.identifiers[0])); } async function createChannelFollowing(data: Partial = {}) { return await channelFollowingsRepository .insert({ id: idService.gen(), ...data, }) .then(x => channelFollowingsRepository.findOneByOrFail(x.identifiers[0])); } async function fetchChannelFollowing() { return await channelFollowingsRepository.findBy({}); } async function createDriveFile(data: Partial = {}) { return await driveFilesRepository .insert({ id: idService.gen(), md5: 'md5', name: 'name', size: 0, type: 'type', storedInternal: false, url: 'url', ...data, }) .then(x => driveFilesRepository.findOneByOrFail(x.identifiers[0])); } beforeAll(async () => { app = await Test.createTestingModule({ imports: [ GlobalModule, CoreModule, ], providers: [ GlobalEventService, IdService, ChannelFollowingService, ], }).compile(); app.enableShutdownHooks(); service = app.get(ChannelFollowingService); idService = app.get(IdService); channelsRepository = app.get(DI.channelsRepository); channelFollowingsRepository = app.get(DI.channelFollowingsRepository); usersRepository = app.get(DI.usersRepository); userProfilesRepository = app.get(DI.userProfilesRepository); driveFilesRepository = app.get(DI.driveFilesRepository); }); afterAll(async () => { await app.close(); }); beforeEach(async () => { alice = { ...await createUser({ username: 'alice' }), host: null, uri: null }; bob = { ...await createUser({ username: 'bob' }), host: null, uri: null }; driveFile1 = await createDriveFile(); driveFile2 = await createDriveFile(); channel1 = await createChannel({ name: 'channel1', userId: alice.id, bannerId: driveFile1.id }); channel2 = await createChannel({ name: 'channel2', userId: alice.id, bannerId: driveFile2.id }); channel3 = await createChannel({ name: 'channel3', userId: alice.id, bannerId: driveFile2.id }); }); afterEach(async () => { await channelFollowingsRepository.delete({}); await channelsRepository.delete({}); await userProfilesRepository.delete({}); await usersRepository.delete({}); }); describe('list', () => { test('default', async () => { await createChannelFollowing({ followerId: alice.id, followeeId: channel1.id }); await createChannelFollowing({ followerId: alice.id, followeeId: channel2.id }); await createChannelFollowing({ followerId: bob.id, followeeId: channel3.id }); const followings = await service.list({ requestUserId: alice.id }); expect(followings).toHaveLength(2); expect(followings[0].id).toBe(channel1.id); expect(followings[0].userId).toBe(alice.id); expect(followings[0].user).toBeFalsy(); expect(followings[0].bannerId).toBe(driveFile1.id); expect(followings[0].banner).toBeFalsy(); expect(followings[1].id).toBe(channel2.id); expect(followings[1].userId).toBe(alice.id); expect(followings[1].user).toBeFalsy(); expect(followings[1].bannerId).toBe(driveFile2.id); expect(followings[1].banner).toBeFalsy(); }); test('idOnly', async () => { await createChannelFollowing({ followerId: alice.id, followeeId: channel1.id }); await createChannelFollowing({ followerId: alice.id, followeeId: channel2.id }); await createChannelFollowing({ followerId: bob.id, followeeId: channel3.id }); const followings = await service.list({ requestUserId: alice.id }, { idOnly: true }); expect(followings).toHaveLength(2); expect(followings[0].id).toBe(channel1.id); expect(followings[1].id).toBe(channel2.id); }); test('joinUser', async () => { await createChannelFollowing({ followerId: alice.id, followeeId: channel1.id }); await createChannelFollowing({ followerId: alice.id, followeeId: channel2.id }); await createChannelFollowing({ followerId: bob.id, followeeId: channel3.id }); const followings = await service.list({ requestUserId: alice.id }, { joinUser: true }); expect(followings).toHaveLength(2); expect(followings[0].id).toBe(channel1.id); expect(followings[0].user).toEqual(alice); expect(followings[0].banner).toBeFalsy(); expect(followings[1].id).toBe(channel2.id); expect(followings[1].user).toEqual(alice); expect(followings[1].banner).toBeFalsy(); }); test('joinBannerFile', async () => { await createChannelFollowing({ followerId: alice.id, followeeId: channel1.id }); await createChannelFollowing({ followerId: alice.id, followeeId: channel2.id }); await createChannelFollowing({ followerId: bob.id, followeeId: channel3.id }); const followings = await service.list({ requestUserId: alice.id }, { joinBannerFile: true }); expect(followings).toHaveLength(2); expect(followings[0].id).toBe(channel1.id); expect(followings[0].user).toBeFalsy(); expect(followings[0].banner).toEqual(driveFile1); expect(followings[1].id).toBe(channel2.id); expect(followings[1].user).toBeFalsy(); expect(followings[1].banner).toEqual(driveFile2); }); }); describe('follow', () => { test('default', async () => { await service.follow(alice, channel1); const followings = await fetchChannelFollowing(); expect(followings).toHaveLength(1); expect(followings[0].followeeId).toBe(channel1.id); expect(followings[0].followerId).toBe(alice.id); }); }); describe('unfollow', () => { test('default', async () => { await createChannelFollowing({ followerId: alice.id, followeeId: channel1.id }); await service.unfollow(alice, channel1); const followings = await fetchChannelFollowing(); expect(followings).toHaveLength(0); }); }); });