From 5bd41077afe6c1537831c202e592fea6a37f0cf6 Mon Sep 17 00:00:00 2001 From: Mathias Date: Thu, 1 Oct 2026 23:21:36 +0200 Subject: [PATCH] test(store): the reconciliation survives the round trip, and its absence stays absent (red) Counts and contested spots round-trip; a single-engine transcript has NO reconciliation (nil, not empty -- the page must not claim a second opinion); a skipped reconciliation keeps its reason. Red: Transcription.Reconciliation is stored nowhere and UploadedTranscript has none. Co-Authored-By: Claude Sonnet 5.5 --- .../store/uploaded_transcripts_test.go | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/internal/adapters/store/uploaded_transcripts_test.go b/internal/adapters/store/uploaded_transcripts_test.go index a313468..8ac9143 100644 --- a/internal/adapters/store/uploaded_transcripts_test.go +++ b/internal/adapters/store/uploaded_transcripts_test.go @@ -230,3 +230,57 @@ func TestUploadHadVideo_SurvivesCompletionAndFailure(t *testing.T) { assert.True(t, got.HadVideo, "completing or failing must not clear it: the notice outlives the job") } } + +func TestUploadLifecycle_ReconciliationRoundTripsWithItsContestedSpots(t *testing.T) { + s := newStore(t) + seedUsers(t, userA) + ctx := context.Background() + id, err := s.CreateUpload(ctx, userA, "m", false) + require.NoError(t, err) + require.NoError(t, s.StartTranscribing(ctx, userA, id)) + want := &domain.Reconciliation{ + Status: domain.ReconcileDone, Base: "iguana/pianissimo", Alt: "iguana/kb-whisper", Reconciler: "iguana/gemma4-26b", + Disputes: 380, AutoResolved: 90, Adjudicated: 285, Changed: 120, Unsure: 5, Errors: 0, + Contested: []domain.ContestedSpot{ + {Seconds: 2210.5, Base: "SEB", Alt: "SCB", Used: "alt"}, + {Seconds: 3400, Base: "T+1", Alt: "en T", Used: "base", Unsure: true}, + }, + } + + require.NoError(t, s.CompleteUpload(ctx, userA, id, domain.Transcription{Text: "x", Endpoint: "e", Reconciliation: want})) + + got, err := s.GetUpload(ctx, userA, id) + require.NoError(t, err) + assert.Equal(t, want, got.Reconciliation) +} + +func TestUploadLifecycle_ASingleEngineTranscriptHasNoReconciliation(t *testing.T) { + s := newStore(t) + seedUsers(t, userA) + ctx := context.Background() + id, err := s.CreateUpload(ctx, userA, "m", false) + require.NoError(t, err) + require.NoError(t, s.StartTranscribing(ctx, userA, id)) + require.NoError(t, s.CompleteUpload(ctx, userA, id, domain.Transcription{Text: "x", Endpoint: "e"})) + + got, err := s.GetUpload(ctx, userA, id) + + require.NoError(t, err) + assert.Nil(t, got.Reconciliation, "no reconciliation is not an empty one: the page must not claim a second opinion") +} + +func TestUploadLifecycle_ASkippedReconciliationKeepsItsReason(t *testing.T) { + s := newStore(t) + seedUsers(t, userA) + ctx := context.Background() + id, err := s.CreateUpload(ctx, userA, "m", false) + require.NoError(t, err) + require.NoError(t, s.StartTranscribing(ctx, userA, id)) + rec := &domain.Reconciliation{Status: domain.ReconcileSkipped, Reason: "the model failed 3 times in a row: gateway down", Errors: 3} + + require.NoError(t, s.CompleteUpload(ctx, userA, id, domain.Transcription{Text: "x", Endpoint: "e", Reconciliation: rec})) + + got, err := s.GetUpload(ctx, userA, id) + require.NoError(t, err) + assert.Equal(t, rec, got.Reconciliation) +}