@@ -10,7 +10,9 @@ import (
1010 "github.com/google/go-cmp/cmp"
1111 "github.com/hashicorp/terraform-plugin-framework/resource/schema/dynamicplanmodifier"
1212 "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
13+ "github.com/hashicorp/terraform-plugin-framework/tfsdk"
1314 "github.com/hashicorp/terraform-plugin-framework/types"
15+ "github.com/hashicorp/terraform-plugin-go/tftypes"
1416)
1517
1618func TestUseStateForUnknownModifierPlanModifyDynamic (t * testing.T ) {
@@ -23,6 +25,16 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
2325 "null-state" : {
2426 // when we first create the resource, use the unknown value
2527 request : planmodifier.DynamicRequest {
28+ State : tfsdk.State {
29+ Raw : tftypes .NewValue (
30+ tftypes.Object {
31+ AttributeTypes : map [string ]tftypes.Type {
32+ "attr" : tftypes .DynamicPseudoType ,
33+ },
34+ },
35+ nil ,
36+ ),
37+ },
2638 StateValue : types .DynamicNull (),
2739 PlanValue : types .DynamicUnknown (),
2840 ConfigValue : types .DynamicNull (),
@@ -31,23 +43,23 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
3143 PlanValue : types .DynamicUnknown (),
3244 },
3345 },
34- "null-underlying-state-value" : {
35- // if the state value has a known underlying type, but a null underlying value,
36- // use the unknown value
37- request : planmodifier.DynamicRequest {
38- StateValue : types .DynamicValue (types .StringNull ()),
39- PlanValue : types .DynamicUnknown (),
40- ConfigValue : types .DynamicNull (),
41- },
42- expected : & planmodifier.DynamicResponse {
43- PlanValue : types .DynamicUnknown (),
44- },
45- },
4646 "known-plan" : {
4747 // this would really only happen if we had a plan
4848 // modifier setting the value before this plan modifier
4949 // got to it. We still want to preserve that value, in this case
5050 request : planmodifier.DynamicRequest {
51+ State : tfsdk.State {
52+ Raw : tftypes .NewValue (
53+ tftypes.Object {
54+ AttributeTypes : map [string ]tftypes.Type {
55+ "attr" : tftypes .DynamicPseudoType ,
56+ },
57+ },
58+ map [string ]tftypes.Value {
59+ "attr" : tftypes .NewValue (tftypes .String , "other" ),
60+ },
61+ ),
62+ },
5163 StateValue : types .DynamicValue (types .StringValue ("other" )),
5264 PlanValue : types .DynamicValue (types .StringValue ("test" )),
5365 ConfigValue : types .DynamicNull (),
@@ -61,6 +73,18 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
6173 // modifier setting the value before this plan modifier
6274 // got to it. We still want to preserve that value, in this case
6375 request : planmodifier.DynamicRequest {
76+ State : tfsdk.State {
77+ Raw : tftypes .NewValue (
78+ tftypes.Object {
79+ AttributeTypes : map [string ]tftypes.Type {
80+ "attr" : tftypes .DynamicPseudoType ,
81+ },
82+ },
83+ map [string ]tftypes.Value {
84+ "attr" : tftypes .NewValue (tftypes .String , "other" ),
85+ },
86+ ),
87+ },
6488 StateValue : types .DynamicValue (types .StringValue ("other" )),
6589 PlanValue : types .DynamicNull (),
6690 ConfigValue : types .DynamicNull (),
@@ -74,6 +98,18 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
7498 // modifier setting the value before this plan modifier
7599 // got to it. We still want to preserve that value, in this case
76100 request : planmodifier.DynamicRequest {
101+ State : tfsdk.State {
102+ Raw : tftypes .NewValue (
103+ tftypes.Object {
104+ AttributeTypes : map [string ]tftypes.Type {
105+ "attr" : tftypes .DynamicPseudoType ,
106+ },
107+ },
108+ map [string ]tftypes.Value {
109+ "attr" : tftypes .NewValue (tftypes .String , "other" ),
110+ },
111+ ),
112+ },
77113 StateValue : types .DynamicValue (types .StringValue ("other" )),
78114 PlanValue : types .DynamicValue (types .StringNull ()),
79115 ConfigValue : types .DynamicNull (),
@@ -82,9 +118,21 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
82118 PlanValue : types .DynamicValue (types .StringNull ()),
83119 },
84120 },
85- "non-null-state-unknown-plan" : {
121+ "non-null-state-value- unknown-plan" : {
86122 // this is the situation we want to preserve the state in
87123 request : planmodifier.DynamicRequest {
124+ State : tfsdk.State {
125+ Raw : tftypes .NewValue (
126+ tftypes.Object {
127+ AttributeTypes : map [string ]tftypes.Type {
128+ "attr" : tftypes .DynamicPseudoType ,
129+ },
130+ },
131+ map [string ]tftypes.Value {
132+ "attr" : tftypes .NewValue (tftypes .String , "test" ),
133+ },
134+ ),
135+ },
88136 StateValue : types .DynamicValue (types .StringValue ("test" )),
89137 PlanValue : types .DynamicUnknown (),
90138 ConfigValue : types .DynamicNull (),
@@ -93,10 +141,22 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
93141 PlanValue : types .DynamicValue (types .StringValue ("test" )),
94142 },
95143 },
96- "non-null-state-unknown-underlying-plan-value" : {
144+ "non-null-state-value- unknown-underlying-plan-value" : {
97145 // if the plan value has a known underlying type, but an unknown underlying value
98146 // we want to preserve the state
99147 request : planmodifier.DynamicRequest {
148+ State : tfsdk.State {
149+ Raw : tftypes .NewValue (
150+ tftypes.Object {
151+ AttributeTypes : map [string ]tftypes.Type {
152+ "attr" : tftypes .DynamicPseudoType ,
153+ },
154+ },
155+ map [string ]tftypes.Value {
156+ "attr" : tftypes .NewValue (tftypes .String , "test" ),
157+ },
158+ ),
159+ },
100160 StateValue : types .DynamicValue (types .StringValue ("test" )),
101161 PlanValue : types .DynamicValue (types .StringUnknown ()),
102162 ConfigValue : types .DynamicNull (),
@@ -105,6 +165,52 @@ func TestUseStateForUnknownModifierPlanModifyDynamic(t *testing.T) {
105165 PlanValue : types .DynamicValue (types .StringValue ("test" )),
106166 },
107167 },
168+ "null-state-value-unknown-plan" : {
169+ // Null state values are still known, so we should preserve this as well.
170+ request : planmodifier.DynamicRequest {
171+ State : tfsdk.State {
172+ Raw : tftypes .NewValue (
173+ tftypes.Object {
174+ AttributeTypes : map [string ]tftypes.Type {
175+ "attr" : tftypes .DynamicPseudoType ,
176+ },
177+ },
178+ map [string ]tftypes.Value {
179+ "attr" : tftypes .NewValue (tftypes .DynamicPseudoType , nil ),
180+ },
181+ ),
182+ },
183+ StateValue : types .DynamicNull (),
184+ PlanValue : types .DynamicUnknown (),
185+ ConfigValue : types .DynamicNull (),
186+ },
187+ expected : & planmodifier.DynamicResponse {
188+ PlanValue : types .DynamicNull (),
189+ },
190+ },
191+ "null-underlying-state-value-unknown-plan" : {
192+ // if the state value has a known underlying type, but a null underlying value, we should preserve this as well.
193+ request : planmodifier.DynamicRequest {
194+ State : tfsdk.State {
195+ Raw : tftypes .NewValue (
196+ tftypes.Object {
197+ AttributeTypes : map [string ]tftypes.Type {
198+ "attr" : tftypes .DynamicPseudoType ,
199+ },
200+ },
201+ map [string ]tftypes.Value {
202+ "attr" : tftypes .NewValue (tftypes .String , nil ),
203+ },
204+ ),
205+ },
206+ StateValue : types .DynamicValue (types .StringNull ()),
207+ PlanValue : types .DynamicUnknown (),
208+ ConfigValue : types .DynamicNull (),
209+ },
210+ expected : & planmodifier.DynamicResponse {
211+ PlanValue : types .DynamicValue (types .StringNull ()),
212+ },
213+ },
108214 "unknown-config" : {
109215 // this is the situation in which a user is
110216 // interpolating into a field. We want that to still
0 commit comments