terraform-provider-file/internal/provider/local/file_local_data_source_test.go

256 lines
8.2 KiB
Go

// SPDX-License-Identifier: MPL-2.0
package local
import (
"context"
"slices"
"strconv"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)
func TestLocalDataSourceMetadata(t *testing.T) {
t.Run("Metadata function", func(t *testing.T) {
testCases := []struct {
name string
fit LocalDataSource
want datasource.MetadataResponse
}{
{"Basic test", LocalDataSource{}, datasource.MetadataResponse{TypeName: "file_local"}},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res := datasource.MetadataResponse{}
tc.fit.Metadata(context.Background(), datasource.MetadataRequest{ProviderTypeName: "file"}, &res)
got := res
if got != tc.want {
t.Errorf("%#v.Metadata() is %v; want %v", tc.fit, got, tc.want)
}
})
}
})
}
func TestLocalDataSourceRead(t *testing.T) {
t.Run("Read function", func(t *testing.T) {
testCases := []struct {
name string
fit LocalDataSource
have datasource.ReadRequest
want datasource.ReadResponse
setup map[string]string
}{
{
"Unprotected",
LocalDataSource{client: &memoryFileClient{}},
// have
getDataSourceReadRequest(t, map[string]string{
"id": "60cef95046105ff4522c0c1f1aeeeba43d0d729dbcabdd8846c317c98cac60a2",
"name": "read.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is an unprotected read test",
"hmac_secret_key": defaultHmacSecretKey,
}),
// want
getDataSourceReadResponse(t, map[string]string{
"id": "60cef95046105ff4522c0c1f1aeeeba43d0d729dbcabdd8846c317c98cac60a2",
"name": "read.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is an unprotected read test",
"hmac_secret_key": defaultHmacSecretKey,
}),
map[string]string{
"mode": defaultPerm,
"directory": defaultDirectory,
"name": "read.tmp",
"contents": "this is an unprotected read test",
},
},
{
"Protected",
LocalDataSource{client: &memoryFileClient{}},
// have
getDataSourceReadRequest(t, map[string]string{
"id": "ec4407ba53b2c40ac2ac18ff7372a6fe6e4f7f8aa04f340503aefc7d9a5fa4e1",
"name": "read_protected.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is a protected read test",
"hmac_secret_key": "this-is-a-test-key",
}),
// want
getDataSourceReadResponse(t, map[string]string{
"id": "ec4407ba53b2c40ac2ac18ff7372a6fe6e4f7f8aa04f340503aefc7d9a5fa4e1",
"name": "read_protected.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is a protected read test",
"hmac_secret_key": "this-is-a-test-key",
}),
// reality
map[string]string{
"mode": defaultPerm,
"directory": defaultDirectory,
"name": "read_protected.tmp",
"contents": "this is a protected read test",
},
},
{
"Protected with content update",
LocalDataSource{client: &memoryFileClient{}},
// have
getDataSourceReadRequest(t, map[string]string{
"id": "ec4407ba53b2c40ac2ac18ff7372a6fe6e4f7f8aa04f340503aefc7d9a5fa4e1",
"name": "read_protected_content.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is a protected read test",
"hmac_secret_key": "this-is-a-test-key",
}),
// want
getDataSourceReadResponse(t, map[string]string{
"id": "84326116e261654e44ca3cb73fa026580853794062d472bc817b7ec2c82ff648",
"name": "read_protected_content.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is a change in contents in the real file",
"hmac_secret_key": "this-is-a-test-key",
}),
// reality
map[string]string{
"mode": defaultPerm,
"directory": defaultDirectory,
"name": "read_protected_content.tmp",
"contents": "this is a change in contents in the real file",
},
},
{
"Protected with mode update",
LocalDataSource{client: &memoryFileClient{}},
// have
getDataSourceReadRequest(t, map[string]string{
"id": "ec4407ba53b2c40ac2ac18ff7372a6fe6e4f7f8aa04f340503aefc7d9a5fa4e1",
"name": "read_protected_mode.tmp",
"directory": defaultDirectory,
"permissions": defaultPerm,
"contents": "this is a protected read test",
"hmac_secret_key": "this-is-a-test-key",
}),
// want
getDataSourceReadResponse(t, map[string]string{
"id": "ec4407ba53b2c40ac2ac18ff7372a6fe6e4f7f8aa04f340503aefc7d9a5fa4e1",
"name": "read_protected_mode.tmp",
"directory": defaultDirectory,
"permissions": "0755",
"contents": "this is a protected read test",
"hmac_secret_key": "this-is-a-test-key",
}),
// reality
map[string]string{
"mode": "0755",
"directory": defaultDirectory,
"name": "read_protected_mode.tmp",
"contents": "this is a protected read test",
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if err := tc.fit.client.Create(tc.setup["directory"], tc.setup["name"], tc.setup["contents"], tc.setup["mode"]); err != nil {
t.Errorf("Error setting up: %v", err)
}
defer func() {
if err := tc.fit.client.Delete(tc.setup["directory"], tc.setup["name"]); err != nil {
t.Errorf("Error tearing down: %v", err)
}
}()
r := getDataSourceReadResponseContainer()
tc.fit.Read(context.Background(), tc.have, &r)
got := r
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("Read() mismatch (-want +got):\n%s", diff)
}
})
}
})
}
// *** Test Helper Functions *** //
func getDataSourceReadRequest(t *testing.T, data map[string]string) datasource.ReadRequest {
stateMap := make(map[string]tftypes.Value)
for key, value := range data {
if slices.Contains(booleanFields, key) { // booleanFields is a constant
v, err := strconv.ParseBool(value)
if err != nil {
t.Errorf("Error converting %s to bool %s: ", value, err.Error())
}
stateMap[key] = tftypes.NewValue(tftypes.Bool, v)
} else {
stateMap[key] = tftypes.NewValue(tftypes.String, value)
}
}
stateValue := tftypes.NewValue(getDataSourceObjectAttributeTypes(), stateMap)
return datasource.ReadRequest{
Config: tfsdk.Config{
Raw: stateValue,
Schema: getLocalDataSourceSchema().Schema,
},
}
}
func getDataSourceReadResponseContainer() datasource.ReadResponse {
return datasource.ReadResponse{
State: tfsdk.State{Schema: getLocalDataSourceSchema().Schema},
}
}
func getDataSourceReadResponse(t *testing.T, data map[string]string) datasource.ReadResponse {
stateMap := make(map[string]tftypes.Value)
for key, value := range data {
if slices.Contains(booleanFields, key) { // booleanFields is a constant
v, err := strconv.ParseBool(value)
if err != nil {
t.Errorf("Error converting %s to bool %s: ", value, err.Error())
}
stateMap[key] = tftypes.NewValue(tftypes.Bool, v)
} else {
stateMap[key] = tftypes.NewValue(tftypes.String, value)
}
}
stateValue := tftypes.NewValue(getDataSourceObjectAttributeTypes(), stateMap)
return datasource.ReadResponse{
State: tfsdk.State{
Raw: stateValue,
Schema: getLocalDataSourceSchema().Schema,
},
}
}
func getDataSourceObjectAttributeTypes() tftypes.Object {
return tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"id": tftypes.String,
"name": tftypes.String,
"directory": tftypes.String,
"permissions": tftypes.String,
"contents": tftypes.String,
"hmac_secret_key": tftypes.String,
},
}
}
func getLocalDataSourceSchema() *datasource.SchemaResponse {
var testResource LocalDataSource
r := &datasource.SchemaResponse{}
testResource.Schema(context.Background(), datasource.SchemaRequest{}, r)
return r
}