test(catalog-backend): add ON CONFLICT DO UPDATE coverage for original_value overwrite

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 <freben@spotify.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Fredrik Adelöw
2026-05-11 13:33:01 +02:00
parent 930c575e58
commit 63036124cc
@@ -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<DbSearchRow>('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 = [