First commit
This commit is contained in:
96
backend/utils/datatype.go
Normal file
96
backend/utils/datatype.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Date time.Time // 2006-01-02
|
||||
type DateTime time.Time // 2006-01-02 15:04:05
|
||||
|
||||
func (date *Date) UnmarshalJSON(b []byte) error {
|
||||
s := strings.Trim(string(b), "\"")
|
||||
t, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*date = Date(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (date Date) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(time.Time(date))
|
||||
}
|
||||
|
||||
func (date Date) Format(s string) string {
|
||||
t := time.Time(date)
|
||||
return t.Format(s)
|
||||
}
|
||||
|
||||
func (date *Date) Scan(value interface{}) (err error) {
|
||||
nullTime := &sql.NullTime{}
|
||||
err = nullTime.Scan(value)
|
||||
*date = Date(nullTime.Time)
|
||||
return
|
||||
}
|
||||
|
||||
func (date Date) Value() (driver.Value, error) {
|
||||
return time.Time(date), nil
|
||||
}
|
||||
|
||||
func (date Date) GormDataType() string {
|
||||
return "date"
|
||||
}
|
||||
|
||||
func (date Date) GobEncode() ([]byte, error) {
|
||||
return time.Time(date).GobEncode()
|
||||
}
|
||||
|
||||
func (date *Date) GobDecode(b []byte) error {
|
||||
return (*time.Time)(date).GobDecode(b)
|
||||
}
|
||||
|
||||
func (dateTime *DateTime) UnmarshalJSON(b []byte) error {
|
||||
s := strings.Trim(string(b), "\"")
|
||||
t, err := time.Parse("2006-01-02 15:04:05", s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*dateTime = DateTime(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dateTime DateTime) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(time.Time(dateTime))
|
||||
}
|
||||
|
||||
func (dateTime DateTime) Format(s string) string {
|
||||
t := time.Time(dateTime)
|
||||
return t.Format(s)
|
||||
}
|
||||
|
||||
func (date *DateTime) Scan(value interface{}) (err error) {
|
||||
nullTime := &sql.NullTime{}
|
||||
err = nullTime.Scan(value)
|
||||
*date = DateTime(nullTime.Time)
|
||||
return
|
||||
}
|
||||
|
||||
func (date DateTime) Value() (driver.Value, error) {
|
||||
return time.Time(date), nil
|
||||
}
|
||||
|
||||
func (date DateTime) GormDataType() string {
|
||||
return "datetime"
|
||||
}
|
||||
|
||||
func (date DateTime) GobEncode() ([]byte, error) {
|
||||
return time.Time(date).GobEncode()
|
||||
}
|
||||
|
||||
func (date *DateTime) GobDecode(b []byte) error {
|
||||
return (*time.Time)(date).GobDecode(b)
|
||||
}
|
191
backend/utils/datatype_test.go
Normal file
191
backend/utils/datatype_test.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDateUnmarshalJSON(t *testing.T) {
|
||||
want := "1985-02-23 00:00:00 +0000 UTC"
|
||||
var date Date
|
||||
err := date.UnmarshalJSON([]byte("\"1985-02-23\""))
|
||||
msg := time.Time(date).String()
|
||||
if msg != want {
|
||||
t.Fatalf(`date.UnmarshalJSON([]byte("\"1985-02-23\"") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateUnmarshalJSONMalformed(t *testing.T) {
|
||||
want := error(&time.ParseError{})
|
||||
var date Date
|
||||
err := date.UnmarshalJSON([]byte("\"1985/02/23\""))
|
||||
msg := time.Time(date).String()
|
||||
if reflect.TypeOf(err) != reflect.TypeOf(want) {
|
||||
t.Fatalf(`date.UnmarshalJSON([]byte("\"1985/02/23\"") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateMarshalJSON(t *testing.T) {
|
||||
want := "\"1985-02-23T00:00:00Z\""
|
||||
parsed, _ := time.Parse("2006-01-02", "1985-02-23")
|
||||
var date Date = Date(parsed)
|
||||
msg, err := date.MarshalJSON()
|
||||
if string(msg) != want {
|
||||
t.Fatalf(`date.MarshalJSON() = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateFormat(t *testing.T) {
|
||||
want := "Feb 23, 1985"
|
||||
parsed, _ := time.Parse("2006-01-02", "1985-02-23")
|
||||
var date Date = Date(parsed)
|
||||
msg := date.Format("Jan 2, 2006")
|
||||
if msg != want {
|
||||
t.Fatalf(`date.Format("Jan 2, 2006") = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateScan(t *testing.T) {
|
||||
want := "0001-01-01T00:00:00Z"
|
||||
parsed, _ := time.Parse("2006-01-02", "1985-02-23")
|
||||
var date Date = Date(parsed)
|
||||
err := date.Scan(Date{})
|
||||
msg := date.Format("2006-01-02T15:04:05Z07:00")
|
||||
if msg != want {
|
||||
t.Fatalf(`date.Scan(Date{}) = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateValue(t *testing.T) {
|
||||
var want time.Time
|
||||
parsed, _ := time.Parse("2006-01-02", "1985-02-23")
|
||||
var date Date = Date(parsed)
|
||||
msg, _ := date.Value()
|
||||
if reflect.TypeOf(msg) != reflect.TypeOf(want) {
|
||||
t.Fatalf(`date.Value() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateGormDateType(t *testing.T) {
|
||||
want := "date"
|
||||
parsed, _ := time.Parse("2006-01-02", "1985-02-23")
|
||||
var date Date = Date(parsed)
|
||||
msg := date.GormDataType()
|
||||
if msg != want {
|
||||
t.Fatalf(`date.GormDateType() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateGobEncode(t *testing.T) {
|
||||
want := "\x01\x00\x00\x00\x0e\x94\x0f!\x00\x00\x00\x00\x00\xff\xff"
|
||||
parsed, _ := time.Parse("2006-01-02", "1985-02-23")
|
||||
var date Date = Date(parsed)
|
||||
msg, err := date.GobEncode()
|
||||
if string(msg) != want {
|
||||
t.Fatalf(`date.GobEncode() = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateGobDecode(t *testing.T) {
|
||||
want := "1985-02-23T00:00:00Z"
|
||||
parsed, _ := time.Parse("2006-01-02", "2006-01-02")
|
||||
var date Date = Date(parsed)
|
||||
err := date.GobDecode([]byte("\x01\x00\x00\x00\x0e\x94\x0f!\x00\x00\x00\x00\x00\xff\xff"))
|
||||
msg := date.Format("2006-01-02T15:04:05Z07:00")
|
||||
if string(msg) != want {
|
||||
t.Fatalf(`date.GobDecode([]byte()) = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeUnmarshalJSON(t *testing.T) {
|
||||
want := "1985-02-23 12:13:14 +0000 UTC"
|
||||
var dateTime DateTime
|
||||
err := dateTime.UnmarshalJSON([]byte("\"1985-02-23 12:13:14\""))
|
||||
msg := time.Time(dateTime).String()
|
||||
if msg != want {
|
||||
t.Fatalf(`dateTime.UnmarshalJSON([]byte("\"1985-02-23 12:13:14\"") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeUnmarshalJSONMalformed(t *testing.T) {
|
||||
want := error(&time.ParseError{})
|
||||
var dateTime DateTime
|
||||
err := dateTime.UnmarshalJSON([]byte("\"1985/02/23 12-13-14\""))
|
||||
msg := time.Time(dateTime).String()
|
||||
if reflect.TypeOf(err) != reflect.TypeOf(want) {
|
||||
t.Fatalf(`dateTime.UnmarshalJSON([]byte("\"1985/02/23 12-13-14\"") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeMarshalJSON(t *testing.T) {
|
||||
want := "\"1985-02-23T12:13:14Z\""
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "1985-02-23 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
msg, err := dateTime.MarshalJSON()
|
||||
if string(msg) != want {
|
||||
t.Fatalf(`dateTime.MarshalJSON() = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeFormat(t *testing.T) {
|
||||
want := "Feb 23, 1985 12:13:14"
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "1985-02-23 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
msg := dateTime.Format("Jan 2, 2006 15:04:05")
|
||||
if msg != want {
|
||||
t.Fatalf(`dateTime.Format("Jan 2, 2006 15:04:05") = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeScan(t *testing.T) {
|
||||
want := "0001-01-01T00:00:00Z"
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "1985-02-23 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
err := dateTime.Scan(Date{})
|
||||
msg := dateTime.Format("2006-01-02T15:04:05Z07:00")
|
||||
if msg != want {
|
||||
t.Fatalf(`dateTime.Scan(Date{}) = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeValue(t *testing.T) {
|
||||
var want time.Time
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "1985-02-23 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
msg, _ := dateTime.Value()
|
||||
if reflect.TypeOf(msg) != reflect.TypeOf(want) {
|
||||
t.Fatalf(`dateTime.Value() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeGormDateType(t *testing.T) {
|
||||
want := "datetime"
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "1985-02-23 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
msg := dateTime.GormDataType()
|
||||
if msg != want {
|
||||
t.Fatalf(`dateTime.GormDateType() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeGobEncode(t *testing.T) {
|
||||
want := "\x01\x00\x00\x00\x0e\x94\x0f\xcc\xda\x00\x00\x00\x00\xff\xff"
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "1985-02-23 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
msg, err := dateTime.GobEncode()
|
||||
if string(msg) != want {
|
||||
t.Fatalf(`dateTime.GobEncode() = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeGobDecode(t *testing.T) {
|
||||
want := "1985-02-23T12:13:14Z"
|
||||
parsed, _ := time.Parse("2006-01-02 15:04:05", "2006-01-02 12:13:14")
|
||||
var dateTime DateTime = DateTime(parsed)
|
||||
err := dateTime.GobDecode([]byte("\x01\x00\x00\x00\x0e\x94\x0f\xcc\xda\x00\x00\x00\x00\xff\xff"))
|
||||
msg := dateTime.Format("2006-01-02T15:04:05Z07:00")
|
||||
if string(msg) != want {
|
||||
t.Fatalf(`dateTime.GobDecode([]byte()) = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
16
backend/utils/json.go
Normal file
16
backend/utils/json.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type ErrorMessage struct {
|
||||
ErrorMessage string `json:"error_message"`
|
||||
}
|
||||
|
||||
func JSONErrorOutput(writer http.ResponseWriter, status int, msg string) {
|
||||
writer.Header().Set("Content-Type", "application/json")
|
||||
writer.WriteHeader(status)
|
||||
json.NewEncoder(writer).Encode(ErrorMessage{ErrorMessage: msg})
|
||||
}
|
52
backend/utils/jwt.go
Normal file
52
backend/utils/jwt.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
type JWTClaim struct {
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func GenerateJWT(email string, username string) (tokenString string, err error) {
|
||||
expirationTime := time.Now().Add(1 * time.Hour)
|
||||
claims := &JWTClaim{
|
||||
Email: email,
|
||||
Username: username,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(expirationTime),
|
||||
},
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
tokenString, err = token.SignedString(os.Getenv("JWT_SECRET"))
|
||||
return
|
||||
}
|
||||
|
||||
func ValidateToken(signedToken string) (err error) {
|
||||
token, err := jwt.ParseWithClaims(
|
||||
signedToken,
|
||||
&JWTClaim{},
|
||||
func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(os.Getenv("JWT_SECRET")), nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
claims, ok := token.Claims.(*JWTClaim)
|
||||
if !ok {
|
||||
err = errors.New("couldn't parse claims")
|
||||
return
|
||||
}
|
||||
if claims.ExpiresAt.Unix() < jwt.NewNumericDate(time.Now().Local()).Unix() {
|
||||
err = errors.New("token expired")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
115
backend/utils/rut.go
Normal file
115
backend/utils/rut.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RutType int8
|
||||
|
||||
const (
|
||||
Run RutType = iota
|
||||
Rut
|
||||
)
|
||||
|
||||
func (r RutType) String() string {
|
||||
switch r {
|
||||
case Run:
|
||||
return "RUN"
|
||||
case Rut:
|
||||
return "RUT"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func CleanRut(rut *string) {
|
||||
*rut = strings.ToUpper(*rut)
|
||||
*rut = strings.TrimSpace(*rut)
|
||||
*rut = strings.Replace(*rut, ".", "", -1)
|
||||
*rut = strings.Replace(*rut, "-", "", -1)
|
||||
}
|
||||
|
||||
func PrettyRut(rut *string) {
|
||||
tempRut := *rut
|
||||
verifier := strings.ToUpper(tempRut[len(tempRut)-1:])
|
||||
tempRut = tempRut[:len(tempRut)-1]
|
||||
tempRut = Reverse(tempRut)
|
||||
tempRut = InsertNth(tempRut, 3, '.')
|
||||
tempRut = Reverse(tempRut)
|
||||
tempRut = tempRut + "-" + verifier
|
||||
*rut = tempRut
|
||||
}
|
||||
|
||||
func IsValidRut(rut string) (bool, error) {
|
||||
// rut should be 8 or 9 characters
|
||||
if len(rut) != 8 && len(rut) != 9 {
|
||||
return false, errors.New("incorrect RUT length")
|
||||
}
|
||||
|
||||
verifier := strings.ToUpper(rut[len(rut)-1:])
|
||||
tempRut := rut[:len(rut)-1]
|
||||
|
||||
_, err := strconv.Atoi(verifier)
|
||||
if err != nil && verifier != "K" {
|
||||
return false, errors.New("invalid RUT identifier")
|
||||
}
|
||||
|
||||
generatedVerifier, err := generateVerifier(tempRut)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if verifier != generatedVerifier {
|
||||
return false, errors.New("incorrect RUT verifier")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func GetRutType(rut string) (RutType, error) {
|
||||
tempRut := rut[:len(rut)-1]
|
||||
numericRut, err := strconv.Atoi(tempRut)
|
||||
if err != nil {
|
||||
return Run, errors.New("invalid RUN/RUT")
|
||||
}
|
||||
|
||||
if numericRut < 100000000 && numericRut > 50000000 {
|
||||
return Rut, nil
|
||||
} else {
|
||||
return Run, nil
|
||||
}
|
||||
}
|
||||
|
||||
func generateVerifier(rut string) (string, error) {
|
||||
if _, err := strconv.Atoi(rut); err != nil {
|
||||
return "", errors.New("invalid RUT")
|
||||
}
|
||||
|
||||
var multiplier = 2
|
||||
var sum = 0
|
||||
var remainder int
|
||||
var division int
|
||||
var rutLength = len(rut)
|
||||
|
||||
for i := rutLength - 1; i >= 0; i-- {
|
||||
sum = sum + toInt(rut[i:i+1])*multiplier
|
||||
multiplier++
|
||||
if multiplier == 8 {
|
||||
multiplier = 2
|
||||
}
|
||||
}
|
||||
|
||||
division = sum / 11
|
||||
division = division * 11.0
|
||||
remainder = sum - int(division)
|
||||
|
||||
if remainder != 0 {
|
||||
remainder = 11 - remainder
|
||||
}
|
||||
|
||||
if remainder == 10 {
|
||||
return "K", nil
|
||||
} else {
|
||||
return strconv.Itoa(remainder), nil
|
||||
}
|
||||
}
|
138
backend/utils/rut_test.go
Normal file
138
backend/utils/rut_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRutTypeRun(t *testing.T) {
|
||||
typeTest := Run
|
||||
want := "RUN"
|
||||
msg := typeTest.String()
|
||||
if msg != want {
|
||||
t.Fatalf(`typeTest.String() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRutTypeRut(t *testing.T) {
|
||||
typeTest := Rut
|
||||
want := "RUT"
|
||||
msg := typeTest.String()
|
||||
if msg != want {
|
||||
t.Fatalf(`typeTest.String() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRutTypeUnknown(t *testing.T) {
|
||||
var typeTest RutType = 2
|
||||
want := "unknown"
|
||||
msg := typeTest.String()
|
||||
if msg != want {
|
||||
t.Fatalf(`typeTest.String() = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanRut(t *testing.T) {
|
||||
want := "8675309K"
|
||||
msg := "8.675.309-k"
|
||||
CleanRut(&msg)
|
||||
if msg != want {
|
||||
t.Fatalf(`CleanRut(&msg) = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrettyRut(t *testing.T) {
|
||||
want := "8.675.309-K"
|
||||
msg := "8675309k"
|
||||
PrettyRut(&msg)
|
||||
if msg != want {
|
||||
t.Fatalf(`PrettyRut(&msg) = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateVerifier(t *testing.T) {
|
||||
want := "K"
|
||||
msg, err := generateVerifier("8675309")
|
||||
if msg != want {
|
||||
t.Fatalf(`generateVerifier("8675309") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateVerifier2(t *testing.T) {
|
||||
want := "9"
|
||||
msg, err := generateVerifier("86753095")
|
||||
if msg != want {
|
||||
t.Fatalf(`generateVerifier("86753095") = %q, %v, want match for %q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateVerifierInvalidString(t *testing.T) {
|
||||
want := "invalid RUT"
|
||||
_, err := generateVerifier("8675f309")
|
||||
if err.Error() != want {
|
||||
t.Fatalf(`generateVerifier("8675f309") = %q, want %q, nil`, err.Error(), want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidRut(t *testing.T) {
|
||||
want := true
|
||||
msg, err := IsValidRut("8675309K")
|
||||
if msg != want {
|
||||
t.Fatalf(`IsValidRut("8675309K") = false, %v, want match for true, nil`, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidRutInvalid(t *testing.T) {
|
||||
want := false
|
||||
msg, err := IsValidRut("86753T99")
|
||||
if msg != want {
|
||||
t.Fatalf(`IsValidRut("86753T99") = true, %v, want match for false, nil`, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidRutInvalidIdentifier(t *testing.T) {
|
||||
want := false
|
||||
msg, err := IsValidRut("8675309C")
|
||||
if msg != want {
|
||||
t.Fatalf(`IsValidRut("8675309C") = true, %v, want match for false, nil`, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidRutIncorrectLength(t *testing.T) {
|
||||
want := false
|
||||
msg, err := IsValidRut("123234")
|
||||
if msg != want {
|
||||
t.Fatalf(`IsValidRut("123234") = true, %v, want match for false, nil`, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidRutIncorrectIdentifier(t *testing.T) {
|
||||
want := false
|
||||
msg, err := IsValidRut("86753096")
|
||||
if msg != want {
|
||||
t.Fatalf(`IsValidRut("86753096") = true, %v, want match for false, nil`, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRutTypeRun(t *testing.T) {
|
||||
want := Run
|
||||
msg, err := GetRutType("8675309K")
|
||||
if msg != want {
|
||||
t.Fatalf(`GetRutType("8675309") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRutTypeRut(t *testing.T) {
|
||||
want := Rut
|
||||
msg, err := GetRutType("867530959")
|
||||
if msg != want {
|
||||
t.Fatalf(`GetRutType("867530959") = %q, %v, want match for %#q, nil`, msg, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRutTypeRutInvalid(t *testing.T) {
|
||||
want := "invalid RUN/RUT"
|
||||
_, err := GetRutType("8675f309")
|
||||
if err.Error() != want {
|
||||
t.Fatalf(`GetRutType("8675f309") = %q, want %q, nil`, err.Error(), want)
|
||||
}
|
||||
}
|
32
backend/utils/utils.go
Normal file
32
backend/utils/utils.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func toInt(toConvert string) int {
|
||||
converted, _ := strconv.Atoi(toConvert)
|
||||
return converted
|
||||
}
|
||||
|
||||
func Reverse(s string) string {
|
||||
r := []rune(s)
|
||||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
||||
r[i], r[j] = r[j], r[i]
|
||||
}
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func InsertNth(s string, n int, symbol rune) string {
|
||||
var buffer bytes.Buffer
|
||||
var n_1 = n - 1
|
||||
var l_1 = len(s) - 1
|
||||
for i, rune := range s {
|
||||
buffer.WriteRune(rune)
|
||||
if i%n == n_1 && i != l_1 {
|
||||
buffer.WriteRune(symbol)
|
||||
}
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
37
backend/utils/utils_test.go
Normal file
37
backend/utils/utils_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
want := "8675309"
|
||||
msg := Reverse("9035768")
|
||||
if msg != want {
|
||||
t.Fatalf(`Reverse("9035768") = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInsertNth(t *testing.T) {
|
||||
want := "867.530.9"
|
||||
msg := InsertNth("8675309", 3, '.')
|
||||
if msg != want {
|
||||
t.Fatalf(`InsertNth("8675309") = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToInt(t *testing.T) {
|
||||
want := 123
|
||||
msg := toInt("123")
|
||||
if msg != want {
|
||||
t.Fatalf(`toInt("123") = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToIntInvalid(t *testing.T) {
|
||||
want := 123
|
||||
msg := toInt("12f3")
|
||||
if msg == want {
|
||||
t.Fatalf(`toInt("12f3") = %q, want match for %#q, nil`, msg, want)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user