Files
tower/apps/api/src/modules/rules/rules.service.spec.ts
T
2026-06-09 02:02:40 +05:30

81 lines
3.7 KiB
TypeScript

import { Test, TestingModule } from '@nestjs/testing';
import { ConflictException, NotFoundException } from '@nestjs/common';
import { RulesService } from './rules.service';
import { PrismaService } from '../../prisma/prisma.service';
describe('RulesService', () => {
let service: RulesService;
const mockPrisma: any = {
tenantRule: { findMany: jest.fn(), findUnique: jest.fn(), findFirst: jest.fn(), create: jest.fn(), update: jest.fn(), delete: jest.fn() },
};
beforeEach(async () => {
jest.clearAllMocks();
const module: TestingModule = await Test.createTestingModule({
providers: [
RulesService,
{ provide: PrismaService, useValue: mockPrisma },
],
}).compile();
service = module.get<RulesService>(RulesService);
});
describe('list', () => {
it('returns rules ordered by priority', async () => {
mockPrisma.tenantRule.findMany.mockResolvedValue([
{ id: 'r1', tenantId: 'tnt-1', matchType: 'HASHTAG', matchValue: '#important', action: 'FLAG', priority: 0, isActive: true, createdAt: new Date('2026-01-01'), updatedAt: new Date('2026-01-01') },
{ id: 'r2', tenantId: 'tnt-1', matchType: 'PREFIX', matchValue: '/tower', action: 'FLAG', priority: 1, isActive: true, createdAt: new Date('2026-01-02'), updatedAt: new Date('2026-01-02') },
]);
const res = await service.list('tnt-1');
expect(res).toHaveLength(2);
expect(res[0].matchValue).toBe('#important');
expect(mockPrisma.tenantRule.findMany).toHaveBeenCalledWith(expect.objectContaining({ where: { tenantId: 'tnt-1' } }));
});
});
describe('create', () => {
it('creates and returns a rule', async () => {
mockPrisma.tenantRule.findUnique.mockResolvedValue(null);
mockPrisma.tenantRule.create.mockResolvedValue({
id: 'r1', tenantId: 'tnt-1', matchType: 'HASHTAG', matchValue: '#event', action: 'FLAG', priority: 0, isActive: true, createdAt: new Date('2026-01-01'), updatedAt: new Date('2026-01-01'),
});
const res = await service.create('tnt-1', { matchType: 'HASHTAG', matchValue: '#event', action: 'FLAG' });
expect(res.matchValue).toBe('#event');
});
it('rejects duplicate rule', async () => {
mockPrisma.tenantRule.findUnique.mockResolvedValue({ id: 'existing' });
await expect(service.create('tnt-1', { matchType: 'HASHTAG', matchValue: '#event', action: 'FLAG' })).rejects.toThrow(ConflictException);
});
});
describe('update', () => {
it('updates and returns a rule', async () => {
mockPrisma.tenantRule.findFirst.mockResolvedValue({ id: 'r1', tenantId: 'tnt-1' });
mockPrisma.tenantRule.update.mockResolvedValue({
id: 'r1', tenantId: 'tnt-1', matchType: 'HASHTAG', matchValue: '#event', action: 'AUTO_APPROVE', priority: 0, isActive: true, createdAt: new Date('2026-01-01'), updatedAt: new Date('2026-01-02'),
});
const res = await service.update('tnt-1', 'r1', { action: 'AUTO_APPROVE' });
expect(res.action).toBe('AUTO_APPROVE');
});
it('throws on non-existent rule', async () => {
mockPrisma.tenantRule.findFirst.mockResolvedValue(null);
await expect(service.update('tnt-1', 'missing', { action: 'AUTO_APPROVE' })).rejects.toThrow(NotFoundException);
});
});
describe('remove', () => {
it('deletes a rule', async () => {
mockPrisma.tenantRule.findFirst.mockResolvedValue({ id: 'r1', tenantId: 'tnt-1' });
mockPrisma.tenantRule.delete.mockResolvedValue({});
await expect(service.remove('tnt-1', 'r1')).resolves.toBeUndefined();
});
it('throws on non-existent rule', async () => {
mockPrisma.tenantRule.findFirst.mockResolvedValue(null);
await expect(service.remove('tnt-1', 'missing')).rejects.toThrow(NotFoundException);
});
});
});