package trim import ( "encoding/json" "strings" "testing" "gitea.maximumdirect.net/eric/seriatim/schema" ) func TestParseArtifactJSONRejectsMalformedJSON(t *testing.T) { _, err := ParseArtifactJSON([]byte(`{"metadata":`)) if err == nil { t.Fatal("expected malformed JSON error") } if !strings.Contains(err.Error(), "input JSON is malformed") { t.Fatalf("unexpected error: %v", err) } } func TestParseArtifactJSONRejectsDuplicateSegmentIDs(t *testing.T) { first := 10 second := 20 value := schema.Transcript{ Metadata: schema.Metadata{ Application: "seriatim", Version: "v-test", }, Segments: []schema.Segment{ {ID: 1, Source: "a.json", SourceSegmentIndex: &first, Speaker: "A", Start: 1, End: 2, Text: "one"}, {ID: 1, Source: "a.json", SourceSegmentIndex: &second, Speaker: "B", Start: 2, End: 3, Text: "two"}, }, OverlapGroups: []schema.OverlapGroup{}, } data := mustMarshalJSON(t, value) _, err := ParseArtifactJSON(data) if err == nil { t.Fatal("expected invalid artifact error") } if !strings.Contains(err.Error(), "not a valid seriatim output artifact") { t.Fatalf("unexpected error: %v", err) } } func TestParseArtifactJSONRejectsNonSequentialSegmentIDs(t *testing.T) { first := 10 second := 20 value := schema.Transcript{ Metadata: schema.Metadata{ Application: "seriatim", Version: "v-test", }, Segments: []schema.Segment{ {ID: 1, Source: "a.json", SourceSegmentIndex: &first, Speaker: "A", Start: 1, End: 2, Text: "one"}, {ID: 3, Source: "a.json", SourceSegmentIndex: &second, Speaker: "B", Start: 2, End: 3, Text: "two"}, }, OverlapGroups: []schema.OverlapGroup{}, } data := mustMarshalJSON(t, value) _, err := ParseArtifactJSON(data) if err == nil { t.Fatal("expected invalid artifact error") } if !strings.Contains(err.Error(), "not a valid seriatim output artifact") { t.Fatalf("unexpected error: %v", err) } } func TestConvertArtifactMinimalToIntermediate(t *testing.T) { value := schema.MinimalTranscript{ Metadata: schema.MinimalMetadata{ Application: "seriatim", Version: "v-test", OutputSchema: SchemaMinimal, }, Segments: []schema.MinimalSegment{ {ID: 1, Start: 1, End: 2, Speaker: "A", Text: "one"}, {ID: 2, Start: 2, End: 3, Speaker: "B", Text: "two"}, }, } artifact := Artifact{ Schema: SchemaMinimal, Minimal: &value, } converted, err := ConvertArtifact(artifact, SchemaIntermediate) if err != nil { t.Fatalf("convert failed: %v", err) } if converted.Schema != SchemaIntermediate { t.Fatalf("schema = %q, want %q", converted.Schema, SchemaIntermediate) } if converted.Intermediate == nil { t.Fatal("expected intermediate artifact") } if len(converted.Intermediate.Segments) != 2 { t.Fatalf("segment count = %d, want 2", len(converted.Intermediate.Segments)) } if converted.Intermediate.Segments[0].ID != 1 || converted.Intermediate.Segments[1].ID != 2 { t.Fatalf("unexpected IDs: %#v", converted.Intermediate.Segments) } } func TestConvertArtifactMinimalToFullFails(t *testing.T) { value := schema.MinimalTranscript{ Metadata: schema.MinimalMetadata{ Application: "seriatim", Version: "v-test", OutputSchema: SchemaMinimal, }, Segments: []schema.MinimalSegment{ {ID: 1, Start: 1, End: 2, Speaker: "A", Text: "one"}, }, } artifact := Artifact{ Schema: SchemaMinimal, Minimal: &value, } _, err := ConvertArtifact(artifact, SchemaFull) if err == nil { t.Fatal("expected conversion error") } if !strings.Contains(err.Error(), "cannot emit") { t.Fatalf("unexpected error: %v", err) } } func TestValidateArtifactRejectsMissingPayloads(t *testing.T) { tests := []struct { name string artifact Artifact want string }{ { name: "full", artifact: Artifact{Schema: SchemaFull}, want: "full artifact payload is missing", }, { name: "intermediate", artifact: Artifact{Schema: SchemaIntermediate}, want: "intermediate artifact payload is missing", }, { name: "minimal", artifact: Artifact{Schema: SchemaMinimal}, want: "minimal artifact payload is missing", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { err := ValidateArtifact(test.artifact) assertErrorContains(t, err, test.want) }) } } func TestApplyArtifactRejectsMissingPayload(t *testing.T) { _, err := ApplyArtifact(Artifact{Schema: SchemaFull}, Options{}) assertErrorContains(t, err, "full artifact payload is missing") } func TestConvertArtifactRejectsMissingPayloadWhenConversionRequested(t *testing.T) { _, err := ConvertArtifact(Artifact{Schema: SchemaFull}, SchemaMinimal) assertErrorContains(t, err, "full artifact payload is missing") } func TestConvertArtifactSameSchemaDoesNotRequirePayload(t *testing.T) { artifact := Artifact{Schema: SchemaFull} converted, err := ConvertArtifact(artifact, SchemaFull) if err != nil { t.Fatalf("convert failed: %v", err) } if converted.Schema != SchemaFull { t.Fatalf("schema = %q, want %q", converted.Schema, SchemaFull) } if converted.Full != nil { t.Fatalf("full payload = %#v, want nil", converted.Full) } } func mustMarshalJSON(t *testing.T, value any) []byte { t.Helper() data, err := json.Marshal(value) if err != nil { t.Fatalf("marshal: %v", err) } return data }