summaryrefslogtreecommitdiff
path: root/packages/backend/test/unit/ChannelMutingService.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/test/unit/ChannelMutingService.ts')
-rw-r--r--packages/backend/test/unit/ChannelMutingService.ts336
1 files changed, 336 insertions, 0 deletions
diff --git a/packages/backend/test/unit/ChannelMutingService.ts b/packages/backend/test/unit/ChannelMutingService.ts
new file mode 100644
index 0000000000..6916701d1f
--- /dev/null
+++ b/packages/backend/test/unit/ChannelMutingService.ts
@@ -0,0 +1,336 @@
+/*
+ * 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 { ChannelMutingService } from '@/core/ChannelMutingService.js';
+import {
+ ChannelMutingRepository,
+ ChannelsRepository,
+ DriveFilesRepository,
+ MiChannel,
+ MiChannelMuting,
+ MiDriveFile,
+ MiUser,
+ UserProfilesRepository,
+ UsersRepository,
+} from '@/models/_.js';
+import { DI } from '@/di-symbols.js';
+import { setTimeout } from 'node:timers/promises';
+
+describe('ChannelMutingService', () => {
+ let app: TestingModule;
+ let service: ChannelMutingService;
+ let channelsRepository: ChannelsRepository;
+ let channelMutingRepository: ChannelMutingRepository;
+ let usersRepository: UsersRepository;
+ let userProfilesRepository: UserProfilesRepository;
+ let driveFilesRepository: DriveFilesRepository;
+ let idService: IdService;
+
+ let alice: MiUser;
+ let bob: MiUser;
+ let channel1: MiChannel;
+ let channel2: MiChannel;
+ let channel3: MiChannel;
+ let driveFile1: MiDriveFile;
+ let driveFile2: MiDriveFile;
+
+ async function createUser(data: Partial<MiUser> = {}) {
+ 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<MiChannel> = {}) {
+ return await channelsRepository
+ .insert({
+ id: idService.gen(),
+ ...data,
+ })
+ .then(x => channelsRepository.findOneByOrFail(x.identifiers[0]));
+ }
+
+ async function createChannelMuting(data: Partial<MiChannelMuting> = {}) {
+ return await channelMutingRepository
+ .insert({
+ id: idService.gen(),
+ ...data,
+ })
+ .then(x => channelMutingRepository.findOneByOrFail(x.identifiers[0]));
+ }
+
+ async function fetchChannelMuting() {
+ return await channelMutingRepository.findBy({});
+ }
+
+ async function createDriveFile(data: Partial<MiDriveFile> = {}) {
+ 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,
+ ChannelMutingService,
+ ],
+ }).compile();
+
+ app.enableShutdownHooks();
+
+ service = app.get<ChannelMutingService>(ChannelMutingService);
+ idService = app.get<IdService>(IdService);
+ channelsRepository = app.get<ChannelsRepository>(DI.channelsRepository);
+ channelMutingRepository = app.get<ChannelMutingRepository>(DI.channelMutingRepository);
+ usersRepository = app.get<UsersRepository>(DI.usersRepository);
+ userProfilesRepository = app.get<UserProfilesRepository>(DI.userProfilesRepository);
+ driveFilesRepository = app.get<DriveFilesRepository>(DI.driveFilesRepository);
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+
+ beforeEach(async () => {
+ alice = await createUser({ username: 'alice' });
+ bob = await createUser({ username: 'bob' });
+ 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 channelMutingRepository.deleteAll();
+ await channelsRepository.deleteAll();
+ await userProfilesRepository.deleteAll();
+ await usersRepository.deleteAll();
+ });
+
+ describe('list', () => {
+ test('default', async () => {
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id });
+ await createChannelMuting({ userId: bob.id, channelId: channel3.id });
+
+ const mutings = await service.list({ requestUserId: alice.id });
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].id).toBe(channel1.id);
+ expect(mutings[0].userId).toBe(alice.id);
+ expect(mutings[0].user).toBeFalsy();
+ expect(mutings[0].bannerId).toBe(driveFile1.id);
+ expect(mutings[0].banner).toBeFalsy();
+ expect(mutings[1].id).toBe(channel2.id);
+ expect(mutings[1].userId).toBe(alice.id);
+ expect(mutings[1].user).toBeFalsy();
+ expect(mutings[1].bannerId).toBe(driveFile2.id);
+ expect(mutings[1].banner).toBeFalsy();
+ });
+
+ test('withoutExpires', async () => {
+ const now = new Date();
+ const past = new Date(now);
+ const future = new Date(now);
+ past.setMinutes(past.getMinutes() - 1);
+ future.setMinutes(future.getMinutes() + 1);
+
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id, expiresAt: past });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id, expiresAt: null });
+ await createChannelMuting({ userId: alice.id, channelId: channel3.id, expiresAt: future });
+
+ const mutings = await service.list({ requestUserId: alice.id });
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].id).toBe(channel2.id);
+ expect(mutings[1].id).toBe(channel3.id);
+ });
+
+ test('idOnly', async () => {
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id });
+ await createChannelMuting({ userId: bob.id, channelId: channel3.id });
+
+ const mutings = await service.list({ requestUserId: alice.id }, { idOnly: true });
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].id).toBe(channel1.id);
+ expect(mutings[1].id).toBe(channel2.id);
+ });
+
+ test('withoutExpires-idOnly', async () => {
+ const now = new Date();
+ const past = new Date(now);
+ const future = new Date(now);
+ past.setMinutes(past.getMinutes() - 1);
+ future.setMinutes(future.getMinutes() + 1);
+
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id, expiresAt: past });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id, expiresAt: null });
+ await createChannelMuting({ userId: alice.id, channelId: channel3.id, expiresAt: future });
+
+ const mutings = await service.list({ requestUserId: alice.id }, { idOnly: true });
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].id).toBe(channel2.id);
+ expect(mutings[1].id).toBe(channel3.id);
+ });
+
+ test('joinUser', async () => {
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id });
+ await createChannelMuting({ userId: bob.id, channelId: channel3.id });
+
+ const mutings = await service.list({ requestUserId: alice.id }, { joinUser: true });
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].id).toBe(channel1.id);
+ expect(mutings[0].user).toEqual(alice);
+ expect(mutings[0].banner).toBeFalsy();
+ expect(mutings[1].id).toBe(channel2.id);
+ expect(mutings[1].user).toEqual(alice);
+ expect(mutings[1].banner).toBeFalsy();
+ });
+
+ test('joinBannerFile', async () => {
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id });
+ await createChannelMuting({ userId: bob.id, channelId: channel3.id });
+
+ const mutings = await service.list({ requestUserId: alice.id }, { joinBannerFile: true });
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].id).toBe(channel1.id);
+ expect(mutings[0].user).toBeFalsy();
+ expect(mutings[0].banner).toEqual(driveFile1);
+ expect(mutings[1].id).toBe(channel2.id);
+ expect(mutings[1].user).toBeFalsy();
+ expect(mutings[1].banner).toEqual(driveFile2);
+ });
+ });
+
+ describe('findExpiredMutings', () => {
+ test('default', async () => {
+ const now = new Date();
+ const future = new Date(now);
+ const past = new Date(now);
+ future.setMinutes(now.getMinutes() + 1);
+ past.setMinutes(now.getMinutes() - 1);
+
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id, expiresAt: past });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id, expiresAt: future });
+ await createChannelMuting({ userId: bob.id, channelId: channel3.id, expiresAt: past });
+
+ const mutings = await service.findExpiredMutings();
+
+ expect(mutings).toHaveLength(2);
+ expect(mutings[0].channelId).toBe(channel1.id);
+ expect(mutings[1].channelId).toBe(channel3.id);
+ });
+ });
+
+ describe('isMuted', () => {
+ test('isMuted: true', async () => {
+ // キャッシュを読むのでServiceの機能を使って登録し、キャッシュを作成する
+ await service.mute({ requestUserId: alice.id, targetChannelId: channel1.id });
+ await service.mute({ requestUserId: alice.id, targetChannelId: channel2.id });
+
+ await setTimeout(500);
+
+ const result = await service.isMuted({ requestUserId: alice.id, targetChannelId: channel1.id });
+
+ expect(result).toBe(true);
+ });
+
+ test('isMuted: false', async () => {
+ await service.mute({ requestUserId: alice.id, targetChannelId: channel2.id });
+
+ await setTimeout(500);
+
+ const result = await service.isMuted({ requestUserId: alice.id, targetChannelId: channel1.id });
+
+ expect(result).toBe(false);
+ });
+ });
+
+ describe('mute', () => {
+ test('default', async () => {
+ await service.mute({ requestUserId: alice.id, targetChannelId: channel1.id });
+
+ const muting = await fetchChannelMuting();
+ expect(muting).toHaveLength(1);
+ expect(muting[0].channelId).toBe(channel1.id);
+ });
+ });
+
+ describe('unmute', () => {
+ test('default', async () => {
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id });
+
+ let muting = await fetchChannelMuting();
+ expect(muting).toHaveLength(1);
+ expect(muting[0].channelId).toBe(channel1.id);
+
+ await service.unmute({ requestUserId: alice.id, targetChannelId: channel1.id });
+
+ muting = await fetchChannelMuting();
+ expect(muting).toHaveLength(0);
+ });
+ });
+
+ describe('eraseExpiredMutings', () => {
+ test('default', async () => {
+ const now = new Date();
+ const future = new Date(now);
+ const past = new Date(now);
+ future.setMinutes(now.getMinutes() + 1);
+ past.setMinutes(now.getMinutes() - 1);
+
+ await createChannelMuting({ userId: alice.id, channelId: channel1.id, expiresAt: past });
+ await createChannelMuting({ userId: alice.id, channelId: channel2.id, expiresAt: future });
+ await createChannelMuting({ userId: bob.id, channelId: channel3.id, expiresAt: past });
+
+ await service.eraseExpiredMutings();
+
+ const mutings = await fetchChannelMuting();
+ expect(mutings).toHaveLength(1);
+ expect(mutings[0].channelId).toBe(channel2.id);
+ });
+ });
+});