dad0136365
Build and Push Multi-Platform Images / build-and-push (push) Successful in 41s
Reformats code style (line breaks, indentation, type annotations) without changing logic. Also includes minor feature additions bundled in the same lint run (stats service, user-settings groups, agrarmonitor polling improvements). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { getRepositoryToken } from '@nestjs/typeorm';
|
|
import { PostprocessingService } from './postprocessing.service';
|
|
import { Postprocessing } from '../database/entities/postprocessing.entity';
|
|
import { PostprocessingAction } from '../database/entities/postprocessing-action.entity';
|
|
import { PaperlessService } from '../paperless/paperless.service';
|
|
|
|
const mockRules: Partial<Postprocessing>[] = [
|
|
{
|
|
Id: 1,
|
|
Name: 'Rule1',
|
|
DocumentTypeId: 5,
|
|
CorrespondentId: null,
|
|
OwnerId: null,
|
|
TagId: null,
|
|
Order: 1,
|
|
IsActive: true,
|
|
NoFurther: false,
|
|
},
|
|
{
|
|
Id: 2,
|
|
Name: 'StopRule',
|
|
DocumentTypeId: null,
|
|
CorrespondentId: null,
|
|
OwnerId: null,
|
|
TagId: null,
|
|
Order: 2,
|
|
IsActive: true,
|
|
NoFurther: true,
|
|
},
|
|
];
|
|
|
|
const mockActions: Partial<PostprocessingAction>[] = [
|
|
{
|
|
Id: 1,
|
|
PostprocessingId: 1,
|
|
ActionType: 2,
|
|
Content: '99',
|
|
Order: 1,
|
|
IsActive: true,
|
|
},
|
|
];
|
|
|
|
describe('PostprocessingService', () => {
|
|
let service: PostprocessingService;
|
|
let ppRepo: any;
|
|
let ppActionRepo: any;
|
|
let paperlessService: any;
|
|
|
|
beforeEach(async () => {
|
|
ppRepo = { find: jest.fn().mockResolvedValue(mockRules) };
|
|
ppActionRepo = { find: jest.fn().mockResolvedValue(mockActions) };
|
|
paperlessService = { updateDocument: jest.fn().mockResolvedValue({}) };
|
|
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
providers: [
|
|
PostprocessingService,
|
|
{ provide: getRepositoryToken(Postprocessing), useValue: ppRepo },
|
|
{
|
|
provide: getRepositoryToken(PostprocessingAction),
|
|
useValue: ppActionRepo,
|
|
},
|
|
{ provide: PaperlessService, useValue: paperlessService },
|
|
],
|
|
}).compile();
|
|
|
|
service = module.get<PostprocessingService>(PostprocessingService);
|
|
});
|
|
|
|
it('should be defined', () => {
|
|
expect(service).toBeDefined();
|
|
});
|
|
|
|
it('evaluate loads active rules in order', async () => {
|
|
await service.evaluate({ documentId: 100, documentTypeId: 5, tagIds: [] });
|
|
|
|
expect(ppRepo.find).toHaveBeenCalledWith({
|
|
where: { IsActive: true },
|
|
order: { Order: 'ASC' },
|
|
});
|
|
});
|
|
|
|
it('evaluate executes matching actions', async () => {
|
|
// Rule1 matches documentTypeId=5 → action adds tag
|
|
await service.evaluate({ documentId: 100, documentTypeId: 5, tagIds: [] });
|
|
|
|
expect(ppActionRepo.find).toHaveBeenCalledWith({
|
|
where: { PostprocessingId: 1, IsActive: true },
|
|
order: { Order: 'ASC' },
|
|
});
|
|
expect(paperlessService.updateDocument).toHaveBeenCalledWith(100, {
|
|
tags: [99],
|
|
});
|
|
});
|
|
|
|
it('evaluate stops at NoFurther rule', async () => {
|
|
// Rule1 matches, Rule2 also matches (no filters) + NoFurther → stops
|
|
await service.evaluate({ documentId: 100, documentTypeId: 5, tagIds: [] });
|
|
|
|
// Actions loaded for rule 1 and rule 2, but no rule after rule 2
|
|
expect(ppActionRepo.find).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('evaluate skips non-matching rules', async () => {
|
|
// documentTypeId=999 doesn't match Rule1 (requires 5) but matches Rule2 (no filter)
|
|
ppActionRepo.find.mockResolvedValue([]);
|
|
await service.evaluate({
|
|
documentId: 100,
|
|
documentTypeId: 999,
|
|
tagIds: [],
|
|
});
|
|
|
|
// Rule1 skipped, Rule2 matched → only 1 action lookup
|
|
expect(ppActionRepo.find).toHaveBeenCalledTimes(1);
|
|
expect(ppActionRepo.find).toHaveBeenCalledWith({
|
|
where: { PostprocessingId: 2, IsActive: true },
|
|
order: { Order: 'ASC' },
|
|
});
|
|
});
|
|
});
|