gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

formvalidation_test.go (12438B)


      1 // GoToSocial
      2 // Copyright (C) GoToSocial Authors admin@gotosocial.org
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 package validate_test
     19 
     20 import (
     21 	"errors"
     22 	"fmt"
     23 	"testing"
     24 
     25 	"github.com/stretchr/testify/suite"
     26 	"github.com/superseriousbusiness/gotosocial/internal/config"
     27 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     28 	"github.com/superseriousbusiness/gotosocial/internal/validate"
     29 )
     30 
     31 type ValidationTestSuite struct {
     32 	suite.Suite
     33 }
     34 
     35 func (suite *ValidationTestSuite) TestCheckPasswordStrength() {
     36 	empty := ""
     37 	terriblePassword := "password"
     38 	weakPassword := "OKPassword"
     39 	shortPassword := "Ok12"
     40 	specialPassword := "Ok12%"
     41 	longPassword := "thisisafuckinglongpasswordbutnospecialchars"
     42 	tooLong := "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, ante id iaculis suscipit, nibh nibh varius enim, eget euismod augue augue eget mi. Praesent tincidunt, ex id finibus congue, enim nunc euismod nulla, id tincidunt ipsum neque at nunc. Sed id convallis libero. Sed euismod augue augue eget mi. Praesent tincidunt, ex id finibus congue, enim nunc euismod nulla, id tincidunt ipsum neque at nunc. Sed id convallis libero. Sed euismod augue augue eget mi. Praesent tincidunt, ex id finibus congue, enim nunc euismod nulla, id tincidunt ipsum neque at nunc."
     43 	strongPassword := "3dX5@Zc%mV*W2MBNEy$@"
     44 	var err error
     45 
     46 	err = validate.NewPassword(empty)
     47 	if suite.Error(err) {
     48 		suite.Equal(errors.New("no password provided"), err)
     49 	}
     50 
     51 	err = validate.NewPassword(terriblePassword)
     52 	if suite.Error(err) {
     53 		suite.Equal(errors.New("password is only 62% strength, try including more special characters, using uppercase letters, using numbers or using a longer password"), err)
     54 	}
     55 
     56 	err = validate.NewPassword(weakPassword)
     57 	if suite.Error(err) {
     58 		suite.Equal(errors.New("password is only 95% strength, try including more special characters, using numbers or using a longer password"), err)
     59 	}
     60 
     61 	err = validate.NewPassword(shortPassword)
     62 	if suite.Error(err) {
     63 		suite.Equal(errors.New("password is only 39% strength, try including more special characters or using a longer password"), err)
     64 	}
     65 
     66 	err = validate.NewPassword(specialPassword)
     67 	if suite.Error(err) {
     68 		suite.Equal(errors.New("password is only 53% strength, try including more special characters or using a longer password"), err)
     69 	}
     70 
     71 	err = validate.NewPassword(longPassword)
     72 	if suite.NoError(err) {
     73 		suite.Equal(nil, err)
     74 	}
     75 
     76 	err = validate.NewPassword(tooLong)
     77 	if suite.Error(err) {
     78 		suite.Equal(errors.New("password should be no more than 256 chars"), err)
     79 	}
     80 
     81 	err = validate.NewPassword(strongPassword)
     82 	if suite.NoError(err) {
     83 		suite.Equal(nil, err)
     84 	}
     85 }
     86 
     87 func (suite *ValidationTestSuite) TestValidateUsername() {
     88 	empty := ""
     89 	tooLong := "holycrapthisisthelongestusernameiveeverseeninmylifethatstoomuchman"
     90 	withSpaces := "this username has spaces in it"
     91 	weirdChars := "thisusername&&&&&&&istooweird!!"
     92 	leadingSpace := " see_that_leading_space"
     93 	trailingSpace := "thisusername_ends_with_a_space "
     94 	newlines := "this_is\n_almost_ok"
     95 	goodUsername := "this_is_a_good_username"
     96 	singleChar := "s"
     97 	var err error
     98 
     99 	err = validate.Username(empty)
    100 	suite.EqualError(err, "no username provided")
    101 
    102 	err = validate.Username(tooLong)
    103 	suite.EqualError(err, fmt.Sprintf("given username %s was invalid: must contain only lowercase letters, numbers, and underscores, max 64 characters", tooLong))
    104 
    105 	err = validate.Username(withSpaces)
    106 	suite.EqualError(err, fmt.Sprintf("given username %s was invalid: must contain only lowercase letters, numbers, and underscores, max 64 characters", withSpaces))
    107 
    108 	err = validate.Username(weirdChars)
    109 	suite.EqualError(err, fmt.Sprintf("given username %s was invalid: must contain only lowercase letters, numbers, and underscores, max 64 characters", weirdChars))
    110 
    111 	err = validate.Username(leadingSpace)
    112 	suite.EqualError(err, fmt.Sprintf("given username %s was invalid: must contain only lowercase letters, numbers, and underscores, max 64 characters", leadingSpace))
    113 
    114 	err = validate.Username(trailingSpace)
    115 	suite.EqualError(err, fmt.Sprintf("given username %s was invalid: must contain only lowercase letters, numbers, and underscores, max 64 characters", trailingSpace))
    116 
    117 	err = validate.Username(newlines)
    118 	suite.EqualError(err, fmt.Sprintf("given username %s was invalid: must contain only lowercase letters, numbers, and underscores, max 64 characters", newlines))
    119 
    120 	err = validate.Username(goodUsername)
    121 	suite.NoError(err)
    122 
    123 	err = validate.Username(singleChar)
    124 	suite.NoError(err)
    125 }
    126 
    127 func (suite *ValidationTestSuite) TestValidateEmail() {
    128 	empty := ""
    129 	notAnEmailAddress := "this-is-no-email-address!"
    130 	almostAnEmailAddress := "@thisisalmostan@email.address"
    131 	aWebsite := "https://thisisawebsite.com"
    132 	emailAddress := "thisis.actually@anemail.address"
    133 	var err error
    134 
    135 	err = validate.Email(empty)
    136 	if suite.Error(err) {
    137 		suite.Equal(errors.New("no email provided"), err)
    138 	}
    139 
    140 	err = validate.Email(notAnEmailAddress)
    141 	if suite.Error(err) {
    142 		suite.Equal(errors.New("mail: missing '@' or angle-addr"), err)
    143 	}
    144 
    145 	err = validate.Email(almostAnEmailAddress)
    146 	if suite.Error(err) {
    147 		suite.Equal(errors.New("mail: no angle-addr"), err)
    148 	}
    149 
    150 	err = validate.Email(aWebsite)
    151 	if suite.Error(err) {
    152 		suite.Equal(errors.New("mail: missing '@' or angle-addr"), err)
    153 	}
    154 
    155 	err = validate.Email(emailAddress)
    156 	if suite.NoError(err) {
    157 		suite.Equal(nil, err)
    158 	}
    159 }
    160 
    161 func (suite *ValidationTestSuite) TestValidateLanguage() {
    162 	empty := ""
    163 	notALanguage := "this isn't a language at all!"
    164 	english := "en"
    165 	capitalEnglish := "EN"
    166 	arabic3Letters := "ara"
    167 	mixedCapsEnglish := "eN"
    168 	englishUS := "en-us"
    169 	dutch := "nl"
    170 	german := "de"
    171 	var err error
    172 
    173 	err = validate.Language(empty)
    174 	if suite.Error(err) {
    175 		suite.Equal(errors.New("no language provided"), err)
    176 	}
    177 
    178 	err = validate.Language(notALanguage)
    179 	if suite.Error(err) {
    180 		suite.Equal(errors.New("language: tag is not well-formed"), err)
    181 	}
    182 
    183 	err = validate.Language(english)
    184 	if suite.NoError(err) {
    185 		suite.Equal(nil, err)
    186 	}
    187 
    188 	err = validate.Language(capitalEnglish)
    189 	if suite.NoError(err) {
    190 		suite.Equal(nil, err)
    191 	}
    192 
    193 	err = validate.Language(arabic3Letters)
    194 	if suite.NoError(err) {
    195 		suite.Equal(nil, err)
    196 	}
    197 
    198 	err = validate.Language(mixedCapsEnglish)
    199 	if suite.NoError(err) {
    200 		suite.Equal(nil, err)
    201 	}
    202 
    203 	err = validate.Language(englishUS)
    204 	if suite.Error(err) {
    205 		suite.Equal(errors.New("language: tag is not well-formed"), err)
    206 	}
    207 
    208 	err = validate.Language(dutch)
    209 	if suite.NoError(err) {
    210 		suite.Equal(nil, err)
    211 	}
    212 
    213 	err = validate.Language(german)
    214 	if suite.NoError(err) {
    215 		suite.Equal(nil, err)
    216 	}
    217 }
    218 
    219 func (suite *ValidationTestSuite) TestValidateReason() {
    220 	empty := ""
    221 	badReason := "because"
    222 	goodReason := "to smash the state and destroy capitalism ultimately and completely"
    223 	tooLong := "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris auctor mollis viverra. Maecenas maximus mollis sem, nec fermentum velit consectetur non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Quisque a enim nibh. Vestibulum bibendum leo ac porttitor auctor. Curabitur velit tellus, facilisis vitae lorem a, ullamcorper efficitur leo. Sed a auctor tortor. Sed ut finibus ante, sit amet laoreet sapien. Donec ullamcorper tellus a nibh sodales vulputate. Donec id dolor eu odio mollis bibendum. Pellentesque habitant morbi tristique senectus et netus at."
    224 	unicode := "⎾⎿⏀⏁⏂⏃⏄⏅⏆⏇"
    225 	var err error
    226 
    227 	// check with no reason required
    228 	err = validate.SignUpReason(empty, false)
    229 	if suite.NoError(err) {
    230 		suite.Equal(nil, err)
    231 	}
    232 
    233 	err = validate.SignUpReason(badReason, false)
    234 	if suite.NoError(err) {
    235 		suite.Equal(nil, err)
    236 	}
    237 
    238 	err = validate.SignUpReason(tooLong, false)
    239 	if suite.NoError(err) {
    240 		suite.Equal(nil, err)
    241 	}
    242 
    243 	err = validate.SignUpReason(goodReason, false)
    244 	if suite.NoError(err) {
    245 		suite.Equal(nil, err)
    246 	}
    247 
    248 	err = validate.SignUpReason(unicode, false)
    249 	if suite.NoError(err) {
    250 		suite.Equal(nil, err)
    251 	}
    252 
    253 	// check with reason required
    254 	err = validate.SignUpReason(empty, true)
    255 	if suite.Error(err) {
    256 		suite.Equal(errors.New("no reason provided"), err)
    257 	}
    258 
    259 	err = validate.SignUpReason(badReason, true)
    260 	if suite.Error(err) {
    261 		suite.Equal(errors.New("reason should be at least 40 chars but 'because' was 7"), err)
    262 	}
    263 
    264 	err = validate.SignUpReason(tooLong, true)
    265 	if suite.Error(err) {
    266 		suite.Equal(errors.New("reason should be no more than 500 chars but given reason was 600"), err)
    267 	}
    268 
    269 	err = validate.SignUpReason(goodReason, true)
    270 	if suite.NoError(err) {
    271 		suite.Equal(nil, err)
    272 	}
    273 }
    274 
    275 func (suite *ValidationTestSuite) TestValidateProfileField() {
    276 	var (
    277 		shortProfileField   = "pronouns"
    278 		tooLongProfileField = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer eu bibendum elit. Sed ac interdum nisi. Vestibulum vulputate eros quis euismod imperdiet. Nulla sit amet dui sit amet lorem consectetur iaculis. Mauris eget lacinia metus. Curabitur nec dui eleifend massa nunc."
    279 		trimmedProfileField = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer eu bibendum elit. Sed ac interdum nisi. Vestibulum vulputate eros quis euismod imperdiet. Nulla sit amet dui sit amet lorem consectetur iaculis. Mauris eget lacinia metus. Curabitur nec dui "
    280 		err                 error
    281 	)
    282 
    283 	okFields := []*gtsmodel.Field{
    284 		{
    285 			Name:  "example",
    286 			Value: shortProfileField,
    287 		},
    288 	}
    289 	err = validate.ProfileFields(okFields)
    290 	suite.NoError(err)
    291 	suite.Equal(shortProfileField, okFields[0].Value)
    292 
    293 	dodgyFields := []*gtsmodel.Field{
    294 		{
    295 			Name:  "example",
    296 			Value: tooLongProfileField,
    297 		},
    298 	}
    299 	err = validate.ProfileFields(dodgyFields)
    300 	suite.NoError(err)
    301 	suite.Equal(trimmedProfileField, dodgyFields[0].Value)
    302 	suite.Len(dodgyFields[0].Value, 255)
    303 }
    304 
    305 func (suite *ValidationTestSuite) TestValidateCustomCSSDisabled() {
    306 	config.SetAccountsAllowCustomCSS(false)
    307 
    308 	err := validate.CustomCSS("this will fail")
    309 	suite.EqualError(err, "accounts-allow-custom-css is not enabled for this instance")
    310 }
    311 
    312 func (suite *ValidationTestSuite) TestValidateCustomCSSEnabled() {
    313 	config.SetAccountsAllowCustomCSS(true)
    314 
    315 	err := validate.CustomCSS("this will pass")
    316 	suite.NoError(err)
    317 }
    318 
    319 func (suite *ValidationTestSuite) TestValidateCustomCSSTooLong() {
    320 	config.SetAccountsAllowCustomCSS(true)
    321 	config.SetAccountsCustomCSSLength(5)
    322 
    323 	err := validate.CustomCSS("this will fail")
    324 	suite.EqualError(err, "custom_css must be less than 5 characters, but submitted custom_css was 14 characters")
    325 }
    326 
    327 func (suite *ValidationTestSuite) TestValidateCustomCSSTooLongZalgo() {
    328 	config.SetAccountsAllowCustomCSS(true)
    329 	config.SetAccountsCustomCSSLength(5)
    330 	zalgo := "p̵̹̜͇̺̜̱͊̓̈́͛̀͊͘͜e̷̡̱̲̼̪̗̙̐͐̃́̄̉͛̔e̷̞̰̜̲̥̘̻͔̜̞̬͚͋̊͑͗̅̓͛͗̎̃̈́̐̂̕͝ ̷̨̢̡̱̖̤͇̻͕̲̤̞̑ͅp̶̰̜̟̠̏̇̇̆̐̒͋̔͘ḛ̵̾͘ę̷̝͙͕͓͓̱̠̤̳̻̜̗͖̞͙̻̆̓̄͋̎͊̀̋̿́̐͛͗̄̈́̚͠ ̵̨̨̫͕̲͚̮͕̳̉̾̔̍͐p̶̘̞̠̘̎̓̍̑̀͗̃̈́͂́̈́͆͘͜͝͝o̶̜͛̒͒̉̑͒̿͗̐̃͝o̵̼̒͌̓ ̵̢̗̦͔͉͈̰̘̋̃̐̑̅̽̏̄̅͐͆̔͊̃̋͝p̵̩̱̆̆͂̂͛̓̋̅͝o̶̪̰̲̝̻̳̦̮̮͔̒ͅơ̸̧̨̟͇̪̰̜̠̦͇̇̎͗̏̏̈́͂̉̏͐́̃̀͆͠ͅ"
    331 
    332 	err := validate.CustomCSS(zalgo)
    333 	suite.EqualError(err, "custom_css must be less than 5 characters, but submitted custom_css was 275 characters")
    334 }
    335 
    336 func (suite *ValidationTestSuite) TestValidateCustomCSSTooLongUnicode() {
    337 	config.SetAccountsAllowCustomCSS(true)
    338 	config.SetAccountsCustomCSSLength(5)
    339 	unicode := "⎾⎿⏀⏁⏂⏃⏄⏅⏆⏇"
    340 
    341 	err := validate.CustomCSS(unicode)
    342 	suite.EqualError(err, "custom_css must be less than 5 characters, but submitted custom_css was 10 characters")
    343 }
    344 
    345 func TestValidationTestSuite(t *testing.T) {
    346 	suite.Run(t, new(ValidationTestSuite))
    347 }