Files
ulitka/src/modules/comment/presentation/guards/issue-visible.guard.spec.ts
T
2026-10-01 12:02:03 +03:00

45 lines
1.9 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { BadRequestException, type ExecutionContext, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { CommentAccessService } from '../../application/services/comment-access.service.js';
import { IssueVisibleGuard } from './issue-visible.guard.js';
const buildContext = (params: Record<string, string>, userId?: string) =>
({
switchToHttp: () => ({
getRequest: () => ({ params, session: userId ? { user: { id: userId } } : undefined }),
}),
}) as unknown as ExecutionContext;
const buildGuard = (visible: boolean) => {
const commentAccess = { isIssueVisible: vi.fn().mockResolvedValue(visible) } as unknown as CommentAccessService;
return { guard: new IssueVisibleGuard(commentAccess), commentAccess };
};
describe('IssueVisibleGuard', () => {
it('allows access to a visible issue', async () => {
const { guard, commentAccess } = buildGuard(true);
await expect(guard.canActivate(buildContext({ issueId: '1' }, 'user-1'))).resolves.toBe(true);
expect(commentAccess.isIssueVisible).toHaveBeenCalledWith(1, 'user-1');
});
it('throws NotFoundException when the issue is not visible', async () => {
const { guard } = buildGuard(false);
await expect(guard.canActivate(buildContext({ issueId: '1' }, 'user-2'))).rejects.toThrow(NotFoundException);
});
it('throws BadRequestException for a non-numeric issueId', async () => {
const { guard, commentAccess } = buildGuard(true);
await expect(guard.canActivate(buildContext({ issueId: 'abc' }, 'user-1'))).rejects.toThrow(BadRequestException);
expect(commentAccess.isIssueVisible).not.toHaveBeenCalled();
});
it('throws UnauthorizedException without a session', async () => {
const { guard } = buildGuard(true);
await expect(guard.canActivate(buildContext({ issueId: '1' }))).rejects.toThrow(UnauthorizedException);
});
});