feat: phase 8 serviceadapter crd rollout (32/33 tasks)
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
package serviceadapter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidateString(t *testing.T) {
|
||||
schema := &FieldSchema{Type: "string"}
|
||||
v := &Validator{schema: schema}
|
||||
|
||||
errs := v.Validate("hello")
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors for valid string, got %v", errs)
|
||||
}
|
||||
|
||||
errs = v.Validate(42)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for non-string")
|
||||
}
|
||||
if len(errs) > 0 && !stringContains(errs[0].Reason, "type_mismatch") {
|
||||
t.Errorf("expected type_mismatch error, got %s", errs[0].Reason)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNumber(t *testing.T) {
|
||||
schema := &FieldSchema{Type: "number"}
|
||||
v := &Validator{schema: schema}
|
||||
|
||||
errs := v.Validate(42.0)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors for float64, got %v", errs)
|
||||
}
|
||||
|
||||
errs = v.Validate("not a number")
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for non-number")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNullable(t *testing.T) {
|
||||
schemaNullable := &FieldSchema{Type: "string", Nullable: true}
|
||||
vNullable := &Validator{schema: schemaNullable}
|
||||
|
||||
errs := vNullable.Validate(nil)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors for null on nullable field, got %v", errs)
|
||||
}
|
||||
|
||||
schemaNotNullable := &FieldSchema{Type: "string", Nullable: false}
|
||||
vNotNullable := &Validator{schema: schemaNotNullable}
|
||||
|
||||
errs = vNotNullable.Validate(nil)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for null on non-nullable field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateObject(t *testing.T) {
|
||||
schema := &FieldSchema{
|
||||
Type: "object",
|
||||
Required: []string{"name"},
|
||||
Fields: map[string]FieldSchema{
|
||||
"name": {Type: "string"},
|
||||
"age": {Type: "number"},
|
||||
},
|
||||
}
|
||||
v := &Validator{schema: schema}
|
||||
|
||||
// Valid object
|
||||
obj := map[string]interface{}{
|
||||
"name": "Alice",
|
||||
"age": 30.0,
|
||||
}
|
||||
errs := v.Validate(obj)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors for valid object, got %v", errs)
|
||||
}
|
||||
|
||||
// Missing required field
|
||||
objMissing := map[string]interface{}{
|
||||
"age": 30.0,
|
||||
}
|
||||
errs = v.Validate(objMissing)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for missing required field")
|
||||
}
|
||||
if len(errs) > 0 && errs[0].Reason != "missing" {
|
||||
t.Errorf("expected 'missing' error, got %s", errs[0].Reason)
|
||||
}
|
||||
|
||||
// Type mismatch
|
||||
objBadType := map[string]interface{}{
|
||||
"name": "Alice",
|
||||
"age": "thirty",
|
||||
}
|
||||
errs = v.Validate(objBadType)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for type mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateObjectStrict(t *testing.T) {
|
||||
schema := &FieldSchema{
|
||||
Type: "object",
|
||||
Strict: true,
|
||||
Fields: map[string]FieldSchema{
|
||||
"name": {Type: "string"},
|
||||
},
|
||||
}
|
||||
v := &Validator{schema: schema}
|
||||
|
||||
// Unknown field rejected in strict mode
|
||||
obj := map[string]interface{}{
|
||||
"name": "Alice",
|
||||
"unknown": "field",
|
||||
}
|
||||
errs := v.Validate(obj)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for unknown field in strict mode")
|
||||
}
|
||||
found := false
|
||||
for _, err := range errs {
|
||||
if err.Reason == "unknown_field" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("expected unknown_field error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateArray(t *testing.T) {
|
||||
schema := &FieldSchema{
|
||||
Type: "array",
|
||||
Items: &FieldSchema{
|
||||
Type: "string",
|
||||
},
|
||||
}
|
||||
v := &Validator{schema: schema}
|
||||
|
||||
// Valid array
|
||||
arr := []interface{}{"a", "b", "c"}
|
||||
errs := v.Validate(arr)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors for valid string array, got %v", errs)
|
||||
}
|
||||
|
||||
// Invalid element type
|
||||
arrBad := []interface{}{"a", 42, "c"}
|
||||
errs = v.Validate(arrBad)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected error for wrong type in array")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateArrayOfObjects(t *testing.T) {
|
||||
schema := &FieldSchema{
|
||||
Type: "array",
|
||||
Items: &FieldSchema{
|
||||
Type: "object",
|
||||
Fields: map[string]FieldSchema{
|
||||
"id": {Type: "number"},
|
||||
"name": {Type: "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
v := &Validator{schema: schema}
|
||||
|
||||
arr := []interface{}{
|
||||
map[string]interface{}{"id": 1.0, "name": "Alice"},
|
||||
map[string]interface{}{"id": 2.0, "name": "Bob"},
|
||||
}
|
||||
errs := v.Validate(arr)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors for valid array of objects, got %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNoSchema(t *testing.T) {
|
||||
// No schema means no validation
|
||||
v := &Validator{schema: nil}
|
||||
|
||||
errs := v.Validate(map[string]interface{}{"anything": "goes"})
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected no errors when schema is nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSchema(t *testing.T) {
|
||||
schema, err := parseSchema("name: string, age: number")
|
||||
if err != nil {
|
||||
t.Fatalf("parse error: %v", err)
|
||||
}
|
||||
|
||||
if schema.Type != "object" {
|
||||
t.Errorf("expected type object, got %s", schema.Type)
|
||||
}
|
||||
|
||||
if len(schema.Fields) != 2 {
|
||||
t.Errorf("expected 2 fields, got %d", len(schema.Fields))
|
||||
}
|
||||
|
||||
if f, ok := schema.Fields["name"]; !ok || f.Type != "string" {
|
||||
t.Errorf("expected name: string in parsed schema")
|
||||
}
|
||||
}
|
||||
|
||||
func stringContains(s, substr string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if i+len(substr) <= len(s) && s[i:i+len(substr)] == substr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user