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  }