package responseschema import ( "bytes" "crypto/sha256" "encoding/hex" "encoding/json" "io" "testing" jsonschema "github.com/santhosh-tekuri/jsonschema/v6" ) func TestPromptKitSchemaPathsUseCanonicalAssets(t *testing.T) { for _, key := range []Key{CorrectionSetKey, CorrectionRepairKey, ValidatorDecisionSetKey} { path, ok := AssetPath(key) if !ok { t.Fatalf("missing path for %q", key) } file, err := Filesystem().Open(AssetRoot + "/" + path) if err != nil { t.Fatal(err) } data, err := io.ReadAll(file) file.Close() if err != nil { t.Fatal(err) } if !bytes.Equal(data, MustLookup(key).JSONSchema) { t.Fatalf("PromptKit schema differs for %q", key) } } } func TestLookupKnownSchemas(t *testing.T) { correction, ok := Lookup(CorrectionSetKey) if !ok { t.Fatalf("expected correction-set schema to be registered") } if correction.ID != correctionSetSchemaID { t.Fatalf("unexpected correction-set schema id %q", correction.ID) } if correction.Version != schemaVersionV1 { t.Fatalf("unexpected correction-set schema version %q", correction.Version) } if correction.Name != "audita_correction_set_v1" { t.Fatalf("unexpected correction-set schema name %q", correction.Name) } validation, ok := Lookup(ValidatorDecisionSetKey) if !ok { t.Fatalf("expected validator-decision schema to be registered") } if validation.ID != validatorDecisionSchemaID { t.Fatalf("unexpected validator-decision schema id %q", validation.ID) } if validation.Version != schemaVersionV1 { t.Fatalf("unexpected validator-decision schema version %q", validation.Version) } if validation.Name != "audita_validator_decision_set_v1" { t.Fatalf("unexpected validator-decision schema name %q", validation.Name) } } func TestLookupUnknownSchema(t *testing.T) { if _, ok := Lookup(Key("missing")); ok { t.Fatalf("expected unknown schema lookup to fail") } } func TestRegisteredSchemasLoadReadableEmbeddedJSON(t *testing.T) { for _, schema := range Registered() { if len(schema.JSONSchema) == 0 { t.Fatalf("expected non-empty JSON schema for %q", schema.ID) } if !json.Valid(schema.JSONSchema) { t.Fatalf("expected valid JSON schema for %q", schema.ID) } if !bytes.Contains(schema.JSONSchema, []byte("\n ")) { t.Fatalf("expected readable formatted JSON schema for %q", schema.ID) } } } func TestSchemaHashesMatchRegisteredJSON(t *testing.T) { for _, key := range []Key{CorrectionSetKey, CorrectionRepairKey, ValidatorDecisionSetKey} { schema, ok := Lookup(key) if !ok { t.Fatalf("missing schema %q", key) } sum := sha256.Sum256(schema.JSONSchema) expected := hex.EncodeToString(sum[:]) if schema.SHA256 != expected { t.Fatalf("unexpected hash for %q: got %q want %q", key, schema.SHA256, expected) } } } func TestLookupReturnsSchemaCopy(t *testing.T) { schema, ok := Lookup(CorrectionSetKey) if !ok { t.Fatalf("missing correction-set schema") } if len(schema.JSONSchema) == 0 { t.Fatalf("expected non-empty schema payload") } schema.JSONSchema[0] = 'x' again, ok := Lookup(CorrectionSetKey) if !ok { t.Fatalf("missing correction-set schema on second lookup") } if len(again.JSONSchema) == 0 { t.Fatalf("unexpected empty schema payload") } if again.JSONSchema[0] != '{' { t.Fatalf("expected lookup to return independent schema copy") } } func TestDiagnosticsMapIncludesStableSchemaMetadataShapeForAllSchemas(t *testing.T) { registered := Registered() if len(registered) == 0 { t.Fatalf("expected registered response schemas") } for _, schema := range registered { metadataMap := schema.DiagnosticsMap() if metadataMap["id"] != schema.ID || metadataMap["version"] != schema.Version || metadataMap["name"] != schema.Name || metadataMap["sha256"] != schema.SHA256 { t.Fatalf("unexpected diagnostics metadata map for %q: %+v", schema.ID, metadataMap) } } } func TestCorrectionRepairSchema(t *testing.T) { var document any if err := json.Unmarshal(MustLookup(CorrectionRepairKey).JSONSchema, &document); err != nil { t.Fatal(err) } compiler := jsonschema.NewCompiler() if err := compiler.AddResource("repair.json", document); err != nil { t.Fatal(err) } schema, err := compiler.Compile("repair.json") if err != nil { t.Fatal(err) } for _, tc := range []struct { name, content string valid bool }{ {"delete whitespace", `{"proposal_ref":1,"action":"revise","correction":{"id":1,"original_text":" ","corrected_text":"","confidence":0}}`, true}, {"withdraw", `{"proposal_ref":1,"action":"withdraw","correction":null}`, true}, {"missing correction", `{"proposal_ref":1,"action":"withdraw"}`, false}, {"extra field", `{"proposal_ref":1,"action":"withdraw","correction":null,"extra":1}`, false}, {"zero reference", `{"proposal_ref":0,"action":"withdraw","correction":null}`, false}, {"unknown action", `{"proposal_ref":1,"action":"other","correction":null}`, false}, {"empty original", `{"proposal_ref":1,"action":"revise","correction":{"id":1,"original_text":"","corrected_text":"x","confidence":1}}`, false}, {"confidence outside range", `{"proposal_ref":1,"action":"revise","correction":{"id":1,"original_text":"x","corrected_text":"y","confidence":2}}`, false}, } { t.Run(tc.name, func(t *testing.T) { var value any if err := json.Unmarshal([]byte(tc.content), &value); err != nil { t.Fatal(err) } if err := schema.Validate(value); (err == nil) != tc.valid { t.Fatalf("validation = %v", err) } }) } }