Compare commits
No commits in common. "062b6391f6c20d6d6149b84b19a01a78ddfd0cdd" and "3613409eed9c014eb0d291fb792d53540922a2ae" have entirely different histories.
062b6391f6
...
3613409eed
|
@ -512,28 +512,6 @@ describe('Timelines', () => {
|
||||||
assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
|
assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.concurrent('ノートミュートが機能する', async () => {
|
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
|
||||||
|
|
||||||
await api('following/create', { userId: bob.id }, alice);
|
|
||||||
await setTimeout(1000);
|
|
||||||
const bobNote = await post(bob, { text: 'hi' });
|
|
||||||
|
|
||||||
await waitForPushToTl();
|
|
||||||
|
|
||||||
// ミュート前はノートが表示される
|
|
||||||
const res1 = await api('notes/timeline', { limit: 100 }, alice);
|
|
||||||
assert.strictEqual(res1.body.some(note => note.id === bobNote.id), true);
|
|
||||||
|
|
||||||
// ノートをミュート
|
|
||||||
await api('notes/muting/create', { noteId: bobNote.id }, alice);
|
|
||||||
await setTimeout(1000);
|
|
||||||
|
|
||||||
// ミュート後はノートが表示されない
|
|
||||||
const res2 = await api('notes/timeline', { limit: 100 }, alice);
|
|
||||||
assert.strictEqual(res2.body.some(note => note.id === bobNote.id), false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test.concurrent('FTT: ローカルユーザーの HTL にはプッシュされる', async () => {
|
test.concurrent('FTT: ローカルユーザーの HTL にはプッシュされる', async () => {
|
||||||
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
|
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
|
||||||
|
|
||||||
|
@ -766,27 +744,7 @@ describe('Timelines', () => {
|
||||||
|
|
||||||
assert.strictEqual(res.body.some(note => note.id === bobNote1.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 === bobNote2.id), true);
|
||||||
}, 1000 * 30);
|
}, 1000 * 10);
|
||||||
|
|
||||||
test.concurrent('ノートミュートが機能する', async () => {
|
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
|
||||||
|
|
||||||
const bobNote = await post(bob, { text: 'hi' });
|
|
||||||
|
|
||||||
await waitForPushToTl();
|
|
||||||
|
|
||||||
// ミュート前はノートが表示される
|
|
||||||
const res1 = await api('notes/local-timeline', { limit: 100 }, alice);
|
|
||||||
assert.strictEqual(res1.body.some(note => note.id === bobNote.id), true);
|
|
||||||
|
|
||||||
// ノートをミュート
|
|
||||||
await api('notes/muting/create', { noteId: bobNote.id }, alice);
|
|
||||||
await setTimeout(1000);
|
|
||||||
|
|
||||||
// ミュート後はノートが表示されない
|
|
||||||
const res2 = await api('notes/local-timeline', { limit: 100 }, alice);
|
|
||||||
assert.strictEqual(res2.body.some(note => note.id === bobNote.id), false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Social TL', () => {
|
describe('Social TL', () => {
|
||||||
|
@ -997,27 +955,7 @@ describe('Timelines', () => {
|
||||||
|
|
||||||
assert.strictEqual(res.body.some(note => note.id === bobNote1.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 === bobNote2.id), true);
|
||||||
}, 1000 * 30);
|
}, 1000 * 10);
|
||||||
|
|
||||||
test.concurrent('ノートミュートが機能する', async () => {
|
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
|
||||||
|
|
||||||
const bobNote = await post(bob, { text: 'hi' });
|
|
||||||
|
|
||||||
await waitForPushToTl();
|
|
||||||
|
|
||||||
// ミュート前はノートが表示される
|
|
||||||
const res1 = await api('notes/hybrid-timeline', { limit: 100 }, alice);
|
|
||||||
assert.strictEqual(res1.body.some(note => note.id === bobNote.id), true);
|
|
||||||
|
|
||||||
// ノートをミュート
|
|
||||||
await api('notes/muting/create', { noteId: bobNote.id }, alice);
|
|
||||||
await setTimeout(1000);
|
|
||||||
|
|
||||||
// ミュート後はノートが表示されない
|
|
||||||
const res2 = await api('notes/hybrid-timeline', { limit: 100 }, alice);
|
|
||||||
assert.strictEqual(res2.body.some(note => note.id === bobNote.id), false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('User List TL', () => {
|
describe('User List TL', () => {
|
||||||
|
@ -1230,7 +1168,7 @@ describe('Timelines', () => {
|
||||||
|
|
||||||
assert.strictEqual(res.body.some(note => note.id === bobNote1.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 === bobNote2.id), true);
|
||||||
}, 1000 * 30);
|
}, 1000 * 10);
|
||||||
|
|
||||||
test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => {
|
test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => {
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
const [alice, bob] = await Promise.all([signup(), signup()]);
|
||||||
|
@ -1263,29 +1201,6 @@ describe('Timelines', () => {
|
||||||
|
|
||||||
assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
|
assert.strictEqual(res.body.some(note => note.id === bobNote.id), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.concurrent('ノートミュートが機能する', async () => {
|
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
|
||||||
|
|
||||||
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);
|
|
||||||
await setTimeout(1000);
|
|
||||||
const bobNote = await post(bob, { text: 'hi' });
|
|
||||||
|
|
||||||
await waitForPushToTl();
|
|
||||||
|
|
||||||
// ミュート前はノートが表示される
|
|
||||||
const res1 = await api('notes/user-list-timeline', { listId: list.id }, alice);
|
|
||||||
assert.strictEqual(res1.body.some(note => note.id === bobNote.id), true);
|
|
||||||
|
|
||||||
// ノートをミュート
|
|
||||||
await api('notes/muting/create', { noteId: bobNote.id }, alice);
|
|
||||||
await setTimeout(1000);
|
|
||||||
|
|
||||||
// ミュート後はノートが表示されない
|
|
||||||
const res2 = await api('notes/user-list-timeline', { listId: list.id }, alice);
|
|
||||||
assert.strictEqual(res2.body.some(note => note.id === bobNote.id), false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('User TL', () => {
|
describe('User TL', () => {
|
||||||
|
@ -1412,7 +1327,7 @@ describe('Timelines', () => {
|
||||||
|
|
||||||
assert.strictEqual(res.body.some(note => note.id === bobNote1.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 === bobNote2.id), true);
|
||||||
}, 1000 * 30);
|
}, 1000 * 10);
|
||||||
|
|
||||||
test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => {
|
test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => {
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
const [alice, bob] = await Promise.all([signup(), signup()]);
|
||||||
|
@ -1536,26 +1451,6 @@ describe('Timelines', () => {
|
||||||
const res = await api('users/notes', { userId: alice.id, sinceId: noteSince.id, untilId: noteUntil.id });
|
const res = await api('users/notes', { userId: alice.id, sinceId: noteSince.id, untilId: noteUntil.id });
|
||||||
assert.deepStrictEqual(res.body, [note3, note2, note1]);
|
assert.deepStrictEqual(res.body, [note3, note2, note1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.concurrent('ノートミュートが機能する', async () => {
|
|
||||||
const [alice, bob] = await Promise.all([signup(), signup()]);
|
|
||||||
|
|
||||||
const bobNote = await post(bob, { text: 'hi' });
|
|
||||||
|
|
||||||
await waitForPushToTl();
|
|
||||||
|
|
||||||
// ミュート前はノートが表示される
|
|
||||||
const res1 = await api('users/notes', { userId: bob.id }, alice);
|
|
||||||
assert.strictEqual(res1.body.some(note => note.id === bobNote.id), true);
|
|
||||||
|
|
||||||
// ノートをミュート
|
|
||||||
await api('notes/muting/create', { noteId: bobNote.id }, alice);
|
|
||||||
await setTimeout(1000);
|
|
||||||
|
|
||||||
// ミュート後はノートが表示されない
|
|
||||||
const res2 = await api('users/notes', { userId: bob.id }, alice);
|
|
||||||
assert.strictEqual(res2.body.some(note => note.id === bobNote.id), false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: リノートミュート済みユーザーのテスト
|
// TODO: リノートミュート済みユーザーのテスト
|
||||||
|
|
|
@ -1,369 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { describe, jest, expect, beforeAll, beforeEach, afterEach, afterAll, test } from '@jest/globals';
|
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { randomString } from '../utils.js';
|
|
||||||
import { NoteMutingService } from '@/core/note/NoteMutingService.js';
|
|
||||||
import {
|
|
||||||
MiNoteMuting,
|
|
||||||
MiNote,
|
|
||||||
MiUser,
|
|
||||||
NoteMutingsRepository,
|
|
||||||
NotesRepository,
|
|
||||||
UsersRepository,
|
|
||||||
} from '@/models/_.js';
|
|
||||||
import { DI } from '@/di-symbols.js';
|
|
||||||
import { GlobalModule } from '@/GlobalModule.js';
|
|
||||||
import { CoreModule } from '@/core/CoreModule.js';
|
|
||||||
import { IdService } from '@/core/IdService.js';
|
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
|
||||||
import { QueryService } from '@/core/QueryService.js';
|
|
||||||
|
|
||||||
process.env.NODE_ENV = 'test';
|
|
||||||
|
|
||||||
describe('NoteMutingService', () => {
|
|
||||||
let app: TestingModule;
|
|
||||||
let service: NoteMutingService;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
let notesRepository: NotesRepository;
|
|
||||||
let noteMutingsRepository: NoteMutingsRepository;
|
|
||||||
let usersRepository: UsersRepository;
|
|
||||||
let idService: IdService;
|
|
||||||
let globalEventService: GlobalEventService;
|
|
||||||
let queryService: QueryService;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper function to create a user
|
|
||||||
async function createUser(data: Partial<MiUser> = {}): Promise<MiUser> {
|
|
||||||
const user = {
|
|
||||||
id: idService.gen(),
|
|
||||||
username: randomString(),
|
|
||||||
usernameLower: randomString().toLowerCase(),
|
|
||||||
host: null,
|
|
||||||
...data,
|
|
||||||
};
|
|
||||||
|
|
||||||
return await usersRepository.insert(user)
|
|
||||||
.then(x => usersRepository.findOneByOrFail(x.identifiers[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to create a note
|
|
||||||
async function createNote(data: Partial<MiNote> = {}): Promise<MiNote> {
|
|
||||||
return await notesRepository.insert({
|
|
||||||
id: idService.gen(),
|
|
||||||
userId: data.userId ?? (await createUser()).id,
|
|
||||||
text: randomString(),
|
|
||||||
visibility: 'public',
|
|
||||||
...data,
|
|
||||||
})
|
|
||||||
.then(x => notesRepository.findOneByOrFail(x.identifiers[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to create a note muting
|
|
||||||
async function createNoteMuting(data: Partial<MiNoteMuting> = {}): Promise<MiNoteMuting> {
|
|
||||||
const id = idService.gen();
|
|
||||||
const noteMuting = {
|
|
||||||
id,
|
|
||||||
userId: data.userId || (await createUser()).id,
|
|
||||||
noteId: data.noteId || (await createNote()).id,
|
|
||||||
expiresAt: null,
|
|
||||||
...data,
|
|
||||||
};
|
|
||||||
|
|
||||||
return await noteMutingsRepository.insert(noteMuting)
|
|
||||||
.then(x => noteMutingsRepository.findOneByOrFail(x.identifiers[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
app = await Test
|
|
||||||
.createTestingModule({
|
|
||||||
imports: [
|
|
||||||
GlobalModule,
|
|
||||||
CoreModule,
|
|
||||||
],
|
|
||||||
})
|
|
||||||
.compile();
|
|
||||||
|
|
||||||
service = app.get(NoteMutingService);
|
|
||||||
idService = app.get(IdService);
|
|
||||||
queryService = app.get(QueryService);
|
|
||||||
globalEventService = app.get(GlobalEventService);
|
|
||||||
notesRepository = app.get(DI.notesRepository);
|
|
||||||
noteMutingsRepository = app.get(DI.noteMutingsRepository);
|
|
||||||
usersRepository = app.get(DI.usersRepository);
|
|
||||||
|
|
||||||
app.enableShutdownHooks();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
// Clean database before each test
|
|
||||||
await noteMutingsRepository.delete({});
|
|
||||||
await notesRepository.delete({});
|
|
||||||
await usersRepository.delete({});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(async () => {
|
|
||||||
// Clean database after each test
|
|
||||||
await noteMutingsRepository.delete({});
|
|
||||||
await notesRepository.delete({});
|
|
||||||
await usersRepository.delete({});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
await app.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
describe('create', () => {
|
|
||||||
test('should create a note muting', async () => {
|
|
||||||
// Create a user and a note
|
|
||||||
const user = await createUser();
|
|
||||||
const note = await createNote();
|
|
||||||
|
|
||||||
// Create a note muting
|
|
||||||
await service.create({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note.id,
|
|
||||||
expiresAt: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify the note muting was created
|
|
||||||
const noteMuting = await noteMutingsRepository.findOneBy({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(noteMuting).not.toBeNull();
|
|
||||||
expect(noteMuting?.userId).toBe(user.id);
|
|
||||||
expect(noteMuting?.noteId).toBe(note.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw NoSuchNoteError if note does not exist', async () => {
|
|
||||||
// Create a user
|
|
||||||
const user = await createUser();
|
|
||||||
const nonexistentNoteId = idService.gen();
|
|
||||||
|
|
||||||
// Attempt to create a note muting with a non-existent note
|
|
||||||
await expect(service.create({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: nonexistentNoteId,
|
|
||||||
expiresAt: null,
|
|
||||||
})).rejects.toThrow(NoteMutingService.NoSuchNoteError);
|
|
||||||
|
|
||||||
// Verify no note muting was created
|
|
||||||
const noteMuting = await noteMutingsRepository.findOneBy({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: nonexistentNoteId,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(noteMuting).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('delete', () => {
|
|
||||||
test('should delete a note muting', async () => {
|
|
||||||
// Create a user, note, and note muting
|
|
||||||
const user = await createUser();
|
|
||||||
const note = await createNote();
|
|
||||||
const noteMuting = await createNoteMuting({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify the note muting exists
|
|
||||||
const beforeDelete = await noteMutingsRepository.findOneBy({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note.id,
|
|
||||||
});
|
|
||||||
expect(beforeDelete).not.toBeNull();
|
|
||||||
|
|
||||||
// Delete the note muting
|
|
||||||
await service.delete(user.id, note.id);
|
|
||||||
|
|
||||||
// Verify the note muting was deleted
|
|
||||||
const afterDelete = await noteMutingsRepository.findOneBy({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note.id,
|
|
||||||
});
|
|
||||||
expect(afterDelete).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw NotMutedError if muting does not exist', async () => {
|
|
||||||
// Create a user and note
|
|
||||||
const user = await createUser();
|
|
||||||
const note = await createNote();
|
|
||||||
|
|
||||||
// Attempt to delete a non-existent note muting
|
|
||||||
await expect(service.delete(user.id, note.id)).rejects.toThrow(NoteMutingService.NotMutedError);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isMuting', () => {
|
|
||||||
test('should return true if user is muting the note', async () => {
|
|
||||||
// Create a user, note, and note muting
|
|
||||||
const user = await createUser();
|
|
||||||
const note = await createNote();
|
|
||||||
await createNoteMuting({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if the user is muting the note
|
|
||||||
const result = await service.isMuting(user.id, note.id);
|
|
||||||
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should return false if user is not muting the note', async () => {
|
|
||||||
// Create a user and note, but no muting
|
|
||||||
const user = await createUser();
|
|
||||||
const note = await createNote();
|
|
||||||
|
|
||||||
// Check if the user is muting the note
|
|
||||||
const result = await service.isMuting(user.id, note.id);
|
|
||||||
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getMutingNoteIdsSet', () => {
|
|
||||||
test('should return a set of muted note IDs', async () => {
|
|
||||||
// Create a user and multiple notes
|
|
||||||
const user = await createUser();
|
|
||||||
const note1 = await createNote();
|
|
||||||
const note2 = await createNote();
|
|
||||||
const note3 = await createNote();
|
|
||||||
|
|
||||||
// Create note mutings for two of the notes
|
|
||||||
await createNoteMuting({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note1.id,
|
|
||||||
});
|
|
||||||
await createNoteMuting({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note2.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the set of muted note IDs
|
|
||||||
const result = await service.getMutingNoteIdsSet(user.id);
|
|
||||||
|
|
||||||
// Verify the result is a Set containing the muted note IDs
|
|
||||||
expect(result).toBeInstanceOf(Set);
|
|
||||||
expect(result.has(note1.id)).toBe(true);
|
|
||||||
expect(result.has(note2.id)).toBe(true);
|
|
||||||
expect(result.has(note3.id)).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('listByUserId', () => {
|
|
||||||
test('should return a list of note mutings for a user', async () => {
|
|
||||||
// Create a user and multiple notes
|
|
||||||
const user = await createUser();
|
|
||||||
const note1 = await createNote();
|
|
||||||
const note2 = await createNote();
|
|
||||||
|
|
||||||
// Create note mutings
|
|
||||||
const muting1 = await createNoteMuting({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note1.id,
|
|
||||||
});
|
|
||||||
const muting2 = await createNoteMuting({
|
|
||||||
userId: user.id,
|
|
||||||
noteId: note2.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the list of note mutings
|
|
||||||
const result = await service.listByUserId({ userId: user.id });
|
|
||||||
|
|
||||||
// Verify the result contains the expected mutings
|
|
||||||
expect(result).toHaveLength(2);
|
|
||||||
expect(result.map(m => m.id).sort()).toEqual([muting1.id, muting2.id].sort());
|
|
||||||
expect(result.map(m => m.noteId).sort()).toEqual([note1.id, note2.id].sort());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('cleanupExpiredMutes', () => {
|
|
||||||
test('should delete expired mutes', async () => {
|
|
||||||
// Create users and notes
|
|
||||||
const user1 = await createUser();
|
|
||||||
const user2 = await createUser();
|
|
||||||
const note1 = await createNote();
|
|
||||||
const note2 = await createNote();
|
|
||||||
const note3 = await createNote();
|
|
||||||
|
|
||||||
// Set the expiration date to 1 hour ago
|
|
||||||
const expiredDate = new Date();
|
|
||||||
expiredDate.setHours(expiredDate.getHours() - 1);
|
|
||||||
|
|
||||||
// Set the expiration date to 1 hour in the future
|
|
||||||
const futureDate = new Date();
|
|
||||||
futureDate.setHours(futureDate.getHours() + 1);
|
|
||||||
|
|
||||||
// Create expired note mutings
|
|
||||||
const expiredMuting1 = await createNoteMuting({
|
|
||||||
userId: user1.id,
|
|
||||||
noteId: note1.id,
|
|
||||||
expiresAt: expiredDate,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expiredMuting2 = await createNoteMuting({
|
|
||||||
userId: user1.id,
|
|
||||||
noteId: note2.id,
|
|
||||||
expiresAt: expiredDate,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expiredMuting3 = await createNoteMuting({
|
|
||||||
userId: user2.id,
|
|
||||||
noteId: note3.id,
|
|
||||||
expiresAt: expiredDate,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create non-expired note muting
|
|
||||||
const activeMuting = await createNoteMuting({
|
|
||||||
userId: user2.id,
|
|
||||||
noteId: note1.id,
|
|
||||||
expiresAt: futureDate,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create permanent note muting (no expiration)
|
|
||||||
const permanentMuting = await createNoteMuting({
|
|
||||||
userId: user2.id,
|
|
||||||
noteId: note2.id,
|
|
||||||
expiresAt: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify all mutings exist before cleanup
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: expiredMuting1.id })).not.toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: expiredMuting2.id })).not.toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: expiredMuting3.id })).not.toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: activeMuting.id })).not.toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: permanentMuting.id })).not.toBeNull();
|
|
||||||
|
|
||||||
// Run cleanup
|
|
||||||
await service.cleanupExpiredMutes();
|
|
||||||
|
|
||||||
// Verify expired mutings are deleted and others remain
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: expiredMuting1.id })).toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: expiredMuting2.id })).toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: expiredMuting3.id })).toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: activeMuting.id })).not.toBeNull();
|
|
||||||
expect(await noteMutingsRepository.findOneBy({ id: permanentMuting.id })).not.toBeNull();
|
|
||||||
|
|
||||||
// Verify cache is updated by checking isMuting
|
|
||||||
expect(await service.isMuting(user1.id, note1.id)).toBe(false);
|
|
||||||
expect(await service.isMuting(user1.id, note2.id)).toBe(false);
|
|
||||||
expect(await service.isMuting(user2.id, note3.id)).toBe(false);
|
|
||||||
expect(await service.isMuting(user2.id, note1.id)).toBe(true);
|
|
||||||
expect(await service.isMuting(user2.id, note2.id)).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue