···8899 _ "github.com/mattn/go-sqlite3"
1010 "github.com/stormlightlabs/noteleaf/internal/models"
1111+ "github.com/stormlightlabs/noteleaf/internal/shared"
1112)
12131314func TestArticleRepository(t *testing.T) {
···20212122 article := CreateSampleArticle()
2223 id, err := repo.Create(ctx, article)
2323- AssertNoError(t, err, "Failed to create article")
2424- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2525- AssertEqual(t, id, article.ID, "Expected article ID to be set correctly")
2626- AssertFalse(t, article.Created.IsZero(), "Expected Created timestamp to be set")
2727- AssertFalse(t, article.Modified.IsZero(), "Expected Modified timestamp to be set")
2424+ shared.AssertNoError(t, err, "Failed to create article")
2525+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2626+ shared.AssertEqual(t, id, article.ID, "Expected article ID to be set correctly")
2727+ shared.AssertFalse(t, article.Created.IsZero(), "Expected Created timestamp to be set")
2828+ shared.AssertFalse(t, article.Modified.IsZero(), "Expected Modified timestamp to be set")
2829 })
29303031 t.Run("Get article", func(t *testing.T) {
···33343435 original := CreateSampleArticle()
3536 id, err := repo.Create(ctx, original)
3636- AssertNoError(t, err, "Failed to create article")
3737+ shared.AssertNoError(t, err, "Failed to create article")
37383839 retrieved, err := repo.Get(ctx, id)
3939- AssertNoError(t, err, "Failed to get article")
4040- AssertEqual(t, original.ID, retrieved.ID, "ID mismatch")
4141- AssertEqual(t, original.URL, retrieved.URL, "URL mismatch")
4242- AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
4343- AssertEqual(t, original.Author, retrieved.Author, "Author mismatch")
4444- AssertEqual(t, original.Date, retrieved.Date, "Date mismatch")
4545- AssertEqual(t, original.MarkdownPath, retrieved.MarkdownPath, "MarkdownPath mismatch")
4646- AssertEqual(t, original.HTMLPath, retrieved.HTMLPath, "HTMLPath mismatch")
4040+ shared.AssertNoError(t, err, "Failed to get article")
4141+ shared.AssertEqual(t, original.ID, retrieved.ID, "ID mismatch")
4242+ shared.AssertEqual(t, original.URL, retrieved.URL, "URL mismatch")
4343+ shared.AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
4444+ shared.AssertEqual(t, original.Author, retrieved.Author, "Author mismatch")
4545+ shared.AssertEqual(t, original.Date, retrieved.Date, "Date mismatch")
4646+ shared.AssertEqual(t, original.MarkdownPath, retrieved.MarkdownPath, "MarkdownPath mismatch")
4747+ shared.AssertEqual(t, original.HTMLPath, retrieved.HTMLPath, "HTMLPath mismatch")
4748 })
48494950 t.Run("Update article", func(t *testing.T) {
···52535354 article := CreateSampleArticle()
5455 id, err := repo.Create(ctx, article)
5555- AssertNoError(t, err, "Failed to create article")
5656+ shared.AssertNoError(t, err, "Failed to create article")
56575758 originalModified := article.Modified
5859 article.Title = "Updated Title"
···6263 article.HTMLPath = "/updated/path/article.html"
63646465 err = repo.Update(ctx, article)
6565- AssertNoError(t, err, "Failed to update article")
6666+ shared.AssertNoError(t, err, "Failed to update article")
66676768 retrieved, err := repo.Get(ctx, id)
6868- AssertNoError(t, err, "Failed to get updated article")
6969- AssertEqual(t, "Updated Title", retrieved.Title, "Expected updated title")
7070- AssertEqual(t, "Updated Author", retrieved.Author, "Expected updated author")
7171- AssertEqual(t, "2024-01-02", retrieved.Date, "Expected updated date")
7272- AssertEqual(t, "/updated/path/article.md", retrieved.MarkdownPath, "Expected updated markdown path")
7373- AssertEqual(t, "/updated/path/article.html", retrieved.HTMLPath, "Expected updated HTML path")
7474- AssertTrue(t, retrieved.Modified.After(originalModified), "Expected Modified timestamp to be updated")
6969+ shared.AssertNoError(t, err, "Failed to get updated article")
7070+ shared.AssertEqual(t, "Updated Title", retrieved.Title, "Expected updated title")
7171+ shared.AssertEqual(t, "Updated Author", retrieved.Author, "Expected updated author")
7272+ shared.AssertEqual(t, "2024-01-02", retrieved.Date, "Expected updated date")
7373+ shared.AssertEqual(t, "/updated/path/article.md", retrieved.MarkdownPath, "Expected updated markdown path")
7474+ shared.AssertEqual(t, "/updated/path/article.html", retrieved.HTMLPath, "Expected updated HTML path")
7575+ shared.AssertTrue(t, retrieved.Modified.After(originalModified), "Expected Modified timestamp to be updated")
7576 })
76777778 t.Run("Delete article", func(t *testing.T) {
···80818182 article := CreateSampleArticle()
8283 id, err := repo.Create(ctx, article)
8383- AssertNoError(t, err, "Failed to create article")
8484+ shared.AssertNoError(t, err, "Failed to create article")
84858586 err = repo.Delete(ctx, id)
8686- AssertNoError(t, err, "Failed to delete article")
8787+ shared.AssertNoError(t, err, "Failed to delete article")
87888889 _, err = repo.Get(ctx, id)
8989- AssertError(t, err, "Expected error when getting deleted article")
9090+ shared.AssertError(t, err, "Expected error when getting deleted article")
9091 })
9192 })
9293···99100 article := CreateSampleArticle()
100101 article.Title = ""
101102 _, err := repo.Create(ctx, article)
102102- AssertError(t, err, "Expected error when creating article with empty title")
103103+ shared.AssertError(t, err, "Expected error when creating article with empty title")
103104 })
104105105106 t.Run("Fails with missing URL", func(t *testing.T) {
106107 article := CreateSampleArticle()
107108 article.URL = ""
108109 _, err := repo.Create(ctx, article)
109109- AssertError(t, err, "Expected error when creating article with empty URL")
110110+ shared.AssertError(t, err, "Expected error when creating article with empty URL")
110111 })
111112112113 t.Run("Fails with duplicate URL", func(t *testing.T) {
113114 article1 := CreateSampleArticle()
114115 _, err := repo.Create(ctx, article1)
115115- AssertNoError(t, err, "Failed to create first article")
116116+ shared.AssertNoError(t, err, "Failed to create first article")
116117117118 article2 := CreateSampleArticle()
118119 article2.URL = article1.URL
119120 _, err = repo.Create(ctx, article2)
120120- AssertError(t, err, "Expected error when creating article with duplicate URL")
121121+ shared.AssertError(t, err, "Expected error when creating article with duplicate URL")
121122 })
122123123124 t.Run("Fails with missing markdown path", func(t *testing.T) {
124125 article := CreateSampleArticle()
125126 article.MarkdownPath = ""
126127 _, err := repo.Create(ctx, article)
127127- AssertError(t, err, "Expected error when creating article with empty markdown path")
128128- AssertContains(t, err.Error(), "MarkdownPath", "Expected MarkdownPath validation error")
128128+ shared.AssertError(t, err, "Expected error when creating article with empty markdown path")
129129+ shared.AssertContains(t, err.Error(), "MarkdownPath", "Expected MarkdownPath validation error")
129130 })
130131131132 t.Run("Fails with missing HTML path", func(t *testing.T) {
132133 article := CreateSampleArticle()
133134 article.HTMLPath = ""
134135 _, err := repo.Create(ctx, article)
135135- AssertError(t, err, "Expected error when creating article with empty HTML path")
136136- AssertContains(t, err.Error(), "HTMLPath", "Expected HTMLPath validation error")
136136+ shared.AssertError(t, err, "Expected error when creating article with empty HTML path")
137137+ shared.AssertContains(t, err.Error(), "HTMLPath", "Expected HTMLPath validation error")
137138 })
138139139140 t.Run("Fails with invalid URL format", func(t *testing.T) {
140141 article := CreateSampleArticle()
141142 article.URL = "not-a-valid-url"
142143 _, err := repo.Create(ctx, article)
143143- AssertError(t, err, "Expected error when creating article with invalid URL format")
144144- AssertContains(t, err.Error(), "URL", "Expected URL format validation error")
144144+ shared.AssertError(t, err, "Expected error when creating article with invalid URL format")
145145+ shared.AssertContains(t, err.Error(), "URL", "Expected URL format validation error")
145146 })
146147147148 t.Run("Fails with invalid date format", func(t *testing.T) {
148149 article := CreateSampleArticle()
149150 article.Date = "invalid-date"
150151 _, err := repo.Create(ctx, article)
151151- AssertError(t, err, "Expected error when creating article with invalid date format")
152152- AssertContains(t, err.Error(), "Date", "Expected date validation error")
152152+ shared.AssertError(t, err, "Expected error when creating article with invalid date format")
153153+ shared.AssertContains(t, err.Error(), "Date", "Expected date validation error")
153154 })
154155155156 t.Run("Fails with title too long", func(t *testing.T) {
156157 article := CreateSampleArticle()
157158 article.Title = strings.Repeat("a", 501)
158159 _, err := repo.Create(ctx, article)
159159- AssertError(t, err, "Expected error when creating article with title too long")
160160- AssertContains(t, err.Error(), "Title", "Expected title length validation error")
160160+ shared.AssertError(t, err, "Expected error when creating article with title too long")
161161+ shared.AssertContains(t, err.Error(), "Title", "Expected title length validation error")
161162 })
162163163164 t.Run("Fails with author too long", func(t *testing.T) {
164165 article := CreateSampleArticle()
165166 article.Author = strings.Repeat("a", 201)
166167 _, err := repo.Create(ctx, article)
167167- AssertError(t, err, "Expected error when creating article with author too long")
168168- AssertContains(t, err.Error(), "Author", "Expected author length validation error")
168168+ shared.AssertError(t, err, "Expected error when creating article with author too long")
169169+ shared.AssertContains(t, err.Error(), "Author", "Expected author length validation error")
169170 })
170171171172 t.Run("Validates timestamps", func(t *testing.T) {
···174175 article.Modified = now
175176 article.Created = now.Add(time.Hour)
176177 err := repo.Validate(article)
177177- AssertError(t, err, "Expected error when created is after modified")
178178- AssertContains(t, err.Error(), "Created", "Expected timestamp validation error")
178178+ shared.AssertError(t, err, "Expected error when created is after modified")
179179+ shared.AssertContains(t, err.Error(), "Created", "Expected timestamp validation error")
179180 })
180181181182 t.Run("Succeeds when created equals modified", func(t *testing.T) {
···184185 article.Created = now
185186 article.Modified = now
186187 err := repo.Validate(article)
187187- AssertNoError(t, err, "Expected no error when created equals modified")
188188+ shared.AssertNoError(t, err, "Expected no error when created equals modified")
188189 })
189190190191 t.Run("Succeeds when created is before modified", func(t *testing.T) {
···193194 article.Created = now
194195 article.Modified = now.Add(time.Hour)
195196 err := repo.Validate(article)
196196- AssertNoError(t, err, "Expected no error when created is before modified")
197197+ shared.AssertNoError(t, err, "Expected no error when created is before modified")
197198 })
198199199200 t.Run("Succeeds with valid optional fields", func(t *testing.T) {
···201202 article.Date = "2024-01-01"
202203 article.Author = "Test Author"
203204 err := repo.Validate(article)
204204- AssertNoError(t, err, "Expected no error with valid optional fields")
205205+ shared.AssertNoError(t, err, "Expected no error with valid optional fields")
205206 })
206207207208 t.Run("Succeeds with empty optional fields", func(t *testing.T) {
···209210 article.Date = ""
210211 article.Author = ""
211212 err := repo.Validate(article)
212212- AssertNoError(t, err, "Expected no error with empty optional fields")
213213+ shared.AssertNoError(t, err, "Expected no error with empty optional fields")
213214 })
214215 })
215216···221222 t.Run("Successfully retrieves article by URL", func(t *testing.T) {
222223 original := CreateSampleArticle()
223224 _, err := repo.Create(ctx, original)
224224- AssertNoError(t, err, "Failed to create article")
225225+ shared.AssertNoError(t, err, "Failed to create article")
225226226227 retrieved, err := repo.GetByURL(ctx, original.URL)
227227- AssertNoError(t, err, "Failed to get article by URL")
228228- AssertEqual(t, original.ID, retrieved.ID, "ID mismatch")
229229- AssertEqual(t, original.URL, retrieved.URL, "URL mismatch")
230230- AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
228228+ shared.AssertNoError(t, err, "Failed to get article by URL")
229229+ shared.AssertEqual(t, original.ID, retrieved.ID, "ID mismatch")
230230+ shared.AssertEqual(t, original.URL, retrieved.URL, "URL mismatch")
231231+ shared.AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
231232 })
232233233234 t.Run("Fails when URL not found", func(t *testing.T) {
234235 nonexistent := "https://example.com/nonexistent"
235236 _, err := repo.GetByURL(ctx, nonexistent)
236236- AssertError(t, err, "Expected error when getting article by non-existent URL")
237237- AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
237237+ shared.AssertError(t, err, "Expected error when getting article by non-existent URL")
238238+ shared.AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
238239 })
239240 })
240241···272273273274 for _, article := range articles {
274275 _, err := repo.Create(ctx, article)
275275- AssertNoError(t, err, "Failed to create test article")
276276+ shared.AssertNoError(t, err, "Failed to create test article")
276277 }
277278278279 t.Run("List all articles", func(t *testing.T) {
279280 results, err := repo.List(ctx, nil)
280280- AssertNoError(t, err, "Failed to list all articles")
281281- AssertEqual(t, 3, len(results), "Expected 3 articles")
281281+ shared.AssertNoError(t, err, "Failed to list all articles")
282282+ shared.AssertEqual(t, 3, len(results), "Expected 3 articles")
282283 })
283284284285 t.Run("Filter by title", func(t *testing.T) {
285286 opts := &ArticleListOptions{Title: "Important"}
286287 results, err := repo.List(ctx, opts)
287287- AssertNoError(t, err, "Failed to list articles by title")
288288- AssertEqual(t, 1, len(results), "Expected 1 article matching title")
289289- AssertEqual(t, "Important Article", results[0].Title, "Wrong article returned")
288288+ shared.AssertNoError(t, err, "Failed to list articles by title")
289289+ shared.AssertEqual(t, 1, len(results), "Expected 1 article matching title")
290290+ shared.AssertEqual(t, "Important Article", results[0].Title, "Wrong article returned")
290291 })
291292292293 t.Run("Filter by author", func(t *testing.T) {
293294 opts := &ArticleListOptions{Author: "John Doe"}
294295 results, err := repo.List(ctx, opts)
295295- AssertNoError(t, err, "Failed to list articles by author")
296296- AssertEqual(t, 2, len(results), "Expected 2 articles by John Doe")
296296+ shared.AssertNoError(t, err, "Failed to list articles by author")
297297+ shared.AssertEqual(t, 2, len(results), "Expected 2 articles by John Doe")
297298 })
298299299300 t.Run("Filter by URL", func(t *testing.T) {
300301 opts := &ArticleListOptions{URL: "different.com"}
301302 results, err := repo.List(ctx, opts)
302302- AssertNoError(t, err, "Failed to list articles by URL")
303303- AssertEqual(t, 1, len(results), "Expected 1 article from different.com")
303303+ shared.AssertNoError(t, err, "Failed to list articles by URL")
304304+ shared.AssertEqual(t, 1, len(results), "Expected 1 article from different.com")
304305 })
305306306307 t.Run("Filter by date range", func(t *testing.T) {
307308 opts := &ArticleListOptions{DateFrom: "2024-01-02", DateTo: "2024-01-03"}
308309 results, err := repo.List(ctx, opts)
309309- AssertNoError(t, err, "Failed to list articles by date range")
310310- AssertEqual(t, 2, len(results), "Expected 2 articles in date range")
310310+ shared.AssertNoError(t, err, "Failed to list articles by date range")
311311+ shared.AssertEqual(t, 2, len(results), "Expected 2 articles in date range")
311312 })
312313313314 t.Run("With limit", func(t *testing.T) {
314315 opts := &ArticleListOptions{Limit: 2}
315316 results, err := repo.List(ctx, opts)
316316- AssertNoError(t, err, "Failed to list articles with limit")
317317- AssertEqual(t, 2, len(results), "Expected 2 articles due to limit")
317317+ shared.AssertNoError(t, err, "Failed to list articles with limit")
318318+ shared.AssertEqual(t, 2, len(results), "Expected 2 articles due to limit")
318319 })
319320320321 t.Run("With limit and offset", func(t *testing.T) {
321322 opts := &ArticleListOptions{Limit: 2, Offset: 1}
322323 results, err := repo.List(ctx, opts)
323323- AssertNoError(t, err, "Failed to list articles with limit and offset")
324324- AssertEqual(t, 2, len(results), "Expected 2 articles due to limit")
324324+ shared.AssertNoError(t, err, "Failed to list articles with limit and offset")
325325+ shared.AssertEqual(t, 2, len(results), "Expected 2 articles due to limit")
325326 })
326327327328 t.Run("Multiple filters", func(t *testing.T) {
328329 opts := &ArticleListOptions{Author: "John Doe", DateFrom: "2024-01-02"}
329330 results, err := repo.List(ctx, opts)
330330- AssertNoError(t, err, "Failed to list articles with multiple filters")
331331- AssertEqual(t, 1, len(results), "Expected 1 article matching all filters")
332332- AssertEqual(t, "Important Article", results[0].Title, "Wrong article returned")
331331+ shared.AssertNoError(t, err, "Failed to list articles with multiple filters")
332332+ shared.AssertEqual(t, 1, len(results), "Expected 1 article matching all filters")
333333+ shared.AssertEqual(t, "Important Article", results[0].Title, "Wrong article returned")
333334 })
334335335336 t.Run("No results", func(t *testing.T) {
336337 opts := &ArticleListOptions{Title: "Nonexistent"}
337338 results, err := repo.List(ctx, opts)
338338- AssertNoError(t, err, "Failed to list articles")
339339- AssertEqual(t, 0, len(results), "Expected no articles")
339339+ shared.AssertNoError(t, err, "Failed to list articles")
340340+ shared.AssertEqual(t, 0, len(results), "Expected no articles")
340341 })
341342 })
342343···359360360361 for _, article := range articles {
361362 _, err := repo.Create(ctx, article)
362362- AssertNoError(t, err, "Failed to create test article")
363363+ shared.AssertNoError(t, err, "Failed to create test article")
363364 }
364365365366 t.Run("Count all articles", func(t *testing.T) {
366367 count, err := repo.Count(ctx, nil)
367367- AssertNoError(t, err, "Failed to count articles")
368368- AssertEqual(t, int64(2), count, "Expected 2 articles")
368368+ shared.AssertNoError(t, err, "Failed to count articles")
369369+ shared.AssertEqual(t, int64(2), count, "Expected 2 articles")
369370 })
370371371372 t.Run("Count with filter", func(t *testing.T) {
372373 opts := &ArticleListOptions{Author: "Test Author"}
373374 count, err := repo.Count(ctx, opts)
374374- AssertNoError(t, err, "Failed to count articles with filter")
375375- AssertEqual(t, int64(1), count, "Expected 1 article by Test Author")
375375+ shared.AssertNoError(t, err, "Failed to count articles with filter")
376376+ shared.AssertEqual(t, int64(1), count, "Expected 1 article by Test Author")
376377 })
377378378379 t.Run("Count with no results", func(t *testing.T) {
379380 opts := &ArticleListOptions{Title: "Nonexistent"}
380381 count, err := repo.Count(ctx, opts)
381381- AssertNoError(t, err, "Failed to count articles")
382382- AssertEqual(t, int64(0), count, "Expected 0 articles")
382382+ shared.AssertNoError(t, err, "Failed to count articles")
383383+ shared.AssertEqual(t, int64(0), count, "Expected 0 articles")
383384 })
384385 })
385386···390391391392 article := CreateSampleArticle()
392393 id, err := repo.Create(ctx, article)
393393- AssertNoError(t, err, "Failed to create article")
394394+ shared.AssertNoError(t, err, "Failed to create article")
394395395396 t.Run("Create with cancelled context", func(t *testing.T) {
396397 newArticle := CreateSampleArticle()
···437438438439 t.Run("Get non-existent article", func(t *testing.T) {
439440 _, err := repo.Get(ctx, 99999)
440440- AssertError(t, err, "Expected error for non-existent article")
441441- AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
441441+ shared.AssertError(t, err, "Expected error for non-existent article")
442442+ shared.AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
442443 })
443444444445 t.Run("Update non-existent article", func(t *testing.T) {
445446 article := CreateSampleArticle()
446447 article.ID = 99999
447448 err := repo.Update(ctx, article)
448448- AssertError(t, err, "Expected error when updating non-existent article")
449449- AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
449449+ shared.AssertError(t, err, "Expected error when updating non-existent article")
450450+ shared.AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
450451 })
451452452453 t.Run("Delete non-existent article", func(t *testing.T) {
453454 err := repo.Delete(ctx, 99999)
454454- AssertError(t, err, "Expected error when deleting non-existent article")
455455- AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
455455+ shared.AssertError(t, err, "Expected error when deleting non-existent article")
456456+ shared.AssertContains(t, err.Error(), "not found", "Expected 'not found' in error message")
456457 })
457458458459 t.Run("Update validation - remove required title", func(t *testing.T) {
···461462462463 article := CreateSampleArticle()
463464 _, err := repo.Create(ctx, article)
464464- AssertNoError(t, err, "Failed to create article")
465465+ shared.AssertNoError(t, err, "Failed to create article")
465466466467 article.Title = ""
467468 err = repo.Update(ctx, article)
468468- AssertError(t, err, "Expected error when updating article with empty title")
469469+ shared.AssertError(t, err, "Expected error when updating article with empty title")
469470 })
470471471472 t.Run("Update validation - invalid URL format", func(t *testing.T) {
···474475475476 article := CreateSampleArticle()
476477 _, err := repo.Create(ctx, article)
477477- AssertNoError(t, err, "Failed to create article")
478478+ shared.AssertNoError(t, err, "Failed to create article")
478479479480 article.URL = "not-a-valid-url"
480481 err = repo.Update(ctx, article)
481481- AssertError(t, err, "Expected error when updating article with invalid URL format")
482482- AssertContains(t, err.Error(), "URL", "Expected URL format validation error")
482482+ shared.AssertError(t, err, "Expected error when updating article with invalid URL format")
483483+ shared.AssertContains(t, err.Error(), "URL", "Expected URL format validation error")
483484 })
484485485486 t.Run("Update validation - invalid date format", func(t *testing.T) {
···488489489490 article := CreateSampleArticle()
490491 _, err := repo.Create(ctx, article)
491491- AssertNoError(t, err, "Failed to create article")
492492+ shared.AssertNoError(t, err, "Failed to create article")
492493493494 article.Date = "invalid-date"
494495 err = repo.Update(ctx, article)
495495- AssertError(t, err, "Expected error when updating article with invalid date format")
496496- AssertContains(t, err.Error(), "Date", "Expected date validation error")
496496+ shared.AssertError(t, err, "Expected error when updating article with invalid date format")
497497+ shared.AssertContains(t, err.Error(), "Date", "Expected date validation error")
497498 })
498499499500 t.Run("Update validation - title too long", func(t *testing.T) {
···502503503504 article := CreateSampleArticle()
504505 _, err := repo.Create(ctx, article)
505505- AssertNoError(t, err, "Failed to create article")
506506+ shared.AssertNoError(t, err, "Failed to create article")
506507507508 article.Title = strings.Repeat("a", 501)
508509 err = repo.Update(ctx, article)
509509- AssertError(t, err, "Expected error when updating article with title too long")
510510- AssertContains(t, err.Error(), "Title", "Expected title length validation error")
510510+ shared.AssertError(t, err, "Expected error when updating article with title too long")
511511+ shared.AssertContains(t, err.Error(), "Title", "Expected title length validation error")
511512 })
512513513514 t.Run("Update validation - author too long", func(t *testing.T) {
···516517517518 article := CreateSampleArticle()
518519 _, err := repo.Create(ctx, article)
519519- AssertNoError(t, err, "Failed to create article")
520520+ shared.AssertNoError(t, err, "Failed to create article")
520521521522 article.Author = strings.Repeat("a", 201)
522523 err = repo.Update(ctx, article)
523523- AssertError(t, err, "Expected error when updating article with author too long")
524524- AssertContains(t, err.Error(), "Author", "Expected author length validation error")
524524+ shared.AssertError(t, err, "Expected error when updating article with author too long")
525525+ shared.AssertContains(t, err.Error(), "Author", "Expected author length validation error")
525526 })
526527527528 t.Run("Update validation - remove markdown path", func(t *testing.T) {
···530531531532 article := CreateSampleArticle()
532533 _, err := repo.Create(ctx, article)
533533- AssertNoError(t, err, "Failed to create article")
534534+ shared.AssertNoError(t, err, "Failed to create article")
534535535536 article.MarkdownPath = ""
536537 err = repo.Update(ctx, article)
537537- AssertError(t, err, "Expected error when updating article with empty markdown path")
538538- AssertContains(t, err.Error(), "MarkdownPath", "Expected MarkdownPath validation error")
538538+ shared.AssertError(t, err, "Expected error when updating article with empty markdown path")
539539+ shared.AssertContains(t, err.Error(), "MarkdownPath", "Expected MarkdownPath validation error")
539540 })
540541541542 t.Run("Update validation - remove HTML path", func(t *testing.T) {
···544545545546 article := CreateSampleArticle()
546547 _, err := repo.Create(ctx, article)
547547- AssertNoError(t, err, "Failed to create article")
548548+ shared.AssertNoError(t, err, "Failed to create article")
548549549550 article.HTMLPath = ""
550551 err = repo.Update(ctx, article)
551551- AssertError(t, err, "Expected error when updating article with empty HTML path")
552552- AssertContains(t, err.Error(), "HTMLPath", "Expected HTMLPath validation error")
552552+ shared.AssertError(t, err, "Expected error when updating article with empty HTML path")
553553+ shared.AssertContains(t, err.Error(), "HTMLPath", "Expected HTMLPath validation error")
553554 })
554555555556 t.Run("List with no results", func(t *testing.T) {
556557 opts := &ArticleListOptions{Author: "NonExistentAuthor"}
557558 articles, err := repo.List(ctx, opts)
558558- AssertNoError(t, err, "Should not error when no articles found")
559559- AssertEqual(t, 0, len(articles), "Expected empty result set")
559559+ shared.AssertNoError(t, err, "Should not error when no articles found")
560560+ shared.AssertEqual(t, 0, len(articles), "Expected empty result set")
560561 })
561562 })
562563}
+54-53
internal/repo/base_media_repository_test.go
···6677 _ "github.com/mattn/go-sqlite3"
88 "github.com/stormlightlabs/noteleaf/internal/models"
99+ "github.com/stormlightlabs/noteleaf/internal/shared"
910)
10111112func TestBaseMediaRepository(t *testing.T) {
···2324 }
24252526 id, err := repo.Create(ctx, book)
2626- AssertNoError(t, err, "Failed to create book")
2727- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2727+ shared.AssertNoError(t, err, "Failed to create book")
2828+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
28292930 retrieved, err := repo.Get(ctx, id)
3030- AssertNoError(t, err, "Failed to get book")
3131- AssertEqual(t, book.Title, retrieved.Title, "Title mismatch")
3232- AssertEqual(t, book.Author, retrieved.Author, "Author mismatch")
3333- AssertEqual(t, book.Status, retrieved.Status, "Status mismatch")
3131+ shared.AssertNoError(t, err, "Failed to get book")
3232+ shared.AssertEqual(t, book.Title, retrieved.Title, "Title mismatch")
3333+ shared.AssertEqual(t, book.Author, retrieved.Author, "Author mismatch")
3434+ shared.AssertEqual(t, book.Status, retrieved.Status, "Status mismatch")
3435 })
35363637 t.Run("Update", func(t *testing.T) {
···4445 }
45464647 id, err := repo.Create(ctx, book)
4747- AssertNoError(t, err, "Failed to create book")
4848+ shared.AssertNoError(t, err, "Failed to create book")
48494950 book.Title = "Updated Title"
5051 book.Author = "Updated Author"
5152 book.Status = "reading"
52535354 err = repo.Update(ctx, book)
5454- AssertNoError(t, err, "Failed to update book")
5555+ shared.AssertNoError(t, err, "Failed to update book")
55565657 retrieved, err := repo.Get(ctx, id)
5757- AssertNoError(t, err, "Failed to get updated book")
5858- AssertEqual(t, "Updated Title", retrieved.Title, "Title not updated")
5959- AssertEqual(t, "Updated Author", retrieved.Author, "Author not updated")
6060- AssertEqual(t, "reading", retrieved.Status, "Status not updated")
5858+ shared.AssertNoError(t, err, "Failed to get updated book")
5959+ shared.AssertEqual(t, "Updated Title", retrieved.Title, "Title not updated")
6060+ shared.AssertEqual(t, "Updated Author", retrieved.Author, "Author not updated")
6161+ shared.AssertEqual(t, "reading", retrieved.Status, "Status not updated")
6162 })
62636364 t.Run("Delete", func(t *testing.T) {
···7071 }
71727273 id, err := repo.Create(ctx, book)
7373- AssertNoError(t, err, "Failed to create book")
7474+ shared.AssertNoError(t, err, "Failed to create book")
74757576 err = repo.Delete(ctx, id)
7676- AssertNoError(t, err, "Failed to delete book")
7777+ shared.AssertNoError(t, err, "Failed to delete book")
77787879 _, err = repo.Get(ctx, id)
7979- AssertError(t, err, "Expected error when getting deleted book")
8080+ shared.AssertError(t, err, "Expected error when getting deleted book")
8081 })
81828283 t.Run("Get non-existent", func(t *testing.T) {
···8485 repo := NewBookRepository(db)
85868687 _, err := repo.Get(ctx, 9999)
8787- AssertError(t, err, "Expected error for non-existent book")
8888- AssertContains(t, err.Error(), "not found", "Error should mention 'not found'")
8888+ shared.AssertError(t, err, "Expected error for non-existent book")
8989+ shared.AssertContains(t, err.Error(), "not found", "Error should mention 'not found'")
8990 })
90919192 t.Run("ListQuery with multiple books", func(t *testing.T) {
···100101101102 for _, book := range books {
102103 _, err := repo.Create(ctx, book)
103103- AssertNoError(t, err, "Failed to create book")
104104+ shared.AssertNoError(t, err, "Failed to create book")
104105 }
105106106107 allBooks, err := repo.List(ctx, BookListOptions{})
107107- AssertNoError(t, err, "Failed to list books")
108108+ shared.AssertNoError(t, err, "Failed to list books")
108109 if len(allBooks) != 3 {
109110 t.Errorf("Expected 3 books, got %d", len(allBooks))
110111 }
···120121 Status: "queued",
121122 }
122123 _, err := repo.Create(ctx, book)
123123- AssertNoError(t, err, "Failed to create book")
124124+ shared.AssertNoError(t, err, "Failed to create book")
124125 }
125126126127 count, err := repo.Count(ctx, BookListOptions{})
127127- AssertNoError(t, err, "Failed to count books")
128128+ shared.AssertNoError(t, err, "Failed to count books")
128129 if count != 5 {
129130 t.Errorf("Expected count of 5, got %d", count)
130131 }
···143144 }
144145145146 id, err := repo.Create(ctx, movie)
146146- AssertNoError(t, err, "Failed to create movie")
147147- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
147147+ shared.AssertNoError(t, err, "Failed to create movie")
148148+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
148149149150 retrieved, err := repo.Get(ctx, id)
150150- AssertNoError(t, err, "Failed to get movie")
151151- AssertEqual(t, movie.Title, retrieved.Title, "Title mismatch")
152152- AssertEqual(t, movie.Year, retrieved.Year, "Year mismatch")
153153- AssertEqual(t, movie.Status, retrieved.Status, "Status mismatch")
151151+ shared.AssertNoError(t, err, "Failed to get movie")
152152+ shared.AssertEqual(t, movie.Title, retrieved.Title, "Title mismatch")
153153+ shared.AssertEqual(t, movie.Year, retrieved.Year, "Year mismatch")
154154+ shared.AssertEqual(t, movie.Status, retrieved.Status, "Status mismatch")
154155 })
155156156157 t.Run("Update", func(t *testing.T) {
···164165 }
165166166167 id, err := repo.Create(ctx, movie)
167167- AssertNoError(t, err, "Failed to create movie")
168168+ shared.AssertNoError(t, err, "Failed to create movie")
168169169170 movie.Title = "Updated Movie"
170171 movie.Year = 2023
171172 movie.Status = "watched"
172173173174 err = repo.Update(ctx, movie)
174174- AssertNoError(t, err, "Failed to update movie")
175175+ shared.AssertNoError(t, err, "Failed to update movie")
175176176177 retrieved, err := repo.Get(ctx, id)
177177- AssertNoError(t, err, "Failed to get updated movie")
178178- AssertEqual(t, "Updated Movie", retrieved.Title, "Title not updated")
179179- AssertEqual(t, 2023, retrieved.Year, "Year not updated")
180180- AssertEqual(t, "watched", retrieved.Status, "Status not updated")
178178+ shared.AssertNoError(t, err, "Failed to get updated movie")
179179+ shared.AssertEqual(t, "Updated Movie", retrieved.Title, "Title not updated")
180180+ shared.AssertEqual(t, 2023, retrieved.Year, "Year not updated")
181181+ shared.AssertEqual(t, "watched", retrieved.Status, "Status not updated")
181182 })
182183183184 t.Run("Delete", func(t *testing.T) {
···190191 }
191192192193 id, err := repo.Create(ctx, movie)
193193- AssertNoError(t, err, "Failed to create movie")
194194+ shared.AssertNoError(t, err, "Failed to create movie")
194195195196 err = repo.Delete(ctx, id)
196196- AssertNoError(t, err, "Failed to delete movie")
197197+ shared.AssertNoError(t, err, "Failed to delete movie")
197198198199 _, err = repo.Get(ctx, id)
199199- AssertError(t, err, "Expected error when getting deleted movie")
200200+ shared.AssertError(t, err, "Expected error when getting deleted movie")
200201 })
201202 })
202203···213214 }
214215215216 id, err := repo.Create(ctx, show)
216216- AssertNoError(t, err, "Failed to create TV show")
217217- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
217217+ shared.AssertNoError(t, err, "Failed to create TV show")
218218+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
218219219220 retrieved, err := repo.Get(ctx, id)
220220- AssertNoError(t, err, "Failed to get TV show")
221221- AssertEqual(t, show.Title, retrieved.Title, "Title mismatch")
222222- AssertEqual(t, show.Season, retrieved.Season, "Season mismatch")
223223- AssertEqual(t, show.Episode, retrieved.Episode, "Episode mismatch")
224224- AssertEqual(t, show.Status, retrieved.Status, "Status mismatch")
221221+ shared.AssertNoError(t, err, "Failed to get TV show")
222222+ shared.AssertEqual(t, show.Title, retrieved.Title, "Title mismatch")
223223+ shared.AssertEqual(t, show.Season, retrieved.Season, "Season mismatch")
224224+ shared.AssertEqual(t, show.Episode, retrieved.Episode, "Episode mismatch")
225225+ shared.AssertEqual(t, show.Status, retrieved.Status, "Status mismatch")
225226 })
226227227228 t.Run("Update", func(t *testing.T) {
···236237 }
237238238239 id, err := repo.Create(ctx, show)
239239- AssertNoError(t, err, "Failed to create TV show")
240240+ shared.AssertNoError(t, err, "Failed to create TV show")
240241241242 show.Title = "Updated Show"
242243 show.Season = 2
···244245 show.Status = "watching"
245246246247 err = repo.Update(ctx, show)
247247- AssertNoError(t, err, "Failed to update TV show")
248248+ shared.AssertNoError(t, err, "Failed to update TV show")
248249249250 retrieved, err := repo.Get(ctx, id)
250250- AssertNoError(t, err, "Failed to get updated TV show")
251251- AssertEqual(t, "Updated Show", retrieved.Title, "Title not updated")
252252- AssertEqual(t, 2, retrieved.Season, "Season not updated")
253253- AssertEqual(t, 5, retrieved.Episode, "Episode not updated")
254254- AssertEqual(t, "watching", retrieved.Status, "Status not updated")
251251+ shared.AssertNoError(t, err, "Failed to get updated TV show")
252252+ shared.AssertEqual(t, "Updated Show", retrieved.Title, "Title not updated")
253253+ shared.AssertEqual(t, 2, retrieved.Season, "Season not updated")
254254+ shared.AssertEqual(t, 5, retrieved.Episode, "Episode not updated")
255255+ shared.AssertEqual(t, "watching", retrieved.Status, "Status not updated")
255256 })
256257257258 t.Run("Delete", func(t *testing.T) {
···264265 }
265266266267 id, err := repo.Create(ctx, show)
267267- AssertNoError(t, err, "Failed to create TV show")
268268+ shared.AssertNoError(t, err, "Failed to create TV show")
268269269270 err = repo.Delete(ctx, id)
270270- AssertNoError(t, err, "Failed to delete TV show")
271271+ shared.AssertNoError(t, err, "Failed to delete TV show")
271272272273 _, err = repo.Get(ctx, id)
273273- AssertError(t, err, "Expected error when getting deleted TV show")
274274+ shared.AssertError(t, err, "Expected error when getting deleted TV show")
274275 })
275276 })
276277
+97-96
internal/repo/book_repository_test.go
···7788 _ "github.com/mattn/go-sqlite3"
99 "github.com/stormlightlabs/noteleaf/internal/models"
1010+ "github.com/stormlightlabs/noteleaf/internal/shared"
1011)
11121213func TestBookRepository(t *testing.T) {
···1920 book := CreateSampleBook()
20212122 id, err := repo.Create(ctx, book)
2222- AssertNoError(t, err, "Failed to create book")
2323- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2424- AssertEqual(t, id, book.ID, "Expected book ID to be set correctly")
2525- AssertFalse(t, book.Added.IsZero(), "Expected Added timestamp to be set")
2323+ shared.AssertNoError(t, err, "Failed to create book")
2424+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2525+ shared.AssertEqual(t, id, book.ID, "Expected book ID to be set correctly")
2626+ shared.AssertFalse(t, book.Added.IsZero(), "Expected Added timestamp to be set")
2627 })
27282829 t.Run("Get Book", func(t *testing.T) {
2930 original := CreateSampleBook()
3031 id, err := repo.Create(ctx, original)
3131- AssertNoError(t, err, "Failed to create book")
3232+ shared.AssertNoError(t, err, "Failed to create book")
32333334 retrieved, err := repo.Get(ctx, id)
3434- AssertNoError(t, err, "Failed to get book")
3535+ shared.AssertNoError(t, err, "Failed to get book")
35363636- AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
3737- AssertEqual(t, original.Author, retrieved.Author, "Author mismatch")
3838- AssertEqual(t, original.Status, retrieved.Status, "Status mismatch")
3939- AssertEqual(t, original.Progress, retrieved.Progress, "Progress mismatch")
4040- AssertEqual(t, original.Pages, retrieved.Pages, "Pages mismatch")
4141- AssertEqual(t, original.Rating, retrieved.Rating, "Rating mismatch")
4242- AssertEqual(t, original.Notes, retrieved.Notes, "Notes mismatch")
3737+ shared.AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
3838+ shared.AssertEqual(t, original.Author, retrieved.Author, "Author mismatch")
3939+ shared.AssertEqual(t, original.Status, retrieved.Status, "Status mismatch")
4040+ shared.AssertEqual(t, original.Progress, retrieved.Progress, "Progress mismatch")
4141+ shared.AssertEqual(t, original.Pages, retrieved.Pages, "Pages mismatch")
4242+ shared.AssertEqual(t, original.Rating, retrieved.Rating, "Rating mismatch")
4343+ shared.AssertEqual(t, original.Notes, retrieved.Notes, "Notes mismatch")
4344 })
44454546 t.Run("Update Book", func(t *testing.T) {
4647 book := CreateSampleBook()
4748 id, err := repo.Create(ctx, book)
4848- AssertNoError(t, err, "Failed to create book")
4949+ shared.AssertNoError(t, err, "Failed to create book")
49505051 book.Title = "Updated Book"
5152 book.Status = "reading"
···5556 book.Started = &now
56575758 err = repo.Update(ctx, book)
5858- AssertNoError(t, err, "Failed to update book")
5959+ shared.AssertNoError(t, err, "Failed to update book")
59606061 updated, err := repo.Get(ctx, id)
6161- AssertNoError(t, err, "Failed to get updated book")
6262+ shared.AssertNoError(t, err, "Failed to get updated book")
62636363- AssertEqual(t, "Updated Book", updated.Title, "Expected updated title")
6464- AssertEqual(t, "reading", updated.Status, "Expected reading status")
6565- AssertEqual(t, 50, updated.Progress, "Expected progress 50")
6666- AssertEqual(t, 5.0, updated.Rating, "Expected rating 5.0")
6767- AssertTrue(t, updated.Started != nil, "Expected started time to be set")
6464+ shared.AssertEqual(t, "Updated Book", updated.Title, "Expected updated title")
6565+ shared.AssertEqual(t, "reading", updated.Status, "Expected reading status")
6666+ shared.AssertEqual(t, 50, updated.Progress, "Expected progress 50")
6767+ shared.AssertEqual(t, 5.0, updated.Rating, "Expected rating 5.0")
6868+ shared.AssertTrue(t, updated.Started != nil, "Expected started time to be set")
6869 })
69707071 t.Run("Delete Book", func(t *testing.T) {
7172 book := CreateSampleBook()
7273 id, err := repo.Create(ctx, book)
7373- AssertNoError(t, err, "Failed to create book")
7474+ shared.AssertNoError(t, err, "Failed to create book")
74757576 err = repo.Delete(ctx, id)
7676- AssertNoError(t, err, "Failed to delete book")
7777+ shared.AssertNoError(t, err, "Failed to delete book")
77787879 _, err = repo.Get(ctx, id)
7979- AssertError(t, err, "Expected error when getting deleted book")
8080+ shared.AssertError(t, err, "Expected error when getting deleted book")
8081 })
8182 })
8283···94959596 for _, book := range books {
9697 _, err := repo.Create(ctx, book)
9797- AssertNoError(t, err, "Failed to create book")
9898+ shared.AssertNoError(t, err, "Failed to create book")
9899 }
99100100101 t.Run("List All Books", func(t *testing.T) {
101102 results, err := repo.List(ctx, BookListOptions{})
102102- AssertNoError(t, err, "Failed to list books")
103103- AssertEqual(t, 4, len(results), "Expected 4 books")
103103+ shared.AssertNoError(t, err, "Failed to list books")
104104+ shared.AssertEqual(t, 4, len(results), "Expected 4 books")
104105 })
105106106107 t.Run("List Books with Status Filter", func(t *testing.T) {
107108 results, err := repo.List(ctx, BookListOptions{Status: "queued"})
108108- AssertNoError(t, err, "Failed to list books")
109109- AssertEqual(t, 2, len(results), "Expected 2 queued books")
109109+ shared.AssertNoError(t, err, "Failed to list books")
110110+ shared.AssertEqual(t, 2, len(results), "Expected 2 queued books")
110111111112 for _, book := range results {
112112- AssertEqual(t, "queued", book.Status, "Expected queued status")
113113+ shared.AssertEqual(t, "queued", book.Status, "Expected queued status")
113114 }
114115 })
115116116117 t.Run("List Books by Author", func(t *testing.T) {
117118 results, err := repo.List(ctx, BookListOptions{Author: "Author A"})
118118- AssertNoError(t, err, "Failed to list books")
119119- AssertEqual(t, 2, len(results), "Expected 2 books by Author A")
119119+ shared.AssertNoError(t, err, "Failed to list books")
120120+ shared.AssertEqual(t, 2, len(results), "Expected 2 books by Author A")
120121121122 for _, book := range results {
122122- AssertEqual(t, "Author A", book.Author, "Expected author 'Author A'")
123123+ shared.AssertEqual(t, "Author A", book.Author, "Expected author 'Author A'")
123124 }
124125 })
125126126127 t.Run("List Books with Progress Filter", func(t *testing.T) {
127128 results, err := repo.List(ctx, BookListOptions{MinProgress: 50})
128128- AssertNoError(t, err, "Failed to list books")
129129- AssertEqual(t, 2, len(results), "Expected 2 books with progress >= 50")
129129+ shared.AssertNoError(t, err, "Failed to list books")
130130+ shared.AssertEqual(t, 2, len(results), "Expected 2 books with progress >= 50")
130131131132 for _, book := range results {
132132- AssertTrue(t, book.Progress >= 50, "Expected progress >= 50")
133133+ shared.AssertTrue(t, book.Progress >= 50, "Expected progress >= 50")
133134 }
134135 })
135136136137 t.Run("List Books with Rating Filter", func(t *testing.T) {
137138 results, err := repo.List(ctx, BookListOptions{MinRating: 4.5})
138138- AssertNoError(t, err, "Failed to list books")
139139- AssertEqual(t, 2, len(results), "Expected 2 books with rating >= 4.5")
139139+ shared.AssertNoError(t, err, "Failed to list books")
140140+ shared.AssertEqual(t, 2, len(results), "Expected 2 books with rating >= 4.5")
140141141142 for _, book := range results {
142142- AssertTrue(t, book.Rating >= 4.5, "Expected rating >= 4.5")
143143+ shared.AssertTrue(t, book.Rating >= 4.5, "Expected rating >= 4.5")
143144 }
144145 })
145146146147 t.Run("List Books with Search", func(t *testing.T) {
147148 results, err := repo.List(ctx, BookListOptions{Search: "Book 1"})
148148- AssertNoError(t, err, "Failed to list books")
149149- AssertEqual(t, 1, len(results), "Expected 1 book matching search")
149149+ shared.AssertNoError(t, err, "Failed to list books")
150150+ shared.AssertEqual(t, 1, len(results), "Expected 1 book matching search")
150151151152 if len(results) > 0 {
152152- AssertEqual(t, "Book 1", results[0].Title, "Expected 'Book 1'")
153153+ shared.AssertEqual(t, "Book 1", results[0].Title, "Expected 'Book 1'")
153154 }
154155 })
155156156157 t.Run("List Books with Limit", func(t *testing.T) {
157158 results, err := repo.List(ctx, BookListOptions{Limit: 2})
158158- AssertNoError(t, err, "Failed to list books")
159159- AssertEqual(t, 2, len(results), "Expected 2 books due to limit")
159159+ shared.AssertNoError(t, err, "Failed to list books")
160160+ shared.AssertEqual(t, 2, len(results), "Expected 2 books due to limit")
160161 })
161162 })
162163···173174 var book1ID int64
174175 for _, book := range []*models.Book{book1, book2, book3, book4} {
175176 id, err := repo.Create(ctx, book)
176176- AssertNoError(t, err, "Failed to create book")
177177+ shared.AssertNoError(t, err, "Failed to create book")
177178 if book == book1 {
178179 book1ID = id
179180 }
···181182182183 t.Run("GetQueued", func(t *testing.T) {
183184 results, err := repo.GetQueued(ctx)
184184- AssertNoError(t, err, "Failed to get queued books")
185185- AssertEqual(t, 2, len(results), "Expected 2 queued books")
185185+ shared.AssertNoError(t, err, "Failed to get queued books")
186186+ shared.AssertEqual(t, 2, len(results), "Expected 2 queued books")
186187187188 for _, book := range results {
188188- AssertEqual(t, "queued", book.Status, "Expected queued status")
189189+ shared.AssertEqual(t, "queued", book.Status, "Expected queued status")
189190 }
190191 })
191192192193 t.Run("GetReading", func(t *testing.T) {
193194 results, err := repo.GetReading(ctx)
194194- AssertNoError(t, err, "Failed to get reading books")
195195- AssertEqual(t, 1, len(results), "Expected 1 reading book")
195195+ shared.AssertNoError(t, err, "Failed to get reading books")
196196+ shared.AssertEqual(t, 1, len(results), "Expected 1 reading book")
196197197198 if len(results) > 0 {
198198- AssertEqual(t, "reading", results[0].Status, "Expected reading status")
199199+ shared.AssertEqual(t, "reading", results[0].Status, "Expected reading status")
199200 }
200201 })
201202202203 t.Run("GetFinished", func(t *testing.T) {
203204 results, err := repo.GetFinished(ctx)
204204- AssertNoError(t, err, "Failed to get finished books")
205205- AssertEqual(t, 1, len(results), "Expected 1 finished book")
205205+ shared.AssertNoError(t, err, "Failed to get finished books")
206206+ shared.AssertEqual(t, 1, len(results), "Expected 1 finished book")
206207207208 if len(results) > 0 {
208208- AssertEqual(t, "finished", results[0].Status, "Expected finished status")
209209+ shared.AssertEqual(t, "finished", results[0].Status, "Expected finished status")
209210 }
210211 })
211212212213 t.Run("GetByAuthor", func(t *testing.T) {
213214 results, err := repo.GetByAuthor(ctx, "Author A")
214214- AssertNoError(t, err, "Failed to get books by author")
215215- AssertEqual(t, 2, len(results), "Expected 2 books by Author A")
215215+ shared.AssertNoError(t, err, "Failed to get books by author")
216216+ shared.AssertEqual(t, 2, len(results), "Expected 2 books by Author A")
216217217218 for _, book := range results {
218218- AssertEqual(t, "Author A", book.Author, "Expected author 'Author A'")
219219+ shared.AssertEqual(t, "Author A", book.Author, "Expected author 'Author A'")
219220 }
220221 })
221222222223 t.Run("StartReading", func(t *testing.T) {
223224 err := repo.StartReading(ctx, book1ID)
224224- AssertNoError(t, err, "Failed to start reading book")
225225+ shared.AssertNoError(t, err, "Failed to start reading book")
225226226227 updated, err := repo.Get(ctx, book1ID)
227227- AssertNoError(t, err, "Failed to get updated book")
228228+ shared.AssertNoError(t, err, "Failed to get updated book")
228229229229- AssertEqual(t, "reading", updated.Status, "Expected status to be reading")
230230- AssertTrue(t, updated.Started != nil, "Expected started timestamp to be set")
230230+ shared.AssertEqual(t, "reading", updated.Status, "Expected status to be reading")
231231+ shared.AssertTrue(t, updated.Started != nil, "Expected started timestamp to be set")
231232 })
232233233234 t.Run("FinishReading", func(t *testing.T) {
234235 newBook := &models.Book{Title: "New Book", Status: "reading", Progress: 80}
235236 id, err := repo.Create(ctx, newBook)
236236- AssertNoError(t, err, "Failed to create new book")
237237+ shared.AssertNoError(t, err, "Failed to create new book")
237238238239 err = repo.FinishReading(ctx, id)
239239- AssertNoError(t, err, "Failed to finish reading book")
240240+ shared.AssertNoError(t, err, "Failed to finish reading book")
240241241242 updated, err := repo.Get(ctx, id)
242242- AssertNoError(t, err, "Failed to get updated book")
243243+ shared.AssertNoError(t, err, "Failed to get updated book")
243244244244- AssertEqual(t, "finished", updated.Status, "Expected status to be finished")
245245- AssertEqual(t, 100, updated.Progress, "Expected progress to be 100")
246246- AssertTrue(t, updated.Finished != nil, "Expected finished timestamp to be set")
245245+ shared.AssertEqual(t, "finished", updated.Status, "Expected status to be finished")
246246+ shared.AssertEqual(t, 100, updated.Progress, "Expected progress to be 100")
247247+ shared.AssertTrue(t, updated.Finished != nil, "Expected finished timestamp to be set")
247248 })
248249249250 t.Run("UpdateProgress", func(t *testing.T) {
250251 newBook := &models.Book{Title: "Progress Book", Status: "queued", Progress: 0}
251252 id, err := repo.Create(ctx, newBook)
252252- AssertNoError(t, err, "Failed to create new book")
253253+ shared.AssertNoError(t, err, "Failed to create new book")
253254254255 err = repo.UpdateProgress(ctx, id, 25)
255255- AssertNoError(t, err, "Failed to update progress")
256256+ shared.AssertNoError(t, err, "Failed to update progress")
256257257258 updated, err := repo.Get(ctx, id)
258258- AssertNoError(t, err, "Failed to get updated book")
259259+ shared.AssertNoError(t, err, "Failed to get updated book")
259260260260- AssertEqual(t, "reading", updated.Status, "Expected status to be reading when progress > 0")
261261- AssertEqual(t, 25, updated.Progress, "Expected progress 25")
262262- AssertTrue(t, updated.Started != nil, "Expected started timestamp to be set when progress > 0")
261261+ shared.AssertEqual(t, "reading", updated.Status, "Expected status to be reading when progress > 0")
262262+ shared.AssertEqual(t, 25, updated.Progress, "Expected progress 25")
263263+ shared.AssertTrue(t, updated.Started != nil, "Expected started timestamp to be set when progress > 0")
263264264265 err = repo.UpdateProgress(ctx, id, 100)
265265- AssertNoError(t, err, "Failed to update progress to 100")
266266+ shared.AssertNoError(t, err, "Failed to update progress to 100")
266267267268 updated, err = repo.Get(ctx, id)
268268- AssertNoError(t, err, "Failed to get updated book")
269269+ shared.AssertNoError(t, err, "Failed to get updated book")
269270270270- AssertEqual(t, "finished", updated.Status, "Expected status to be finished when progress = 100")
271271- AssertEqual(t, 100, updated.Progress, "Expected progress 100")
272272- AssertTrue(t, updated.Finished != nil, "Expected finished timestamp to be set when progress = 100")
271271+ shared.AssertEqual(t, "finished", updated.Status, "Expected status to be finished when progress = 100")
272272+ shared.AssertEqual(t, 100, updated.Progress, "Expected progress 100")
273273+ shared.AssertTrue(t, updated.Finished != nil, "Expected finished timestamp to be set when progress = 100")
273274 })
274275 })
275276···287288288289 for _, book := range books {
289290 _, err := repo.Create(ctx, book)
290290- AssertNoError(t, err, "Failed to create book")
291291+ shared.AssertNoError(t, err, "Failed to create book")
291292 }
292293293294 t.Run("Count all books", func(t *testing.T) {
294295 count, err := repo.Count(ctx, BookListOptions{})
295295- AssertNoError(t, err, "Failed to count books")
296296- AssertEqual(t, int64(4), count, "Expected 4 books")
296296+ shared.AssertNoError(t, err, "Failed to count books")
297297+ shared.AssertEqual(t, int64(4), count, "Expected 4 books")
297298 })
298299299300 t.Run("Count queued books", func(t *testing.T) {
300301 count, err := repo.Count(ctx, BookListOptions{Status: "queued"})
301301- AssertNoError(t, err, "Failed to count queued books")
302302- AssertEqual(t, int64(2), count, "Expected 2 queued books")
302302+ shared.AssertNoError(t, err, "Failed to count queued books")
303303+ shared.AssertEqual(t, int64(2), count, "Expected 2 queued books")
303304 })
304305305306 t.Run("Count books by progress", func(t *testing.T) {
306307 count, err := repo.Count(ctx, BookListOptions{MinProgress: 50})
307307- AssertNoError(t, err, "Failed to count books with progress >= 50")
308308- AssertEqual(t, int64(2), count, "Expected 2 books with progress >= 50")
308308+ shared.AssertNoError(t, err, "Failed to count books with progress >= 50")
309309+ shared.AssertEqual(t, int64(2), count, "Expected 2 books with progress >= 50")
309310 })
310311311312 t.Run("Count books by rating", func(t *testing.T) {
312313 count, err := repo.Count(ctx, BookListOptions{MinRating: 4.0})
313313- AssertNoError(t, err, "Failed to count high-rated books")
314314- AssertEqual(t, int64(3), count, "Expected 3 books with rating >= 4.0")
314314+ shared.AssertNoError(t, err, "Failed to count high-rated books")
315315+ shared.AssertEqual(t, int64(3), count, "Expected 3 books with rating >= 4.0")
315316 })
316317317318 t.Run("Count with context cancellation", func(t *testing.T) {
···327328328329 book := NewBookBuilder().WithTitle("Test Book").WithAuthor("Test Author").Build()
329330 id, err := repo.Create(ctx, book)
330330- AssertNoError(t, err, "Failed to create book")
331331+ shared.AssertNoError(t, err, "Failed to create book")
331332332333 t.Run("Create with cancelled context", func(t *testing.T) {
333334 newBook := NewBookBuilder().WithTitle("Cancelled").Build()
···399400400401 t.Run("Get non-existent book", func(t *testing.T) {
401402 _, err := repo.Get(ctx, 99999)
402402- AssertError(t, err, "Expected error for non-existent book")
403403+ shared.AssertError(t, err, "Expected error for non-existent book")
403404 })
404405405406 t.Run("Update non-existent book succeeds with no rows affected", func(t *testing.T) {
406407 book := NewBookBuilder().WithTitle("Non-existent").Build()
407408 book.ID = 99999
408409 err := repo.Update(ctx, book)
409409- AssertNoError(t, err, "Update should not error when no rows affected")
410410+ shared.AssertNoError(t, err, "Update should not error when no rows affected")
410411 })
411412412413 t.Run("Delete non-existent book succeeds with no rows affected", func(t *testing.T) {
413414 err := repo.Delete(ctx, 99999)
414414- AssertNoError(t, err, "Delete should not error when no rows affected")
415415+ shared.AssertNoError(t, err, "Delete should not error when no rows affected")
415416 })
416417417418 t.Run("StartReading non-existent book", func(t *testing.T) {
418419 err := repo.StartReading(ctx, 99999)
419419- AssertError(t, err, "Expected error for non-existent book")
420420+ shared.AssertError(t, err, "Expected error for non-existent book")
420421 })
421422422423 t.Run("FinishReading non-existent book", func(t *testing.T) {
423424 err := repo.FinishReading(ctx, 99999)
424424- AssertError(t, err, "Expected error for non-existent book")
425425+ shared.AssertError(t, err, "Expected error for non-existent book")
425426 })
426427427428 t.Run("UpdateProgress non-existent book", func(t *testing.T) {
428429 err := repo.UpdateProgress(ctx, 99999, 50)
429429- AssertError(t, err, "Expected error for non-existent book")
430430+ shared.AssertError(t, err, "Expected error for non-existent book")
430431 })
431432432433 t.Run("GetByAuthor with no results", func(t *testing.T) {
433434 books, err := repo.GetByAuthor(ctx, "NonExistentAuthor")
434434- AssertNoError(t, err, "Should not error when no books found")
435435- AssertEqual(t, 0, len(books), "Expected empty result set")
435435+ shared.AssertNoError(t, err, "Should not error when no books found")
436436+ shared.AssertEqual(t, 0, len(books), "Expected empty result set")
436437 })
437438 })
438439}
+73-71
internal/repo/find_methods_test.go
···33import (
44 "context"
55 "testing"
66+77+ "github.com/stormlightlabs/noteleaf/internal/shared"
68)
79810func TestFindMethods(t *testing.T) {
···1618 Status: "pending",
1719 }
1820 tasks, err := repos.Tasks.Find(ctx, options)
1919- AssertNoError(t, err, "Find should succeed")
2020- AssertTrue(t, len(tasks) >= 1, "Should find at least one pending task")
2121+ shared.AssertNoError(t, err, "Find should succeed")
2222+ shared.AssertTrue(t, len(tasks) >= 1, "Should find at least one pending task")
2123 for _, task := range tasks {
2222- AssertEqual(t, "pending", task.Status, "All returned tasks should be pending")
2424+ shared.AssertEqual(t, "pending", task.Status, "All returned tasks should be pending")
2325 }
2426 })
2527···2830 Priority: "high",
2931 }
3032 tasks, err := repos.Tasks.Find(ctx, options)
3131- AssertNoError(t, err, "Find should succeed")
3232- AssertTrue(t, len(tasks) >= 1, "Should find at least one high priority task")
3333+ shared.AssertNoError(t, err, "Find should succeed")
3434+ shared.AssertTrue(t, len(tasks) >= 1, "Should find at least one high priority task")
3335 for _, task := range tasks {
3434- AssertEqual(t, "high", task.Priority, "All returned tasks should be high priority")
3636+ shared.AssertEqual(t, "high", task.Priority, "All returned tasks should be high priority")
3537 }
3638 })
3739···4042 Project: "test-project",
4143 }
4244 tasks, err := repos.Tasks.Find(ctx, options)
4343- AssertNoError(t, err, "Find should succeed")
4444- AssertTrue(t, len(tasks) >= 1, "Should find tasks in test-project")
4545+ shared.AssertNoError(t, err, "Find should succeed")
4646+ shared.AssertTrue(t, len(tasks) >= 1, "Should find tasks in test-project")
4547 for _, task := range tasks {
4646- AssertEqual(t, "test-project", task.Project, "All returned tasks should be in test-project")
4848+ shared.AssertEqual(t, "test-project", task.Project, "All returned tasks should be in test-project")
4749 }
4850 })
4951···5254 Context: "test-context",
5355 }
5456 tasks, err := repos.Tasks.Find(ctx, options)
5555- AssertNoError(t, err, "Find should succeed")
5656- AssertTrue(t, len(tasks) >= 1, "Should find tasks in test-context")
5757+ shared.AssertNoError(t, err, "Find should succeed")
5858+ shared.AssertTrue(t, len(tasks) >= 1, "Should find tasks in test-context")
5759 for _, task := range tasks {
5858- AssertEqual(t, "test-context", task.Context, "All returned tasks should be in test-context")
6060+ shared.AssertEqual(t, "test-context", task.Context, "All returned tasks should be in test-context")
5961 }
6062 })
6163···6668 Project: "test-project",
6769 }
6870 tasks, err := repos.Tasks.Find(ctx, options)
6969- AssertNoError(t, err, "Find should succeed")
7171+ shared.AssertNoError(t, err, "Find should succeed")
7072 for _, task := range tasks {
7171- AssertEqual(t, "pending", task.Status, "Task should be pending")
7272- AssertEqual(t, "high", task.Priority, "Task should be high priority")
7373- AssertEqual(t, "test-project", task.Project, "Task should be in test-project")
7373+ shared.AssertEqual(t, "pending", task.Status, "Task should be pending")
7474+ shared.AssertEqual(t, "high", task.Priority, "Task should be high priority")
7575+ shared.AssertEqual(t, "test-project", task.Project, "Task should be in test-project")
7476 }
7577 })
7678···7981 Status: "non-existent-status",
8082 }
8183 tasks, err := repos.Tasks.Find(ctx, options)
8282- AssertNoError(t, err, "Find should succeed even with no results")
8383- AssertEqual(t, 0, len(tasks), "Should find no tasks")
8484+ shared.AssertNoError(t, err, "Find should succeed even with no results")
8585+ shared.AssertEqual(t, 0, len(tasks), "Should find no tasks")
8486 })
85878688 t.Run("returns all tasks with empty options", func(t *testing.T) {
8789 options := TaskListOptions{}
8890 tasks, err := repos.Tasks.Find(ctx, options)
8989- AssertNoError(t, err, "Find should succeed with empty options")
9090- AssertTrue(t, len(tasks) >= 2, "Should return all tasks for empty options")
9191+ shared.AssertNoError(t, err, "Find should succeed with empty options")
9292+ shared.AssertTrue(t, len(tasks) >= 2, "Should return all tasks for empty options")
9193 })
9294 })
9395···9799 Status: "reading",
98100 }
99101 books, err := repos.Books.Find(ctx, options)
100100- AssertNoError(t, err, "Find should succeed")
101101- AssertTrue(t, len(books) >= 1, "Should find at least one book being read")
102102+ shared.AssertNoError(t, err, "Find should succeed")
103103+ shared.AssertTrue(t, len(books) >= 1, "Should find at least one book being read")
102104 for _, book := range books {
103103- AssertEqual(t, "reading", book.Status, "All returned books should be reading")
105105+ shared.AssertEqual(t, "reading", book.Status, "All returned books should be reading")
104106 }
105107 })
106108···109111 Author: "Test Author",
110112 }
111113 books, err := repos.Books.Find(ctx, options)
112112- AssertNoError(t, err, "Find should succeed")
113113- AssertTrue(t, len(books) >= 1, "Should find at least one book by Test Author")
114114+ shared.AssertNoError(t, err, "Find should succeed")
115115+ shared.AssertTrue(t, len(books) >= 1, "Should find at least one book by Test Author")
114116 for _, book := range books {
115115- AssertEqual(t, "Test Author", book.Author, "All returned books should be by Test Author")
117117+ shared.AssertEqual(t, "Test Author", book.Author, "All returned books should be by Test Author")
116118 }
117119 })
118120···121123 MinProgress: 0,
122124 }
123125 books, err := repos.Books.Find(ctx, options)
124124- AssertNoError(t, err, "Find should succeed")
125125- AssertTrue(t, len(books) >= 1, "Should find books with progress >= 0")
126126+ shared.AssertNoError(t, err, "Find should succeed")
127127+ shared.AssertTrue(t, len(books) >= 1, "Should find books with progress >= 0")
126128 for _, book := range books {
127127- AssertTrue(t, book.Progress >= 0, "All returned books should have progress >= 0")
129129+ shared.AssertTrue(t, book.Progress >= 0, "All returned books should have progress >= 0")
128130 }
129131 })
130132···135137 MinProgress: 0,
136138 }
137139 books, err := repos.Books.Find(ctx, options)
138138- AssertNoError(t, err, "Find should succeed")
140140+ shared.AssertNoError(t, err, "Find should succeed")
139141 for _, book := range books {
140140- AssertEqual(t, "reading", book.Status, "Book should be reading")
141141- AssertEqual(t, "Test Author", book.Author, "Book should be by Test Author")
142142- AssertTrue(t, book.Progress >= 0, "Book should have progress >= 0")
142142+ shared.AssertEqual(t, "reading", book.Status, "Book should be reading")
143143+ shared.AssertEqual(t, "Test Author", book.Author, "Book should be by Test Author")
144144+ shared.AssertTrue(t, book.Progress >= 0, "Book should have progress >= 0")
143145 }
144146 })
145147···148150 Status: "non-existent-status",
149151 }
150152 books, err := repos.Books.Find(ctx, options)
151151- AssertNoError(t, err, "Find should succeed even with no results")
152152- AssertEqual(t, 0, len(books), "Should find no books")
153153+ shared.AssertNoError(t, err, "Find should succeed even with no results")
154154+ shared.AssertEqual(t, 0, len(books), "Should find no books")
153155 })
154156155157 t.Run("returns all books with empty options", func(t *testing.T) {
156158 options := BookListOptions{}
157159 books, err := repos.Books.Find(ctx, options)
158158- AssertNoError(t, err, "Find should succeed with empty options")
159159- AssertTrue(t, len(books) >= 2, "Should return all books for empty options")
160160+ shared.AssertNoError(t, err, "Find should succeed with empty options")
161161+ shared.AssertTrue(t, len(books) >= 2, "Should return all books for empty options")
160162 })
161163 })
162164···166168 Status: "watched",
167169 }
168170 movies, err := repos.Movies.Find(ctx, options)
169169- AssertNoError(t, err, "Find should succeed")
170170- AssertTrue(t, len(movies) >= 1, "Should find at least one watched movie")
171171+ shared.AssertNoError(t, err, "Find should succeed")
172172+ shared.AssertTrue(t, len(movies) >= 1, "Should find at least one watched movie")
171173 for _, movie := range movies {
172172- AssertEqual(t, "watched", movie.Status, "All returned movies should be watched")
174174+ shared.AssertEqual(t, "watched", movie.Status, "All returned movies should be watched")
173175 }
174176 })
175177···178180 Year: 2023,
179181 }
180182 movies, err := repos.Movies.Find(ctx, options)
181181- AssertNoError(t, err, "Find should succeed")
182182- AssertTrue(t, len(movies) >= 1, "Should find movies from 2023")
183183+ shared.AssertNoError(t, err, "Find should succeed")
184184+ shared.AssertTrue(t, len(movies) >= 1, "Should find movies from 2023")
183185 for _, movie := range movies {
184184- AssertEqual(t, 2023, movie.Year, "Movie should be from 2023")
186186+ shared.AssertEqual(t, 2023, movie.Year, "Movie should be from 2023")
185187 }
186188 })
187189···190192 MinRating: 0.0,
191193 }
192194 movies, err := repos.Movies.Find(ctx, options)
193193- AssertNoError(t, err, "Find should succeed")
194194- AssertTrue(t, len(movies) >= 1, "Should find movies with rating >= 0")
195195+ shared.AssertNoError(t, err, "Find should succeed")
196196+ shared.AssertTrue(t, len(movies) >= 1, "Should find movies with rating >= 0")
195197 for _, movie := range movies {
196196- AssertTrue(t, movie.Rating >= 0.0, "Movie rating should be >= 0")
198198+ shared.AssertTrue(t, movie.Rating >= 0.0, "Movie rating should be >= 0")
197199 }
198200 })
199201···204206 MinRating: 0.0,
205207 }
206208 movies, err := repos.Movies.Find(ctx, options)
207207- AssertNoError(t, err, "Find should succeed")
209209+ shared.AssertNoError(t, err, "Find should succeed")
208210 for _, movie := range movies {
209209- AssertEqual(t, "watched", movie.Status, "Movie should be watched")
210210- AssertEqual(t, 2023, movie.Year, "Movie should be from 2023")
211211- AssertTrue(t, movie.Rating >= 0.0, "Movie rating should be >= 0")
211211+ shared.AssertEqual(t, "watched", movie.Status, "Movie should be watched")
212212+ shared.AssertEqual(t, 2023, movie.Year, "Movie should be from 2023")
213213+ shared.AssertTrue(t, movie.Rating >= 0.0, "Movie rating should be >= 0")
212214 }
213215 })
214216···217219 Status: "non-existent-status",
218220 }
219221 movies, err := repos.Movies.Find(ctx, options)
220220- AssertNoError(t, err, "Find should succeed even with no results")
221221- AssertEqual(t, 0, len(movies), "Should find no movies")
222222+ shared.AssertNoError(t, err, "Find should succeed even with no results")
223223+ shared.AssertEqual(t, 0, len(movies), "Should find no movies")
222224 })
223225224226 t.Run("returns all movies with empty options", func(t *testing.T) {
225227 options := MovieListOptions{}
226228 movies, err := repos.Movies.Find(ctx, options)
227227- AssertNoError(t, err, "Find should succeed with empty options")
228228- AssertTrue(t, len(movies) >= 2, "Should return all movies for empty options")
229229+ shared.AssertNoError(t, err, "Find should succeed with empty options")
230230+ shared.AssertTrue(t, len(movies) >= 2, "Should return all movies for empty options")
229231 })
230232 })
231233···235237 Status: "watching",
236238 }
237239 shows, err := repos.TV.Find(ctx, options)
238238- AssertNoError(t, err, "Find should succeed")
239239- AssertTrue(t, len(shows) >= 1, "Should find at least one TV show being watched")
240240+ shared.AssertNoError(t, err, "Find should succeed")
241241+ shared.AssertTrue(t, len(shows) >= 1, "Should find at least one TV show being watched")
240242 for _, show := range shows {
241241- AssertEqual(t, "watching", show.Status, "All returned shows should be watching")
243243+ shared.AssertEqual(t, "watching", show.Status, "All returned shows should be watching")
242244 }
243245 })
244246···247249 Season: 1,
248250 }
249251 shows, err := repos.TV.Find(ctx, options)
250250- AssertNoError(t, err, "Find should succeed")
251251- AssertTrue(t, len(shows) >= 1, "Should find TV shows with season 1")
252252+ shared.AssertNoError(t, err, "Find should succeed")
253253+ shared.AssertTrue(t, len(shows) >= 1, "Should find TV shows with season 1")
252254 for _, show := range shows {
253253- AssertEqual(t, 1, show.Season, "All returned shows should be season 1")
255255+ shared.AssertEqual(t, 1, show.Season, "All returned shows should be season 1")
254256 }
255257 })
256258···259261 MinRating: 0.0,
260262 }
261263 shows, err := repos.TV.Find(ctx, options)
262262- AssertNoError(t, err, "Find should succeed")
263263- AssertTrue(t, len(shows) >= 1, "Should find TV shows with rating >= 0")
264264+ shared.AssertNoError(t, err, "Find should succeed")
265265+ shared.AssertTrue(t, len(shows) >= 1, "Should find TV shows with rating >= 0")
264266 for _, show := range shows {
265265- AssertTrue(t, show.Rating >= 0.0, "Show rating should be >= 0")
267267+ shared.AssertTrue(t, show.Rating >= 0.0, "Show rating should be >= 0")
266268 }
267269 })
268270···273275 MinRating: 0.0,
274276 }
275277 shows, err := repos.TV.Find(ctx, options)
276276- AssertNoError(t, err, "Find should succeed")
278278+ shared.AssertNoError(t, err, "Find should succeed")
277279 for _, show := range shows {
278278- AssertEqual(t, "watching", show.Status, "Show should be watching")
279279- AssertEqual(t, 1, show.Season, "Show should be season 1")
280280- AssertTrue(t, show.Rating >= 0.0, "Show rating should be >= 0")
280280+ shared.AssertEqual(t, "watching", show.Status, "Show should be watching")
281281+ shared.AssertEqual(t, 1, show.Season, "Show should be season 1")
282282+ shared.AssertTrue(t, show.Rating >= 0.0, "Show rating should be >= 0")
281283 }
282284 })
283285···286288 Status: "non-existent-status",
287289 }
288290 shows, err := repos.TV.Find(ctx, options)
289289- AssertNoError(t, err, "Find should succeed even with no results")
290290- AssertEqual(t, 0, len(shows), "Should find no TV shows")
291291+ shared.AssertNoError(t, err, "Find should succeed even with no results")
292292+ shared.AssertEqual(t, 0, len(shows), "Should find no TV shows")
291293 })
292294293295 t.Run("returns all TV shows with empty options", func(t *testing.T) {
294296 options := TVListOptions{}
295297 shows, err := repos.TV.Find(ctx, options)
296296- AssertNoError(t, err, "Find should succeed with empty options")
297297- AssertTrue(t, len(shows) >= 2, "Should return all TV shows for empty options")
298298+ shared.AssertNoError(t, err, "Find should succeed with empty options")
299299+ shared.AssertTrue(t, len(shows) >= 2, "Should return all TV shows for empty options")
298300 })
299301 })
300302}
+64-63
internal/repo/movie_repository_test.go
···7788 _ "github.com/mattn/go-sqlite3"
99 "github.com/stormlightlabs/noteleaf/internal/models"
1010+ "github.com/stormlightlabs/noteleaf/internal/shared"
1011)
11121213func TestMovieRepository(t *testing.T) {
···1920 movie := CreateSampleMovie()
20212122 id, err := repo.Create(ctx, movie)
2222- AssertNoError(t, err, "Failed to create movie")
2323- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2424- AssertEqual(t, id, movie.ID, "Expected movie ID to be set correctly")
2525- AssertFalse(t, movie.Added.IsZero(), "Expected Added timestamp to be set")
2323+ shared.AssertNoError(t, err, "Failed to create movie")
2424+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2525+ shared.AssertEqual(t, id, movie.ID, "Expected movie ID to be set correctly")
2626+ shared.AssertFalse(t, movie.Added.IsZero(), "Expected Added timestamp to be set")
2627 })
27282829 t.Run("Get Movie", func(t *testing.T) {
2930 original := CreateSampleMovie()
3031 id, err := repo.Create(ctx, original)
3131- AssertNoError(t, err, "Failed to create movie")
3232+ shared.AssertNoError(t, err, "Failed to create movie")
32333334 retrieved, err := repo.Get(ctx, id)
3434- AssertNoError(t, err, "Failed to get movie")
3535+ shared.AssertNoError(t, err, "Failed to get movie")
35363636- AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
3737- AssertEqual(t, original.Year, retrieved.Year, "Year mismatch")
3838- AssertEqual(t, original.Status, retrieved.Status, "Status mismatch")
3939- AssertEqual(t, original.Rating, retrieved.Rating, "Rating mismatch")
4040- AssertEqual(t, original.Notes, retrieved.Notes, "Notes mismatch")
3737+ shared.AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
3838+ shared.AssertEqual(t, original.Year, retrieved.Year, "Year mismatch")
3939+ shared.AssertEqual(t, original.Status, retrieved.Status, "Status mismatch")
4040+ shared.AssertEqual(t, original.Rating, retrieved.Rating, "Rating mismatch")
4141+ shared.AssertEqual(t, original.Notes, retrieved.Notes, "Notes mismatch")
4142 })
42434344 t.Run("Update Movie", func(t *testing.T) {
4445 movie := CreateSampleMovie()
4546 id, err := repo.Create(ctx, movie)
4646- AssertNoError(t, err, "Failed to create movie")
4747+ shared.AssertNoError(t, err, "Failed to create movie")
47484849 movie.Title = "Updated Movie"
4950 movie.Status = "watched"
···5253 movie.Watched = &now
53545455 err = repo.Update(ctx, movie)
5555- AssertNoError(t, err, "Failed to update movie")
5656+ shared.AssertNoError(t, err, "Failed to update movie")
56575758 updated, err := repo.Get(ctx, id)
5858- AssertNoError(t, err, "Failed to get updated movie")
5959+ shared.AssertNoError(t, err, "Failed to get updated movie")
59606060- AssertEqual(t, "Updated Movie", updated.Title, "Expected updated title")
6161- AssertEqual(t, "watched", updated.Status, "Expected watched status")
6262- AssertEqual(t, 9.0, updated.Rating, "Expected rating 9.0")
6363- AssertTrue(t, updated.Watched != nil, "Expected watched time to be set")
6161+ shared.AssertEqual(t, "Updated Movie", updated.Title, "Expected updated title")
6262+ shared.AssertEqual(t, "watched", updated.Status, "Expected watched status")
6363+ shared.AssertEqual(t, 9.0, updated.Rating, "Expected rating 9.0")
6464+ shared.AssertTrue(t, updated.Watched != nil, "Expected watched time to be set")
6465 })
65666667 t.Run("Delete Movie", func(t *testing.T) {
6768 movie := CreateSampleMovie()
6869 id, err := repo.Create(ctx, movie)
6969- AssertNoError(t, err, "Failed to create movie")
7070+ shared.AssertNoError(t, err, "Failed to create movie")
70717172 err = repo.Delete(ctx, id)
7272- AssertNoError(t, err, "Failed to delete movie")
7373+ shared.AssertNoError(t, err, "Failed to delete movie")
73747475 _, err = repo.Get(ctx, id)
7575- AssertError(t, err, "Expected error when getting deleted movie")
7676+ shared.AssertError(t, err, "Expected error when getting deleted movie")
7677 })
7778 })
7879···89909091 for _, movie := range movies {
9192 _, err := repo.Create(ctx, movie)
9292- AssertNoError(t, err, "Failed to create movie")
9393+ shared.AssertNoError(t, err, "Failed to create movie")
9394 }
94959596 t.Run("List All Movies", func(t *testing.T) {
9697 results, err := repo.List(ctx, MovieListOptions{})
9797- AssertNoError(t, err, "Failed to list movies")
9898- AssertEqual(t, 3, len(results), "Expected 3 movies")
9898+ shared.AssertNoError(t, err, "Failed to list movies")
9999+ shared.AssertEqual(t, 3, len(results), "Expected 3 movies")
99100 })
100101101102 t.Run("List Movies with Status Filter", func(t *testing.T) {
102103 results, err := repo.List(ctx, MovieListOptions{Status: "queued"})
103103- AssertNoError(t, err, "Failed to list movies")
104104- AssertEqual(t, 2, len(results), "Expected 2 queued movies")
104104+ shared.AssertNoError(t, err, "Failed to list movies")
105105+ shared.AssertEqual(t, 2, len(results), "Expected 2 queued movies")
105106106107 for _, movie := range results {
107107- AssertEqual(t, "queued", movie.Status, "Expected queued status")
108108+ shared.AssertEqual(t, "queued", movie.Status, "Expected queued status")
108109 }
109110 })
110111111112 t.Run("List Movies with Year Filter", func(t *testing.T) {
112113 results, err := repo.List(ctx, MovieListOptions{Year: 2021})
113113- AssertNoError(t, err, "Failed to list movies")
114114- AssertEqual(t, 1, len(results), "Expected 1 movie from 2021")
114114+ shared.AssertNoError(t, err, "Failed to list movies")
115115+ shared.AssertEqual(t, 1, len(results), "Expected 1 movie from 2021")
115116116117 if len(results) > 0 {
117117- AssertEqual(t, 2021, results[0].Year, "Expected year 2021")
118118+ shared.AssertEqual(t, 2021, results[0].Year, "Expected year 2021")
118119 }
119120 })
120121121122 t.Run("List Movies with Rating Filter", func(t *testing.T) {
122123 results, err := repo.List(ctx, MovieListOptions{MinRating: 8.0})
123123- AssertNoError(t, err, "Failed to list movies")
124124- AssertEqual(t, 2, len(results), "Expected 2 movies with rating >= 8.0")
124124+ shared.AssertNoError(t, err, "Failed to list movies")
125125+ shared.AssertEqual(t, 2, len(results), "Expected 2 movies with rating >= 8.0")
125126126127 for _, movie := range results {
127127- AssertTrue(t, movie.Rating >= 8.0, "Expected rating >= 8.0")
128128+ shared.AssertTrue(t, movie.Rating >= 8.0, "Expected rating >= 8.0")
128129 }
129130 })
130131131132 t.Run("List Movies with Search", func(t *testing.T) {
132133 results, err := repo.List(ctx, MovieListOptions{Search: "Movie 1"})
133133- AssertNoError(t, err, "Failed to list movies")
134134- AssertEqual(t, 1, len(results), "Expected 1 movie matching search")
134134+ shared.AssertNoError(t, err, "Failed to list movies")
135135+ shared.AssertEqual(t, 1, len(results), "Expected 1 movie matching search")
135136136137 if len(results) > 0 {
137137- AssertEqual(t, "Movie 1", results[0].Title, "Expected 'Movie 1'")
138138+ shared.AssertEqual(t, "Movie 1", results[0].Title, "Expected 'Movie 1'")
138139 }
139140 })
140141141142 t.Run("List Movies with Limit", func(t *testing.T) {
142143 results, err := repo.List(ctx, MovieListOptions{Limit: 2})
143143- AssertNoError(t, err, "Failed to list movies")
144144- AssertEqual(t, 2, len(results), "Expected 2 movies due to limit")
144144+ shared.AssertNoError(t, err, "Failed to list movies")
145145+ shared.AssertEqual(t, 2, len(results), "Expected 2 movies due to limit")
145146 })
146147 })
147148···157158 var movie1ID int64
158159 for _, movie := range []*models.Movie{movie1, movie2, movie3} {
159160 id, err := repo.Create(ctx, movie)
160160- AssertNoError(t, err, "Failed to create movie")
161161+ shared.AssertNoError(t, err, "Failed to create movie")
161162 if movie == movie1 {
162163 movie1ID = id
163164 }
···165166166167 t.Run("GetQueued", func(t *testing.T) {
167168 results, err := repo.GetQueued(ctx)
168168- AssertNoError(t, err, "Failed to get queued movies")
169169- AssertEqual(t, 2, len(results), "Expected 2 queued movies")
169169+ shared.AssertNoError(t, err, "Failed to get queued movies")
170170+ shared.AssertEqual(t, 2, len(results), "Expected 2 queued movies")
170171171172 for _, movie := range results {
172172- AssertEqual(t, "queued", movie.Status, "Expected queued status")
173173+ shared.AssertEqual(t, "queued", movie.Status, "Expected queued status")
173174 }
174175 })
175176176177 t.Run("GetWatched", func(t *testing.T) {
177178 results, err := repo.GetWatched(ctx)
178178- AssertNoError(t, err, "Failed to get watched movies")
179179- AssertEqual(t, 1, len(results), "Expected 1 watched movie")
179179+ shared.AssertNoError(t, err, "Failed to get watched movies")
180180+ shared.AssertEqual(t, 1, len(results), "Expected 1 watched movie")
180181181182 if len(results) > 0 {
182182- AssertEqual(t, "watched", results[0].Status, "Expected watched status")
183183+ shared.AssertEqual(t, "watched", results[0].Status, "Expected watched status")
183184 }
184185 })
185186186187 t.Run("MarkWatched", func(t *testing.T) {
187188 err := repo.MarkWatched(ctx, movie1ID)
188188- AssertNoError(t, err, "Failed to mark movie as watched")
189189+ shared.AssertNoError(t, err, "Failed to mark movie as watched")
189190190191 updated, err := repo.Get(ctx, movie1ID)
191191- AssertNoError(t, err, "Failed to get updated movie")
192192+ shared.AssertNoError(t, err, "Failed to get updated movie")
192193193193- AssertEqual(t, "watched", updated.Status, "Expected status to be watched")
194194- AssertTrue(t, updated.Watched != nil, "Expected watched timestamp to be set")
194194+ shared.AssertEqual(t, "watched", updated.Status, "Expected status to be watched")
195195+ shared.AssertTrue(t, updated.Watched != nil, "Expected watched timestamp to be set")
195196 })
196197 })
197198···208209209210 for _, movie := range movies {
210211 _, err := repo.Create(ctx, movie)
211211- AssertNoError(t, err, "Failed to create movie")
212212+ shared.AssertNoError(t, err, "Failed to create movie")
212213 }
213214214215 t.Run("Count all movies", func(t *testing.T) {
215216 count, err := repo.Count(ctx, MovieListOptions{})
216216- AssertNoError(t, err, "Failed to count movies")
217217- AssertEqual(t, int64(3), count, "Expected 3 movies")
217217+ shared.AssertNoError(t, err, "Failed to count movies")
218218+ shared.AssertEqual(t, int64(3), count, "Expected 3 movies")
218219 })
219220220221 t.Run("Count queued movies", func(t *testing.T) {
221222 count, err := repo.Count(ctx, MovieListOptions{Status: "queued"})
222222- AssertNoError(t, err, "Failed to count queued movies")
223223- AssertEqual(t, int64(2), count, "Expected 2 queued movies")
223223+ shared.AssertNoError(t, err, "Failed to count queued movies")
224224+ shared.AssertEqual(t, int64(2), count, "Expected 2 queued movies")
224225 })
225226226227 t.Run("Count movies by rating", func(t *testing.T) {
227228 count, err := repo.Count(ctx, MovieListOptions{MinRating: 8.0})
228228- AssertNoError(t, err, "Failed to count high-rated movies")
229229- AssertEqual(t, int64(2), count, "Expected 2 movies with rating >= 8.0")
229229+ shared.AssertNoError(t, err, "Failed to count high-rated movies")
230230+ shared.AssertEqual(t, int64(2), count, "Expected 2 movies with rating >= 8.0")
230231 })
231232232233 t.Run("Count with context cancellation", func(t *testing.T) {
···242243243244 movie := NewMovieBuilder().WithTitle("Test Movie").WithYear(2023).Build()
244245 id, err := repo.Create(ctx, movie)
245245- AssertNoError(t, err, "Failed to create movie")
246246+ shared.AssertNoError(t, err, "Failed to create movie")
246247247248 t.Run("Create with cancelled context", func(t *testing.T) {
248249 newMovie := NewMovieBuilder().WithTitle("Cancelled").Build()
···294295295296 t.Run("Get non-existent movie", func(t *testing.T) {
296297 _, err := repo.Get(ctx, 99999)
297297- AssertError(t, err, "Expected error for non-existent movie")
298298+ shared.AssertError(t, err, "Expected error for non-existent movie")
298299 })
299300300301 t.Run("Update non-existent movie succeeds with no rows affected", func(t *testing.T) {
301302 movie := NewMovieBuilder().WithTitle("Non-existent").Build()
302303 movie.ID = 99999
303304 err := repo.Update(ctx, movie)
304304- AssertNoError(t, err, "Update should not error when no rows affected")
305305+ shared.AssertNoError(t, err, "Update should not error when no rows affected")
305306 })
306307307308 t.Run("Delete non-existent movie succeeds with no rows affected", func(t *testing.T) {
308309 err := repo.Delete(ctx, 99999)
309309- AssertNoError(t, err, "Delete should not error when no rows affected")
310310+ shared.AssertNoError(t, err, "Delete should not error when no rows affected")
310311 })
311312312313 t.Run("MarkWatched non-existent movie", func(t *testing.T) {
313314 err := repo.MarkWatched(ctx, 99999)
314314- AssertError(t, err, "Expected error for non-existent movie")
315315+ shared.AssertError(t, err, "Expected error for non-existent movie")
315316 })
316317317318 t.Run("List with no results", func(t *testing.T) {
318319 movies, err := repo.List(ctx, MovieListOptions{Year: 1900})
319319- AssertNoError(t, err, "Should not error when no movies found")
320320- AssertEqual(t, 0, len(movies), "Expected empty result set")
320320+ shared.AssertNoError(t, err, "Should not error when no movies found")
321321+ shared.AssertEqual(t, 0, len(movies), "Expected empty result set")
321322 })
322323 })
323324}
+107-106
internal/repo/note_repository_test.go
···6677 _ "github.com/mattn/go-sqlite3"
88 "github.com/stormlightlabs/noteleaf/internal/models"
99+ "github.com/stormlightlabs/noteleaf/internal/shared"
910)
10111112func TestNoteRepository(t *testing.T) {
···1819 note := CreateSampleNote()
19202021 id, err := repo.Create(ctx, note)
2121- AssertNoError(t, err, "Failed to create note")
2222- AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2323- AssertEqual(t, id, note.ID, "Expected note ID to be set correctly")
2424- AssertFalse(t, note.Created.IsZero(), "Expected Created timestamp to be set")
2525- AssertFalse(t, note.Modified.IsZero(), "Expected Modified timestamp to be set")
2222+ shared.AssertNoError(t, err, "Failed to create note")
2323+ shared.AssertNotEqual(t, int64(0), id, "Expected non-zero ID")
2424+ shared.AssertEqual(t, id, note.ID, "Expected note ID to be set correctly")
2525+ shared.AssertFalse(t, note.Created.IsZero(), "Expected Created timestamp to be set")
2626+ shared.AssertFalse(t, note.Modified.IsZero(), "Expected Modified timestamp to be set")
2627 })
27282829 t.Run("Get Note", func(t *testing.T) {
2930 original := CreateSampleNote()
3031 id, err := repo.Create(ctx, original)
3131- AssertNoError(t, err, "Failed to create note")
3232+ shared.AssertNoError(t, err, "Failed to create note")
32333334 retrieved, err := repo.Get(ctx, id)
3434- AssertNoError(t, err, "Failed to get note")
3535+ shared.AssertNoError(t, err, "Failed to get note")
35363636- AssertEqual(t, original.ID, retrieved.ID, "ID mismatch")
3737- AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
3838- AssertEqual(t, original.Content, retrieved.Content, "Content mismatch")
3939- AssertEqual(t, len(original.Tags), len(retrieved.Tags), "Tags length mismatch")
4040- AssertEqual(t, original.Archived, retrieved.Archived, "Archived mismatch")
4141- AssertEqual(t, original.FilePath, retrieved.FilePath, "FilePath mismatch")
3737+ shared.AssertEqual(t, original.ID, retrieved.ID, "ID mismatch")
3838+ shared.AssertEqual(t, original.Title, retrieved.Title, "Title mismatch")
3939+ shared.AssertEqual(t, original.Content, retrieved.Content, "Content mismatch")
4040+ shared.AssertEqual(t, len(original.Tags), len(retrieved.Tags), "Tags length mismatch")
4141+ shared.AssertEqual(t, original.Archived, retrieved.Archived, "Archived mismatch")
4242+ shared.AssertEqual(t, original.FilePath, retrieved.FilePath, "FilePath mismatch")
4243 })
43444445 t.Run("Update Note", func(t *testing.T) {
4546 note := CreateSampleNote()
4647 id, err := repo.Create(ctx, note)
4747- AssertNoError(t, err, "Failed to create note")
4848+ shared.AssertNoError(t, err, "Failed to create note")
48494950 originalModified := note.Modified
5051···5556 note.FilePath = "/new/path/note.md"
56575758 err = repo.Update(ctx, note)
5858- AssertNoError(t, err, "Failed to update note")
5959+ shared.AssertNoError(t, err, "Failed to update note")
59606061 retrieved, err := repo.Get(ctx, id)
6161- AssertNoError(t, err, "Failed to get updated note")
6262+ shared.AssertNoError(t, err, "Failed to get updated note")
62636363- AssertEqual(t, "Updated Title", retrieved.Title, "Expected updated title")
6464- AssertEqual(t, "Updated content", retrieved.Content, "Expected updated content")
6565- AssertEqual(t, 2, len(retrieved.Tags), "Expected 2 tags")
6464+ shared.AssertEqual(t, "Updated Title", retrieved.Title, "Expected updated title")
6565+ shared.AssertEqual(t, "Updated content", retrieved.Content, "Expected updated content")
6666+ shared.AssertEqual(t, 2, len(retrieved.Tags), "Expected 2 tags")
6667 if len(retrieved.Tags) >= 2 {
6767- AssertEqual(t, "updated", retrieved.Tags[0], "Expected first tag to be 'updated'")
6868- AssertEqual(t, "test", retrieved.Tags[1], "Expected second tag to be 'test'")
6868+ shared.AssertEqual(t, "updated", retrieved.Tags[0], "Expected first tag to be 'updated'")
6969+ shared.AssertEqual(t, "test", retrieved.Tags[1], "Expected second tag to be 'test'")
6970 }
7070- AssertTrue(t, retrieved.Archived, "Expected note to be archived")
7171- AssertEqual(t, "/new/path/note.md", retrieved.FilePath, "Expected updated file path")
7272- AssertTrue(t, retrieved.Modified.After(originalModified), "Expected Modified timestamp to be updated")
7171+ shared.AssertTrue(t, retrieved.Archived, "Expected note to be archived")
7272+ shared.AssertEqual(t, "/new/path/note.md", retrieved.FilePath, "Expected updated file path")
7373+ shared.AssertTrue(t, retrieved.Modified.After(originalModified), "Expected Modified timestamp to be updated")
7374 })
74757576 t.Run("Delete Note", func(t *testing.T) {
7677 note := CreateSampleNote()
7778 id, err := repo.Create(ctx, note)
7878- AssertNoError(t, err, "Failed to create note")
7979+ shared.AssertNoError(t, err, "Failed to create note")
79808081 err = repo.Delete(ctx, id)
8181- AssertNoError(t, err, "Failed to delete note")
8282+ shared.AssertNoError(t, err, "Failed to delete note")
82838384 _, err = repo.Get(ctx, id)
8484- AssertError(t, err, "Expected error when getting deleted note")
8585+ shared.AssertError(t, err, "Expected error when getting deleted note")
8586 })
8687 })
8788···989999100 for _, note := range notes {
100101 _, err := repo.Create(ctx, note)
101101- AssertNoError(t, err, "Failed to create test note")
102102+ shared.AssertNoError(t, err, "Failed to create test note")
102103 }
103104104105 t.Run("List All Notes", func(t *testing.T) {
105106 results, err := repo.List(ctx, NoteListOptions{})
106106- AssertNoError(t, err, "Failed to list notes")
107107- AssertEqual(t, 3, len(results), "Expected 3 notes")
107107+ shared.AssertNoError(t, err, "Failed to list notes")
108108+ shared.AssertEqual(t, 3, len(results), "Expected 3 notes")
108109 })
109110110111 t.Run("List Archived Notes Only", func(t *testing.T) {
111112 archived := true
112113 results, err := repo.List(ctx, NoteListOptions{Archived: &archived})
113113- AssertNoError(t, err, "Failed to list archived notes")
114114- AssertEqual(t, 1, len(results), "Expected 1 archived note")
114114+ shared.AssertNoError(t, err, "Failed to list archived notes")
115115+ shared.AssertEqual(t, 1, len(results), "Expected 1 archived note")
115116 if len(results) > 0 {
116116- AssertTrue(t, results[0].Archived, "Retrieved note should be archived")
117117+ shared.AssertTrue(t, results[0].Archived, "Retrieved note should be archived")
117118 }
118119 })
119120120121 t.Run("List Active Notes Only", func(t *testing.T) {
121122 archived := false
122123 results, err := repo.List(ctx, NoteListOptions{Archived: &archived})
123123- AssertNoError(t, err, "Failed to list active notes")
124124- AssertEqual(t, 2, len(results), "Expected 2 active notes")
124124+ shared.AssertNoError(t, err, "Failed to list active notes")
125125+ shared.AssertEqual(t, 2, len(results), "Expected 2 active notes")
125126 for _, note := range results {
126126- AssertFalse(t, note.Archived, "Retrieved note should not be archived")
127127+ shared.AssertFalse(t, note.Archived, "Retrieved note should not be archived")
127128 }
128129 })
129130130131 t.Run("Search by Title", func(t *testing.T) {
131132 results, err := repo.List(ctx, NoteListOptions{Title: "First"})
132132- AssertNoError(t, err, "Failed to search by title")
133133- AssertEqual(t, 1, len(results), "Expected 1 note")
133133+ shared.AssertNoError(t, err, "Failed to search by title")
134134+ shared.AssertEqual(t, 1, len(results), "Expected 1 note")
134135 if len(results) > 0 {
135135- AssertEqual(t, "First Note", results[0].Title, "Expected 'First Note'")
136136+ shared.AssertEqual(t, "First Note", results[0].Title, "Expected 'First Note'")
136137 }
137138 })
138139139140 t.Run("Search by Content", func(t *testing.T) {
140141 results, err := repo.List(ctx, NoteListOptions{Content: "Important"})
141141- AssertNoError(t, err, "Failed to search by content")
142142- AssertEqual(t, 1, len(results), "Expected 1 note")
142142+ shared.AssertNoError(t, err, "Failed to search by content")
143143+ shared.AssertEqual(t, 1, len(results), "Expected 1 note")
143144 if len(results) > 0 {
144144- AssertEqual(t, "Third Note", results[0].Title, "Expected 'Third Note'")
145145+ shared.AssertEqual(t, "Third Note", results[0].Title, "Expected 'Third Note'")
145146 }
146147 })
147148148149 t.Run("Limit and Offset", func(t *testing.T) {
149150 results, err := repo.List(ctx, NoteListOptions{Limit: 2})
150150- AssertNoError(t, err, "Failed to list with limit")
151151- AssertEqual(t, 2, len(results), "Expected 2 notes")
151151+ shared.AssertNoError(t, err, "Failed to list with limit")
152152+ shared.AssertEqual(t, 2, len(results), "Expected 2 notes")
152153153154 results, err = repo.List(ctx, NoteListOptions{Limit: 2, Offset: 1})
154154- AssertNoError(t, err, "Failed to list with limit and offset")
155155- AssertEqual(t, 2, len(results), "Expected 2 notes with offset")
155155+ shared.AssertNoError(t, err, "Failed to list with limit and offset")
156156+ shared.AssertEqual(t, 2, len(results), "Expected 2 notes with offset")
156157 })
157158 })
158159···169170170171 for _, note := range notes {
171172 _, err := repo.Create(ctx, note)
172172- AssertNoError(t, err, "Failed to create test note")
173173+ shared.AssertNoError(t, err, "Failed to create test note")
173174 }
174175175176 t.Run("GetByTitle", func(t *testing.T) {
176177 results, err := repo.GetByTitle(ctx, "Work")
177177- AssertNoError(t, err, "Failed to get by title")
178178- AssertEqual(t, 1, len(results), "Expected 1 note")
178178+ shared.AssertNoError(t, err, "Failed to get by title")
179179+ shared.AssertEqual(t, 1, len(results), "Expected 1 note")
179180 if len(results) > 0 {
180180- AssertEqual(t, "Work Note", results[0].Title, "Expected 'Work Note'")
181181+ shared.AssertEqual(t, "Work Note", results[0].Title, "Expected 'Work Note'")
181182 }
182183 })
183184184185 t.Run("GetArchived", func(t *testing.T) {
185186 results, err := repo.GetArchived(ctx)
186186- AssertNoError(t, err, "Failed to get archived notes")
187187- AssertEqual(t, 1, len(results), "Expected 1 archived note")
187187+ shared.AssertNoError(t, err, "Failed to get archived notes")
188188+ shared.AssertEqual(t, 1, len(results), "Expected 1 archived note")
188189 if len(results) > 0 {
189189- AssertTrue(t, results[0].Archived, "Retrieved note should be archived")
190190+ shared.AssertTrue(t, results[0].Archived, "Retrieved note should be archived")
190191 }
191192 })
192193193194 t.Run("GetActive", func(t *testing.T) {
194195 results, err := repo.GetActive(ctx)
195195- AssertNoError(t, err, "Failed to get active notes")
196196- AssertEqual(t, 2, len(results), "Expected 2 active notes")
196196+ shared.AssertNoError(t, err, "Failed to get active notes")
197197+ shared.AssertEqual(t, 2, len(results), "Expected 2 active notes")
197198 for _, note := range results {
198198- AssertFalse(t, note.Archived, "Retrieved note should not be archived")
199199+ shared.AssertFalse(t, note.Archived, "Retrieved note should not be archived")
199200 }
200201 })
201202···206207 Archived: false,
207208 }
208209 id, err := repo.Create(ctx, note)
209209- AssertNoError(t, err, "Failed to create note")
210210+ shared.AssertNoError(t, err, "Failed to create note")
210211211212 err = repo.Archive(ctx, id)
212212- AssertNoError(t, err, "Failed to archive note")
213213+ shared.AssertNoError(t, err, "Failed to archive note")
213214214215 retrieved, err := repo.Get(ctx, id)
215215- AssertNoError(t, err, "Failed to get note")
216216- AssertTrue(t, retrieved.Archived, "Note should be archived")
216216+ shared.AssertNoError(t, err, "Failed to get note")
217217+ shared.AssertTrue(t, retrieved.Archived, "Note should be archived")
217218218219 err = repo.Unarchive(ctx, id)
219219- AssertNoError(t, err, "Failed to unarchive note")
220220+ shared.AssertNoError(t, err, "Failed to unarchive note")
220221221222 retrieved, err = repo.Get(ctx, id)
222222- AssertNoError(t, err, "Failed to get note")
223223- AssertFalse(t, retrieved.Archived, "Note should not be archived")
223223+ shared.AssertNoError(t, err, "Failed to get note")
224224+ shared.AssertFalse(t, retrieved.Archived, "Note should not be archived")
224225 })
225226226227 t.Run("SearchContent", func(t *testing.T) {
227228 results, err := repo.SearchContent(ctx, "Important")
228228- AssertNoError(t, err, "Failed to search content")
229229- AssertEqual(t, 1, len(results), "Expected 1 note")
229229+ shared.AssertNoError(t, err, "Failed to search content")
230230+ shared.AssertEqual(t, 1, len(results), "Expected 1 note")
230231 if len(results) > 0 {
231231- AssertEqual(t, "Important Note", results[0].Title, "Expected 'Important Note'")
232232+ shared.AssertEqual(t, "Important Note", results[0].Title, "Expected 'Important Note'")
232233 }
233234 })
234235235236 t.Run("GetRecent", func(t *testing.T) {
236237 results, err := repo.GetRecent(ctx, 2)
237237- AssertNoError(t, err, "Failed to get recent notes")
238238- AssertEqual(t, 2, len(results), "Expected 2 notes")
238238+ shared.AssertNoError(t, err, "Failed to get recent notes")
239239+ shared.AssertEqual(t, 2, len(results), "Expected 2 notes")
239240 })
240241 })
241242···250251 Tags: []string{"initial"},
251252 }
252253 id, err := repo.Create(ctx, note)
253253- AssertNoError(t, err, "Failed to create note")
254254+ shared.AssertNoError(t, err, "Failed to create note")
254255255256 t.Run("AddTag", func(t *testing.T) {
256257 err := repo.AddTag(ctx, id, "new-tag")
257257- AssertNoError(t, err, "Failed to add tag")
258258+ shared.AssertNoError(t, err, "Failed to add tag")
258259259260 retrieved, err := repo.Get(ctx, id)
260260- AssertNoError(t, err, "Failed to get note")
261261+ shared.AssertNoError(t, err, "Failed to get note")
261262262262- AssertEqual(t, 2, len(retrieved.Tags), "Expected 2 tags")
263263+ shared.AssertEqual(t, 2, len(retrieved.Tags), "Expected 2 tags")
263264264265 found := false
265266 for _, tag := range retrieved.Tags {
···268269 break
269270 }
270271 }
271271- AssertTrue(t, found, "New tag not found in note")
272272+ shared.AssertTrue(t, found, "New tag not found in note")
272273 })
273274274275 t.Run("AddTag Duplicate", func(t *testing.T) {
275276 err := repo.AddTag(ctx, id, "new-tag")
276276- AssertNoError(t, err, "Failed to add duplicate tag")
277277+ shared.AssertNoError(t, err, "Failed to add duplicate tag")
277278278279 retrieved, err := repo.Get(ctx, id)
279279- AssertNoError(t, err, "Failed to get note")
280280+ shared.AssertNoError(t, err, "Failed to get note")
280281281281- AssertEqual(t, 2, len(retrieved.Tags), "Expected 2 tags (no duplicate)")
282282+ shared.AssertEqual(t, 2, len(retrieved.Tags), "Expected 2 tags (no duplicate)")
282283 })
283284284285 t.Run("RemoveTag", func(t *testing.T) {
285286 err := repo.RemoveTag(ctx, id, "initial")
286286- AssertNoError(t, err, "Failed to remove tag")
287287+ shared.AssertNoError(t, err, "Failed to remove tag")
287288288289 retrieved, err := repo.Get(ctx, id)
289289- AssertNoError(t, err, "Failed to get note")
290290+ shared.AssertNoError(t, err, "Failed to get note")
290291291291- AssertEqual(t, 1, len(retrieved.Tags), "Expected 1 tag after removal")
292292+ shared.AssertEqual(t, 1, len(retrieved.Tags), "Expected 1 tag after removal")
292293293294 for _, tag := range retrieved.Tags {
294294- AssertNotEqual(t, "initial", tag, "Removed tag still found in note")
295295+ shared.AssertNotEqual(t, "initial", tag, "Removed tag still found in note")
295296 }
296297 })
297298···313314 }
314315315316 _, err := repo.Create(ctx, note1)
316316- AssertNoError(t, err, "Failed to create note1")
317317+ shared.AssertNoError(t, err, "Failed to create note1")
317318 _, err = repo.Create(ctx, note2)
318318- AssertNoError(t, err, "Failed to create note2")
319319+ shared.AssertNoError(t, err, "Failed to create note2")
319320 _, err = repo.Create(ctx, note3)
320320- AssertNoError(t, err, "Failed to create note3")
321321+ shared.AssertNoError(t, err, "Failed to create note3")
321322322323 results, err := repo.GetByTags(ctx, []string{"work"})
323323- AssertNoError(t, err, "Failed to get notes by tag")
324324- AssertTrue(t, len(results) >= 2, "Expected at least 2 notes with 'work' tag")
324324+ shared.AssertNoError(t, err, "Failed to get notes by tag")
325325+ shared.AssertTrue(t, len(results) >= 2, "Expected at least 2 notes with 'work' tag")
325326326327 results, err = repo.GetByTags(ctx, []string{"nonexistent"})
327327- AssertNoError(t, err, "Failed to get notes by nonexistent tag")
328328- AssertEqual(t, 0, len(results), "Expected 0 notes with nonexistent tag")
328328+ shared.AssertNoError(t, err, "Failed to get notes by nonexistent tag")
329329+ shared.AssertEqual(t, 0, len(results), "Expected 0 notes with nonexistent tag")
329330330331 results, err = repo.GetByTags(ctx, []string{})
331331- AssertNoError(t, err, "Failed to get notes with empty tags")
332332- AssertEqual(t, 0, len(results), "Expected 0 notes with empty tag list")
332332+ shared.AssertNoError(t, err, "Failed to get notes with empty tags")
333333+ shared.AssertEqual(t, 0, len(results), "Expected 0 notes with empty tag list")
333334 })
334335 })
335336···340341341342 note := NewNoteBuilder().WithTitle("Test Note").WithContent("Test content").Build()
342343 id, err := repo.Create(ctx, note)
343343- AssertNoError(t, err, "Failed to create note")
344344+ shared.AssertNoError(t, err, "Failed to create note")
344345345346 t.Run("Create with cancelled context", func(t *testing.T) {
346347 newNote := NewNoteBuilder().WithTitle("Cancelled").Build()
···427428428429 t.Run("Get non-existent note", func(t *testing.T) {
429430 _, err := repo.Get(ctx, 99999)
430430- AssertError(t, err, "Expected error for non-existent note")
431431+ shared.AssertError(t, err, "Expected error for non-existent note")
431432 })
432433433434 t.Run("Update non-existent note", func(t *testing.T) {
···438439 }
439440440441 err := repo.Update(ctx, note)
441441- AssertError(t, err, "Expected error when updating non-existent note")
442442+ shared.AssertError(t, err, "Expected error when updating non-existent note")
442443 })
443444444445 t.Run("Delete non-existent note", func(t *testing.T) {
445446 err := repo.Delete(ctx, 99999)
446446- AssertError(t, err, "Expected error when deleting non-existent note")
447447+ shared.AssertError(t, err, "Expected error when deleting non-existent note")
447448 })
448449449450 t.Run("Archive non-existent note", func(t *testing.T) {
450451 err := repo.Archive(ctx, 99999)
451451- AssertError(t, err, "Expected error when archiving non-existent note")
452452+ shared.AssertError(t, err, "Expected error when archiving non-existent note")
452453 })
453454454455 t.Run("AddTag to non-existent note", func(t *testing.T) {
455456 err := repo.AddTag(ctx, 99999, "tag")
456456- AssertError(t, err, "Expected error when adding tag to non-existent note")
457457+ shared.AssertError(t, err, "Expected error when adding tag to non-existent note")
457458 })
458459459460 t.Run("Note with empty tags", func(t *testing.T) {
···464465 }
465466466467 id, err := repo.Create(ctx, note)
467467- AssertNoError(t, err, "Failed to create note with empty tags")
468468+ shared.AssertNoError(t, err, "Failed to create note with empty tags")
468469469470 retrieved, err := repo.Get(ctx, id)
470470- AssertNoError(t, err, "Failed to get note")
471471+ shared.AssertNoError(t, err, "Failed to get note")
471472472472- AssertEqual(t, 0, len(retrieved.Tags), "Expected empty tags slice")
473473+ shared.AssertEqual(t, 0, len(retrieved.Tags), "Expected empty tags slice")
473474 })
474475475476 t.Run("Note with nil tags", func(t *testing.T) {
···480481 }
481482482483 id, err := repo.Create(ctx, note)
483483- AssertNoError(t, err, "Failed to create note with nil tags")
484484+ shared.AssertNoError(t, err, "Failed to create note with nil tags")
484485485486 retrieved, err := repo.Get(ctx, id)
486486- AssertNoError(t, err, "Failed to get note")
487487+ shared.AssertNoError(t, err, "Failed to get note")
487488488488- AssertEqual(t, 0, len(retrieved.Tags), "Expected empty tags")
489489+ shared.AssertEqual(t, 0, len(retrieved.Tags), "Expected empty tags")
489490 })
490491491492 t.Run("Note with long content", func(t *testing.T) {
···500501 }
501502502503 id, err := repo.Create(ctx, note)
503503- AssertNoError(t, err, "Failed to create note with long content")
504504+ shared.AssertNoError(t, err, "Failed to create note with long content")
504505505506 retrieved, err := repo.Get(ctx, id)
506506- AssertNoError(t, err, "Failed to get note")
507507+ shared.AssertNoError(t, err, "Failed to get note")
507508508508- AssertEqual(t, longContent, retrieved.Content, "Long content was not stored/retrieved correctly")
509509+ shared.AssertEqual(t, longContent, retrieved.Content, "Long content was not stored/retrieved correctly")
509510 })
510511511512 t.Run("List with no results", func(t *testing.T) {
512513 notes, err := repo.List(ctx, NoteListOptions{Title: "NonexistentTitle"})
513513- AssertNoError(t, err, "Should not error when no notes found")
514514- AssertEqual(t, 0, len(notes), "Expected empty result set")
514514+ shared.AssertNoError(t, err, "Should not error when no notes found")
515515+ shared.AssertEqual(t, 0, len(notes), "Expected empty result set")
515516 })
516517 })
517518}