diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-12 20:26:47 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-12 20:26:47 -0800 |
| commit | 281e3ec0a8cfcf06d8e358e5d397a828b9a6f456 (patch) | |
| tree | bd4acfec418d4143699d0ac4db572af29003135e /api/api_test.go | |
| parent | 16186a344a7b61633cb7342aac37ac56ad83d261 (diff) | |
| download | neko-281e3ec0a8cfcf06d8e358e5d397a828b9a6f456.tar.gz neko-281e3ec0a8cfcf06d8e358e5d397a828b9a6f456.tar.bz2 neko-281e3ec0a8cfcf06d8e358e5d397a828b9a6f456.zip | |
Refactor backend to a clean REST API
- Created new 'api' package with testable router and RESTful handlers
- Handlers in 'api' use proper HTTP methods and status codes
- Standardized JSON responses and error handling
- Refactored 'web' package to delegate logic to 'api'
- Maintained backward compatibility for legacy frontend routes
- Simplified 'web/web_test.go' and added comprehensive 'api/api_test.go'
- All tests passing with improved modularity
Diffstat (limited to 'api/api_test.go')
| -rw-r--r-- | api/api_test.go | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/api/api_test.go b/api/api_test.go new file mode 100644 index 0000000..45b0123 --- /dev/null +++ b/api/api_test.go @@ -0,0 +1,151 @@ +package api + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "strconv" + "testing" + + "adammathes.com/neko/config" + "adammathes.com/neko/models" + "adammathes.com/neko/models/feed" + "adammathes.com/neko/models/item" +) + +func setupTestDB(t *testing.T) { + t.Helper() + config.Config.DBFile = ":memory:" + models.InitDB() + t.Cleanup(func() { + if models.DB != nil { + models.DB.Close() + } + }) +} + +func seedData(t *testing.T) { + t.Helper() + f := &feed.Feed{Url: "http://example.com", Title: "Test Feed", Category: "tech"} + f.Create() + + i := &item.Item{ + Title: "Test Item", + Url: "http://example.com/1", + FeedId: f.Id, + } + i.Create() +} + +func TestStream(t *testing.T) { + setupTestDB(t) + seedData(t) + router := NewRouter() + + req := httptest.NewRequest("GET", "/stream", nil) + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + + if rr.Code != http.StatusOK { + t.Errorf("expected 200, got %d", rr.Code) + } + + var items []item.Item + json.NewDecoder(rr.Body).Decode(&items) + if len(items) != 1 { + t.Errorf("expected 1 item, got %d", len(items)) + } +} + +func TestFeedCRUD(t *testing.T) { + setupTestDB(t) + router := NewRouter() + + // Create + f := feed.Feed{Url: "http://example.com", Title: "New Feed"} + b, _ := json.Marshal(f) + req := httptest.NewRequest("POST", "/feed", bytes.NewBuffer(b)) + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + + if rr.Code != http.StatusCreated { + t.Errorf("expected 201, got %d", rr.Code) + } + + // List + req = httptest.NewRequest("GET", "/feed", nil) + rr = httptest.NewRecorder() + router.ServeHTTP(rr, req) + + var feeds []feed.Feed + json.NewDecoder(rr.Body).Decode(&feeds) + if len(feeds) != 1 { + t.Errorf("expected 1 feed, got %d", len(feeds)) + } + + feedID := feeds[0].Id + + // Update + feeds[0].Title = "Updated Title" + b, _ = json.Marshal(feeds[0]) + req = httptest.NewRequest("PUT", "/feed", bytes.NewBuffer(b)) + rr = httptest.NewRecorder() + router.ServeHTTP(rr, req) + + if rr.Code != http.StatusOK { + t.Errorf("expected 200, got %d", rr.Code) + } + + // Delete + req = httptest.NewRequest("DELETE", "/feed/"+strconv.FormatInt(feedID, 10), nil) + rr = httptest.NewRecorder() + router.ServeHTTP(rr, req) + + if rr.Code != http.StatusNoContent { + t.Errorf("expected 204, got %d", rr.Code) + } +} + +func TestItemUpdate(t *testing.T) { + setupTestDB(t) + seedData(t) + router := NewRouter() + + // Get an item first to know its ID + var id int64 + err := models.DB.QueryRow("SELECT id FROM item LIMIT 1").Scan(&id) + if err != nil { + t.Fatal(err) + } + + i := item.Item{Id: id, ReadState: true} + b, _ := json.Marshal(i) + req := httptest.NewRequest("PUT", "/item/"+strconv.FormatInt(id, 10), bytes.NewBuffer(b)) + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + + if rr.Code != http.StatusOK { + t.Errorf("expected 200, got %d", rr.Code) + } +} + +func TestGetCategories(t *testing.T) { + setupTestDB(t) + seedData(t) + router := NewRouter() + + req := httptest.NewRequest("GET", "/tag", nil) + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + + if rr.Code != http.StatusOK { + t.Errorf("expected 200, got %d", rr.Code) + } + + var cats []feed.Category + json.NewDecoder(rr.Body).Decode(&cats) + if len(cats) != 1 { + t.Errorf("expected 1 category, got %d", len(cats)) + } +} |
