Initial commit with Email Import Wizard and Task Processor updates

This commit is contained in:
2026-05-04 08:02:11 +02:00
commit effdc5d59f
170 changed files with 67739 additions and 0 deletions
@@ -0,0 +1,84 @@
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' },
});
});
});