cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm
leaflet
readability
golang
1package repo
2
3import (
4 "context"
5 "testing"
6
7 _ "github.com/mattn/go-sqlite3"
8 "github.com/stormlightlabs/noteleaf/internal/models"
9 "github.com/stormlightlabs/noteleaf/internal/shared"
10)
11
12func TestBaseMediaRepository(t *testing.T) {
13 ctx := context.Background()
14
15 t.Run("Books", func(t *testing.T) {
16 t.Run("Create and Get", func(t *testing.T) {
17 db := CreateTestDB(t)
18 repo := NewBookRepository(db)
19
20 book := &models.Book{
21 Title: "Test Book",
22 Author: "Test Author",
23 Status: "queued",
24 }
25
26 id, err := repo.Create(ctx, book)
27 shared.AssertNoError(t, err, "Failed to create book")
28 shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
29
30 retrieved, err := repo.Get(ctx, id)
31 shared.AssertNoError(t, err, "Failed to get book")
32 shared.AssertEqual(t, book.Title, retrieved.Title, "Title mismatch")
33 shared.AssertEqual(t, book.Author, retrieved.Author, "Author mismatch")
34 shared.AssertEqual(t, book.Status, retrieved.Status, "Status mismatch")
35 })
36
37 t.Run("Update", func(t *testing.T) {
38 db := CreateTestDB(t)
39 repo := NewBookRepository(db)
40
41 book := &models.Book{
42 Title: "Original Title",
43 Author: "Original Author",
44 Status: "queued",
45 }
46
47 id, err := repo.Create(ctx, book)
48 shared.AssertNoError(t, err, "Failed to create book")
49
50 book.Title = "Updated Title"
51 book.Author = "Updated Author"
52 book.Status = "reading"
53
54 err = repo.Update(ctx, book)
55 shared.AssertNoError(t, err, "Failed to update book")
56
57 retrieved, err := repo.Get(ctx, id)
58 shared.AssertNoError(t, err, "Failed to get updated book")
59 shared.AssertEqual(t, "Updated Title", retrieved.Title, "Title not updated")
60 shared.AssertEqual(t, "Updated Author", retrieved.Author, "Author not updated")
61 shared.AssertEqual(t, "reading", retrieved.Status, "Status not updated")
62 })
63
64 t.Run("Delete", func(t *testing.T) {
65 db := CreateTestDB(t)
66 repo := NewBookRepository(db)
67
68 book := &models.Book{
69 Title: "To Delete",
70 Status: "queued",
71 }
72
73 id, err := repo.Create(ctx, book)
74 shared.AssertNoError(t, err, "Failed to create book")
75
76 err = repo.Delete(ctx, id)
77 shared.AssertNoError(t, err, "Failed to delete book")
78
79 _, err = repo.Get(ctx, id)
80 shared.AssertError(t, err, "Expected error when getting deleted book")
81 })
82
83 t.Run("Get non-existent", func(t *testing.T) {
84 db := CreateTestDB(t)
85 repo := NewBookRepository(db)
86
87 _, err := repo.Get(ctx, 9999)
88 shared.AssertError(t, err, "Expected error for non-existent book")
89 shared.AssertContains(t, err.Error(), "not found", "Error should mention 'not found'")
90 })
91
92 t.Run("ListQuery with multiple books", func(t *testing.T) {
93 db := CreateTestDB(t)
94 repo := NewBookRepository(db)
95
96 books := []*models.Book{
97 {Title: "Book 1", Author: "Author A", Status: "queued"},
98 {Title: "Book 2", Author: "Author B", Status: "reading"},
99 {Title: "Book 3", Author: "Author A", Status: "finished"},
100 }
101
102 for _, book := range books {
103 _, err := repo.Create(ctx, book)
104 shared.AssertNoError(t, err, "Failed to create book")
105 }
106
107 allBooks, err := repo.List(ctx, BookListOptions{})
108 shared.AssertNoError(t, err, "Failed to list books")
109 if len(allBooks) != 3 {
110 t.Errorf("Expected 3 books, got %d", len(allBooks))
111 }
112 })
113
114 t.Run("CountQuery", func(t *testing.T) {
115 db := CreateTestDB(t)
116 repo := NewBookRepository(db)
117
118 for i := 0; i < 5; i++ {
119 book := &models.Book{
120 Title: "Book",
121 Status: "queued",
122 }
123 _, err := repo.Create(ctx, book)
124 shared.AssertNoError(t, err, "Failed to create book")
125 }
126
127 count, err := repo.Count(ctx, BookListOptions{})
128 shared.AssertNoError(t, err, "Failed to count books")
129 if count != 5 {
130 t.Errorf("Expected count of 5, got %d", count)
131 }
132 })
133 })
134
135 t.Run("Movies", func(t *testing.T) {
136 t.Run("Create and Get", func(t *testing.T) {
137 db := CreateTestDB(t)
138 repo := NewMovieRepository(db)
139
140 movie := &models.Movie{
141 Title: "Test Movie",
142 Year: 2023,
143 Status: "queued",
144 }
145
146 id, err := repo.Create(ctx, movie)
147 shared.AssertNoError(t, err, "Failed to create movie")
148 shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
149
150 retrieved, err := repo.Get(ctx, id)
151 shared.AssertNoError(t, err, "Failed to get movie")
152 shared.AssertEqual(t, movie.Title, retrieved.Title, "Title mismatch")
153 shared.AssertEqual(t, movie.Year, retrieved.Year, "Year mismatch")
154 shared.AssertEqual(t, movie.Status, retrieved.Status, "Status mismatch")
155 })
156
157 t.Run("Update", func(t *testing.T) {
158 db := CreateTestDB(t)
159 repo := NewMovieRepository(db)
160
161 movie := &models.Movie{
162 Title: "Original Movie",
163 Year: 2020,
164 Status: "queued",
165 }
166
167 id, err := repo.Create(ctx, movie)
168 shared.AssertNoError(t, err, "Failed to create movie")
169
170 movie.Title = "Updated Movie"
171 movie.Year = 2023
172 movie.Status = "watched"
173
174 err = repo.Update(ctx, movie)
175 shared.AssertNoError(t, err, "Failed to update movie")
176
177 retrieved, err := repo.Get(ctx, id)
178 shared.AssertNoError(t, err, "Failed to get updated movie")
179 shared.AssertEqual(t, "Updated Movie", retrieved.Title, "Title not updated")
180 shared.AssertEqual(t, 2023, retrieved.Year, "Year not updated")
181 shared.AssertEqual(t, "watched", retrieved.Status, "Status not updated")
182 })
183
184 t.Run("Delete", func(t *testing.T) {
185 db := CreateTestDB(t)
186 repo := NewMovieRepository(db)
187
188 movie := &models.Movie{
189 Title: "To Delete",
190 Status: "queued",
191 }
192
193 id, err := repo.Create(ctx, movie)
194 shared.AssertNoError(t, err, "Failed to create movie")
195
196 err = repo.Delete(ctx, id)
197 shared.AssertNoError(t, err, "Failed to delete movie")
198
199 _, err = repo.Get(ctx, id)
200 shared.AssertError(t, err, "Expected error when getting deleted movie")
201 })
202 })
203
204 t.Run("TV Shows", func(t *testing.T) {
205 t.Run("Create and Get", func(t *testing.T) {
206 db := CreateTestDB(t)
207 repo := NewTVRepository(db)
208
209 show := &models.TVShow{
210 Title: "Test Show",
211 Season: 1,
212 Episode: 1,
213 Status: "queued",
214 }
215
216 id, err := repo.Create(ctx, show)
217 shared.AssertNoError(t, err, "Failed to create TV show")
218 shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
219
220 retrieved, err := repo.Get(ctx, id)
221 shared.AssertNoError(t, err, "Failed to get TV show")
222 shared.AssertEqual(t, show.Title, retrieved.Title, "Title mismatch")
223 shared.AssertEqual(t, show.Season, retrieved.Season, "Season mismatch")
224 shared.AssertEqual(t, show.Episode, retrieved.Episode, "Episode mismatch")
225 shared.AssertEqual(t, show.Status, retrieved.Status, "Status mismatch")
226 })
227
228 t.Run("Update", func(t *testing.T) {
229 db := CreateTestDB(t)
230 repo := NewTVRepository(db)
231
232 show := &models.TVShow{
233 Title: "Original Show",
234 Season: 1,
235 Episode: 1,
236 Status: "queued",
237 }
238
239 id, err := repo.Create(ctx, show)
240 shared.AssertNoError(t, err, "Failed to create TV show")
241
242 show.Title = "Updated Show"
243 show.Season = 2
244 show.Episode = 5
245 show.Status = "watching"
246
247 err = repo.Update(ctx, show)
248 shared.AssertNoError(t, err, "Failed to update TV show")
249
250 retrieved, err := repo.Get(ctx, id)
251 shared.AssertNoError(t, err, "Failed to get updated TV show")
252 shared.AssertEqual(t, "Updated Show", retrieved.Title, "Title not updated")
253 shared.AssertEqual(t, 2, retrieved.Season, "Season not updated")
254 shared.AssertEqual(t, 5, retrieved.Episode, "Episode not updated")
255 shared.AssertEqual(t, "watching", retrieved.Status, "Status not updated")
256 })
257
258 t.Run("Delete", func(t *testing.T) {
259 db := CreateTestDB(t)
260 repo := NewTVRepository(db)
261
262 show := &models.TVShow{
263 Title: "To Delete",
264 Status: "queued",
265 }
266
267 id, err := repo.Create(ctx, show)
268 shared.AssertNoError(t, err, "Failed to create TV show")
269
270 err = repo.Delete(ctx, id)
271 shared.AssertNoError(t, err, "Failed to delete TV show")
272
273 _, err = repo.Get(ctx, id)
274 shared.AssertError(t, err, "Expected error when getting deleted TV show")
275 })
276 })
277
278 t.Run("Edge Cases", func(t *testing.T) {
279 t.Run("buildPlaceholders", func(t *testing.T) {
280 emptyResult := buildPlaceholders([]any{})
281 if emptyResult != "" {
282 t.Errorf("Expected empty string for empty values, got '%s'", emptyResult)
283 }
284
285 singleResult := buildPlaceholders([]any{1})
286 if singleResult != "?" {
287 t.Errorf("Expected '?' for single value, got '%s'", singleResult)
288 }
289
290 multipleResult := buildPlaceholders([]any{1, 2, 3})
291 if multipleResult != "?,?,?" {
292 t.Errorf("Expected '?,?,?' for three values, got '%s'", multipleResult)
293 }
294
295 largeResult := buildPlaceholders(make([]any, 10))
296 expected := "?,?,?,?,?,?,?,?,?,?"
297 if largeResult != expected {
298 t.Errorf("Expected '%s' for ten values, got '%s'", expected, largeResult)
299 }
300 })
301 })
302}