package noop import ( "context" "encoding/json" "reflect" "testing" "gitea.maximumdirect.net/eric/notarius/internal/core/artifacts" "gitea.maximumdirect.net/eric/notarius/internal/core/source" "gitea.maximumdirect.net/eric/notarius/internal/framework/contracts" "gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline" ) func TestModuleSpecAndRegister(t *testing.T) { want := pipeline.ModuleSpec{ Key: Key, Stage: pipeline.StageNormalize, Requires: []string{"merged"}, Provides: []string{"normalized"}, } if got := ModuleSpec(); !reflect.DeepEqual(got, want) { t.Fatalf("ModuleSpec() = %#v, want %#v", got, want) } registry := pipeline.NewNormalizerRegistry() if err := Register(registry); err != nil { t.Fatalf("Register() error = %v, want nil", err) } spec, ok := registry.Spec(Key) if !ok { t.Fatalf("Spec(%q) ok = false, want true", Key) } if !reflect.DeepEqual(spec, want) { t.Fatalf("registered spec = %#v, want %#v", spec, want) } normalizer, err := registry.Build(Key) if err != nil { t.Fatalf("Build(%q) error = %v, want nil", Key, err) } if slots := normalizer.ReferenceSlots(); len(slots) != 0 { t.Fatalf("ReferenceSlots() = %#v, want none", slots) } } func TestNormalizePassesThroughOrderAndValues(t *testing.T) { input := []artifacts.ArtifactCandidate{ candidate(3, "third"), candidate(1, "first"), candidate(2, "second"), } result, err := New().Normalize(context.Background(), contracts.NormalizeRequest{Candidates: input}) if err != nil { t.Fatalf("Normalize() error = %v, want nil", err) } if len(result.Warnings) != 0 { t.Fatalf("Warnings = %#v, want none", result.Warnings) } got := candidateNames(result.Candidates) want := []string{"third", "first", "second"} if !reflect.DeepEqual(got, want) { t.Fatalf("candidate order = %#v, want %#v", got, want) } if !reflect.DeepEqual(result.Candidates[0].SourceRefs, input[0].SourceRefs) { t.Fatalf("SourceRefs = %#v, want %#v", result.Candidates[0].SourceRefs, input[0].SourceRefs) } if !reflect.DeepEqual(result.Candidates[0].Metadata, input[0].Metadata) { t.Fatalf("Metadata = %#v, want %#v", result.Candidates[0].Metadata, input[0].Metadata) } } func TestNormalizeDefensivelyCopiesCandidates(t *testing.T) { input := []artifacts.ArtifactCandidate{candidate(1, "original")} result, err := New().Normalize(context.Background(), contracts.NormalizeRequest{Candidates: input}) if err != nil { t.Fatalf("Normalize() error = %v, want nil", err) } if len(result.Candidates) != 1 { t.Fatalf("len(Candidates) = %d, want 1", len(result.Candidates)) } input[0].Index = 99 input[0].Payload[0] = '[' input[0].SourceRefs[0].EndUnitID = "changed" input[0].Metadata["name"] = "changed" got := result.Candidates[0] if got.Index != 1 { t.Fatalf("Index = %d, want 1", got.Index) } if string(got.Payload) != `{"name":"original"}` { t.Fatalf("Payload = %s, want original payload", got.Payload) } if got.SourceRefs[0].EndUnitID != "u1" { t.Fatalf("SourceRefs = %#v, want original source ref", got.SourceRefs) } if got.Metadata["name"] != "original" { t.Fatalf("Metadata = %#v, want original metadata", got.Metadata) } } func TestNormalizeHandlesEmptyInput(t *testing.T) { result, err := New().Normalize(context.Background(), contracts.NormalizeRequest{}) if err != nil { t.Fatalf("Normalize() error = %v, want nil", err) } if len(result.Candidates) != 0 { t.Fatalf("len(Candidates) = %d, want 0", len(result.Candidates)) } if len(result.Warnings) != 0 { t.Fatalf("Warnings = %#v, want none", result.Warnings) } } func candidate(index int, name string) artifacts.ArtifactCandidate { return artifacts.ArtifactCandidate{ Index: index, ExtractorKey: "generic-extractor", ArtifactType: "generic-artifact", SchemaVersion: "v1", Payload: json.RawMessage(`{"name":"` + name + `"}`), SourceRefs: []source.SourceRef{ {SourceID: "source-1", StartUnitID: "u1", EndUnitID: "u1"}, }, Metadata: map[string]any{ "name": name, }, } } func candidateNames(candidates []artifacts.ArtifactCandidate) []string { names := make([]string, 0, len(candidates)) for _, candidate := range candidates { names = append(names, candidate.Metadata["name"].(string)) } return names }