comments implement
This commit is contained in:
1 parent
9e0bef2527
commit
4b6ecfbf5d
41 files changed
+1350
-13
No files matched your search
@@ -0,0 +1,76 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { Comment } from './comment.entity.js';
|
||||
import { CommentForbiddenException } from '../exceptions/comment-forbidden.exception.js';
|
||||
|
||||
const buildComment = (overrides: Partial<{ authorId: string | null; deletedAt: Date | null }> = {}) =>
|
||||
Comment.reconstitute({
|
||||
id: 'comment-1',
|
||||
content: 'Original',
|
||||
issueId: 1,
|
||||
authorId: overrides.authorId === undefined ? 'user-1' : overrides.authorId,
|
||||
editedAt: null,
|
||||
deletedAt: overrides.deletedAt ?? null,
|
||||
createdAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
updatedAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
});
|
||||
|
||||
describe('Comment', () => {
|
||||
describe('create', () => {
|
||||
it('creates a new comment without id and edit/delete marks', () => {
|
||||
const comment = Comment.create({ issueId: 1, authorId: 'user-1', content: ' Hello ' });
|
||||
|
||||
expect(comment.id).toBeNull();
|
||||
expect(comment.content).toBe('Hello');
|
||||
expect(comment.editedAt).toBeNull();
|
||||
expect(comment.isDeleted).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects empty content', () => {
|
||||
expect(() => Comment.create({ issueId: 1, authorId: 'user-1', content: '' })).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('edit', () => {
|
||||
it('changes content and sets editedAt', () => {
|
||||
const comment = buildComment();
|
||||
|
||||
expect(comment.edit('Changed', 'user-1')).toBe(true);
|
||||
expect(comment.content).toBe('Changed');
|
||||
expect(comment.editedAt).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
it('is a no-op when content is the same', () => {
|
||||
const comment = buildComment();
|
||||
|
||||
expect(comment.edit(' Original ', 'user-1')).toBe(false);
|
||||
expect(comment.editedAt).toBeNull();
|
||||
});
|
||||
|
||||
it('forbids editing by someone other than the author', () => {
|
||||
expect(() => buildComment().edit('Changed', 'user-2')).toThrow(CommentForbiddenException);
|
||||
});
|
||||
|
||||
it('forbids editing when the author account is deleted', () => {
|
||||
expect(() => buildComment({ authorId: null }).edit('Changed', 'user-1')).toThrow(CommentForbiddenException);
|
||||
});
|
||||
|
||||
it('forbids editing a deleted comment', () => {
|
||||
expect(() => buildComment({ deletedAt: new Date() }).edit('Changed', 'user-1')).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete', () => {
|
||||
it('soft-deletes the comment', () => {
|
||||
const comment = buildComment();
|
||||
|
||||
comment.delete('user-1');
|
||||
|
||||
expect(comment.isDeleted).toBe(true);
|
||||
expect(comment.deletedAt).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
it('forbids deletion by someone other than the author', () => {
|
||||
expect(() => buildComment().delete('user-2')).toThrow(CommentForbiddenException);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user