2 files changed,
37 insertions(+),
14 deletions(-)
Author:
Olexandr Smirnov
ss2316544@gmail.com
Committed by:
GitHub
noreply@github.com
Committed at:
2025-07-09 20:26:21 +0300
Parent:
d631546
jump to
| M | internal/models/note.go |
| M | internal/models/note_test.go |
M
internal/models/note.go
··· 2 2 3 3 import ( 4 4 "errors" 5 + "strings" 5 6 "time" 6 7 7 8 "github.com/gofrs/uuid/v5" ··· 10 11 var ( 11 12 ErrNoteContentIsEmpty = errors.New("note: content is empty") 12 13 ErrNoteSlugIsAlreadyInUse = errors.New("note: slug is already in use") 14 + ErrNoteSlugIsInvalid = errors.New("note: slug is invalid") 13 15 ErrNoteExpired = errors.New("note: expired") 14 16 ErrNoteNotFound = errors.New("note: not found") 15 17 ) ··· 28 30 func (n Note) Validate() error { 29 31 if n.Content == "" { 30 32 return ErrNoteContentIsEmpty 33 + } 34 + 35 + if n.Slug == "" || strings.Contains(n.Slug, " ") { 36 + return ErrNoteSlugIsInvalid 31 37 } 32 38 33 39 if n.IsExpired() {
M
internal/models/note_test.go
··· 7 7 assert "github.com/stretchr/testify/require" 8 8 ) 9 9 10 +//nolint:exhaustruct 10 11 func TestNote_Validate(t *testing.T) { 11 12 // NOTE: there no need to test if note is expired since it tested in IsExpired test 12 13 13 - t.Run("should pass the validation only if content provided", func(t *testing.T) { 14 - n := Note{Content: "the content"} //nolint:exhaustruct 14 + t.Run("should pass the validation if only slug and content are provided", func(t *testing.T) { 15 + n := Note{Content: "the content", Slug: "s"} 15 16 assert.NoError(t, n.Validate()) 16 17 }) 17 18 t.Run("should pass validation with content and correct expiration time", func(t *testing.T) { 18 - n := Note{ //nolint:exhaustruct 19 + n := Note{ 19 20 Content: "content", 21 + Slug: "s", 20 22 ExpiresAt: time.Now().Add(time.Minute), 21 23 } 22 24 assert.NoError(t, n.Validate()) 23 25 }) 24 26 t.Run("should fail if content is missing", func(t *testing.T) { 25 - n := Note{Content: ""} //nolint:exhaustruct 27 + n := Note{Content: ""} 26 28 assert.EqualError(t, n.Validate(), ErrNoteContentIsEmpty.Error()) 27 29 }) 28 30 t.Run("should fail if content is missing and other fields are set", func(t *testing.T) { 29 - n := Note{ //nolint:exhaustruct 31 + n := Note{ 30 32 Slug: "some-slug", 31 33 Password: "some-password", 32 34 BurnBeforeExpiration: false, ··· 34 36 assert.EqualError(t, n.Validate(), ErrNoteContentIsEmpty.Error()) 35 37 }) 36 38 t.Run("should fail if expiration time is in the past", func(t *testing.T) { 37 - n := Note{Content: "content", ExpiresAt: time.Now().Add(-time.Hour)} //nolint:exhaustruct 39 + n := Note{ 40 + Content: "content", 41 + Slug: "s", 42 + ExpiresAt: time.Now().Add(-time.Hour), 43 + } 38 44 assert.EqualError(t, n.Validate(), ErrNoteExpired.Error()) 39 45 }) 46 + t.Run("should fail if slug is empty", func(t *testing.T) { 47 + n := Note{Content: "the content", Slug: ""} 48 + assert.EqualError(t, n.Validate(), ErrNoteSlugIsInvalid.Error()) 49 + }) 50 + t.Run("should fail if slug is empty", func(t *testing.T) { 51 + n := Note{Content: "the content", Slug: " "} 52 + assert.EqualError(t, n.Validate(), ErrNoteSlugIsInvalid.Error()) 53 + }) 40 54 } 41 55 56 +//nolint:exhaustruct 42 57 func TestNote_IsExpired(t *testing.T) { 43 58 t.Run("should be expired", func(t *testing.T) { 44 - note := Note{ExpiresAt: time.Now().Add(-time.Hour)} //nolint:exhaustruct 59 + note := Note{ExpiresAt: time.Now().Add(-time.Hour)} 45 60 assert.True(t, note.IsExpired()) 46 61 }) 47 62 t.Run("should be not expired", func(t *testing.T) { 48 - note := Note{ExpiresAt: time.Now().Add(time.Hour)} //nolint:exhaustruct 63 + note := Note{ExpiresAt: time.Now().Add(time.Hour)} 49 64 assert.False(t, note.IsExpired()) 50 65 }) 51 66 t.Run("should be not expired when [ExpiredAt] is zero", func(t *testing.T) { 52 - note := Note{ExpiresAt: time.Time{}} //nolint:exhaustruct 67 + note := Note{ExpiresAt: time.Time{}} 53 68 assert.False(t, note.IsExpired()) 54 69 }) 55 70 } 56 71 72 +//nolint:exhaustruct 57 73 func TestNote_ShouldBeBurnt(t *testing.T) { 58 74 t.Run("should be burnt", func(t *testing.T) { 59 - note := Note{ //nolint:exhaustruct 75 + note := Note{ 60 76 BurnBeforeExpiration: true, 61 77 ExpiresAt: time.Now().Add(time.Hour), 62 78 } 63 79 assert.True(t, note.ShouldBeBurnt()) 64 80 }) 65 81 t.Run("should not be burnt", func(t *testing.T) { 66 - note := Note{ //nolint:exhaustruct 82 + note := Note{ 67 83 BurnBeforeExpiration: true, 68 84 ExpiresAt: time.Time{}, 69 85 } 70 86 assert.False(t, note.ShouldBeBurnt()) 71 87 }) 72 88 t.Run("could not be burnt when expiration and shouldBurn set to false", func(t *testing.T) { 73 - note := Note{ //nolint:exhaustruct 89 + note := Note{ 74 90 BurnBeforeExpiration: false, 75 91 ExpiresAt: time.Time{}, 76 92 } ··· 78 94 }) 79 95 } 80 96 97 +//nolint:exhaustruct 81 98 func TestNote_IsRead(t *testing.T) { 82 99 t.Run("should be unread", func(t *testing.T) { 83 - n := Note{ReadAt: time.Time{}} //nolint:exhaustruct 100 + n := Note{ReadAt: time.Time{}} 84 101 assert.False(t, n.IsRead()) 85 102 }) 86 103 t.Run("should be read", func(t *testing.T) { 87 - n := Note{ReadAt: time.Now()} //nolint:exhaustruct 104 + n := Note{ReadAt: time.Now()} 88 105 assert.True(t, n.IsRead()) 89 106 }) 90 107 }