Persist comment source monitoring
This commit is contained in:
1 parent
5e1fc5def9
commit
8d932fcf36
16 files changed
+376
-24
No files matched your search
@@ -9,6 +9,9 @@ import {
|
||||
import type { PostsRepository, MessagesRepository } from '../src/database/repositories.js';
|
||||
import { createMockLogger } from '../tests/mockLogger.js';
|
||||
import { getTestConfig } from '../tests/testUtils.js';
|
||||
import Database from 'better-sqlite3';
|
||||
import { runMigrations } from '../src/database/client.js';
|
||||
import { CommentSourceWatchRepository } from '../src/database/comment-source-watch-repository.js';
|
||||
|
||||
function createMockRedditApi(posts: RedditPost[] = []): RedditApiClient {
|
||||
return {
|
||||
@@ -677,6 +680,60 @@ describe('MonitorService', () => {
|
||||
});
|
||||
|
||||
describe('comment-author targeting', () => {
|
||||
it('keeps watching a durable source and classifies only new comments newest-first', async () => {
|
||||
const db = new Database(':memory:');
|
||||
runMigrations(db);
|
||||
try {
|
||||
const source: RedditPost = {
|
||||
id: 'post1', name: 't3_post1', subreddit: 'scene', author: 'poster', title: 'A scene',
|
||||
url: 'https://example.com/scene.jpg', permalink: '/r/scene/comments/post1/', thumbnail: '',
|
||||
is_self: false, created_utc: Date.now() / 1_000, over_18: true, spoiler: false,
|
||||
};
|
||||
const first = {
|
||||
fullname: 't1_first', kind: 'comment' as const, subreddit: 'scene', author: 'first',
|
||||
permalink: '/first', createdAt: Date.now(), score: 1, text: 'As a woman I would love that done to me',
|
||||
nsfw: true, parentPostId: 'post1', distinguished: null, removed: false,
|
||||
};
|
||||
const second = { ...first, fullname: 't1_second', author: 'second', permalink: '/second' };
|
||||
const redditApi = createMockRedditApi([source]);
|
||||
redditApi.getNewPosts = vi.fn()
|
||||
.mockResolvedValueOnce([source])
|
||||
.mockResolvedValueOnce([]);
|
||||
redditApi.getBrowsingComments = vi.fn()
|
||||
.mockResolvedValueOnce([first])
|
||||
.mockResolvedValueOnce([second, first]);
|
||||
const screener = { screenCommentReactions: vi.fn(async (comments) => comments.map((item) => ({
|
||||
id: item.id, qualifies: true, expressedGender: 'female' as const, confidence: 0.95, evidence: 'recipient role',
|
||||
}))) };
|
||||
const config = getTestConfig({ reddit: {
|
||||
subreddits: [{ name: 'scene', type: 'image', targetingMode: 'comment-author' }],
|
||||
targetGenders: ['female'], recentWindowMinutes: 600,
|
||||
} });
|
||||
monitor = new MonitorService(
|
||||
redditApi, createMockPostsRepo(), createMockMessagesRepo(), config, logger, 0, undefined, screener,
|
||||
new CommentSourceWatchRepository(db),
|
||||
);
|
||||
|
||||
await expect(monitor.fetchCandidates(config.reddit.subreddits[0]))
|
||||
.resolves.toEqual([expect.objectContaining({ id: 't1_first' })]);
|
||||
await expect(monitor.fetchCandidates(config.reddit.subreddits[0]))
|
||||
.resolves.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ id: 't1_first' }),
|
||||
expect.objectContaining({ id: 't1_second' }),
|
||||
]));
|
||||
expect(screener.screenCommentReactions).toHaveBeenNthCalledWith(1, [
|
||||
{ id: 't1_first', text: first.text },
|
||||
]);
|
||||
expect(screener.screenCommentReactions).toHaveBeenNthCalledWith(2, [
|
||||
{ id: 't1_second', text: second.text },
|
||||
]);
|
||||
expect(redditApi.getNewPosts).toHaveBeenCalledWith('scene', 100, 'image');
|
||||
expect(redditApi.getBrowsingComments).toHaveBeenCalledWith('scene', 'post1', 100, 'new');
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('turns a high-confidence targeted reaction into a commenter candidate with source media intact', async () => {
|
||||
const source: RedditPost = {
|
||||
id: 'post1', name: 't3_post1', subreddit: 'scene', author: 'poster', title: 'A scene',
|
||||
|
||||
Reference in new issue
Block a user