Skip to content

Commit f6fff8c

Browse files
authored
Fixes #2396: Updates implementation for func StrMaxLength (#2398)
1 parent a584912 commit f6fff8c

5 files changed

Lines changed: 108 additions & 2 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
resource "okta_group" "test" {
2+
name = "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもらりるれろ"
3+
}
4+
5+
resource "okta_group_rule" "test" {
6+
name = "ABCDEFGHIJKLMNOPQRSTUVWXYZあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもらりるれろ"
7+
status = "ACTIVE"
8+
group_assignments = [okta_group.test.id]
9+
expression_type = "urn:okta:expression:1.0"
10+
expression_value = "String.startsWith(user.firstName,\"andy\")"
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
resource "okta_group" "test" {
2+
name = "[xx]ZZZ_ああああ_yyyyyyあいうえおかきくけ1ww1"
3+
}
4+
5+
resource "okta_group_rule" "test" {
6+
name = "[xx]ZZZ_ああああ_yyyyyyあいうw1w1えおかきくけ1"
7+
status = "ACTIVE"
8+
group_assignments = [okta_group.test.id]
9+
expression_type = "urn:okta:expression:1.0"
10+
expression_value = "String.startsWith(user.firstName,\"andy\")"
11+
}

okta/services/idaas/resource_okta_group_rule_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,28 @@ func TestAccResourceOktaGroupRule_statusIsInvalidDiffFn(t *testing.T) {
197197
})
198198
}
199199
}
200+
201+
func TestAccResourceOktaGroupRule_nameLengthVerification_Issue2396(t *testing.T) {
202+
resourceName := fmt.Sprintf("%s.test", resources.OktaIDaaSGroupRule)
203+
mgr := newFixtureManager("resources", "okta_group_rule", t.Name())
204+
config := mgr.GetFixtures("basic_group_rule_name_length_verify.tf", t)
205+
failConfig := mgr.GetFixtures("basic_group_rule_name_length_fail.tf", t)
206+
acctest.OktaResourceTest(t, resource.TestCase{
207+
PreCheck: acctest.AccPreCheck(t),
208+
ErrorCheck: testAccErrorChecks(t),
209+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactoriesForTestAcc(t),
210+
CheckDestroy: checkResourceDestroy(resources.OktaIDaaSGroupRule, doesGroupRuleExist),
211+
Steps: []resource.TestStep{
212+
{
213+
Config: config,
214+
Check: resource.ComposeTestCheckFunc(
215+
resource.TestCheckResourceAttr(resourceName, "name", "[xx]ZZZ_ああああ_yyyyyyあいうw1w1えおかきくけ1"),
216+
),
217+
},
218+
{
219+
Config: failConfig,
220+
ExpectError: regexp.MustCompile(`\[\{\{\} name\}\] cannot be longer than 50 runes`),
221+
},
222+
},
223+
})
224+
}

okta/utils/utils.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -715,14 +715,18 @@ func LinksValue(links interface{}, keys ...string) string {
715715
return LinksValue(l[keys[0]], keys[1:]...)
716716
}
717717

718+
// StrMaxLength validates that the string is not longer than the specified maximum length.
718719
func StrMaxLength(max int) schema.SchemaValidateDiagFunc {
719720
return func(i interface{}, k cty.Path) diag.Diagnostics {
720721
v, ok := i.(string)
721722
if !ok {
722723
return diag.Errorf("expected type of %s to be string", k)
723724
}
724-
if len(v) > max {
725-
return diag.Errorf("%s cannot be longer than %d characters", k, max)
725+
726+
// https://github.com/okta/terraform-provider-okta/issues/2396
727+
runes := []rune(v)
728+
if len(runes) > max {
729+
return diag.Errorf("%s cannot be longer than %d runes", k, max)
726730
}
727731
return nil
728732
}

okta/utils/utils_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package utils
22

33
import (
44
"encoding/json"
5+
"github.com/hashicorp/go-cty/cty"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
57
"log"
68
"reflect"
79
"strings"
@@ -474,3 +476,56 @@ func TestLinksValue(t *testing.T) {
474476
})
475477
}
476478
}
479+
480+
func TestStrMaxLength(t *testing.T) {
481+
tests := []struct {
482+
name string
483+
input interface{}
484+
max int
485+
expectError bool
486+
}{
487+
{
488+
name: "valid ascii under max",
489+
input: "hello world",
490+
max: 50,
491+
expectError: false,
492+
},
493+
{
494+
name: "valid multibyte under max",
495+
input: "こんにちは世界", // 7 runes
496+
max: 50,
497+
expectError: false,
498+
},
499+
{
500+
name: "ascii over max",
501+
input: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
502+
max: 50, // 52 runes
503+
expectError: true,
504+
},
505+
{
506+
name: "multibyte over max",
507+
input: "あいうえおかきくけこさしすせそたちつてと", // 20 runes
508+
max: 10,
509+
expectError: true,
510+
},
511+
}
512+
513+
for _, tt := range tests {
514+
t.Run(tt.name, func(t *testing.T) {
515+
validator := StrMaxLength(tt.max)
516+
path := cty.Path{cty.GetAttrStep{Name: "name"}}
517+
diags := validator(tt.input, path)
518+
519+
gotError := false
520+
for _, d := range diags {
521+
if d.Severity == diag.Error {
522+
gotError = true
523+
break
524+
}
525+
}
526+
if gotError != tt.expectError {
527+
t.Errorf("expected error: %v, got: %v, input: %#v", tt.expectError, gotError, tt.input)
528+
}
529+
})
530+
}
531+
}

0 commit comments

Comments
 (0)