fix: reconcile physique targeting for queued posts
This commit is contained in:
1 parent
d0a8bd0e2f
commit
d8d635e1ee
10 files changed
+250
-12
No files matched your search
@@ -26,13 +26,13 @@ function post(id: string, author: string, created = 100): RedditPost {
|
||||
};
|
||||
}
|
||||
|
||||
function prepared(candidate: RedditPost): ProcessedPost {
|
||||
function prepared(candidate: RedditPost, physiqueScore: number | null = 5): ProcessedPost {
|
||||
return {
|
||||
post: candidate,
|
||||
imageAnalysis: 'analysis',
|
||||
detectedGender: 'female',
|
||||
attractivenessScore: 64,
|
||||
physiqueScore: 5,
|
||||
physiqueScore,
|
||||
physiqueTargeting: { enabled: true, minScore: 3, maxScore: 7 },
|
||||
sourceImageUrl: 'https://i.redd.it/example.jpg',
|
||||
generatedMessage: 'prepared message',
|
||||
@@ -180,6 +180,56 @@ describe('CandidateQueueRepository', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('reconciles ready and retryable images when the physique range changes', () => {
|
||||
queue.enqueue([
|
||||
post('inside', 'alice', 300),
|
||||
post('outside', 'bob', 200),
|
||||
post('retry', 'carol', 100),
|
||||
], 'image', 1, 1_000);
|
||||
|
||||
for (const worker of ['screen-1', 'screen-2', 'screen-3']) {
|
||||
const candidate = queue.claimForScreening(worker, 100, 1_010)!;
|
||||
const score = candidate.postId === 'outside' ? 7 : 4;
|
||||
queue.markReady(candidate.postId, worker, prepared(candidate.post, score), 1_011);
|
||||
}
|
||||
const retry = queue.claimReady('account-a', 'send', 100, 1_012)!;
|
||||
expect(retry.postId).toBe('inside');
|
||||
queue.deferDelivery(retry.postId, 'send', 'rate limited', 2_000, 1_013);
|
||||
|
||||
expect(queue.reconcilePhysiqueTargeting(
|
||||
{ enabled: true, minScore: 1, maxScore: 6 },
|
||||
1_020,
|
||||
)).toEqual({ retained: 2, rejected: 1 });
|
||||
|
||||
const active = queue.listActive();
|
||||
expect(active.map((candidate) => candidate.postId)).toEqual(['inside', 'retry']);
|
||||
expect(active.every((candidate) => (
|
||||
candidate.prepared?.physiqueTargeting?.enabled === true
|
||||
&& candidate.prepared.physiqueTargeting.maxScore === 6
|
||||
))).toBe(true);
|
||||
expect(queue.getStats().byStatus.rejected).toBe(1);
|
||||
});
|
||||
|
||||
it('fails closed for an unscored prepared image but does not touch a leased send', () => {
|
||||
queue.enqueue([
|
||||
post('unscored', 'alice', 200),
|
||||
post('sending', 'bob', 100),
|
||||
], 'image', 1, 1_000);
|
||||
for (const worker of ['screen-1', 'screen-2']) {
|
||||
const candidate = queue.claimForScreening(worker, 100, 1_010)!;
|
||||
queue.markReady(candidate.postId, worker, prepared(candidate.post, null), 1_011);
|
||||
}
|
||||
const sending = queue.claimReady('account-a', 'send', 100, 1_012)!;
|
||||
|
||||
expect(queue.reconcilePhysiqueTargeting(
|
||||
{ enabled: true, minScore: 1, maxScore: 6 },
|
||||
1_020,
|
||||
)).toEqual({ retained: 0, rejected: 1 });
|
||||
expect(queue.listActive()).toEqual([
|
||||
expect.objectContaining({ postId: sending.postId, status: 'sending' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('lists only active candidates in newest-post order across stages', () => {
|
||||
queue.enqueue([
|
||||
post('waiting', 'alice', 100),
|
||||
|
||||
Reference in new issue
Block a user