aboutsummaryrefslogtreecommitdiffstats
path: root/exporter/exporter_test.go
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-12 19:55:05 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-12 19:55:05 -0800
commit16186a344a7b61633cb7342aac37ac56ad83d261 (patch)
tree739556a9dc80457d072a6f3ab1db4226fa25a9f5 /exporter/exporter_test.go
parent39ed5fcfe9327ab4eb81c4863d9e6353f08f6c07 (diff)
downloadneko-16186a344a7b61633cb7342aac37ac56ad83d261.tar.gz
neko-16186a344a7b61633cb7342aac37ac56ad83d261.tar.bz2
neko-16186a344a7b61633cb7342aac37ac56ad83d261.zip
Add comprehensive test suite — 81% cross-package coverage
Bug fixes: - config: remove unused log import - item: fix Printf format %d->%t for boolean ReadState - util: update stale config.Read -> config.Init, remove config.Config.DBServer Test files added: - config/config_test.go: Init, readConfig, addDefaults (100%) - vlog/vlog_test.go: Printf, Println verbose/silent (100%) - models/db_test.go: InitDB tests - models/feed/feed_test.go: CRUD, filter, Categories, NewFeed, ResolveFeedURL (87%) - models/item/item_test.go: CRUD, Filter with category/search/starred, rewriteImages (71%) - exporter/exporter_test.go: all export formats (91%) - importer/importer_test.go: InsertIItem, ImportJSON (90%) - crawler/crawler_test.go: GetFeedContent, CrawlFeed, CrawlWorker, Crawl (89%) - web/web_test.go: auth, login/logout, stream, item, feed, category, export, crawl, imageProxy handlers (77%) Remaining 0% functions require HTTP/rice.MustFindBox/main entry and can't be unit tested without refactoring (see tickets NK-gqkh96, NK-6q9nyg).
Diffstat (limited to 'exporter/exporter_test.go')
-rw-r--r--exporter/exporter_test.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/exporter/exporter_test.go b/exporter/exporter_test.go
new file mode 100644
index 0000000..d4cc994
--- /dev/null
+++ b/exporter/exporter_test.go
@@ -0,0 +1,111 @@
+package exporter
+
+import (
+ "encoding/json"
+ "strings"
+ "testing"
+
+ "adammathes.com/neko/config"
+ "adammathes.com/neko/models"
+)
+
+func setupTestDB(t *testing.T) {
+ t.Helper()
+ config.Config.DBFile = ":memory:"
+ models.InitDB()
+ t.Cleanup(func() {
+ if models.DB != nil {
+ models.DB.Close()
+ }
+ })
+}
+
+func seedFeeds(t *testing.T) {
+ t.Helper()
+ _, err := models.DB.Exec("INSERT INTO feed(url, web_url, title, category) VALUES(?, ?, ?, ?)",
+ "https://a.com/feed", "https://a.com", "Alpha Feed", "tech")
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = models.DB.Exec("INSERT INTO feed(url, web_url, title, category) VALUES(?, ?, ?, ?)",
+ "https://b.com/feed", "https://b.com", "Beta Feed", "news")
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestExportText(t *testing.T) {
+ setupTestDB(t)
+ seedFeeds(t)
+
+ result := ExportFeeds("text")
+ if !strings.Contains(result, "https://a.com/feed") {
+ t.Error("text export should contain feed URL a")
+ }
+ if !strings.Contains(result, "https://b.com/feed") {
+ t.Error("text export should contain feed URL b")
+ }
+}
+
+func TestExportJSON(t *testing.T) {
+ setupTestDB(t)
+ seedFeeds(t)
+
+ result := ExportFeeds("json")
+ var feeds []interface{}
+ err := json.Unmarshal([]byte(result), &feeds)
+ if err != nil {
+ t.Fatalf("JSON export should be valid JSON: %v", err)
+ }
+ if len(feeds) != 2 {
+ t.Errorf("JSON export should contain 2 feeds, got %d", len(feeds))
+ }
+}
+
+func TestExportOPML(t *testing.T) {
+ setupTestDB(t)
+ seedFeeds(t)
+
+ result := ExportFeeds("opml")
+ if !strings.Contains(result, "<opml") {
+ t.Error("OPML export should contain opml tag")
+ }
+ if !strings.Contains(result, "Alpha Feed") || !strings.Contains(result, "Beta Feed") {
+ t.Error("OPML export should contain feed titles")
+ }
+ if !strings.Contains(result, "</opml>") {
+ t.Error("OPML export should close opml tag")
+ }
+}
+
+func TestExportHTML(t *testing.T) {
+ setupTestDB(t)
+ seedFeeds(t)
+
+ result := ExportFeeds("html")
+ if !strings.Contains(result, "<html>") {
+ t.Error("HTML export should contain html tag")
+ }
+ if !strings.Contains(result, "Alpha Feed") {
+ t.Error("HTML export should contain feed title")
+ }
+}
+
+func TestExportUnknownFormat(t *testing.T) {
+ setupTestDB(t)
+ seedFeeds(t)
+
+ result := ExportFeeds("unknown")
+ if result != "" {
+ t.Errorf("Unknown format should return empty string, got %q", result)
+ }
+}
+
+func TestExportEmpty(t *testing.T) {
+ setupTestDB(t)
+
+ result := ExportFeeds("text")
+ if result != "" {
+ t.Errorf("Export with no feeds should be empty, got %q", result)
+ }
+}