feat(release): prepare 1.1.0 candidate
This commit is contained in:
parent
5a34f66981
commit
5205dcdfa9
736 changed files with 115667 additions and 12203 deletions
|
|
@ -0,0 +1,101 @@
|
|||
import {
|
||||
ContentReportRequestError,
|
||||
mapContentReportRpcError,
|
||||
parseContentReportReceipt,
|
||||
parseContentReportRequest,
|
||||
parseIdempotencyKey,
|
||||
} from './content-report-contract.ts'
|
||||
|
||||
function assert(condition: boolean, message: string): void {
|
||||
if (!condition) throw new Error(message)
|
||||
}
|
||||
|
||||
function rejects(action: () => unknown): boolean {
|
||||
try {
|
||||
action()
|
||||
return false
|
||||
} catch (error) {
|
||||
return error instanceof ContentReportRequestError
|
||||
}
|
||||
}
|
||||
|
||||
const generationId = '29100000-0000-4000-8000-000000000001'
|
||||
|
||||
Deno.test('content report contract normalizes a bounded Talk AI report', () => {
|
||||
const report = parseContentReportRequest({
|
||||
kind: 'ai_output',
|
||||
source: { type: 'talk_response', generationId: generationId.toUpperCase() },
|
||||
reason: 'harmful',
|
||||
comment: ' review this ',
|
||||
snapshot: ' generated answer ',
|
||||
})
|
||||
assert(report.source.generationId === generationId, 'generation id should be normalized')
|
||||
assert(report.comment === 'review this', 'comment should be trimmed')
|
||||
assert(report.snapshot === 'generated answer', 'snapshot should be trimmed')
|
||||
})
|
||||
|
||||
Deno.test('content report contract admits only implemented AI response surfaces', () => {
|
||||
for (const sourceType of [
|
||||
'talk_response',
|
||||
'command_response',
|
||||
'action_response',
|
||||
'meeting_document',
|
||||
]) {
|
||||
const report = parseContentReportRequest({
|
||||
kind: 'ai_output',
|
||||
source: { type: sourceType, generationId },
|
||||
reason: 'other',
|
||||
snapshot: 'answer',
|
||||
})
|
||||
assert(report.source.type === sourceType, `${sourceType} should be supported`)
|
||||
}
|
||||
})
|
||||
|
||||
Deno.test('content report contract rejects unknown fields, sources, reasons and bad lengths', () => {
|
||||
const valid = {
|
||||
kind: 'ai_output',
|
||||
source: { type: 'talk_response', generationId },
|
||||
reason: 'other',
|
||||
snapshot: 'answer',
|
||||
}
|
||||
const invalid: unknown[] = [
|
||||
{ ...valid, extra: true },
|
||||
{ ...valid, source: { ...valid.source, extra: true } },
|
||||
{ ...valid, kind: 'user_content' },
|
||||
{ ...valid, source: { type: 'chat_message', generationId } },
|
||||
{ ...valid, reason: 'dislike' },
|
||||
{ ...valid, snapshot: ' ' },
|
||||
{ ...valid, snapshot: 'x'.repeat(4_001) },
|
||||
{ ...valid, comment: '' },
|
||||
{ ...valid, comment: 'x'.repeat(501) },
|
||||
]
|
||||
for (const value of invalid) {
|
||||
assert(rejects(() => parseContentReportRequest(value)), 'invalid report was accepted')
|
||||
}
|
||||
})
|
||||
|
||||
Deno.test('content report idempotency and RPC receipts require strict UUIDs and shape', () => {
|
||||
assert(parseIdempotencyKey(generationId.toUpperCase()) === generationId, 'header UUID not normalized')
|
||||
assert(rejects(() => parseIdempotencyKey(null)), 'missing idempotency header was accepted')
|
||||
assert(rejects(() => parseIdempotencyKey('not-a-uuid')), 'bad idempotency header was accepted')
|
||||
|
||||
const receipt = parseContentReportReceipt({
|
||||
reportId: generationId,
|
||||
status: 'submitted',
|
||||
idempotent: false,
|
||||
createdAt: '2026-08-24T00:00:00.000Z',
|
||||
})
|
||||
assert(receipt.reportId === generationId && !receipt.idempotent, 'valid receipt was not parsed')
|
||||
assert(rejects(() => parseContentReportReceipt({ reportId: generationId })), 'bad RPC result was accepted')
|
||||
})
|
||||
|
||||
Deno.test('content report RPC errors expose stable non-sensitive API codes', () => {
|
||||
assert(mapContentReportRpcError({ message: 'content_report_source_not_found' }).status === 404,
|
||||
'source error should be hidden behind 404')
|
||||
assert(mapContentReportRpcError({ message: 'content_report_rate_limited' }).status === 429,
|
||||
'rate error should map to 429')
|
||||
assert(mapContentReportRpcError({ message: 'content_report_idempotency_conflict' }).status === 409,
|
||||
'idempotency error should map to 409')
|
||||
assert(mapContentReportRpcError({ message: 'database detail that must not escape' }).code === 'internal_error',
|
||||
'unknown database details should not be exposed')
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue