From f472d877eff65b6fbac4c35300d0d0736d40e789 Mon Sep 17 00:00:00 2001 From: Ada Date: Wed, 10 Apr 2024 19:34:36 +0200 Subject: [PATCH] :lipstick: pass linter --- internal/config/config.go | 12 +++-- internal/constant/constants.go | 4 ++ internal/database/db.go | 16 +++--- internal/{httpServer => httpserver}/server.go | 12 ++--- internal/secret/crypto.go | 40 +++++++++----- internal/utils/utils.go | 27 ++++++---- internal/web/plak/plak.go | 50 ++++++++++------- main.go | 8 +-- test/secret/secret_test.go | 23 +++++--- test/utils/utils_test.go | 54 ++++++++++++++----- 10 files changed, 163 insertions(+), 83 deletions(-) rename internal/{httpServer => httpserver}/server.go (90%) diff --git a/internal/config/config.go b/internal/config/config.go index 373f03e..5d70b4d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -4,19 +4,21 @@ import ( "log" "os" "strconv" + + "git.gnous.eu/gnouseu/plakken/internal/constant" ) -// InitConfig Structure for program initialisation +// InitConfig Structure for program initialisation. type InitConfig struct { ListenAddress string RedisAddress string RedisUser string RedisPassword string RedisDB int - UrlLength uint8 + URLLength uint8 } -// GetConfig Initialise configuration form .env +// GetConfig Initialise configuration form .env. func GetConfig() InitConfig { listenAddress := os.Getenv("PLAKKEN_LISTEN") redisAddress := os.Getenv("PLAKKEN_REDIS_ADDRESS") @@ -37,7 +39,7 @@ func GetConfig() InitConfig { log.Fatal("Invalid PLAKKEN_URL_LENGTH") } - if urlLength > 255 { + if urlLength > constant.MaxURLLength { log.Fatal("PLAKKEN_URL_LENGTH cannot be greater than 255") } @@ -47,6 +49,6 @@ func GetConfig() InitConfig { RedisUser: os.Getenv("PLAKKEN_REDIS_USER"), RedisPassword: os.Getenv("PLAKKEN_REDIS_PASSWORD"), RedisDB: redisDB, - UrlLength: uint8(urlLength), + URLLength: uint8(urlLength), } } diff --git a/internal/constant/constants.go b/internal/constant/constants.go index ae9e4d5..15c4efd 100644 --- a/internal/constant/constants.go +++ b/internal/constant/constants.go @@ -11,4 +11,8 @@ const ( ArgonThreads = 4 ArgonKeyLength = 32 ArgonIterations = 2 + MaxURLLength = 255 + SecondsInDay = 86400 + SecondsInHour = 3600 + SecondsInMinute = 60 ) diff --git a/internal/database/db.go b/internal/database/db.go index 8c5ec68..b26b1f8 100644 --- a/internal/database/db.go +++ b/internal/database/db.go @@ -13,9 +13,9 @@ type DBConfig struct { DB *redis.Client } -var ctx = context.Background() +var ctx = context.Background() //nolint:gochecknoglobals -// InitDB initialise redis connection settings +// InitDB initialise redis connection settings. func InitDB(addr string, user string, password string, db int) *redis.Options { DBConfig := &redis.Options{ Addr: addr, @@ -27,18 +27,20 @@ func InitDB(addr string, user string, password string, db int) *redis.Options { return DBConfig } -// ConnectDB make new database connection +// ConnectDB make new database connection. func ConnectDB(dbConfig *redis.Options) *redis.Client { - localDb := redis.NewClient(dbConfig) - return localDb + localDB := redis.NewClient(dbConfig) + + return localDB } -// Ping test connection to Redis database +// Ping test connection to Redis database. func Ping(db *redis.Client) error { status := db.Ping(ctx) if status.String() != "ping: PONG" { return &pingError{} } + return nil } @@ -65,7 +67,7 @@ func (config DBConfig) InsertPaste(key string, content string, secret string, tt } } -func (config DBConfig) UrlExist(url string) bool { +func (config DBConfig) URLExist(url string) bool { return config.DB.Exists(ctx, url).Val() == 1 } diff --git a/internal/httpServer/server.go b/internal/httpserver/server.go similarity index 90% rename from internal/httpServer/server.go rename to internal/httpserver/server.go index f17ea63..2065dbd 100644 --- a/internal/httpServer/server.go +++ b/internal/httpserver/server.go @@ -1,4 +1,4 @@ -package httpServer +package httpserver import ( "embed" @@ -12,7 +12,7 @@ import ( type ServerConfig struct { HTTPServer *http.Server - UrlLength uint8 + URLLength uint8 DB *redis.Client Static embed.FS Templates embed.FS @@ -29,11 +29,11 @@ func (config ServerConfig) home(w http.ResponseWriter, _ *http.Request) { } } -// Configure HTTP router +// Configure HTTP router. func (config ServerConfig) router() { WebConfig := plak.WebConfig{ DB: config.DB, - UrlLength: config.UrlLength, + URLLength: config.URLLength, Templates: config.Templates, } staticFiles := http.FS(config.Static) @@ -46,7 +46,7 @@ func (config ServerConfig) router() { http.HandleFunc("DELETE /{key}", WebConfig.DeleteRequest) } -// Config Configure HTTP server +// Config Configure HTTP server. func Config(listenAddress string) *http.Server { server := &http.Server{ Addr: listenAddress, @@ -57,7 +57,7 @@ func Config(listenAddress string) *http.Server { return server } -// Server Start HTTP server +// Server Start HTTP server. func (config ServerConfig) Server() { log.Println("Listening on " + config.HTTPServer.Addr) diff --git a/internal/secret/crypto.go b/internal/secret/crypto.go index 957c260..05276d9 100644 --- a/internal/secret/crypto.go +++ b/internal/secret/crypto.go @@ -5,6 +5,7 @@ import ( "bytes" "crypto/rand" "encoding/base64" + "encoding/hex" "fmt" "strconv" "strings" @@ -18,7 +19,7 @@ type argon2idHash struct { hash []byte } -// Argon2id config +// Argon2id config. type config struct { saltLength uint8 memory uint32 @@ -27,7 +28,7 @@ type config struct { iterations uint32 } -// generateSecret for password hashing or token generation +// generateSecret for password hashing or token generation. func generateSecret(length uint8) ([]byte, error) { secret := make([]byte, length) @@ -39,26 +40,26 @@ func generateSecret(length uint8) ([]byte, error) { return secret, err } -// GenerateToken generate hexadecimal token +// GenerateToken generate hexadecimal token. func GenerateToken() (string, error) { secret, err := generateSecret(constant.TokenLength) if err != nil { return "", err } - token := fmt.Sprintf("%x", secret) + token := hex.EncodeToString(secret) return token, nil } -// generateArgon2ID Generate an argon2id hash from source string and specified salt +// generateArgon2ID Generate an argon2id hash from source string and specified salt. func (config config) generateArgon2ID(source string, salt []byte) []byte { hash := argon2.IDKey([]byte(source), salt, config.iterations, config.memory, config.threads, config.keyLength) return hash } -// Password hash a source string with argon2id, return properly encoded hash +// Password hash a source string with argon2id, return properly encoded hash. func Password(password string) (string, error) { config := config{ saltLength: constant.ArgonSaltSize, @@ -95,10 +96,10 @@ func VerifyPassword(password string, hash string) (bool, error) { return bytes.Equal(result, argon2Hash.hash), nil } -// parseHash parse existing encoded argon2id string +// parseHash parse existing encoded argon2id string. func parseHash(source string) (argon2idHash, config, error) { separateItem := strings.Split(source, "$") - if len(separateItem) != 6 { + if len(separateItem) != 6 { //nolint:gomnd return argon2idHash{}, config{}, &parseError{message: "Hash format is not valid"} } @@ -107,7 +108,7 @@ func parseHash(source string) (argon2idHash, config, error) { } separateParam := strings.Split(separateItem[3], ",") - if len(separateParam) != 3 { + if len(separateParam) != 3 { //nolint:gomnd return argon2idHash{}, config{}, &parseError{message: "Hash config is not valid"} } @@ -126,22 +127,35 @@ func parseHash(source string) (argon2idHash, config, error) { keyLength := uint32(len(hash)) var memory int - memory, err = strconv.Atoi(strings.Replace(separateParam[0], "m=", "", -1)) + memory, err = strconv.Atoi(strings.ReplaceAll(separateParam[0], "m=", "")) if err != nil { return argon2idHash{}, config{}, err } var iterations int - iterations, err = strconv.Atoi(strings.Replace(separateParam[1], "t=", "", -1)) + iterations, err = strconv.Atoi(strings.ReplaceAll(separateParam[1], "t=", "")) if err != nil { return argon2idHash{}, config{}, err } var threads int - threads, err = strconv.Atoi(strings.Replace(separateParam[2], "p=", "", -1)) + threads, err = strconv.Atoi(strings.ReplaceAll(separateParam[2], "p=", "")) if err != nil { return argon2idHash{}, config{}, err } - return argon2idHash{salt: salt, hash: hash}, config{saltLength: saltLength, memory: uint32(memory), threads: uint8(threads), iterations: uint32(iterations), keyLength: keyLength}, nil + argon2idStruct := argon2idHash{ + salt: salt, + hash: hash, + } + + hashConfig := config{ + saltLength: saltLength, + memory: uint32(memory), + threads: uint8(threads), + iterations: uint32(iterations), + keyLength: keyLength, + } + + return argon2idStruct, hashConfig, nil } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index fc86af6..e18d6fb 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -6,10 +6,12 @@ import ( "regexp" "strconv" "strings" + + "git.gnous.eu/gnouseu/plakken/internal/constant" ) -// GenerateUrl generate random string for plak url -func GenerateUrl(length uint8) string { +// GenerateURL generate random string for plak url. +func GenerateURL(length uint8) string { listChars := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") b := make([]rune, length) for i := range b { @@ -19,7 +21,7 @@ func GenerateUrl(length uint8) string { return string(b) } -// CheckCharRedundant verify is a character is redundant in a string +// CheckCharRedundant verify is a character is redundant in a string. func CheckCharRedundant(source string, char string) bool { // Verify if a char is redundant return strings.Count(source, char) > 1 } @@ -34,22 +36,24 @@ func parseIntBeforeSeparator(source *string, sep string) (int, error) { // retur value, err = strconv.Atoi(strings.Split(*source, sep)[0]) if err != nil { log.Println(err) + return 0, &parseIntBeforeSeparatorError{message: *source + ": cannot parse value as int"} } if value < 0 { // Only positive value is correct return 0, &parseIntBeforeSeparatorError{message: *source + ": format only take positive value"} } - if value > 99 { + if value > 99 { //nolint:gomnd return 0, &parseIntBeforeSeparatorError{message: *source + ": Format only take two number"} } *source = strings.Join(strings.Split(*source, sep)[1:], "") } + return value, nil } -// ParseExpiration Parse "1d1h1m1s" duration format. Return 0 & error if error +// ParseExpiration Parse "1d1h1m1s" duration format. Return 0 & error if error. func ParseExpiration(source string) (int, error) { var expiration int var tempOutput int @@ -61,39 +65,44 @@ func ParseExpiration(source string) (int, error) { source = strings.ToLower(source) tempOutput, err = parseIntBeforeSeparator(&source, "d") - expiration = tempOutput * 86400 + expiration = tempOutput * constant.SecondsInDay if err != nil { log.Println(err) + return 0, &ParseExpirationError{message: "Invalid syntax"} } tempOutput, err = parseIntBeforeSeparator(&source, "h") - expiration += tempOutput * 3600 + expiration += tempOutput * constant.SecondsInHour if err != nil { log.Println(err) + return 0, &ParseExpirationError{message: "Invalid syntax"} } tempOutput, err = parseIntBeforeSeparator(&source, "m") - expiration += tempOutput * 60 + expiration += tempOutput * constant.SecondsInMinute if err != nil { log.Println(err) + return 0, &ParseExpirationError{message: "Invalid syntax"} } tempOutput, err = parseIntBeforeSeparator(&source, "s") expiration += tempOutput * 1 if err != nil { log.Println(err) + return 0, &ParseExpirationError{message: "Invalid syntax"} } return expiration, nil } -// ValidKey Verify if a key is valid (only letter, number, - and _) +// ValidKey Verify if a key is valid (only letter, number, - and _). func ValidKey(key string) bool { result, err := regexp.MatchString("^[a-zA-Z0-9_.-]*$", key) if err != nil { return false } log.Println(key, result) + return result } diff --git a/internal/web/plak/plak.go b/internal/web/plak/plak.go index f65f0f5..4223033 100644 --- a/internal/web/plak/plak.go +++ b/internal/web/plak/plak.go @@ -3,6 +3,7 @@ package plak import ( "context" "embed" + "html/template" "io" "log" "net/http" @@ -13,19 +14,17 @@ import ( "git.gnous.eu/gnouseu/plakken/internal/secret" "git.gnous.eu/gnouseu/plakken/internal/utils" "github.com/redis/go-redis/v9" - - "html/template" ) -var ctx = context.Background() +var ctx = context.Background() //nolint:gochecknoglobals type WebConfig struct { DB *redis.Client - UrlLength uint8 + URLLength uint8 Templates embed.FS } -// plak "Object" for plak +// plak "Object" for plak. type plak struct { Key string Content string @@ -33,7 +32,7 @@ type plak struct { DB *redis.Client } -// create a plak +// create a plak. func (plak plak) create() (string, error) { dbConf := database.DBConfig{ DB: plak.DB, @@ -44,7 +43,7 @@ func (plak plak) create() (string, error) { return "", err } - if dbConf.UrlExist(plak.Key) { + if dbConf.URLExist(plak.Key) { return "", &createError{message: "key already exist"} } @@ -59,21 +58,23 @@ func (plak plak) create() (string, error) { return token, nil } -// PostCreate manage POST request for create plak +// PostCreate manage POST request for create plak. func (config WebConfig) PostCreate(w http.ResponseWriter, r *http.Request) { content := r.FormValue("content") if content == "" { w.WriteHeader(http.StatusBadRequest) + return } filename := r.FormValue("filename") var key string if len(filename) == 0 { - key = utils.GenerateUrl(config.UrlLength) + key = utils.GenerateURL(config.URLLength) } else { if !utils.ValidKey(filename) { w.WriteHeader(http.StatusBadRequest) + return } key = filename @@ -90,6 +91,7 @@ func (config WebConfig) PostCreate(w http.ResponseWriter, r *http.Request) { if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) + return } @@ -103,16 +105,18 @@ func (config WebConfig) PostCreate(w http.ResponseWriter, r *http.Request) { if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) + return } http.Redirect(w, r, "/"+key, http.StatusSeeOther) } -// CurlCreate PostCreate plak with minimum param, ideal for curl. Force 7 day expiration +// CurlCreate PostCreate plak with minimum param, ideal for curl. Force 7 day expiration. func (config WebConfig) CurlCreate(w http.ResponseWriter, r *http.Request) { if r.ContentLength == 0 { w.WriteHeader(http.StatusBadRequest) + return } @@ -122,7 +126,7 @@ func (config WebConfig) CurlCreate(w http.ResponseWriter, r *http.Request) { log.Println(err) } - key := utils.GenerateUrl(config.UrlLength) + key := utils.GenerateURL(config.URLLength) plak := plak{ Key: key, @@ -135,6 +139,7 @@ func (config WebConfig) CurlCreate(w http.ResponseWriter, r *http.Request) { token, err = plak.create() if err != nil { w.WriteHeader(http.StatusBadRequest) + return } @@ -154,7 +159,7 @@ func (config WebConfig) CurlCreate(w http.ResponseWriter, r *http.Request) { } } -// View for plak +// View for plak. func (config WebConfig) View(w http.ResponseWriter, r *http.Request) { dbConf := database.DBConfig{ DB: config.DB, @@ -162,7 +167,8 @@ func (config WebConfig) View(w http.ResponseWriter, r *http.Request) { var currentPlak plak key := r.PathValue("key") - if dbConf.UrlExist(key) { + //nolint:nestif + if dbConf.URLExist(key) { currentPlak = plak{ Key: key, DB: config.DB, @@ -179,12 +185,14 @@ func (config WebConfig) View(w http.ResponseWriter, r *http.Request) { if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Println(err) + return } err = t.Execute(w, currentPlak) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Println(err) + return } } @@ -193,7 +201,7 @@ func (config WebConfig) View(w http.ResponseWriter, r *http.Request) { } } -// DeleteRequest manage plak deletion endpoint +// DeleteRequest manage plak deletion endpoint. func (config WebConfig) DeleteRequest(w http.ResponseWriter, r *http.Request) { dbConf := database.DBConfig{ DB: config.DB, @@ -201,7 +209,8 @@ func (config WebConfig) DeleteRequest(w http.ResponseWriter, r *http.Request) { key := r.PathValue("key") var valid bool - if dbConf.UrlExist(key) { + //nolint:nestif + if dbConf.URLExist(key) { var err error token := r.URL.Query().Get("secret") @@ -209,7 +218,6 @@ func (config WebConfig) DeleteRequest(w http.ResponseWriter, r *http.Request) { if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Println(err) - return } if valid { @@ -223,29 +231,31 @@ func (config WebConfig) DeleteRequest(w http.ResponseWriter, r *http.Request) { } w.WriteHeader(http.StatusNoContent) - return } else { w.WriteHeader(http.StatusForbidden) - return } + + return } w.WriteHeader(http.StatusNotFound) } -// delete DeleteRequest plak from database +// delete DeleteRequest plak from database. func (plak plak) delete() error { err := plak.DB.Del(ctx, plak.Key).Err() if err != nil { log.Println(err) + return &deletePlakError{name: plak.Key, err: err} } return nil } -// getContent get plak content +// getContent get plak content. func (plak plak) getContent() plak { plak.Content = plak.DB.HGet(ctx, plak.Key, "content").Val() + return plak } diff --git a/main.go b/main.go index 8af2291..a79b0be 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,7 @@ import ( "git.gnous.eu/gnouseu/plakken/internal/config" "git.gnous.eu/gnouseu/plakken/internal/database" - "git.gnous.eu/gnouseu/plakken/internal/httpServer" + "git.gnous.eu/gnouseu/plakken/internal/httpserver" ) var ( @@ -25,9 +25,9 @@ func main() { log.Fatal(err) } - serverConfig := httpServer.ServerConfig{ - HTTPServer: httpServer.Config(initConfig.ListenAddress), - UrlLength: initConfig.UrlLength, + serverConfig := httpserver.ServerConfig{ + HTTPServer: httpserver.Config(initConfig.ListenAddress), + URLLength: initConfig.URLLength, DB: db, Static: static, Templates: templates, diff --git a/test/secret/secret_test.go b/test/secret/secret_test.go index fad6ba6..2190ef3 100644 --- a/test/secret/secret_test.go +++ b/test/secret/secret_test.go @@ -10,8 +10,17 @@ import ( "golang.org/x/crypto/argon2" ) -func TestPasswordFormat(t *testing.T) { - regex := fmt.Sprintf("\\$argon2id\\$v=%d\\$m=%d,t=%d,p=%d\\$[A-Za-z0-9+/]*\\$[A-Za-z0-9+/]*$", argon2.Version, constant.ArgonMemory, constant.ArgonIterations, constant.ArgonThreads) +func TestSecret(t *testing.T) { + t.Parallel() + + testPasswordFormat(t) + testVerifyPassword(t) + testVerifyPasswordInvalid(t) +} + +func testPasswordFormat(t *testing.T) { + t.Helper() + regex := fmt.Sprintf("\\$argon2id\\$v=%d\\$m=%d,t=%d,p=%d\\$[A-Za-z0-9+/]*\\$[A-Za-z0-9+/]*$", argon2.Version, constant.ArgonMemory, constant.ArgonIterations, constant.ArgonThreads) //nolint:lll got, err := secret.Password("Password!") if err != nil { @@ -24,8 +33,9 @@ func TestPasswordFormat(t *testing.T) { } } -func TestVerifyPassword(t *testing.T) { - result, err := secret.VerifyPassword("Password!", "$argon2id$v=19$m=65536,t=2,p=4$A+t5YGpyy1BHCbvk/LP1xQ$eNuUj6B2ZqXlGi6KEqep39a7N4nysUIojuPXye+Ypp0") +func testVerifyPassword(t *testing.T) { + t.Helper() + result, err := secret.VerifyPassword("Password!", "$argon2id$v=19$m=65536,t=2,p=4$A+t5YGpyy1BHCbvk/LP1xQ$eNuUj6B2ZqXlGi6KEqep39a7N4nysUIojuPXye+Ypp0") //nolint:lll if err != nil { t.Fatal(err) } @@ -35,8 +45,9 @@ func TestVerifyPassword(t *testing.T) { } } -func TestVerifyPasswordInvalid(t *testing.T) { - result, err := secret.VerifyPassword("notsamepassword", "$argon2id$v=19$m=65536,t=2,p=4$A+t5YGpyy1BHCbvk/LP1xQ$eNuUj6B2ZqXlGi6KEqep39a7N4nysUIojuPXye+Ypp0") +func testVerifyPasswordInvalid(t *testing.T) { + t.Helper() + result, err := secret.VerifyPassword("notsamepassword", "$argon2id$v=19$m=65536,t=2,p=4$A+t5YGpyy1BHCbvk/LP1xQ$eNuUj6B2ZqXlGi6KEqep39a7N4nysUIojuPXye+Ypp0") //nolint:lll if err != nil { t.Fatal(err) } diff --git a/test/utils/utils_test.go b/test/utils/utils_test.go index 3525443..d2ae863 100644 --- a/test/utils/utils_test.go +++ b/test/utils/utils_test.go @@ -7,7 +7,25 @@ import ( "git.gnous.eu/gnouseu/plakken/internal/utils" ) -func TestCheckCharNotRedundantTrue(t *testing.T) { // Test CheckCharRedundant with redundant char +func TestUtils(t *testing.T) { + t.Parallel() + + testCheckCharNotRedundantTrue(t) + testCheckCharNotRedundantFalse(t) + testParseExpirationFull(t) + testParseExpirationMissing(t) + testParseExpirationWithCaps(t) + testParseExpirationNull(t) + testParseExpirationNegative(t) + testParseExpirationInvalid(t) + testParseExpirationInvalidRedundant(t) + testParseExpirationInvalidTooHigh(t) + testValidKey(t) + testInValidKey(t) +} + +func testCheckCharNotRedundantTrue(t *testing.T) { // Test CheckCharRedundant with redundant char + t.Helper() want := true got := utils.CheckCharRedundant("2d1h3md4h7s", "h") if got != want { @@ -15,7 +33,8 @@ func TestCheckCharNotRedundantTrue(t *testing.T) { // Test CheckCharRedundant wi } } -func TestCheckCharNotRedundantFalse(t *testing.T) { // Test CheckCharRedundant with not redundant char +func testCheckCharNotRedundantFalse(t *testing.T) { // Test CheckCharRedundant with not redundant char + t.Helper() want := false got := utils.CheckCharRedundant("2d1h3m47s", "h") if got != want { @@ -23,7 +42,8 @@ func TestCheckCharNotRedundantFalse(t *testing.T) { // Test CheckCharRedundant w } } -func TestParseExpirationFull(t *testing.T) { // test parseExpirationFull with all valid separator +func testParseExpirationFull(t *testing.T) { // test parseExpirationFull with all valid separator + t.Helper() result, _ := utils.ParseExpiration("2d1h3m47s") correctValue := 176627 if result != correctValue { @@ -31,7 +51,8 @@ func TestParseExpirationFull(t *testing.T) { // test parseExpirationFull with al } } -func TestParseExpirationMissing(t *testing.T) { // test parseExpirationFull with all valid separator +func testParseExpirationMissing(t *testing.T) { // test parseExpirationFull with all valid separator + t.Helper() result, _ := utils.ParseExpiration("1h47s") correctValue := 3647 if result != correctValue { @@ -39,7 +60,8 @@ func TestParseExpirationMissing(t *testing.T) { // test parseExpirationFull with } } -func TestParseExpirationWithCaps(t *testing.T) { // test parseExpirationFull with all valid separator +func testParseExpirationWithCaps(t *testing.T) { // test parseExpirationFull with all valid separator + t.Helper() result, _ := utils.ParseExpiration("2D1h3M47s") correctValue := 176627 if result != correctValue { @@ -47,7 +69,8 @@ func TestParseExpirationWithCaps(t *testing.T) { // test parseExpirationFull wit } } -func TestParseExpirationNull(t *testing.T) { // test ParseExpirationFull with all valid separator +func testParseExpirationNull(t *testing.T) { // test ParseExpirationFull with all valid separator + t.Helper() result, _ := utils.ParseExpiration("0") correctValue := 0 if result != correctValue { @@ -55,7 +78,8 @@ func TestParseExpirationNull(t *testing.T) { // test ParseExpirationFull with al } } -func TestParseExpirationNegative(t *testing.T) { // test ParseExpirationFull with all valid separator +func testParseExpirationNegative(t *testing.T) { // test ParseExpirationFull with all valid separator + t.Helper() _, got := utils.ParseExpiration("-42h1m4s") want := &utils.ParseExpirationError{} if !errors.As(got, &want) { @@ -63,16 +87,17 @@ func TestParseExpirationNegative(t *testing.T) { // test ParseExpirationFull wit } } -func TestParseExpirationInvalid(t *testing.T) { // test ParseExpirationFull with all valid separator +func testParseExpirationInvalid(t *testing.T) { // test ParseExpirationFull with all valid separator + t.Helper() _, got := utils.ParseExpiration("8h42h1m1d4s") want := &utils.ParseExpirationError{} if !errors.As(got, &want) { t.Fatal("Error in ParseExpirationFull, want : ", want, "got : ", got) } - } -func TestParseExpirationInvalidRedundant(t *testing.T) { // test ParseExpirationFull with all valid separator +func testParseExpirationInvalidRedundant(t *testing.T) { // test ParseExpirationFull with all valid separator + t.Helper() _, got := utils.ParseExpiration("8h42h1m1h4s") want := &utils.ParseExpirationError{} if !errors.As(got, &want) { @@ -80,7 +105,8 @@ func TestParseExpirationInvalidRedundant(t *testing.T) { // test ParseExpiration } } -func TestParseExpirationInvalidTooHigh(t *testing.T) { // test ParseExpirationFull with all valid separator +func testParseExpirationInvalidTooHigh(t *testing.T) { // test ParseExpirationFull with all valid separator + t.Helper() _, got := utils.ParseExpiration("2d1h3m130s") want := &utils.ParseExpirationError{} if !errors.As(got, &want) { @@ -88,7 +114,8 @@ func TestParseExpirationInvalidTooHigh(t *testing.T) { // test ParseExpirationFu } } -func TestValidKey(t *testing.T) { // test ValidKey with a valid key +func testValidKey(t *testing.T) { // test ValidKey with a valid key + t.Helper() got := utils.ValidKey("ab_a-C42") want := true @@ -97,7 +124,8 @@ func TestValidKey(t *testing.T) { // test ValidKey with a valid key } } -func TestInValidKey(t *testing.T) { // test ValidKey with invalid key +func testInValidKey(t *testing.T) { // test ValidKey with invalid key + t.Helper() got := utils.ValidKey("ab_?a-C42") want := false