github.com/opentofu/opentofu@v1.7.1/internal/configs/configschema/marks_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package configschema 7 8 import ( 9 "testing" 10 11 "github.com/opentofu/opentofu/internal/lang/marks" 12 "github.com/zclconf/go-cty/cty" 13 ) 14 15 func TestBlockValueMarks(t *testing.T) { 16 schema := &Block{ 17 Attributes: map[string]*Attribute{ 18 "unsensitive": { 19 Type: cty.String, 20 Optional: true, 21 }, 22 "sensitive": { 23 Type: cty.String, 24 Sensitive: true, 25 }, 26 "nested": { 27 NestedType: &Object{ 28 Attributes: map[string]*Attribute{ 29 "boop": { 30 Type: cty.String, 31 }, 32 "honk": { 33 Type: cty.String, 34 Sensitive: true, 35 }, 36 }, 37 Nesting: NestingList, 38 }, 39 }, 40 }, 41 42 BlockTypes: map[string]*NestedBlock{ 43 "list": { 44 Nesting: NestingList, 45 Block: Block{ 46 Attributes: map[string]*Attribute{ 47 "unsensitive": { 48 Type: cty.String, 49 Optional: true, 50 }, 51 "sensitive": { 52 Type: cty.String, 53 Sensitive: true, 54 }, 55 }, 56 }, 57 }, 58 }, 59 } 60 61 testCases := map[string]struct { 62 given cty.Value 63 expect cty.Value 64 }{ 65 "unknown object": { 66 cty.UnknownVal(schema.ImpliedType()), 67 cty.UnknownVal(schema.ImpliedType()), 68 }, 69 "null object": { 70 cty.NullVal(schema.ImpliedType()), 71 cty.NullVal(schema.ImpliedType()), 72 }, 73 "object with unknown attributes and blocks": { 74 cty.ObjectVal(map[string]cty.Value{ 75 "sensitive": cty.UnknownVal(cty.String), 76 "unsensitive": cty.UnknownVal(cty.String), 77 "nested": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ 78 "boop": cty.String, 79 "honk": cty.String, 80 }))), 81 "list": cty.UnknownVal(schema.BlockTypes["list"].ImpliedType()), 82 }), 83 cty.ObjectVal(map[string]cty.Value{ 84 "sensitive": cty.UnknownVal(cty.String).Mark(marks.Sensitive), 85 "unsensitive": cty.UnknownVal(cty.String), 86 "nested": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ 87 "boop": cty.String, 88 "honk": cty.String, 89 }))), 90 "list": cty.UnknownVal(schema.BlockTypes["list"].ImpliedType()), 91 }), 92 }, 93 "object with block value": { 94 cty.ObjectVal(map[string]cty.Value{ 95 "sensitive": cty.NullVal(cty.String), 96 "unsensitive": cty.UnknownVal(cty.String), 97 "nested": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ 98 "boop": cty.String, 99 "honk": cty.String, 100 }))), 101 "list": cty.ListVal([]cty.Value{ 102 cty.ObjectVal(map[string]cty.Value{ 103 "sensitive": cty.UnknownVal(cty.String), 104 "unsensitive": cty.UnknownVal(cty.String), 105 }), 106 cty.ObjectVal(map[string]cty.Value{ 107 "sensitive": cty.NullVal(cty.String), 108 "unsensitive": cty.NullVal(cty.String), 109 }), 110 }), 111 }), 112 cty.ObjectVal(map[string]cty.Value{ 113 "sensitive": cty.NullVal(cty.String).Mark(marks.Sensitive), 114 "unsensitive": cty.UnknownVal(cty.String), 115 "nested": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ 116 "boop": cty.String, 117 "honk": cty.String, 118 }))), 119 "list": cty.ListVal([]cty.Value{ 120 cty.ObjectVal(map[string]cty.Value{ 121 "sensitive": cty.UnknownVal(cty.String).Mark(marks.Sensitive), 122 "unsensitive": cty.UnknownVal(cty.String), 123 }), 124 cty.ObjectVal(map[string]cty.Value{ 125 "sensitive": cty.NullVal(cty.String).Mark(marks.Sensitive), 126 "unsensitive": cty.NullVal(cty.String), 127 }), 128 }), 129 }), 130 }, 131 "object with known values and nested attribute": { 132 cty.ObjectVal(map[string]cty.Value{ 133 "sensitive": cty.StringVal("foo"), 134 "unsensitive": cty.StringVal("bar"), 135 "nested": cty.ListVal([]cty.Value{ 136 cty.ObjectVal(map[string]cty.Value{ 137 "boop": cty.StringVal("foo"), 138 "honk": cty.StringVal("bar"), 139 }), 140 cty.ObjectVal(map[string]cty.Value{ 141 "boop": cty.NullVal(cty.String), 142 "honk": cty.NullVal(cty.String), 143 }), 144 cty.ObjectVal(map[string]cty.Value{ 145 "boop": cty.UnknownVal(cty.String), 146 "honk": cty.UnknownVal(cty.String), 147 }), 148 }), 149 "list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ 150 "sensitive": cty.String, 151 "unsensitive": cty.String, 152 }))), 153 }), 154 cty.ObjectVal(map[string]cty.Value{ 155 "sensitive": cty.StringVal("foo").Mark(marks.Sensitive), 156 "unsensitive": cty.StringVal("bar"), 157 "nested": cty.ListVal([]cty.Value{ 158 cty.ObjectVal(map[string]cty.Value{ 159 "boop": cty.StringVal("foo"), 160 "honk": cty.StringVal("bar").Mark(marks.Sensitive), 161 }), 162 cty.ObjectVal(map[string]cty.Value{ 163 "boop": cty.NullVal(cty.String), 164 "honk": cty.NullVal(cty.String).Mark(marks.Sensitive), 165 }), 166 cty.ObjectVal(map[string]cty.Value{ 167 "boop": cty.UnknownVal(cty.String), 168 "honk": cty.UnknownVal(cty.String).Mark(marks.Sensitive), 169 }), 170 }), 171 "list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ 172 "sensitive": cty.String, 173 "unsensitive": cty.String, 174 }))), 175 }), 176 }, 177 } 178 179 for name, tc := range testCases { 180 t.Run(name, func(t *testing.T) { 181 got := tc.given.MarkWithPaths(schema.ValueMarks(tc.given, nil)) 182 if !got.RawEquals(tc.expect) { 183 t.Fatalf("\nexpected: %#v\ngot: %#v\n", tc.expect, got) 184 } 185 }) 186 } 187 }