| 1 | package transcript |
| 2 | |
| 3 | import ( |
| 4 | "slices" |
| 5 | "testing" |
| 6 | ) |
| 7 | |
| 8 | func TestRestoreCheckpointRepairsLegacyMissingRecordIdentities(t *testing.T) { |
| 9 | state := Checkpoint{ |
| 10 | Version: ProtocolVersion, Identity: testIdentity, CoveredThroughSeq: 7, |
| 11 | Records: []Message{ |
| 12 | {Role: "notice", Content: "first"}, |
| 13 | {Role: "notice", Content: "second"}, |
| 14 | {Role: "assistant", MessageID: "answer", Content: "answer"}, |
| 15 | {Role: "tool", ToolCallID: "call", Content: "result"}, |
| 16 | }, |
| 17 | } |
| 18 | want := []string{"view:checkpoint:7:0", "view:checkpoint:7:1", "m:answer", "tool:call"} |
| 19 | for range 2 { |
| 20 | projection, err := RestoreCheckpoint(state, testIdentity) |
| 21 | if err != nil { |
| 22 | t.Fatal(err) |
| 23 | } |
| 24 | messages := projection.buffer.Messages() |
| 25 | got := make([]string, len(messages)) |
| 26 | for index := range messages { |
| 27 | got[index] = messages[index].RecordID |
| 28 | } |
| 29 | if !slices.Equal(got, want) { |
| 30 | t.Fatalf("repaired identities = %v, want %v", got, want) |
| 31 | } |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | func TestRestoreCheckpointStillRejectsNonEmptyDuplicateIdentity(t *testing.T) { |
| 36 | state := Checkpoint{Version: ProtocolVersion, Identity: testIdentity, Records: []Message{ |
| 37 | {RecordID: "duplicate", Role: "notice", Content: "first"}, |
| 38 | {RecordID: "duplicate", Role: "notice", Content: "second"}, |
| 39 | }} |
| 40 | if _, err := RestoreCheckpoint(state, testIdentity); err == nil { |
| 41 | t.Fatal("duplicate checkpoint identity was accepted") |
| 42 | } |
| 43 | } |
| 44 |