From 0afa864ba4dadf9022cf752f5dc5772b720e0698 Mon Sep 17 00:00:00 2001 From: Anthony Wat Date: Sat, 30 Mar 2024 17:16:40 -0400 Subject: [PATCH] fix: Count UTF-8 string length by # of chars vs. bytes in message and subject args for aws_cognito_user_pool --- internal/service/cognitoidp/user_pool_test.go | 124 ++++++++++++++---- internal/service/cognitoidp/validate.go | 100 +++++++------- internal/service/cognitoidp/validate_test.go | 18 ++- 3 files changed, 166 insertions(+), 76 deletions(-) diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index 7d4123724643..6d099314abca 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1500,6 +1500,12 @@ func TestAccCognitoIDPUserPool_withVerificationMessageTemplate(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" + emailMessage := "foo {####} bar" + emailMessageByLink := "{##foobar##}" + emailSubject := "foobar {####}" + emailSubjectByLink := "foobar" + smsMessage := "{####} baz" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.CognitoIDPServiceID), @@ -1507,22 +1513,22 @@ func TestAccCognitoIDPUserPool_withVerificationMessageTemplate(t *testing.T) { CheckDestroy: testAccCheckUserPoolDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccUserPoolConfig_verificationMessageTemplate(rName), + Config: testAccUserPoolConfig_verificationMessageTemplate(rName, emailMessage, emailMessageByLink, emailSubject, emailSubjectByLink, smsMessage), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.default_email_option", "CONFIRM_WITH_LINK"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", "foo {####} bar"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message_by_link", "{##foobar##}"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject", "foobar {####}"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject_by_link", "foobar"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.sms_message", "{####} baz"), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message_by_link", emailMessageByLink), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject_by_link", emailSubjectByLink), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.sms_message", smsMessage), /* Setting Verification template attributes like EmailMessage, EmailSubject or SmsMessage will implicitly set EmailVerificationMessage, EmailVerificationSubject and SmsVerificationMessage attributes. */ - resource.TestCheckResourceAttr(resourceName, "email_verification_message", "foo {####} bar"), - resource.TestCheckResourceAttr(resourceName, "email_verification_subject", "foobar {####}"), - resource.TestCheckResourceAttr(resourceName, "sms_verification_message", "{####} baz"), + resource.TestCheckResourceAttr(resourceName, "email_verification_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "email_verification_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "sms_verification_message", smsMessage), ), }, { @@ -1531,19 +1537,81 @@ func TestAccCognitoIDPUserPool_withVerificationMessageTemplate(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccUserPoolConfig_verificationMessageTemplateDefaultEmailOption(rName), + Config: testAccUserPoolConfig_verificationMessageTemplateDefaultEmailOption(rName, emailMessage, emailSubject, smsMessage), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.default_email_option", "CONFIRM_WITH_CODE"), - resource.TestCheckResourceAttr(resourceName, "email_verification_message", "{####} Baz"), - resource.TestCheckResourceAttr(resourceName, "email_verification_subject", "BazBaz {####}"), - resource.TestCheckResourceAttr(resourceName, "sms_verification_message", "{####} BazBazBar?"), + resource.TestCheckResourceAttr(resourceName, "email_verification_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "email_verification_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "sms_verification_message", smsMessage), /* Setting EmailVerificationMessage, EmailVerificationSubject and SmsVerificationMessage attributes will implicitly set verification template attributes like EmailMessage, EmailSubject or SmsMessage. */ - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", "{####} Baz"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject", "BazBaz {####}"), - resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.sms_message", "{####} BazBazBar?"), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.sms_message", smsMessage), + ), + }, + }, + }) +} + +func TestAccCognitoIDPUserPool_withVerificationMessageTemplateUTF8(t *testing.T) { + ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cognito_user_pool.test" + + emailMessage := "{####}" + strings.Repeat("あ", 994) // = 1000 + emailMessageByLink := "{##foobar##}" + strings.Repeat("い", 988) // = 1000 + emailSubject := strings.Repeat("う", 140) + emailSubjectByLink := strings.Repeat("え", 140) + smsMessage := "{####}" + strings.Repeat("お", 134) // = 140 + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.CognitoIDPServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckUserPoolDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccUserPoolConfig_verificationMessageTemplate(rName, emailMessage, emailMessageByLink, emailSubject, emailSubjectByLink, smsMessage), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.default_email_option", "CONFIRM_WITH_LINK"), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message_by_link", emailMessageByLink), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject_by_link", emailSubjectByLink), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.sms_message", smsMessage), + + /* Setting Verification template attributes like EmailMessage, EmailSubject or SmsMessage + will implicitly set EmailVerificationMessage, EmailVerificationSubject and SmsVerificationMessage attributes. + */ + resource.TestCheckResourceAttr(resourceName, "email_verification_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "email_verification_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "sms_verification_message", smsMessage), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccUserPoolConfig_verificationMessageTemplateDefaultEmailOption(rName, emailMessage, emailSubject, smsMessage), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.default_email_option", "CONFIRM_WITH_CODE"), + resource.TestCheckResourceAttr(resourceName, "email_verification_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "email_verification_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "sms_verification_message", smsMessage), + + /* Setting EmailVerificationMessage, EmailVerificationSubject and SmsVerificationMessage attributes + will implicitly set verification template attributes like EmailMessage, EmailSubject or SmsMessage. + */ + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", emailMessage), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_subject", emailSubject), + resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.sms_message", smsMessage), ), }, }, @@ -2657,7 +2725,7 @@ resource "aws_cognito_user_pool" "test" { `, name) } -func testAccUserPoolConfig_verificationMessageTemplate(name string) string { +func testAccUserPoolConfig_verificationMessageTemplate(name, emailMessage, emailMessageByLink, emailSubject, emailSubjectByLink, smsMessage string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "test" { name = %[1]q @@ -2668,30 +2736,30 @@ resource "aws_cognito_user_pool" "test" { verification_message_template { default_email_option = "CONFIRM_WITH_LINK" - email_message = "foo {####} bar" - email_message_by_link = "{##foobar##}" - email_subject = "foobar {####}" - email_subject_by_link = "foobar" - sms_message = "{####} baz" + email_message = %[2]q + email_message_by_link = %[3]q + email_subject = %[4]q + email_subject_by_link = %[5]q + sms_message = %[6]q } } -`, name) +`, name, emailMessage, emailMessageByLink, emailSubject, emailSubjectByLink, smsMessage) } -func testAccUserPoolConfig_verificationMessageTemplateDefaultEmailOption(name string) string { +func testAccUserPoolConfig_verificationMessageTemplateDefaultEmailOption(name, emailVerificationMessage, emailVerificationSubject, smsVerificationMessage string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "test" { name = %[1]q - email_verification_message = "{####} Baz" - email_verification_subject = "BazBaz {####}" - sms_verification_message = "{####} BazBazBar?" + email_verification_message = %[2]q + email_verification_subject = %[3]q + sms_verification_message = %[4]q verification_message_template { default_email_option = "CONFIRM_WITH_CODE" } } -`, name) +`, name, emailVerificationMessage, emailVerificationSubject, smsVerificationMessage) } func testAccUserPoolConfig_update(name string, mfaconfig, smsAuthMsg string) string { diff --git a/internal/service/cognitoidp/validate.go b/internal/service/cognitoidp/validate.go index d04108d8877f..8ec8152fcd0b 100644 --- a/internal/service/cognitoidp/validate.go +++ b/internal/service/cognitoidp/validate.go @@ -5,6 +5,7 @@ package cognitoidp import ( "fmt" + "unicode/utf8" "github.com/YakDriver/regexache" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -44,12 +45,13 @@ func validUserGroupName(v interface{}, k string) (ws []string, es []error) { func validUserPoolEmailVerificationMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 20000 { - es = append(es, fmt.Errorf("%q cannot be longer than 20000 characters", k)) + if count > 20000 { + es = append(es, fmt.Errorf("%q cannot be longer than 20000 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*\{####\}[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*`).MatchString(value) { @@ -60,12 +62,13 @@ func validUserPoolEmailVerificationMessage(v interface{}, k string) (ws []string func validUserPoolEmailVerificationSubject(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 1 { + es = append(es, fmt.Errorf("%q cannot be less than 1 UTF-8 characters", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s]+`).MatchString(value) { @@ -84,12 +87,13 @@ func validUserPoolID(v interface{}, k string) (ws []string, es []error) { func validUserPoolInviteTemplateEmailMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 20000 { - es = append(es, fmt.Errorf("%q cannot be longer than 20000 characters", k)) + if count > 20000 { + es = append(es, fmt.Errorf("%q cannot be longer than 20000 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*\{####\}[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*`).MatchString(value) { @@ -104,12 +108,13 @@ func validUserPoolInviteTemplateEmailMessage(v interface{}, k string) (ws []stri func validUserPoolInviteTemplateSMSMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`.*\{####\}.*`).MatchString(value) { @@ -140,12 +145,13 @@ func validUserPoolSchemaName(v interface{}, k string) (ws []string, es []error) func validUserPoolSMSAuthenticationMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`.*\{####\}.*`).MatchString(value) { @@ -156,12 +162,13 @@ func validUserPoolSMSAuthenticationMessage(v interface{}, k string) (ws []string func validUserPoolSMSVerificationMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`.*\{####\}.*`).MatchString(value) { @@ -172,12 +179,13 @@ func validUserPoolSMSVerificationMessage(v interface{}, k string) (ws []string, func validUserPoolTemplateEmailMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 20000 { - es = append(es, fmt.Errorf("%q cannot be longer than 20000 characters", k)) + if count > 20000 { + es = append(es, fmt.Errorf("%q cannot be longer than 20000 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*\{####\}[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*`).MatchString(value) { @@ -188,12 +196,13 @@ func validUserPoolTemplateEmailMessage(v interface{}, k string) (ws []string, es func validUserPoolTemplateEmailMessageByLink(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 1 { - es = append(es, fmt.Errorf("%q cannot be less than 1 character", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 20000 { - es = append(es, fmt.Errorf("%q cannot be longer than 20000 characters", k)) + if count > 20000 { + es = append(es, fmt.Errorf("%q cannot be longer than 20000 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*\{##[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*##\}[\p{L}\p{M}\p{S}\p{N}\p{P}\s*]*`).MatchString(value) { @@ -204,12 +213,13 @@ func validUserPoolTemplateEmailMessageByLink(v interface{}, k string) (ws []stri func validUserPoolTemplateEmailSubject(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 1 { - es = append(es, fmt.Errorf("%q cannot be less than 1 character", k)) + count := utf8.RuneCountInString(value) + if count < 1 { + es = append(es, fmt.Errorf("%q cannot be less than 1 UTF-8 character", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s]+`).MatchString(value) { @@ -220,12 +230,13 @@ func validUserPoolTemplateEmailSubject(v interface{}, k string) (ws []string, es func validUserPoolTemplateEmailSubjectByLink(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 1 { - es = append(es, fmt.Errorf("%q cannot be less than 1 character", k)) + count := utf8.RuneCountInString(value) + if count < 1 { + es = append(es, fmt.Errorf("%q cannot be less than 1 UTF-8 character", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}\s]+`).MatchString(value) { @@ -236,12 +247,13 @@ func validUserPoolTemplateEmailSubjectByLink(v interface{}, k string) (ws []stri func validUserPoolTemplateSMSMessage(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if len(value) < 6 { - es = append(es, fmt.Errorf("%q cannot be less than 6 characters", k)) + count := utf8.RuneCountInString(value) + if count < 6 { + es = append(es, fmt.Errorf("%q cannot be less than 6 UTF-8 characters", k)) } - if len(value) > 140 { - es = append(es, fmt.Errorf("%q cannot be longer than 140 characters", k)) + if count > 140 { + es = append(es, fmt.Errorf("%q cannot be longer than 140 UTF-8 characters", k)) } if !regexache.MustCompile(`.*\{####\}.*`).MatchString(value) { diff --git a/internal/service/cognitoidp/validate_test.go b/internal/service/cognitoidp/validate_test.go index 00b5d87a9d28..67a873b450e6 100644 --- a/internal/service/cognitoidp/validate_test.go +++ b/internal/service/cognitoidp/validate_test.go @@ -51,6 +51,7 @@ func TestValidUserPoolEmailVerificationMessage(t *testing.T) { "{####} Bar", "AZERTYUIOPQSDFGHJKLMWXCVBN?./+%£*¨°0987654321&é\"'(§è!çà)-@^'{####},=ù`$|´”’[å»ÛÁØ]–Ô¥#‰±•", "{####}" + strings.Repeat("W", 19994), // = 20000 + "{####}" + strings.Repeat("あ", 19994), // = 20000, UTF-8 (2 bytes/char) } for _, s := range validValues { @@ -62,8 +63,10 @@ func TestValidUserPoolEmailVerificationMessage(t *testing.T) { invalidValues := []string{ "Foo", + "あいうえお", "{###}", "{####}" + strings.Repeat("W", 19995), // > 20000 + "{####}" + strings.Repeat("あ", 19995), // > 20000, UTF-8 (2 bytes/char) } for _, s := range invalidValues { @@ -82,6 +85,7 @@ func TestValidUserPoolEmailVerificationSubject(t *testing.T) { "AZERTYUIOPQSDFGHJKLMWXCVBN?./+%£*¨°0987654321&é\" '(§è!çà)-@^'{####},=ù`$|´”’[å»ÛÁØ]–Ô¥#‰±•", "Foo Bar", // special whitespace character strings.Repeat("W", 140), + strings.Repeat("あ", 140), // UTF-8 (2 bytes/char) } for _, s := range validValues { @@ -92,8 +96,8 @@ func TestValidUserPoolEmailVerificationSubject(t *testing.T) { } invalidValues := []string{ - "Foo", - strings.Repeat("W", 141), + strings.Repeat("W", 141), // > 140 + strings.Repeat("あ", 141), // UTF-8 (2 bytes/char) } for _, s := range invalidValues { @@ -143,6 +147,7 @@ func TestValidUserPoolSMSAuthenticationMessage(t *testing.T) { "{####} Bar", "AZERTYUIOPQSDFGHJKLMWXCVBN?./+%£*¨°0987654321&é\"'(§è!çà)-@^'{####},=ù`$|´”’[å»ÛÁØ]–Ô¥#‰±•", "{####}" + strings.Repeat("W", 134), // = 140 + "{####}" + strings.Repeat("あ", 134), // = 140, UTF-8 (2 bytes/char) } for _, s := range validValues { @@ -154,7 +159,9 @@ func TestValidUserPoolSMSAuthenticationMessage(t *testing.T) { invalidValues := []string{ "Foo", - "{####}" + strings.Repeat("W", 135), + "あいうえお", + "{####}" + strings.Repeat("W", 135), // > 140 + "{####}" + strings.Repeat("あ", 135), // > 140, UTF-8 (2 bytes/char) } for _, s := range invalidValues { @@ -174,6 +181,7 @@ func TestValidUserPoolSMSVerificationMessage(t *testing.T) { "{####} Bar", "AZERTYUIOPQSDFGHJKLMWXCVBN?./+%£*¨°0987654321&é\"'(§è!çà)-@^'{####},=ù`$|´”’[å»ÛÁØ]–Ô¥#‰±•", "{####}" + strings.Repeat("W", 134), // = 140 + "{####}" + strings.Repeat("あ", 134), // = 140, UTF-8 (2 bytes/char) } for _, s := range validValues { @@ -185,7 +193,9 @@ func TestValidUserPoolSMSVerificationMessage(t *testing.T) { invalidValues := []string{ "Foo", - "{####}" + strings.Repeat("W", 135), + "あいうえお", + "{####}" + strings.Repeat("W", 135), // > 140 + "{####}" + strings.Repeat("あ", 135), // > 140, UTF-8 (2 bytes/char) } for _, s := range invalidValues {