From 63036124ccf5d620f965206c67e75fa812c5109a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 May 2026 13:33:01 +0200 Subject: [PATCH] test(catalog-backend): add ON CONFLICT DO UPDATE coverage for original_value overwrite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verifies that a conflicting insert with a different original_value casing updates the stored value, and documents that DO UPDATE requires explicit conflict columns unlike DO NOTHING. Signed-off-by: Fredrik Adelöw Co-authored-by: Cursor --- .../operations/stitcher/syncSearchRows.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/catalog-backend/src/database/operations/stitcher/syncSearchRows.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/syncSearchRows.test.ts index 0c7ac6f95a..9733f4361b 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/syncSearchRows.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/syncSearchRows.test.ts @@ -244,6 +244,24 @@ describe.each(databases.eachSupportedId())('syncSearchRows, %p', databaseId => { ); }); + it('overwrites original_value on conflict via ON CONFLICT DO UPDATE', async () => { + await syncSearchRows(knex, 'e1', [row('a', 'x', 'X')]); + + // Simulate a concurrent stitcher inserting the same (entity_id, key, value) + // with a different original_value casing. Unlike DO NOTHING, DO UPDATE + // requires an explicit conflict target — the column list is not optional. + await knex('search') + .insert({ entity_id: 'e1', key: 'a', value: 'x', original_value: 'x' }) + .onConflict(['entity_id', 'key', 'value']) + .merge(['original_value']); + + const rows = await getSearchRows(); + expect(rows).toHaveLength(1); + expect(rows[0]).toEqual( + expect.objectContaining({ key: 'a', value: 'x', original_value: 'x' }), + ); + }); + it('simulates the typical steady-state case with one changed row', async () => { // Build a realistic-ish set of search rows const initial = [