|
1 | 1 | package utils
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "context" |
4 | 5 | "fmt"
|
5 | 6 | "reflect"
|
6 | 7 | "testing"
|
7 | 8 |
|
8 | 9 | "github.com/google/go-cmp/cmp"
|
9 | 10 | "github.com/hashicorp/terraform-plugin-framework/attr"
|
| 11 | + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" |
| 12 | + "github.com/hashicorp/terraform-plugin-framework/path" |
| 13 | + "github.com/hashicorp/terraform-plugin-framework/resource" |
| 14 | + "github.com/hashicorp/terraform-plugin-framework/tfsdk" |
10 | 15 | "github.com/hashicorp/terraform-plugin-framework/types"
|
11 | 16 | "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
12 | 17 | )
|
@@ -378,3 +383,121 @@ func TestBuildInternalTerraformId(t *testing.T) {
|
378 | 383 | })
|
379 | 384 | }
|
380 | 385 | }
|
| 386 | + |
| 387 | +func TestCheckListRemoval(t *testing.T) { |
| 388 | + type model struct { |
| 389 | + AllowedAddresses types.List `tfsdk:"allowed_addresses"` |
| 390 | + } |
| 391 | + tests := []struct { |
| 392 | + description string |
| 393 | + configModelList types.List |
| 394 | + planModelList types.List |
| 395 | + path path.Path |
| 396 | + listType attr.Type |
| 397 | + createEmptyList bool |
| 398 | + expectedAdjustedResp bool |
| 399 | + }{ |
| 400 | + { |
| 401 | + "config and plan are the same - no change", |
| 402 | + types.ListValueMust(types.StringType, []attr.Value{ |
| 403 | + types.StringValue("value1"), |
| 404 | + }), |
| 405 | + types.ListValueMust(types.StringType, []attr.Value{ |
| 406 | + types.StringValue("value1"), |
| 407 | + }), |
| 408 | + path.Root("allowed_addresses"), |
| 409 | + types.StringType, |
| 410 | + false, |
| 411 | + false, |
| 412 | + }, |
| 413 | + { |
| 414 | + "list was removed from config", |
| 415 | + types.ListNull(types.StringType), |
| 416 | + types.ListValueMust(types.StringType, []attr.Value{ |
| 417 | + types.StringValue("value1"), |
| 418 | + }), |
| 419 | + path.Root("allowed_addresses"), |
| 420 | + types.StringType, |
| 421 | + false, |
| 422 | + true, |
| 423 | + }, |
| 424 | + { |
| 425 | + "list was added to config", |
| 426 | + types.ListValueMust(types.StringType, []attr.Value{ |
| 427 | + types.StringValue("value1"), |
| 428 | + }), |
| 429 | + types.ListNull(types.StringType), |
| 430 | + path.Root("allowed_addresses"), |
| 431 | + types.StringType, |
| 432 | + false, |
| 433 | + false, |
| 434 | + }, |
| 435 | + { |
| 436 | + "no list provided at all", |
| 437 | + types.ListNull(types.StringType), |
| 438 | + types.ListNull(types.StringType), |
| 439 | + path.Root("allowed_addresses"), |
| 440 | + types.StringType, |
| 441 | + false, |
| 442 | + false, |
| 443 | + }, |
| 444 | + { |
| 445 | + "create empty list test - list was removed from config", |
| 446 | + types.ListNull(types.StringType), |
| 447 | + types.ListValueMust(types.StringType, []attr.Value{ |
| 448 | + types.StringValue("value1"), |
| 449 | + }), |
| 450 | + path.Root("allowed_addresses"), |
| 451 | + types.StringType, |
| 452 | + true, |
| 453 | + true, |
| 454 | + }, |
| 455 | + } |
| 456 | + for _, tt := range tests { |
| 457 | + t.Run(tt.description, func(t *testing.T) { |
| 458 | + // create resp |
| 459 | + plan := tfsdk.Plan{ |
| 460 | + Schema: schema.Schema{ |
| 461 | + Attributes: map[string]schema.Attribute{ |
| 462 | + "allowed_addresses": schema.ListAttribute{ |
| 463 | + ElementType: basetypes.StringType{}, |
| 464 | + }, |
| 465 | + }, |
| 466 | + }, |
| 467 | + } |
| 468 | + |
| 469 | + // set input planModelList to plan |
| 470 | + if diags := plan.Set(context.Background(), model{tt.planModelList}); diags.HasError() { |
| 471 | + t.Fatalf("cannot create test model: %v", diags) |
| 472 | + } |
| 473 | + resp := resource.ModifyPlanResponse{ |
| 474 | + Plan: plan, |
| 475 | + } |
| 476 | + |
| 477 | + CheckListRemoval(context.Background(), tt.configModelList, tt.planModelList, tt.path, tt.listType, tt.createEmptyList, &resp) |
| 478 | + // check targetList |
| 479 | + var respList types.List |
| 480 | + resp.Plan.GetAttribute(context.Background(), tt.path, &respList) |
| 481 | + |
| 482 | + if tt.createEmptyList { |
| 483 | + emptyList, _ := types.ListValueFrom(context.Background(), tt.listType, []string{}) |
| 484 | + diffEmptyList := cmp.Diff(emptyList, respList) |
| 485 | + if diffEmptyList != "" { |
| 486 | + t.Fatalf("an empty list should have been created but was not: %s", diffEmptyList) |
| 487 | + } |
| 488 | + } |
| 489 | + |
| 490 | + // compare planModelList and resp list |
| 491 | + diff := cmp.Diff(tt.planModelList, respList) |
| 492 | + if tt.expectedAdjustedResp { |
| 493 | + if diff == "" { |
| 494 | + t.Fatalf("plan should be adjusted but was not") |
| 495 | + } |
| 496 | + } else { |
| 497 | + if diff != "" { |
| 498 | + t.Fatalf("plan should not be adjusted but diff is: %s", diff) |
| 499 | + } |
| 500 | + } |
| 501 | + }) |
| 502 | + } |
| 503 | +} |
0 commit comments