package server import ( "context" "path/filepath" "testing" "git.wntrmute.dev/kyle/exo/blob" "git.wntrmute.dev/kyle/exo/db" pb "git.wntrmute.dev/kyle/exo/proto/exo/v1" ) func setup(t *testing.T) *ArtifactServer { t.Helper() dbPath := filepath.Join(t.TempDir(), "test.db") database, err := db.Open(dbPath) if err != nil { t.Fatalf("Open failed: %v", err) } t.Cleanup(func() { _ = database.Close() }) if err := db.Migrate(database); err != nil { t.Fatalf("Migrate failed: %v", err) } blobStore := blob.NewStore(t.TempDir()) return NewArtifactServer(database, blobStore) } func TestCreateAndGetArtifact(t *testing.T) { srv := setup(t) ctx := context.Background() createResp, err := srv.CreateArtifact(ctx, &pb.CreateArtifactRequest{ Artifact: &pb.Artifact{ Type: "Article", Citation: &pb.Citation{ Title: "Test Article", Year: 2024, Published: "2024-01-15 00:00:00", Authors: []string{"Alice", "Bob"}, Publisher: &pb.Publisher{Name: "Test Press", Address: "Testville"}, Source: "https://example.com/article", }, Tags: []string{"test", "grpc"}, Categories: []string{"cs/testing"}, }, }) if err != nil { t.Fatalf("CreateArtifact failed: %v", err) } if createResp.Id == "" { t.Fatal("expected non-empty artifact ID") } getResp, err := srv.GetArtifact(ctx, &pb.GetArtifactRequest{Id: createResp.Id}) if err != nil { t.Fatalf("GetArtifact failed: %v", err) } art := getResp.Artifact if art.Type != "Article" { t.Fatalf("type mismatch: got %q", art.Type) } if art.Citation.Title != "Test Article" { t.Fatalf("title mismatch: got %q", art.Citation.Title) } if len(art.Citation.Authors) != 2 { t.Fatalf("expected 2 authors, got %d", len(art.Citation.Authors)) } } func TestCreateTagAndList(t *testing.T) { srv := setup(t) ctx := context.Background() _, err := srv.CreateTag(ctx, &pb.CreateTagRequest{Tag: "alpha"}) if err != nil { t.Fatalf("CreateTag failed: %v", err) } _, err = srv.CreateTag(ctx, &pb.CreateTagRequest{Tag: "beta"}) if err != nil { t.Fatalf("CreateTag failed: %v", err) } resp, err := srv.ListTags(ctx, &pb.ListTagsRequest{}) if err != nil { t.Fatalf("ListTags failed: %v", err) } if len(resp.Tags) != 2 { t.Fatalf("expected 2 tags, got %d", len(resp.Tags)) } } func TestCreateCategoryAndList(t *testing.T) { srv := setup(t) ctx := context.Background() _, err := srv.CreateCategory(ctx, &pb.CreateCategoryRequest{Category: "cs/ai"}) if err != nil { t.Fatalf("CreateCategory failed: %v", err) } resp, err := srv.ListCategories(ctx, &pb.ListCategoriesRequest{}) if err != nil { t.Fatalf("ListCategories failed: %v", err) } if len(resp.Categories) != 1 || resp.Categories[0] != "cs/ai" { t.Fatalf("unexpected categories: %v", resp.Categories) } } func TestStoreBlobAndGet(t *testing.T) { srv := setup(t) ctx := context.Background() storeResp, err := srv.StoreBlob(ctx, &pb.StoreBlobRequest{ Format: "application/pdf", Data: []byte("fake PDF data"), }) if err != nil { t.Fatalf("StoreBlob failed: %v", err) } if storeResp.Id == "" { t.Fatal("expected non-empty blob ID") } getResp, err := srv.GetBlob(ctx, &pb.GetBlobRequest{Id: storeResp.Id}) if err != nil { t.Fatalf("GetBlob failed: %v", err) } if string(getResp.Data) != "fake PDF data" { t.Fatalf("blob data mismatch: %q", getResp.Data) } } func TestSearchByTag(t *testing.T) { srv := setup(t) ctx := context.Background() _, err := srv.CreateArtifact(ctx, &pb.CreateArtifactRequest{ Artifact: &pb.Artifact{ Type: "Paper", Citation: &pb.Citation{ Title: "Searchable Paper", Year: 2024, Published: "2024-06-01 00:00:00", Publisher: &pb.Publisher{Name: "ACM", Address: "NYC"}, Source: "test", }, Tags: []string{"searchable"}, }, }) if err != nil { t.Fatalf("CreateArtifact failed: %v", err) } resp, err := srv.SearchByTag(ctx, &pb.SearchByTagRequest{Tag: "searchable"}) if err != nil { t.Fatalf("SearchByTag failed: %v", err) } if len(resp.ArtifactIds) != 1 { t.Fatalf("expected 1 result, got %d", len(resp.ArtifactIds)) } } func TestCreateArtifactNil(t *testing.T) { srv := setup(t) ctx := context.Background() _, err := srv.CreateArtifact(ctx, &pb.CreateArtifactRequest{}) if err == nil { t.Fatal("expected error for nil artifact") } } func TestGetArtifactMissing(t *testing.T) { srv := setup(t) ctx := context.Background() _, err := srv.GetArtifact(ctx, &pb.GetArtifactRequest{Id: "nonexistent"}) if err == nil { t.Fatal("expected error for missing artifact") } }