randomayzer/tests/filter-engine.test.ts

197 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, it, expect } from 'vitest';
import { applyFilterRules } from '../src/core/filtering/filter-engine';
import { RawParticipant } from '../src/core/types/participant';
import { FilterRules } from '../src/core/types/giveaway';
describe('Filter Engine', () => {
const sampleParticipants: RawParticipant[] = [
{
platformUserId: '1',
firstName: 'Иван',
lastName: 'Иванов',
source: 'LIKES',
liked: true,
commented: true,
commentsCount: 1,
reposted: true,
subscribed: true,
isAdmin: false,
},
{
platformUserId: '2',
firstName: 'Петр',
lastName: 'Петров',
source: 'LIKES',
liked: false,
commented: true,
commentsCount: 1,
reposted: true,
subscribed: true,
isAdmin: false,
},
{
platformUserId: '3',
firstName: 'Анна',
lastName: 'Сидорова',
source: 'COMMENTS',
liked: true,
commented: false,
commentsCount: 0,
reposted: true,
subscribed: true,
isAdmin: false,
},
{
platformUserId: '4',
firstName: 'Админ',
lastName: 'Группы',
source: 'LIKES',
liked: true,
commented: true,
commentsCount: 1,
reposted: true,
subscribed: true,
isAdmin: true,
},
{
platformUserId: '5',
firstName: 'Не',
lastName: 'Подписан',
source: 'LIKES',
liked: true,
commented: true,
commentsCount: 1,
reposted: true,
subscribed: false,
isAdmin: false,
},
];
it('should filter by like requirement correctly', () => {
const rules: FilterRules = {
requireLike: true,
requireComment: false,
requireRepost: false,
requireSubscription: false,
excludeAdmins: false,
excludeBlacklistedIds: [],
excludeDuplicateComments: true,
};
const result = applyFilterRules(sampleParticipants, rules);
expect(result.stats.eligibleCount).toBe(4);
expect(result.stats.excludedCount).toBe(1);
expect(result.excludedParticipants[0].platformUserId).toBe('2');
expect(result.excludedParticipants[0].exclusionReason).toBe('MISSING_LIKE');
});
it('should filter by comment and subscription requirements', () => {
const rules: FilterRules = {
requireLike: true,
requireComment: true,
requireRepost: false,
requireSubscription: true,
excludeAdmins: false,
excludeBlacklistedIds: [],
excludeDuplicateComments: true,
};
const result = applyFilterRules(sampleParticipants, rules);
// 1: passed
// 2: missing like
// 3: missing comment
// 4: passed (admin allowed here)
// 5: not subscribed
expect(result.stats.eligibleCount).toBe(2);
const eligibleIds = result.eligibleParticipants.map(p => p.platformUserId);
expect(eligibleIds).toEqual(['1', '4']);
});
it('should exclude administrators when excludeAdmins is true', () => {
const rules: FilterRules = {
requireLike: true,
requireComment: false,
requireRepost: false,
requireSubscription: false,
excludeAdmins: true,
excludeBlacklistedIds: [],
excludeDuplicateComments: true,
};
const result = applyFilterRules(sampleParticipants, rules);
const adminParticipant = result.allParticipants.find(p => p.platformUserId === '4');
expect(adminParticipant?.eligible).toBe(false);
expect(adminParticipant?.exclusionReason).toContain('IS_ADMIN');
});
it('should exclude blacklisted user IDs and usernames', () => {
const rules: FilterRules = {
requireLike: false,
requireComment: false,
requireRepost: false,
requireSubscription: false,
excludeAdmins: false,
excludeBlacklistedIds: ['1', '5'],
excludeDuplicateComments: true,
};
const result = applyFilterRules(sampleParticipants, rules);
const blacklisted = result.excludedParticipants.map(p => p.platformUserId);
expect(blacklisted).toContain('1');
expect(blacklisted).toContain('5');
expect(result.stats.reasonsBreakdown['BLACKLISTED']).toBe(2);
});
it('should deduplicate multiple raw comments from the same user into single participant', () => {
const multiComments: RawParticipant[] = [
{
platformUserId: '100',
firstName: 'Спамер',
lastName: 'Обыкновенный',
source: 'COMMENTS',
liked: true,
commented: true,
commentsCount: 1,
reposted: false,
subscribed: true,
},
{
platformUserId: '100',
firstName: 'Спамер',
lastName: 'Обыкновенный',
source: 'COMMENTS',
liked: true,
commented: true,
commentsCount: 1,
reposted: false,
subscribed: true,
},
{
platformUserId: '100',
firstName: 'Спамер',
lastName: 'Обыкновенный',
source: 'COMMENTS',
liked: true,
commented: true,
commentsCount: 1,
reposted: false,
subscribed: true,
},
];
const rules: FilterRules = {
requireLike: true,
requireComment: true,
requireRepost: false,
requireSubscription: true,
excludeAdmins: false,
excludeBlacklistedIds: [],
excludeDuplicateComments: true,
};
const result = applyFilterRules(multiComments, rules);
expect(result.stats.total).toBe(1);
expect(result.stats.eligibleCount).toBe(1);
expect(result.allParticipants[0].commentsCount).toBe(3);
});
});