251 lines
7.4 KiB
Go
251 lines
7.4 KiB
Go
package depot_test
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/flowy-live/llink/internal/depot"
|
|
"github.com/flowy-live/llink/internal/testhelper"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var dbPool *pgxpool.Pool
|
|
|
|
func TestMain(m *testing.M) {
|
|
dbPool = testhelper.SetupTestDB()
|
|
defer testhelper.TeardownTestDB()
|
|
|
|
ret := m.Run()
|
|
os.Exit(ret)
|
|
}
|
|
|
|
// TestDepotRepository tests the repository layer directly
|
|
// These tests can run without GCS since they only test database operations
|
|
func TestDepotRepository_CreateAndGet(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// Create a depot object directly in the database for testing
|
|
var id string
|
|
err := dbPool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id`,
|
|
"dpo_test123", "test-file.txt", "text/plain", int64(1024), "test-bucket", "test-key-123", false,
|
|
).Scan(&id)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "dpo_test123", id)
|
|
|
|
// Query the object back
|
|
var obj struct {
|
|
ID string
|
|
Name string
|
|
ContentType string
|
|
ContentLength int64
|
|
BucketName string
|
|
ObjectKey string
|
|
ContainsContent bool
|
|
CreatedAt time.Time
|
|
}
|
|
err = dbPool.QueryRow(ctx,
|
|
`SELECT id, name, content_type, content_length, bucket_name, object_key, contains_content, created_at
|
|
FROM depot_objects WHERE id = $1`,
|
|
id,
|
|
).Scan(&obj.ID, &obj.Name, &obj.ContentType, &obj.ContentLength,
|
|
&obj.BucketName, &obj.ObjectKey, &obj.ContainsContent, &obj.CreatedAt)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "test-file.txt", obj.Name)
|
|
assert.Equal(t, "text/plain", obj.ContentType)
|
|
assert.Equal(t, int64(1024), obj.ContentLength)
|
|
assert.Equal(t, "test-bucket", obj.BucketName)
|
|
assert.Equal(t, "test-key-123", obj.ObjectKey)
|
|
assert.False(t, obj.ContainsContent)
|
|
assert.False(t, obj.CreatedAt.IsZero())
|
|
|
|
// Clean up
|
|
_, err = dbPool.Exec(ctx, `DELETE FROM depot_objects WHERE id = $1`, id)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDepotRepository_ConfirmUpload(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// Create a depot object
|
|
var id string
|
|
err := dbPool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id`,
|
|
"dpo_confirm123", "confirm-file.txt", "text/plain", int64(2048), "test-bucket", "confirm-key", false,
|
|
).Scan(&id)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify it starts with contains_content = false
|
|
var containsContent bool
|
|
err = dbPool.QueryRow(ctx,
|
|
`SELECT contains_content FROM depot_objects WHERE id = $1`,
|
|
id,
|
|
).Scan(&containsContent)
|
|
assert.NoError(t, err)
|
|
assert.False(t, containsContent)
|
|
|
|
// Confirm upload
|
|
_, err = dbPool.Exec(ctx,
|
|
`UPDATE depot_objects SET contains_content = TRUE WHERE id = $1`,
|
|
id,
|
|
)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify it's now true
|
|
err = dbPool.QueryRow(ctx,
|
|
`SELECT contains_content FROM depot_objects WHERE id = $1`,
|
|
id,
|
|
).Scan(&containsContent)
|
|
assert.NoError(t, err)
|
|
assert.True(t, containsContent)
|
|
|
|
// Clean up
|
|
_, err = dbPool.Exec(ctx, `DELETE FROM depot_objects WHERE id = $1`, id)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDepotRepository_Delete(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// Create a depot object
|
|
var id string
|
|
err := dbPool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id`,
|
|
"dpo_delete123", "delete-file.txt", "text/plain", int64(512), "test-bucket", "delete-key", false,
|
|
).Scan(&id)
|
|
assert.NoError(t, err)
|
|
|
|
// Delete it
|
|
result, err := dbPool.Exec(ctx, `DELETE FROM depot_objects WHERE id = $1`, id)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, int64(1), result.RowsAffected())
|
|
|
|
// Verify it's gone
|
|
var count int
|
|
err = dbPool.QueryRow(ctx,
|
|
`SELECT COUNT(*) FROM depot_objects WHERE id = $1`,
|
|
id,
|
|
).Scan(&count)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 0, count)
|
|
}
|
|
|
|
func TestDepotRepository_Exists(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// Create a depot object
|
|
var id string
|
|
err := dbPool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id`,
|
|
"dpo_exists123", "exists-file.txt", "text/plain", int64(256), "test-bucket", "exists-key", true,
|
|
).Scan(&id)
|
|
assert.NoError(t, err)
|
|
|
|
// Check exists
|
|
var exists bool
|
|
err = dbPool.QueryRow(ctx,
|
|
`SELECT EXISTS(SELECT 1 FROM depot_objects WHERE id = $1)`,
|
|
id,
|
|
).Scan(&exists)
|
|
assert.NoError(t, err)
|
|
assert.True(t, exists)
|
|
|
|
// Check non-existent
|
|
err = dbPool.QueryRow(ctx,
|
|
`SELECT EXISTS(SELECT 1 FROM depot_objects WHERE id = $1)`,
|
|
"dpo_nonexistent",
|
|
).Scan(&exists)
|
|
assert.NoError(t, err)
|
|
assert.False(t, exists)
|
|
|
|
// Clean up
|
|
_, err = dbPool.Exec(ctx, `DELETE FROM depot_objects WHERE id = $1`, id)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDepotRepository_OrphanedIndex(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// Create an orphaned object (contains_content = false)
|
|
var orphanID string
|
|
err := dbPool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id`,
|
|
"dpo_orphan123", "orphan-file.txt", "text/plain", int64(128), "test-bucket", "orphan-key", false,
|
|
).Scan(&orphanID)
|
|
assert.NoError(t, err)
|
|
|
|
// Create a confirmed object (contains_content = true)
|
|
var confirmedID string
|
|
err = dbPool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id`,
|
|
"dpo_confirmed123", "confirmed-file.txt", "text/plain", int64(128), "test-bucket", "confirmed-key", true,
|
|
).Scan(&confirmedID)
|
|
assert.NoError(t, err)
|
|
|
|
// Query orphaned objects using the index
|
|
rows, err := dbPool.Query(ctx,
|
|
`SELECT id FROM depot_objects WHERE contains_content = FALSE`)
|
|
assert.NoError(t, err)
|
|
defer rows.Close()
|
|
|
|
var orphanedIDs []string
|
|
for rows.Next() {
|
|
var id string
|
|
err := rows.Scan(&id)
|
|
assert.NoError(t, err)
|
|
orphanedIDs = append(orphanedIDs, id)
|
|
}
|
|
|
|
// Our orphan should be in the list
|
|
assert.Contains(t, orphanedIDs, orphanID)
|
|
assert.NotContains(t, orphanedIDs, confirmedID)
|
|
|
|
// Clean up
|
|
_, err = dbPool.Exec(ctx, `DELETE FROM depot_objects WHERE id IN ($1, $2)`, orphanID, confirmedID)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// TestDepotModels tests the model structures
|
|
func TestDepotModels(t *testing.T) {
|
|
// Test Config defaults
|
|
config := depot.Config{
|
|
BucketName: "test-bucket",
|
|
}
|
|
assert.Equal(t, "test-bucket", config.BucketName)
|
|
assert.Equal(t, time.Duration(0), config.UploadURLExpiry)
|
|
assert.Equal(t, time.Duration(0), config.DownloadURLExpiry)
|
|
|
|
// Test with explicit values
|
|
config = depot.Config{
|
|
BucketName: "custom-bucket",
|
|
UploadURLExpiry: 10 * time.Minute,
|
|
DownloadURLExpiry: 12 * time.Hour,
|
|
}
|
|
assert.Equal(t, "custom-bucket", config.BucketName)
|
|
assert.Equal(t, 10*time.Minute, config.UploadURLExpiry)
|
|
assert.Equal(t, 12*time.Hour, config.DownloadURLExpiry)
|
|
}
|
|
|
|
// TestDepotErrors tests the error definitions
|
|
func TestDepotErrors(t *testing.T) {
|
|
assert.Error(t, depot.ErrNotFound)
|
|
assert.Error(t, depot.ErrInvalidInput)
|
|
assert.Equal(t, "object not found", depot.ErrNotFound.Error())
|
|
assert.Equal(t, "invalid input", depot.ErrInvalidInput.Error())
|
|
}
|