package runner import ( "context" "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/extractorregistry" validationhelpers "gitea.maximumdirect.net/eric/notarius/internal/framework/validators" ) func TestRunnerUsesExtractorRegistry(t *testing.T) { var builtKeys []string var executedKeys []string registry := extractorregistry.New() registerIntegrationExtractor(t, registry, "second", &builtKeys, &executedKeys, []contracts.Validator{ integrationValidator{name: "reject-second", approve: false}, }) registerIntegrationExtractor(t, registry, "first", &builtKeys, &executedKeys, []contracts.Validator{ integrationValidator{name: "approve-first", approve: true}, }) output, err := New(registry).Run(context.Background(), RunInput{ Source: integrationSourceDocument(), ExtractorKeys: []string{"second", "first"}, }) if err != nil { t.Fatalf("Run() error = %v, want nil", err) } if !reflect.DeepEqual(builtKeys, []string{"second", "first"}) { t.Fatalf("built keys = %#v, want configured order", builtKeys) } if !reflect.DeepEqual(executedKeys, []string{"second", "first"}) { t.Fatalf("executed keys = %#v, want configured order", executedKeys) } if got := artifactKeys(output.Approved); !reflect.DeepEqual(got, []string{"first"}) { t.Fatalf("approved keys = %#v, want [first]", got) } if got := rejectedKeys(output.Rejected); !reflect.DeepEqual(got, []string{"second"}) { t.Fatalf("rejected keys = %#v, want [second]", got) } } func registerIntegrationExtractor(t *testing.T, registry *extractorregistry.Registry, key string, builtKeys *[]string, executedKeys *[]string, validators []contracts.Validator) { t.Helper() if err := registry.Register(key, func() (contracts.Extractor, error) { *builtKeys = append(*builtKeys, key) return integrationExtractor{key: key, executedKeys: executedKeys, validators: validators}, nil }); err != nil { t.Fatalf("Register(%q) error = %v, want nil", key, err) } } type integrationExtractor struct { key string executedKeys *[]string validators []contracts.Validator } func (extractor integrationExtractor) Key() string { return extractor.key } func (extractor integrationExtractor) ArtifactType() string { return "generic-artifact" } func (extractor integrationExtractor) SchemaVersion() string { return "v1" } func (extractor integrationExtractor) Validators() []contracts.Validator { return extractor.validators } func (extractor integrationExtractor) Extract(ctx context.Context, req contracts.ExtractionRequest) (contracts.ExtractionResult, error) { *extractor.executedKeys = append(*extractor.executedKeys, extractor.key) return contracts.ExtractionResult{ Candidates: []artifacts.Candidate{ {Payload: []byte(`{"value":true}`)}, }, }, nil } type integrationValidator struct { name string approve bool } func (validator integrationValidator) Name() string { return validator.name } func (validator integrationValidator) Validate(ctx context.Context, req contracts.ValidationRequest) (contracts.ValidationResult, error) { decisions := make([]contracts.ValidationDecision, 0, len(req.Candidates)) for _, candidate := range req.Candidates { if validator.approve { decisions = append(decisions, validationhelpers.Approved(candidate.Index)) } else { decisions = append(decisions, validationhelpers.Rejected(candidate.Index, "invalid", "not accepted")) } } return contracts.ValidationResult{ ValidatorName: validator.name, Decisions: decisions, }, nil } func integrationSourceDocument() *source.SourceDocument { return &source.SourceDocument{ ID: "source-1", Kind: "document", Format: "text/plain", Digest: "sha256:abc123", Units: []source.SourceUnit{ {ID: "u1", Kind: "unit", Text: "Source unit."}, }, } } func artifactKeys(approved []artifacts.Artifact) []string { keys := make([]string, 0, len(approved)) for _, artifact := range approved { keys = append(keys, artifact.ExtractorKey) } return keys } func rejectedKeys(rejected []artifacts.RejectedArtifact) []string { keys := make([]string, 0, len(rejected)) for _, artifact := range rejected { keys = append(keys, artifact.Candidate.ExtractorKey) } return keys }