146 lines
3.5 KiB
Go
146 lines
3.5 KiB
Go
package models_test
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math/rand/v2"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.hrafn.xyz/aether/notes/internal/models"
|
|
)
|
|
|
|
func TestContentCompletionNoteValidation(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
note models.Note
|
|
expectedError bool
|
|
expectedReasons []error
|
|
}{
|
|
{
|
|
name: "Completely Empty",
|
|
note: models.Note{
|
|
Title: "",
|
|
Content: "",
|
|
ID: 1,
|
|
LastUpdate: time.Now(),
|
|
},
|
|
expectedError: true,
|
|
expectedReasons: []error{&models.ErrEmptyNoteContent{}, &models.ErrEmptyNoteTitle{}},
|
|
},
|
|
{
|
|
name: "Missing title",
|
|
note: models.Note{
|
|
Title: "",
|
|
Content: "Here we go!",
|
|
ID: 1,
|
|
LastUpdate: time.Now(),
|
|
},
|
|
expectedError: true,
|
|
expectedReasons: []error{&models.ErrEmptyNoteTitle{}},
|
|
},
|
|
{
|
|
name: "Missing content",
|
|
note: models.Note{
|
|
Title: "I am not content with this content",
|
|
Content: "",
|
|
ID: 1,
|
|
LastUpdate: time.Now(),
|
|
},
|
|
expectedError: true,
|
|
expectedReasons: []error{&models.ErrEmptyNoteContent{}},
|
|
},
|
|
{
|
|
name: "Good note",
|
|
note: models.Note{
|
|
Title: "I am content with this content",
|
|
Content: "this content",
|
|
ID: 1,
|
|
LastUpdate: time.Now(),
|
|
},
|
|
expectedError: false,
|
|
expectedReasons: []error{},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := tc.note.Validate()
|
|
|
|
// Early out when not needing to test because we're not expecting an error and we didn't get one
|
|
if !tc.expectedError && err == nil {
|
|
fmt.Printf("Test case '%s' passed.\n", tc.name)
|
|
return
|
|
}
|
|
|
|
var expected *models.ErrNoteIncomplete
|
|
if !errors.As(err, &expected) && tc.expectedError {
|
|
t.Errorf("expected *ErrNoteIncomplete, got %T", err)
|
|
}
|
|
for _, reason := range tc.expectedReasons {
|
|
if !errors.Is(err, reason) {
|
|
t.Errorf(`expected error to contain "%v" but it was missing`, reason)
|
|
}
|
|
}
|
|
rv := reflect.ValueOf(err).Elem()
|
|
whyField := rv.FieldByName("why")
|
|
if whyField.Len() != len(tc.expectedReasons) {
|
|
t.Errorf("expected %d errors, got %d", len(tc.expectedReasons), whyField.Len())
|
|
}
|
|
fmt.Printf("Test case '%s' passed.\n", tc.name)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTitleLengthNoteValidation(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
title string
|
|
expectedError bool
|
|
}{
|
|
{
|
|
name: "Max valid title",
|
|
title: strings.Repeat("0", models.NoteTitleMaxLength),
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Just over max valid title",
|
|
title: strings.Repeat("1", models.NoteTitleMaxLength + 1),
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Double max valid title",
|
|
title: strings.Repeat("Bd", models.NoteTitleMaxLength),
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Random overmax valid title length",
|
|
title: strings.Repeat("1", models.NoteTitleMaxLength + rand.IntN(150)),
|
|
expectedError: true,
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
note := models.Note{
|
|
Title: tc.title,
|
|
Content: "Perfectly valid content " + tc.title,
|
|
LastUpdate: time.Now(),
|
|
ID: 1,
|
|
}
|
|
err := note.Validate()
|
|
|
|
if !tc.expectedError {
|
|
if err != nil {
|
|
t.Errorf("expecting no error, got %v", err)
|
|
}
|
|
} else {
|
|
var expected *models.ErrNoteTitleOverflow
|
|
if !errors.As(err, &expected) {
|
|
t.Errorf("expected *ErrNoteTitleOverflow, got %T", err)
|
|
}
|
|
}
|
|
fmt.Printf("Test case '%s' passed.\n", tc.name)
|
|
})
|
|
}
|
|
} |