Files
accounted/tests/pg/pending-operations-ignore-transaction.pg.test.ts
Jakob Wennberg dc07ca8872 feat(transactions): steer private marking in locked periods to ignore, with v1 and MCP ignore verbs (#1661) (#2031)
Decision (option a): a private marking stays a real booking (eget uttag/insattning), so it remains blocked in a locked or closed period; the legal escape for rows that are not affarshandelser is ignore. Private + locked now returns TX_CATEGORIZE_PRIVATE_PERIOD_LOCKED with remediation naming the ignore paths instead of a bare PERIOD_LOCKED, on all four categorize surfaces and the bulk driver. New v1 POST/DELETE /transactions/{id}/ignore (isTransactionBooked-based 409, idempotent) and a staged MCP gnubok_ignore_transaction (+ accounted_ alias, search visibility to respect the tools/list payload ceiling) with operation_type ignore_transaction; the CHECK pair 20260831070000/070001 rebuilds the constraint from main's newest list plus the new value. Dashboard toast gains an Ignorera i stallet action. Closes #1661
2026-08-31 08:39:04 +01:00

56 lines
1.9 KiB
TypeScript

import { beforeAll, describe, expect, it } from 'vitest'
import { getPool } from './setup'
import { seedCompany } from './fixtures'
/**
* The pending_operations_operation_type_check constraint must accept the
* 'ignore_transaction' op type added by migration 20260831070000 (validated
* in 20260831070001, issue #1661). Without the constraint expansion,
* gnubok_ignore_transaction's staging INSERT fails with check_violation on
* every real call while dry_run (which skips the INSERT) previews clean: the
* exact bug class the op-type audit test documents. The second case pins that
* the re-created constraint is still a closed list.
*/
describe('pending_operations operation_type CHECK: ignore_transaction', () => {
let userId: string
let companyId: string
beforeAll(async () => {
const seeded = await seedCompany()
userId = seeded.userId
companyId = seeded.companyId
})
it('accepts ignore_transaction (constraint expanded in 20260831070000)', async () => {
const client = await getPool().connect()
try {
await client.query('BEGIN')
await client.query(
`INSERT INTO public.pending_operations (user_id, company_id, operation_type, title)
VALUES ($1, $2, 'ignore_transaction', 'regression: ignorera transaktion')`,
[userId, companyId],
)
await client.query('ROLLBACK')
} finally {
client.release()
}
})
it('still rejects an unknown op type (the list stays closed)', async () => {
const client = await getPool().connect()
try {
await client.query('BEGIN')
await expect(
client.query(
`INSERT INTO public.pending_operations (user_id, company_id, operation_type, title)
VALUES ($1, $2, 'no_such_operation', 'must fail')`,
[userId, companyId],
),
).rejects.toMatchObject({ code: '23514' })
await client.query('ROLLBACK')
} finally {
client.release()
}
})
})