Files
linkshare/internal/database/links/links_test.go

330 lines
7.0 KiB
Go

package links_test
import (
"os"
"testing"
"time"
"git.omicron.one/omicron/linkshare/internal/database"
"git.omicron.one/omicron/linkshare/internal/database/links"
)
func setupTestDB(t *testing.T) (*database.DB, string) {
t.Helper()
cwd, err := os.Getwd()
t.Logf("Current working directory: %s", cwd)
// Create temp file for database
tempFile, err := os.CreateTemp("", "linkshare-links-test-*.db")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
tempFile.Close()
dbPath := tempFile.Name()
// Open database
db, err := database.Open(dbPath)
if err != nil {
os.Remove(dbPath)
t.Fatalf("Failed to open database: %v", err)
}
// Initialize database with schema
err = db.Initialize("../../../schema")
if err != nil {
db.Close()
os.Remove(dbPath)
t.Fatalf("Failed to initialize database: %v", err)
}
return db, dbPath
}
func TestRepository_Create(t *testing.T) {
db, dbPath := setupTestDB(t)
defer func() {
db.Close()
os.Remove(dbPath)
}()
repo := links.NewRepository(db)
// Test creating a link
id, err := repo.Create("https://example.com", "Example", false)
if err != nil {
t.Fatalf("Failed to create link: %v", err)
}
if id <= 0 {
t.Fatalf("Expected positive ID, got %d", id)
}
// Verify link was created by retrieving it
link, err := repo.Get(id)
if err != nil {
t.Fatalf("Failed to get link: %v", err)
}
if link.URL != "https://example.com" {
t.Errorf("Expected URL 'https://example.com', got '%s'", link.URL)
}
}
func TestRepository_Get(t *testing.T) {
db, dbPath := setupTestDB(t)
defer func() {
db.Close()
os.Remove(dbPath)
}()
repo := links.NewRepository(db)
// Insert test data
id, err := repo.Create("https://example.com", "Example", true)
if err != nil {
t.Fatalf("Failed to create link: %v", err)
}
// Test getting a link
link, err := repo.Get(id)
if err != nil {
t.Fatalf("Failed to get link: %v", err)
}
if link.ID != id {
t.Errorf("Expected ID %d, got %d", id, link.ID)
}
if link.URL != "https://example.com" {
t.Errorf("Expected URL 'https://example.com', got '%s'", link.URL)
}
if link.Title != "Example" {
t.Errorf("Expected Title 'Example', got '%s'", link.Title)
}
if link.IsPrivate != true {
t.Errorf("Expected IsPrivate true, got %v", link.IsPrivate)
}
if link.UpdatedAt.IsSome() {
t.Errorf("Expected UpdatedAt to be None, got %v", link.UpdatedAt)
}
// Test getting non-existent link
_, err = repo.Get(id + 1)
if err == nil {
t.Fatal("Expected error when getting non-existent link")
}
}
func TestRepository_Update(t *testing.T) {
db, dbPath := setupTestDB(t)
defer func() {
db.Close()
os.Remove(dbPath)
}()
repo := links.NewRepository(db)
// Insert test data
id, err := repo.Create("https://example.com", "Example", false)
if err != nil {
t.Fatalf("Failed to create link: %v", err)
}
// Test updating a link
err = repo.Update(id, "https://updated.com", "Updated", true)
if err != nil {
t.Fatalf("Failed to update link: %v", err)
}
// Verify link was updated
link, err := repo.Get(id)
if err != nil {
t.Fatalf("Failed to get link: %v", err)
}
if link.URL != "https://updated.com" {
t.Errorf("Expected URL 'https://updated.com', got '%s'", link.URL)
}
if link.Title != "Updated" {
t.Errorf("Expected Title 'Updated', got '%s'", link.Title)
}
if link.IsPrivate != true {
t.Errorf("Expected IsPrivate true, got %v", link.IsPrivate)
}
if !link.UpdatedAt.IsSome() {
t.Error("Expected UpdatedAt to be set")
}
}
func TestRepository_Delete(t *testing.T) {
db, dbPath := setupTestDB(t)
defer func() {
db.Close()
os.Remove(dbPath)
}()
repo := links.NewRepository(db)
// Insert test data
id, err := repo.Create("https://example.com", "Example", false)
if err != nil {
t.Fatalf("Failed to create link: %v", err)
}
// Test deleting a link
err = repo.Delete(id)
if err != nil {
t.Fatalf("Failed to delete link: %v", err)
}
// Verify link was deleted
_, err = repo.Get(id)
if err == nil {
t.Fatal("Expected error after deletion")
}
}
func TestRepository_List(t *testing.T) {
db, dbPath := setupTestDB(t)
defer func() {
db.Close()
os.Remove(dbPath)
}()
repo := links.NewRepository(db)
// Insert test data
urls := []struct {
url string
isPrivate bool
}{
{"https://example1.com", true},
{"https://example2.com", false},
{"https://example3.com", false},
{"https://example4.com", true},
{"https://example5.com", false},
}
for i, info := range urls {
_, err := repo.Create(info.url, "Example "+string(rune('A'+i)), info.isPrivate)
if err != nil {
t.Fatalf("Failed to create link: %v", err)
}
// Add a small delay to ensure different created_at times
time.Sleep(10 * time.Millisecond)
}
// Test full listing with pagination
links, err := repo.List(true, 0, 3)
if err != nil {
t.Fatalf("Failed to list links: %v", err)
}
if len(links) != 3 {
t.Fatalf("Expected 3 links, got %d", len(links))
}
// Check order (newest first)
for i := 0; i < len(links)-1; i++ {
if links[i].CreatedAt.Before(links[i+1].CreatedAt) {
t.Errorf("Links not in correct order")
}
}
// Test second page of full listing
links, err = repo.List(true, 3, 2)
if err != nil {
t.Fatalf("Failed to list links: %v", err)
}
if len(links) != 2 {
t.Fatalf("Expected 2 links, got %d", len(links))
}
// Test public listing
links, err = repo.List(false, 0, 3)
if err != nil {
t.Fatalf("Failed to list links: %v", err)
}
if len(links) != 3 {
t.Fatalf("Expected 3 links, got %d", len(links))
}
for _, link := range links {
if link.IsPrivate {
t.Fatalf("private link in public listing %v", link)
}
}
// Try to get more public links
links, err = repo.List(false, 3, 3)
if err != nil {
t.Fatalf("Failed to list links: %v", err)
}
if len(links) != 0 {
t.Fatalf("Expected 0 links, got %d", len(links))
}
}
func TestRepository_Count(t *testing.T) {
db, dbPath := setupTestDB(t)
defer func() {
db.Close()
os.Remove(dbPath)
}()
repo := links.NewRepository(db)
// Check full count with empty table
count, err := repo.Count(true)
if err != nil {
t.Fatalf("Failed to count links: %v", err)
}
if count != 0 {
t.Fatalf("Expected 0 links, got %d", count)
}
// Check public count with empty table
count, err = repo.Count(false)
if err != nil {
t.Fatalf("Failed to count links: %v", err)
}
if count != 0 {
t.Fatalf("Expected 0 links, got %d", count)
}
// Insert test data
numLinks := 5
for i := 0; i < numLinks; i++ {
_, err := repo.Create(
"https://example"+string(rune('1'+i))+".com",
"Example "+string(rune('A'+i)),
i%2 == 1,
)
if err != nil {
t.Fatalf("Failed to create link: %v", err)
}
}
pubLinks := numLinks / 2
// Check full count again
count, err = repo.Count(true)
if err != nil {
t.Fatalf("Failed to count links: %v", err)
}
if count != numLinks {
t.Fatalf("Expected %d links, got %d", numLinks, count)
}
// Check public count again
count, err = repo.Count(false)
if err != nil {
t.Fatalf("Failed to count links: %v", err)
}
if count != pubLinks {
t.Fatalf("Expected %d links, got %d", pubLinks, count)
}
}