Files
ulitka/src/modules/comment/application/use-cases/test-helpers.ts
T
vadimandClaude Opus 5.5 60fb39f98f Add attachments to comments
- CommentAttachment link table (comment <-> file) + migration
- fileIds in create/update comment; update replaces the whole set,
  synced in one transaction with the comment
- CommentDto.attachments; empty for deleted comments
- Soft delete drops attachments so GC can collect the files
- Max 10 files per comment, ordered by upload time (uuid v7)
- Registers comments as a file owner
- Rename CommentAuthorExpanderService -> CommentExpanderService
  (expands authors and files)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:18:08 +03:00

76 lines
2.8 KiB
TypeScript

import { vi } from 'vitest';
import type { ICommentRepository } from '../../domain/repositories/comment.repository.interface.js';
import type { IIssueRepository } from '../../../issue/domain/repositories/issue.repository.interface.js';
import { Comment } from '../../domain/entities/comment.entity.js';
import { Issue } from '../../../issue/domain/entities/issue.entity.js';
import { CommentExpanderService } from '../services/comment-expander.service.js';
import { CommentApplicationMapper } from '../mappers/comment-application.mapper.js';
import type { FileAccessService } from '../../../file/application/services/file-access.service.js';
export const buildComment = (
overrides: Partial<{ id: string; issueId: number; authorId: string; deletedAt: Date | null }> = {},
) =>
Comment.reconstitute({
id: overrides.id ?? 'comment-1',
content: 'Original',
issueId: overrides.issueId ?? 1,
authorId: overrides.authorId ?? 'user-1',
editedAt: null,
deletedAt: overrides.deletedAt ?? null,
createdAt: new Date('2026-01-01T00:00:00.000Z'),
updatedAt: new Date('2026-01-01T00:00:00.000Z'),
});
export const buildIssue = () =>
Issue.reconstitute({
id: 1,
key: 'ISSUE-1',
title: 'Issue',
content: null,
status: 'OPEN',
priority: 0,
assignee: null,
reporter: 'user-1',
projectId: 'project-1',
dueDate: null,
createdAt: new Date('2026-01-01T00:00:00.000Z'),
updatedAt: new Date('2026-01-01T00:00:00.000Z'),
});
export const mockCommentRepository = (): ICommentRepository => ({
findById: vi.fn(),
findByIssue: vi.fn(),
create: vi.fn(),
update: vi.fn(),
findIssueIdsByAttachedFile: vi.fn(),
findReferencedFileIds: vi.fn(),
});
export const mockIssueRepository = (): IIssueRepository => ({
findById: vi.fn(),
findByCKey: vi.fn(),
findAll: vi.fn(),
countByStatus: vi.fn(),
create: vi.fn(),
update: vi.fn(),
delete: vi.fn(),
});
/** Все файлы прикрепляемы, кроме перечисленных — для них бросается заданная ошибка */
export const mockFileAccess = (rejections: Record<string, Error> = {}) =>
({
getAttachableFile: vi.fn(async (fileId: string) => {
if (rejections[fileId]) throw rejections[fileId];
return { id: fileId };
}),
}) as unknown as FileAccessService;
/** Экспандер без похода за пользователями и файлами: author всегда null, attachments пустые */
export const mockCommentExpander = () => {
const toDto = (comment: Comment) => CommentApplicationMapper.toDto(comment, new Map());
return {
expand: vi.fn(async (comment: Comment) => toDto(comment)),
expandAll: vi.fn(async (comments: Comment[]) => comments.map(toDto)),
} as unknown as CommentExpanderService;
};