(t *testing.T)
| 1016 | } |
| 1017 | |
| 1018 | func TestNativeStructHiddenField(t *testing.T) { |
| 1019 | envOpts := []cel.EnvOption{ |
| 1020 | NativeTypes( |
| 1021 | reflect.TypeFor[*TestEmbeddedTypes](), |
| 1022 | ParseStructTag("json"), |
| 1023 | ), |
| 1024 | cel.Variable("test", cel.ObjectType("ext.TestEmbeddedTypes")), |
| 1025 | } |
| 1026 | |
| 1027 | env, err := cel.NewEnv(envOpts...) |
| 1028 | if err != nil { |
| 1029 | t.Fatalf("cel.NewEnv(NativeTypes()) failed: %v", err) |
| 1030 | } |
| 1031 | |
| 1032 | // 1. Static reference compilation failure case |
| 1033 | // Attempting to compile `test.Password` should fail static analysis because the field is skipped/hidden. |
| 1034 | _, iss := env.Compile("test.Password") |
| 1035 | if iss.Err() == nil { |
| 1036 | t.Error("env.Compile('test.Password') succeeded, expected a compilation/check error") |
| 1037 | } |
| 1038 | |
| 1039 | // 2. Dynamic reference runtime evaluation failure case |
| 1040 | // Using dyn(test).Password should compile successfully (since dyn disables static type checks), |
| 1041 | // but it must fail at runtime during evaluation because the field is not exposed. |
| 1042 | ast, iss := env.Compile("dyn(test).Password") |
| 1043 | if iss.Err() != nil { |
| 1044 | t.Fatalf("env.Compile('dyn(test).Password') failed: %v", iss.Err()) |
| 1045 | } |
| 1046 | prg, err := env.Program(ast) |
| 1047 | if err != nil { |
| 1048 | t.Fatalf("env.Program() failed: %v", err) |
| 1049 | } |
| 1050 | in := map[string]any{ |
| 1051 | "test": &TestEmbeddedTypes{ |
| 1052 | Skipped: "sensitive_password", |
| 1053 | }, |
| 1054 | } |
| 1055 | out, _, err := prg.Eval(in) |
| 1056 | if err == nil { |
| 1057 | t.Errorf("prg.Eval() succeeded and returned %v, expected runtime error accessing hidden field", out) |
| 1058 | } |
| 1059 | } |
| 1060 | |
| 1061 | type TestNestedStruct struct { |
| 1062 | ListVal []*TestNestedType |
nothing calls this directly
no test coverage detected