* fix: remove unused attribute types and functions from backup models * fix: update API client references to use sqlserverflexalpha package * fix: update package references to use sqlserverflexalpha and modify user data source model * fix: add sqlserverflexalpha user data source to provider * fix: add sqlserverflexalpha user resource and update related functionality * chore: add stackit_sqlserverflexalpha_user resource and instance_id variable * fix: refactor sqlserverflexalpha user resource and enhance schema with status and default_database --------- Co-authored-by: Andre Harms <andre.harms@stackit.cloud> Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
970 lines
16 KiB
Go
970 lines
16 KiB
Go
// Copyright (c) STACKIT
|
|
|
|
package validate
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
|
)
|
|
|
|
func TestUUID(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"cae27bba-c43d-498a-861e-d11d241c4ff8",
|
|
true,
|
|
},
|
|
{
|
|
"too short",
|
|
"a-b-c-d",
|
|
false,
|
|
},
|
|
{
|
|
"Empty",
|
|
"",
|
|
false,
|
|
},
|
|
{
|
|
"not UUID",
|
|
"www-541-%",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
UUID().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNoUUID(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"UUID",
|
|
"cae27bba-c43d-498a-861e-d11d241c4ff8",
|
|
false,
|
|
},
|
|
{
|
|
"no UUID",
|
|
"a-b-c-d",
|
|
true,
|
|
},
|
|
{
|
|
"Empty",
|
|
"",
|
|
true,
|
|
},
|
|
{
|
|
"domain name",
|
|
"www.test.de",
|
|
true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
NoUUID().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIP(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
invalidZero bool
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok IP4",
|
|
false,
|
|
"111.222.111.222",
|
|
true,
|
|
},
|
|
{
|
|
"ok IP6",
|
|
false,
|
|
"2001:0db8:85a3:08d3::0370:7344",
|
|
true,
|
|
},
|
|
{
|
|
"too short",
|
|
false,
|
|
"0.1.2",
|
|
false,
|
|
},
|
|
{
|
|
"Empty",
|
|
false,
|
|
"",
|
|
false,
|
|
},
|
|
{
|
|
"Not an IP",
|
|
false,
|
|
"for-sure-not-an-IP",
|
|
false,
|
|
},
|
|
{
|
|
"valid ipv4 zero",
|
|
true,
|
|
"0.0.0.0",
|
|
true,
|
|
},
|
|
{
|
|
"invalid ipv4 zero",
|
|
false,
|
|
"0.0.0.0",
|
|
false,
|
|
},
|
|
{
|
|
"valid ipv6 zero",
|
|
true,
|
|
"::",
|
|
true,
|
|
},
|
|
{
|
|
"valid ipv6 zero short notation",
|
|
true,
|
|
"::0",
|
|
true,
|
|
},
|
|
{
|
|
"valid ipv6 zero long notation",
|
|
true,
|
|
"0000:0000:0000:0000:0000:0000:0000:0000",
|
|
true,
|
|
},
|
|
{
|
|
"invalid ipv6 zero short notation",
|
|
false,
|
|
"::",
|
|
false,
|
|
},
|
|
{
|
|
"invalid ipv6 zero long notation",
|
|
false,
|
|
"0000:0000:0000:0000:0000:0000:0000:0000",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
IP(tt.invalidZero).ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRecordSet(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
record string
|
|
recordType string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"A record ok IP4",
|
|
"111.222.111.222",
|
|
"A",
|
|
true,
|
|
},
|
|
{
|
|
"A record fail IP6",
|
|
"2001:0db8:85a3:08d3::0370:7344",
|
|
"A",
|
|
false,
|
|
},
|
|
{
|
|
"A record too short",
|
|
"0.1.2",
|
|
"A",
|
|
false,
|
|
},
|
|
{
|
|
"A record Empty",
|
|
"",
|
|
"A",
|
|
false,
|
|
},
|
|
{
|
|
"A record Not an IP",
|
|
"for-sure-not-an-IP",
|
|
"A",
|
|
false,
|
|
},
|
|
{
|
|
"AAAA record fail IP4",
|
|
"111.222.111.222",
|
|
"AAAA",
|
|
false,
|
|
},
|
|
{
|
|
"AAAA record ok IP6",
|
|
"2001:0db8:85a3:08d3::0370:7344",
|
|
"AAAA",
|
|
true,
|
|
},
|
|
{
|
|
"AAAA record too short",
|
|
"0.1.2",
|
|
"AAAA",
|
|
false,
|
|
},
|
|
{
|
|
"AAAA record Empty",
|
|
"",
|
|
"AAAA",
|
|
false,
|
|
},
|
|
{
|
|
"AAAA record Not an IP",
|
|
"for-sure-not-an-IP",
|
|
"AAAA",
|
|
false,
|
|
},
|
|
{
|
|
"CNAME record Not a Fully Qualified Domain Name",
|
|
"stackit.de",
|
|
"CNAME",
|
|
false,
|
|
},
|
|
{
|
|
"CNAME record ok Fully Qualified Domain Name",
|
|
"stackit.de.",
|
|
"CNAME",
|
|
true,
|
|
},
|
|
{
|
|
"NS record",
|
|
"some-record",
|
|
"NS",
|
|
true,
|
|
},
|
|
{
|
|
"MX record",
|
|
"some-record",
|
|
"MX",
|
|
true,
|
|
},
|
|
{
|
|
"TXT record",
|
|
"some-record",
|
|
"TXT",
|
|
true,
|
|
},
|
|
{
|
|
"ALIAS record",
|
|
"some-record",
|
|
"ALIAS",
|
|
true,
|
|
},
|
|
{
|
|
"DNAME record",
|
|
"some-record",
|
|
"DNAME",
|
|
true,
|
|
},
|
|
{
|
|
"CAA record",
|
|
"some-record",
|
|
"CAA",
|
|
true,
|
|
},
|
|
{
|
|
"random record",
|
|
"some-record",
|
|
"random",
|
|
true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
scheme := tftypes.Object{
|
|
AttributeTypes: map[string]tftypes.Type{
|
|
"type": tftypes.String,
|
|
},
|
|
}
|
|
value := map[string]tftypes.Value{
|
|
"type": tftypes.NewValue(tftypes.String, tt.recordType),
|
|
}
|
|
record := tftypes.NewValue(scheme, value)
|
|
|
|
RecordSet().ValidateString(context.Background(), validator.StringRequest{
|
|
Config: tfsdk.Config{
|
|
Schema: schema.Schema{
|
|
Attributes: map[string]schema.Attribute{
|
|
"type": schema.StringAttribute{},
|
|
},
|
|
},
|
|
Raw: record,
|
|
},
|
|
ConfigValue: types.StringValue(tt.record),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNoSeparator(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"ABCD",
|
|
true,
|
|
},
|
|
{
|
|
"ok-2",
|
|
"#$%&/()=.;-",
|
|
true,
|
|
},
|
|
{
|
|
"Empty",
|
|
"",
|
|
true,
|
|
},
|
|
{
|
|
"not ok",
|
|
"ab,",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
NoSeparator().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNonLegacyProjectRole(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"owner",
|
|
true,
|
|
},
|
|
{
|
|
"ok-2",
|
|
"reader",
|
|
true,
|
|
},
|
|
{
|
|
"leagcy-role",
|
|
"project.owner",
|
|
false,
|
|
},
|
|
{
|
|
"leagcy-role-2",
|
|
"project.admin",
|
|
false,
|
|
},
|
|
{
|
|
"leagcy-role-3",
|
|
"project.member",
|
|
false,
|
|
},
|
|
{
|
|
"leagcy-role-4",
|
|
"project.auditor",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
NonLegacyProjectRole().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMinorVersionNumber(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"1.20",
|
|
true,
|
|
},
|
|
{
|
|
"ok-2",
|
|
"1.3",
|
|
true,
|
|
},
|
|
{
|
|
"ok-3",
|
|
"10.1",
|
|
true,
|
|
},
|
|
{
|
|
"Empty",
|
|
"",
|
|
false,
|
|
},
|
|
{
|
|
"not ok",
|
|
"afssfdfs",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-major-version",
|
|
"1",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-patch-version",
|
|
"1.20.1",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-version",
|
|
"v1.20.1",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
MinorVersionNumber().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestVersionNumber(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"1.20",
|
|
true,
|
|
},
|
|
{
|
|
"ok-2",
|
|
"1.3",
|
|
true,
|
|
},
|
|
{
|
|
"ok-3",
|
|
"10.1",
|
|
true,
|
|
},
|
|
{
|
|
"ok-patch-version",
|
|
"1.20.1",
|
|
true,
|
|
},
|
|
{
|
|
"ok-patch-version-2",
|
|
"1.20.10",
|
|
true,
|
|
},
|
|
{
|
|
"ok-patch-version-3",
|
|
"10.20.10",
|
|
true,
|
|
},
|
|
{
|
|
"Empty",
|
|
"",
|
|
false,
|
|
},
|
|
{
|
|
"not ok",
|
|
"afssfdfs",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-major-version",
|
|
"1",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-version",
|
|
"v1.20.1",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
VersionNumber().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRFC3339SecondsOnly(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"9999-01-02T03:04:05Z",
|
|
true,
|
|
},
|
|
{
|
|
"ok_2",
|
|
"9999-01-02T03:04:05+06:00",
|
|
true,
|
|
},
|
|
{
|
|
"empty",
|
|
"",
|
|
false,
|
|
},
|
|
{
|
|
"not_ok",
|
|
"foo-bar",
|
|
false,
|
|
},
|
|
{
|
|
"with_sub_seconds",
|
|
"9999-01-02T03:04:05.678Z",
|
|
false,
|
|
},
|
|
{
|
|
"with_sub_seconds_2",
|
|
"9999-01-02T03:04:05.678+06:00",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
RFC3339SecondsOnly().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCIDR(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"IPv4_block",
|
|
"198.51.100.14/24",
|
|
true,
|
|
},
|
|
{
|
|
"IPv4_block_2",
|
|
"111.222.111.222/22",
|
|
true,
|
|
},
|
|
{
|
|
"IPv4_single",
|
|
"198.51.100.14/32",
|
|
true,
|
|
},
|
|
{
|
|
"IPv4_entire_internet",
|
|
"0.0.0.0/0",
|
|
true,
|
|
},
|
|
{
|
|
"IPv4_block_invalid",
|
|
"198.51.100.14/33",
|
|
false,
|
|
},
|
|
{
|
|
"IPv4_no_block",
|
|
"111.222.111.222",
|
|
false,
|
|
},
|
|
{
|
|
"IPv6_block",
|
|
"2001:db8::/48",
|
|
true,
|
|
},
|
|
{
|
|
"IPv6_single",
|
|
"2001:0db8:85a3:08d3::0370:7344/128",
|
|
true,
|
|
},
|
|
{
|
|
"IPv6_all",
|
|
"::/0",
|
|
true,
|
|
},
|
|
{
|
|
"IPv6_block_invalid",
|
|
"2001:0db8:85a3:08d3::0370:7344/129",
|
|
false,
|
|
},
|
|
{
|
|
"IPv6_no_block",
|
|
"2001:0db8:85a3:08d3::0370:7344",
|
|
false,
|
|
},
|
|
{
|
|
"empty",
|
|
"",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
CIDR().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRrule(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"DTSTART;TZID=Europe/Sofia:20200803T023000 RRULE:FREQ=DAILY;INTERVAL=1",
|
|
true,
|
|
},
|
|
{
|
|
"ok-2",
|
|
"DTSTART;TZID=Europe/Sofia:20200803T023000\nRULE:FREQ=DAILY;INTERVAL=1",
|
|
true,
|
|
},
|
|
{
|
|
"Empty",
|
|
"",
|
|
false,
|
|
},
|
|
{
|
|
"not ok",
|
|
"afssfdfs",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-missing-space-before-rrule",
|
|
"DTSTART;TZID=Europe/Sofia:20200803T023000RRULE:FREQ=DAILY;INTERVAL=1",
|
|
false,
|
|
},
|
|
{
|
|
"not ok-missing-interval",
|
|
"DTSTART;TZID=Europe/Sofia:20200803T023000 RRULE:FREQ=DAILY;INTERVAL=",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
Rrule().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFileExists(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"ok",
|
|
"testdata/file.txt",
|
|
true,
|
|
},
|
|
{
|
|
"not ok",
|
|
"testdata/non-existing-file.txt",
|
|
false,
|
|
},
|
|
{
|
|
"empty",
|
|
"",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
FileExists().ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidTtlDuration(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"valid duration with hours, minutes, and seconds",
|
|
"5h30m40s",
|
|
true,
|
|
},
|
|
{
|
|
"valid duration with hours only",
|
|
"5h",
|
|
true,
|
|
},
|
|
{
|
|
"valid duration with hours and minutes",
|
|
"5h30m",
|
|
true,
|
|
},
|
|
{
|
|
"valid duration with minutes only",
|
|
"30m",
|
|
true,
|
|
},
|
|
{
|
|
"valid duration with seconds only",
|
|
"30s",
|
|
true,
|
|
},
|
|
{
|
|
"invalid duration with incorrect unit",
|
|
"30o",
|
|
false,
|
|
},
|
|
{
|
|
"invalid duration without unit",
|
|
"30",
|
|
false,
|
|
},
|
|
{
|
|
"invalid duration with invalid letters",
|
|
"30e",
|
|
false,
|
|
},
|
|
{
|
|
"invalid duration with letters in middle",
|
|
"1h30x",
|
|
false,
|
|
},
|
|
{
|
|
"empty string",
|
|
"",
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
va := ValidDurationString()
|
|
va.ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Expected validation to fail for input: %v", tt.input)
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Expected validation to succeed for input: %v, but got errors: %v", tt.input, r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidNoTrailingNewline(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input string
|
|
isValid bool
|
|
}{
|
|
{
|
|
"string with no trailing newline",
|
|
"abc",
|
|
true,
|
|
},
|
|
{
|
|
"string with trailing \\n",
|
|
"abc\n",
|
|
false,
|
|
},
|
|
{
|
|
"string with trailing \\r\\n",
|
|
"abc\r\n",
|
|
false,
|
|
},
|
|
{
|
|
"string with internal newlines but not trailing",
|
|
"abc\ndef\nghi",
|
|
true,
|
|
},
|
|
{
|
|
"empty string",
|
|
"",
|
|
true,
|
|
},
|
|
{
|
|
"string that is just \\n",
|
|
"\n",
|
|
false,
|
|
},
|
|
{
|
|
"string that is just \\r\\n",
|
|
"\r\n",
|
|
false,
|
|
},
|
|
{
|
|
"string with multiple newlines, trailing",
|
|
"abc\n\n",
|
|
false,
|
|
},
|
|
{
|
|
"string with newlines but ends with character",
|
|
"abc\ndef\n",
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
r := validator.StringResponse{}
|
|
va := ValidNoTrailingNewline()
|
|
va.ValidateString(context.Background(), validator.StringRequest{
|
|
ConfigValue: types.StringValue(tt.input),
|
|
}, &r)
|
|
|
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
|
t.Fatalf("Expected validation to fail for input: %q", tt.input)
|
|
}
|
|
if tt.isValid && r.Diagnostics.HasError() {
|
|
t.Fatalf("Expected validation to succeed for input: %q, but got errors: %v", tt.input, r.Diagnostics.Errors())
|
|
}
|
|
})
|
|
}
|
|
}
|