Poster search through a posters table and releases_poster_newest_idx; complete releases are final; the tail before everything (-3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c9a9c0155e
commit
c0e00f1707
8 files changed
+105
-8
No files matched your search
@@ -61,7 +61,7 @@ test.group('Final completeness', (group) => {
|
||||
}
|
||||
const final = async (id: number) => {
|
||||
const r = await db.from('releases').where('id', id).firstOrFail()
|
||||
const { rows } = await db.rawQuery(`SELECT release_final(?, ?, ?, ?, ?) AS final`, [r.group_id, r.first_article, r.last_article, r.posted_at, r.last_posted_at])
|
||||
const { rows } = await db.rawQuery(`SELECT release_final(?, ?, ?, ?, ?, ?) AS final`, [r.group_id, r.first_article, r.last_article, r.posted_at, r.last_posted_at, r.complete])
|
||||
return rows[0].final as boolean
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ test.group('Final completeness', (group) => {
|
||||
assert.isTrue(await final(middle))
|
||||
assert.isTrue(await final(first))
|
||||
assert.isFalse(await final(edge))
|
||||
// Complete there: every file found, nothing to wait for.
|
||||
assert.isTrue(await final(await release(196_000, '2026-01-01T22:30:00Z', { files: 5, complete: true, name: 'Complete.Edge' })))
|
||||
assert.isFalse(await final(island))
|
||||
|
||||
// Search: an incomplete release that isn't final isn't left out as incomplete; the API says which is final.
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { test } from '@japa/runner'
|
||||
import db from '@adonisjs/lucid/services/db'
|
||||
import testUtils from '@adonisjs/core/services/test_utils'
|
||||
import BatchStore from '#services/batch_store'
|
||||
import SearchService from '#services/search_service'
|
||||
import { RangeIndexer } from '#lib/edge/index'
|
||||
import { DEFAULT_RULES } from '#lib/rules/index'
|
||||
import type { Overview } from '#lib/nntp/index'
|
||||
|
||||
const GROUP = 'alt.binaries.posters'
|
||||
|
||||
test.group('Poster search', (group) => {
|
||||
group.each.setup(() => testUtils.db().withGlobalTransaction())
|
||||
|
||||
test('the batch store keeps each poster once; a poster search finds releases by part of the name', async ({ assert }) => {
|
||||
const [g] = await db.table('groups').insert({ name: GROUP, priority: 1 }).returning('id')
|
||||
const [node] = await db.table('nodes').insert({ name: 'poster-node' }).returning('id')
|
||||
const [range] = await db
|
||||
.table('ranges')
|
||||
.insert({ group_id: g.id, start_id: 1, end_id: 1000, next_id: 1, status: 'leased', node_id: node.id, rule_version: 1 })
|
||||
.returning('id')
|
||||
const post = (n: number, from: string, name: string): Overview => [
|
||||
n,
|
||||
{ 'subject': `[1/1] - "${name}" yEnc (1/1)`, 'from': from, 'date': 'Mon, 05 Oct 2026 10:00:00 +0000', 'message-id': `<ps${n}@x>`, ':bytes': '1000', 'xref': `x ${GROUP}:${n}` },
|
||||
]
|
||||
const ix = new RangeIndexer({ group: GROUP, start: 1, end: 1000, rules: { ...DEFAULT_RULES, samplePercent: 0, droppedSignatures: [], priorities: { [GROUP]: 1 } } })
|
||||
ix.add([post(1, 'Kitchen Cook <cook@example.com>', 'Soup.Recipes.2026.rar'), post(2, 'Kitchen Cook <cook@example.com>', 'Bread.Recipes.2026.rar'), post(3, 'Gardener <garden@example.com>', 'Roses.2026.rar')], 4)
|
||||
ix.finish()
|
||||
await BatchStore.store(Number(range.id), Number(node.id), ix.take())
|
||||
|
||||
assert.sameMembers((await db.from('posters').select('poster')).map((p) => p.poster), ['Kitchen Cook <cook@example.com>', 'Gardener <garden@example.com>'])
|
||||
const found = await SearchService.search({ poster: 'kitchen' })
|
||||
assert.equal(found.total, 2)
|
||||
assert.isTrue(found.releases.every((r) => r.poster === 'Kitchen Cook <cook@example.com>'))
|
||||
assert.equal((await SearchService.search({ poster: 'nobody' })).total, 0)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user