Single-binary service: push raw markdown via REST/gRPC API, read rendered HTML through mobile-friendly web UI. MCIAS auth on all endpoints, SQLite storage, goldmark rendering with GFM and syntax highlighting. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
146 lines
2.9 KiB
Go
146 lines
2.9 KiB
Go
package db
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func openTestDB(t *testing.T) *DB {
|
|
t.Helper()
|
|
dbPath := filepath.Join(t.TempDir(), "test.db")
|
|
database, err := Open(dbPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := database.Migrate(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { database.Close() })
|
|
return database
|
|
}
|
|
|
|
func TestPutAndGetDocument(t *testing.T) {
|
|
db := openTestDB(t)
|
|
|
|
doc, err := db.PutDocument("test-slug", "Test Title", "# Hello", "kyle")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doc.Slug != "test-slug" {
|
|
t.Errorf("slug = %q, want %q", doc.Slug, "test-slug")
|
|
}
|
|
if doc.Title != "Test Title" {
|
|
t.Errorf("title = %q, want %q", doc.Title, "Test Title")
|
|
}
|
|
if doc.Body != "# Hello" {
|
|
t.Errorf("body = %q, want %q", doc.Body, "# Hello")
|
|
}
|
|
if doc.PushedBy != "kyle" {
|
|
t.Errorf("pushed_by = %q, want %q", doc.PushedBy, "kyle")
|
|
}
|
|
if doc.Read {
|
|
t.Error("new document should not be read")
|
|
}
|
|
|
|
got, err := db.GetDocument("test-slug")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got.Title != "Test Title" {
|
|
t.Errorf("got title = %q, want %q", got.Title, "Test Title")
|
|
}
|
|
}
|
|
|
|
func TestPutDocumentUpsert(t *testing.T) {
|
|
db := openTestDB(t)
|
|
|
|
_, err := db.PutDocument("slug", "V1", "body v1", "alice")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Mark as read.
|
|
_, err = db.MarkRead("slug")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Upsert — should replace and reset read flag.
|
|
doc, err := db.PutDocument("slug", "V2", "body v2", "bob")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doc.Title != "V2" {
|
|
t.Errorf("title = %q, want V2", doc.Title)
|
|
}
|
|
if doc.Body != "body v2" {
|
|
t.Errorf("body = %q, want body v2", doc.Body)
|
|
}
|
|
if doc.PushedBy != "bob" {
|
|
t.Errorf("pushed_by = %q, want bob", doc.PushedBy)
|
|
}
|
|
if doc.Read {
|
|
t.Error("upsert should reset read flag")
|
|
}
|
|
}
|
|
|
|
func TestListDocuments(t *testing.T) {
|
|
db := openTestDB(t)
|
|
|
|
_, _ = db.PutDocument("a", "A", "body", "user")
|
|
_, _ = db.PutDocument("b", "B", "body", "user")
|
|
|
|
docs, err := db.ListDocuments()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(docs) != 2 {
|
|
t.Fatalf("got %d docs, want 2", len(docs))
|
|
}
|
|
}
|
|
|
|
func TestDeleteDocument(t *testing.T) {
|
|
db := openTestDB(t)
|
|
|
|
_, _ = db.PutDocument("del", "Del", "body", "user")
|
|
if err := db.DeleteDocument("del"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err := db.GetDocument("del")
|
|
if err != ErrNotFound {
|
|
t.Errorf("got err = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteDocumentNotFound(t *testing.T) {
|
|
db := openTestDB(t)
|
|
|
|
err := db.DeleteDocument("nope")
|
|
if err != ErrNotFound {
|
|
t.Errorf("got err = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestMarkReadUnread(t *testing.T) {
|
|
db := openTestDB(t)
|
|
|
|
_, _ = db.PutDocument("rw", "RW", "body", "user")
|
|
|
|
doc, err := db.MarkRead("rw")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !doc.Read {
|
|
t.Error("expected read=true after MarkRead")
|
|
}
|
|
|
|
doc, err = db.MarkUnread("rw")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if doc.Read {
|
|
t.Error("expected read=false after MarkUnread")
|
|
}
|
|
}
|