443 lines
13 KiB
Go
443 lines
13 KiB
Go
package repository_test
|
|
|
|
import (
|
|
"testing"
|
|
"testing/synctest"
|
|
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.hrafn.xyz/aether/gotes/internal/models"
|
|
"git.hrafn.xyz/aether/gotes/internal/repository"
|
|
)
|
|
|
|
var fixedTestDate = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) //Date is set by synctest to this specific time
|
|
|
|
func TestCreateNote(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
title string
|
|
content string
|
|
expectedNote models.Note
|
|
expectedError bool
|
|
}{
|
|
{
|
|
name: "Good note",
|
|
title: "Good",
|
|
content: "This is a good note with valid content.",
|
|
expectedNote: models.Note{
|
|
ID: 1,
|
|
LastUpdate: fixedTestDate,
|
|
Title: "Good",
|
|
Content: "This is a good note with valid content.",
|
|
},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Empty content",
|
|
title: "Empty",
|
|
content: "",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Long content",
|
|
title: "Long",
|
|
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
expectedNote: models.Note{
|
|
ID: 2,
|
|
LastUpdate: fixedTestDate,
|
|
Title: "Long",
|
|
Content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Empty title",
|
|
title: "",
|
|
content: "Some content sure",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Fully empty",
|
|
title: "",
|
|
content: "",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Title too long",
|
|
title: strings.Repeat("A", models.NoteTitleMaxLength+1),
|
|
content: "",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Title accept max",
|
|
title: strings.Repeat("U", models.NoteTitleMaxLength),
|
|
content: `That's a whole lot of "U"s`,
|
|
expectedNote: models.Note{
|
|
ID: 3,
|
|
LastUpdate: fixedTestDate,
|
|
Title: strings.Repeat("U", models.NoteTitleMaxLength),
|
|
Content: `That's a whole lot of "U"s`,
|
|
},
|
|
expectedError: false,
|
|
},
|
|
}
|
|
repo := repository.NewNoteRepository(&mockNoteStore{})
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
synctest.Test(t, func(t *testing.T) {
|
|
note, err := repo.CreateNote(context.Background(), tc.title, tc.content)
|
|
if tc.expectedError {
|
|
if err == nil {
|
|
t.Errorf("expected an error but got none")
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
if note.Content != tc.expectedNote.Content {
|
|
t.Errorf("expected content %q but got %q", tc.expectedNote.Content, note.Content)
|
|
}
|
|
if note.Title != tc.expectedNote.Title {
|
|
t.Errorf("expected title %q but got %q", tc.expectedNote.Title, note.Title)
|
|
}
|
|
if note.ID != tc.expectedNote.ID {
|
|
t.Errorf("expected ID %d but got %d", tc.expectedNote.ID, note.ID)
|
|
}
|
|
if !note.LastUpdate.Equal(tc.expectedNote.LastUpdate) {
|
|
t.Errorf("expected LastUpdate %v but got %v", tc.expectedNote.LastUpdate, note.LastUpdate)
|
|
}
|
|
fmt.Printf("Test case '%s' passed.\n", tc.name)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetNotes(t *testing.T) {
|
|
notes := []models.Note{
|
|
{ID: 1, LastUpdate: fixedTestDate, Content: "First note", Title: "One"},
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note", Title: "Two"},
|
|
{ID: 3, LastUpdate: fixedTestDate, Content: "Third note", Title: "Three"},
|
|
// 4th note was clearly deleted, :sadface:
|
|
{ID: 5, LastUpdate: fixedTestDate, Content: "Lorem ipsum note dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", Title: "Lorem"},
|
|
}
|
|
store := &mockNoteStore{Notes: notes}
|
|
repo := repository.NewNoteRepository(store)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
id int
|
|
expectedNote models.Note
|
|
expectedError bool
|
|
}{
|
|
{
|
|
name: "Existing note",
|
|
id: 1,
|
|
expectedNote: notes[0],
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Non-existing note",
|
|
id: 999,
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Secret missing 4th note",
|
|
id: 4,
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "That long lorem ipsum note",
|
|
id: 5,
|
|
expectedNote: notes[3],
|
|
expectedError: false,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
note, err := repo.GetNote(context.Background(), tc.id)
|
|
if tc.expectedError {
|
|
if err == nil {
|
|
t.Errorf("expected an error but got none")
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
if note.Content != tc.expectedNote.Content {
|
|
t.Errorf("expected content %q but got %q", tc.expectedNote.Content, note.Content)
|
|
}
|
|
if note.ID != tc.expectedNote.ID {
|
|
t.Errorf("expected ID %d but got %d", tc.expectedNote.ID, note.ID)
|
|
}
|
|
// Purposefully not checking time as it doesn't make sense in context
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestListNotes(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
notes []models.Note
|
|
expectedNotes []models.Note
|
|
expectedError bool
|
|
}{
|
|
{
|
|
name: "No notes",
|
|
notes: []models.Note{},
|
|
expectedNotes: []models.Note{},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Multiple notes",
|
|
notes: []models.Note{
|
|
{ID: 1, LastUpdate: fixedTestDate, Content: "First note", Title: "Seven"},
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note", Title: "Nine"},
|
|
{ID: 3, LastUpdate: fixedTestDate, Content: "Third note", Title: "FourtyThree"},
|
|
},
|
|
expectedNotes: []models.Note{
|
|
{ID: 1, LastUpdate: fixedTestDate, Content: "First note", Title: "Seven"},
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note", Title: "Nine"},
|
|
{ID: 3, LastUpdate: fixedTestDate, Content: "Third note", Title: "FourtyThree"},
|
|
},
|
|
expectedError: false,
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
store := &mockNoteStore{Notes: tc.notes}
|
|
repo := repository.NewNoteRepository(store)
|
|
notes, err := repo.ListNotes(context.Background())
|
|
if tc.expectedError {
|
|
if err == nil {
|
|
t.Errorf("expected an error but got none")
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
if len(notes) != len(tc.expectedNotes) {
|
|
t.Errorf("expected %d notes but got %d", len(tc.expectedNotes), len(notes))
|
|
}
|
|
for i, note := range notes {
|
|
if note.Content != tc.expectedNotes[i].Content {
|
|
t.Errorf("expected content %q but got %q", tc.expectedNotes[i].Content, note.Content)
|
|
}
|
|
if note.Title != tc.expectedNotes[i].Title {
|
|
t.Errorf("expected title %q but got %q", tc.expectedNotes[i].Title, note.Title)
|
|
}
|
|
if note.ID != tc.expectedNotes[i].ID {
|
|
t.Errorf("expected ID %d but got %d", tc.expectedNotes[i].ID, note.ID)
|
|
}
|
|
// Purposefully not checking time as it doesn't make sense in context
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUpdateNote(t *testing.T) {
|
|
notes := []models.Note{
|
|
{ID: 1, LastUpdate: time.Date(1984, 11, 20, 0, 0, 0, 0, time.UTC), Content: "First note", Title: "Joe"},
|
|
{ID: 2, LastUpdate: time.Date(2018, 6, 8, 0, 0, 0, 0, time.UTC), Content: "Second note", Title: "Momma"},
|
|
{ID: 3, LastUpdate: time.Date(2018, 6, 8, 0, 0, 0, 0, time.UTC), Content: "Third note", Title: "So"},
|
|
{ID: 4, LastUpdate: time.Date(2018, 6, 8, 0, 0, 0, 0, time.UTC), Content: "Four note", Title: "Lovely"},
|
|
{ID: 5, LastUpdate: time.Date(2018, 6, 8, 0, 0, 0, 0, time.UTC), Content: "Fifth note", Title: "No, really"},
|
|
{ID: 6, LastUpdate: time.Date(2018, 6, 8, 0, 0, 0, 0, time.UTC), Content: "six note", Title: "She is!"},
|
|
}
|
|
store := &mockNoteStore{Notes: notes}
|
|
repo := repository.NewNoteRepository(store)
|
|
testcases := []struct {
|
|
name string
|
|
id int
|
|
title string
|
|
content string
|
|
expectedNote models.Note
|
|
expectedError bool
|
|
}{
|
|
{
|
|
name: "Update existing note content only",
|
|
id: 1,
|
|
title: "",
|
|
content: "Updated first note",
|
|
expectedNote: models.Note{
|
|
ID: 1,
|
|
LastUpdate: fixedTestDate,
|
|
Content: "Updated first note",
|
|
Title: "Joe",
|
|
},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Update non-existing note",
|
|
id: 999,
|
|
title: "Does it matter?",
|
|
content: "This note does not exist",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Update with empty content and title",
|
|
id: 2,
|
|
content: "",
|
|
title: "",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Update with unchanged content",
|
|
id: 3,
|
|
content: "Third note",
|
|
title: "So",
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "Update with title only",
|
|
id: 4,
|
|
content: "",
|
|
title: "Davey crocket",
|
|
expectedNote: models.Note{
|
|
ID: 4,
|
|
LastUpdate: fixedTestDate,
|
|
Content: "Four note",
|
|
Title: "Davey crocket",
|
|
},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Update with content only",
|
|
id: 5,
|
|
content: "Just internal screaming",
|
|
title: "",
|
|
expectedNote: models.Note{
|
|
ID: 5,
|
|
LastUpdate: fixedTestDate,
|
|
Content: "Just internal screaming",
|
|
Title: "No, really",
|
|
},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Update title too long",
|
|
id: 6,
|
|
content: "Kinda irrelavant, right?",
|
|
title: strings.Repeat("F", models.NoteTitleMaxLength+1),
|
|
expectedNote: models.Note{},
|
|
expectedError: true,
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
synctest.Test(t, func(t *testing.T) {
|
|
note, err := repo.UpdateNote(context.Background(), tc.id, repository.NoteUpdate{
|
|
Content: tc.content,
|
|
Title: tc.title,
|
|
})
|
|
if tc.expectedError {
|
|
if err == nil {
|
|
t.Errorf("expected an error but got none")
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
if note.Content != tc.expectedNote.Content {
|
|
t.Errorf("expected content %q but got %q", tc.expectedNote.Content, note.Content)
|
|
}
|
|
if note.Title != tc.expectedNote.Title {
|
|
t.Errorf("expected title %q but got %q", tc.expectedNote.Title, note.Title)
|
|
}
|
|
if note.ID != tc.expectedNote.ID {
|
|
t.Errorf("expected ID %d but got %d", tc.expectedNote.ID, note.ID)
|
|
}
|
|
if !note.LastUpdate.Equal(tc.expectedNote.LastUpdate) {
|
|
t.Errorf("expected LastUpdate %v but got %v", tc.expectedNote.LastUpdate, note.LastUpdate)
|
|
}
|
|
fmt.Printf("Test case '%s' passed.\n", tc.name)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteNote(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
id int
|
|
setupNotes []models.Note
|
|
expectedNotes []models.Note
|
|
expectedError bool
|
|
}{
|
|
{
|
|
name: "Delete existing note",
|
|
id: 1,
|
|
setupNotes: []models.Note{
|
|
{ID: 1, LastUpdate: fixedTestDate, Content: "First note"},
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note"},
|
|
},
|
|
expectedNotes: []models.Note{
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note"},
|
|
},
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "Delete non-existing note",
|
|
id: 999,
|
|
setupNotes: []models.Note{
|
|
{ID: 1, LastUpdate: fixedTestDate, Content: "First note"},
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note"},
|
|
},
|
|
expectedNotes: []models.Note{
|
|
{ID: 1, LastUpdate: fixedTestDate, Content: "First note"},
|
|
{ID: 2, LastUpdate: fixedTestDate, Content: "Second note"},
|
|
},
|
|
expectedError: true,
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
store := &mockNoteStore{Notes: tc.setupNotes}
|
|
repo := repository.NewNoteRepository(store)
|
|
err := repo.DeleteNote(context.Background(), tc.id)
|
|
if tc.expectedError {
|
|
if err == nil {
|
|
t.Errorf("expected an error but got none")
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
notes, _ := repo.ListNotes(context.Background())
|
|
if len(notes) != len(tc.expectedNotes) {
|
|
t.Errorf("expected %d notes but got %d", len(tc.expectedNotes), len(notes))
|
|
}
|
|
for i, note := range notes {
|
|
if len(tc.expectedNotes) <= i {
|
|
t.Errorf("unexpected extra note: %v", note)
|
|
continue
|
|
}
|
|
if note.Content != tc.expectedNotes[i].Content {
|
|
t.Errorf("expected content %q but got %q", tc.expectedNotes[i].Content, note.Content)
|
|
}
|
|
if note.ID != tc.expectedNotes[i].ID {
|
|
t.Errorf("expected ID %d but got %d", tc.expectedNotes[i].ID, note.ID)
|
|
}
|
|
// Purposefully not checking time as it doesn't make sense in context
|
|
}
|
|
})
|
|
}
|
|
}
|