mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
148 lines
4.8 KiB
TypeScript
148 lines
4.8 KiB
TypeScript
// @vitest-environment node
|
|
|
|
import { sql } from '@payloadcms/db-postgres'
|
|
import { randomUUID } from 'node:crypto'
|
|
import type { Payload, RequiredDataFromCollectionSlug } from 'payload'
|
|
import { getPayload } from 'payload'
|
|
import { beforeAll, describe, expect, it } from 'vitest'
|
|
|
|
import config from '@/payload.config'
|
|
import { getPostgresTransactionDatabase } from '@/utilities/postgresTransactionLocks'
|
|
import {
|
|
getSpeechCoverage,
|
|
type SpeechCoverage,
|
|
type SpeechLegislatureCoverage,
|
|
} from '@/utilities/speech/speechCoverage'
|
|
|
|
let payload: Payload
|
|
|
|
type SpeechCreateData = RequiredDataFromCollectionSlug<'speech'>
|
|
|
|
const createSpeech = (
|
|
transactionID: number | string,
|
|
data: SpeechCreateData,
|
|
): Promise<{ id: number }> =>
|
|
payload.create({
|
|
collection: 'speech',
|
|
data,
|
|
depth: 0,
|
|
req: { transactionID },
|
|
// Intentional bypass: the spec seeds its own rows.
|
|
overrideAccess: true,
|
|
})
|
|
|
|
const bucketOf = (coverage: SpeechCoverage, legislature: string): SpeechLegislatureCoverage => {
|
|
const found = coverage.byLegislature.find((row) => row.legislature === legislature)
|
|
return (
|
|
found ?? {
|
|
legislature,
|
|
total: 0,
|
|
withExcerpt: 0,
|
|
withVideo: 0,
|
|
withSegments: 0,
|
|
withoutExcerpt: 0,
|
|
withoutSegments: 0,
|
|
fallbackYoutube: 0,
|
|
}
|
|
)
|
|
}
|
|
|
|
const delta = (
|
|
before: SpeechCoverage,
|
|
after: SpeechCoverage,
|
|
legislature: string,
|
|
): Omit<SpeechLegislatureCoverage, 'legislature'> => {
|
|
const from = bucketOf(before, legislature)
|
|
const to = bucketOf(after, legislature)
|
|
return {
|
|
total: to.total - from.total,
|
|
withExcerpt: to.withExcerpt - from.withExcerpt,
|
|
withVideo: to.withVideo - from.withVideo,
|
|
withSegments: to.withSegments - from.withSegments,
|
|
withoutExcerpt: to.withoutExcerpt - from.withoutExcerpt,
|
|
withoutSegments: to.withoutSegments - from.withoutSegments,
|
|
fallbackYoutube: to.fallbackYoutube - from.fallbackYoutube,
|
|
}
|
|
}
|
|
|
|
describe('getSpeechCoverage (C155)', () => {
|
|
beforeAll(async () => {
|
|
payload = await getPayload({ config: await config })
|
|
})
|
|
|
|
it('counts the buckets per legislature and derives the complements', async () => {
|
|
const transactionID = await payload.db.beginTransaction()
|
|
if (transactionID === null) throw new Error('Não foi possível abrir a transação do spec.')
|
|
try {
|
|
const database = await getPostgresTransactionDatabase(payload, { transactionID })
|
|
// Fixed snapshot: the delta between the two reads cannot be moved by
|
|
// parallel specs committing their own fixtures.
|
|
await database.execute(sql`SET TRANSACTION ISOLATION LEVEL REPEATABLE READ`)
|
|
const before = await getSpeechCoverage(payload, { transactionID })
|
|
|
|
const withSegments = await createSpeech(transactionID, {
|
|
sourceKey: `coverage-${randomUUID()}`,
|
|
speechAt: '2012-05-01T10:00',
|
|
year: 2012,
|
|
legislature: '54',
|
|
classifiedBy: 'gazetteer',
|
|
audioId: 11,
|
|
excerptTMs: 1_000,
|
|
vodPlaybackUrl: 'https://vod/a',
|
|
vodDownloadUrl: 'https://vod/a.mp4',
|
|
})
|
|
await payload.create({
|
|
collection: 'speechSegment',
|
|
data: {
|
|
speech: withSegments.id,
|
|
order: 1,
|
|
startSeconds: 0,
|
|
endSeconds: 2,
|
|
text: 'a saúde pública baiana',
|
|
searchText: 'a saude publica baiana',
|
|
},
|
|
depth: 0,
|
|
req: { transactionID },
|
|
// Intentional bypass: the spec seeds its own rows.
|
|
overrideAccess: true,
|
|
})
|
|
// Excerpt identified, VOD absent, no segments (the C153 "sem segmentos" gap).
|
|
await createSpeech(transactionID, {
|
|
sourceKey: `coverage-${randomUUID()}`,
|
|
speechAt: '2012-06-01T10:00',
|
|
year: 2012,
|
|
legislature: '54',
|
|
classifiedBy: 'gazetteer',
|
|
audioId: 12,
|
|
excerptTMs: 2_000,
|
|
})
|
|
// No excerpt at all, but the event has a YouTube record (fallback bucket).
|
|
await createSpeech(transactionID, {
|
|
sourceKey: `coverage-${randomUUID()}`,
|
|
speechAt: '2012-07-01T10:00',
|
|
year: 2012,
|
|
legislature: '54',
|
|
classifiedBy: 'gazetteer',
|
|
youtubeUrl: 'https://www.youtube.com/watch?v=x',
|
|
})
|
|
|
|
const after = await getSpeechCoverage(payload, { transactionID })
|
|
expect(delta(before, after, '54')).toEqual({
|
|
total: 3,
|
|
withExcerpt: 2,
|
|
withVideo: 1,
|
|
withSegments: 1,
|
|
withoutExcerpt: 1,
|
|
withoutSegments: 2,
|
|
fallbackYoutube: 1,
|
|
})
|
|
|
|
const total = after.byLegislature.reduce((sum, row) => sum + row.total, 0)
|
|
expect(after.totals.total).toBe(total)
|
|
expect(after.totals.withExcerpt + after.totals.withoutExcerpt).toBe(total)
|
|
expect(after.totals.withSegments + after.totals.withoutSegments).toBe(total)
|
|
} finally {
|
|
await payload.db.rollbackTransaction(transactionID)
|
|
}
|
|
})
|
|
})
|