Files
spore-registry/main_test.go
2025-10-21 22:43:18 +02:00

280 lines
7.4 KiB
Go

package main
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"testing"
"spore-registry/internal/database"
"spore-registry/internal/handlers"
"spore-registry/internal/models"
"spore-registry/internal/repository"
"spore-registry/internal/service"
"spore-registry/internal/storage"
_ "github.com/mattn/go-sqlite3"
)
// setupTestDB creates a temporary database for testing
func setupTestDB(t *testing.T) (*database.DB, *storage.FileStorage, *handlers.FirmwareHandler) {
// Create temporary directory for test registry
tmpDir, err := os.MkdirTemp("", "registry_test")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
// Clean up temporary directory after test
defer func() {
os.RemoveAll(tmpDir)
}()
// Create test database
db, err := database.NewDB(":memory:")
if err != nil {
t.Fatalf("Failed to open test database: %v", err)
}
// Create repository
repo := repository.NewFirmwareRepository(db.GetConnection())
// Create storage
fileStorage := storage.NewFileStorage(tmpDir)
// Create service
firmwareService := service.NewFirmwareService(repo, fileStorage)
// Create handler
handler := handlers.NewFirmwareHandler(firmwareService)
return db, fileStorage, handler
}
func TestStoreFirmwareMetadata(t *testing.T) {
db, _, _ := setupTestDB(t)
defer db.Close()
metadata := models.FirmwareMetadata{
Name: "test-firmware",
Version: "1.0.0",
Labels: map[string]string{
"app": "test",
},
}
// Create a test service to test the repository directly
repo := repository.NewFirmwareRepository(db.GetConnection())
fileStorage := storage.NewFileStorage("/tmp")
service := service.NewFirmwareService(repo, fileStorage)
_, err := service.UploadFirmware(metadata, bytes.NewReader([]byte("test data")))
if err != nil {
t.Fatalf("Failed to upload firmware: %v", err)
}
// Verify the record was stored by listing firmware
grouped, err := service.ListFirmware("", "")
if err != nil {
t.Fatalf("Failed to retrieve firmware records: %v", err)
}
if len(grouped) != 1 {
t.Fatalf("Expected 1 group, got %d", len(grouped))
}
if len(grouped[0].Firmware) != 1 {
t.Fatalf("Expected 1 firmware record, got %d", len(grouped[0].Firmware))
}
record := grouped[0].Firmware[0]
if record.Name != metadata.Name {
t.Errorf("Expected name %s, got %s", metadata.Name, record.Name)
}
if record.Version != metadata.Version {
t.Errorf("Expected version %s, got %s", metadata.Version, record.Version)
}
if record.Labels["app"] != "test" {
t.Errorf("Expected label app=test, got %s", record.Labels["app"])
}
}
func TestGetFirmwareRecordsWithFilters(t *testing.T) {
db, _, _ := setupTestDB(t)
defer db.Close()
// Create a test service to test the repository directly
repo := repository.NewFirmwareRepository(db.GetConnection())
fileStorage := storage.NewFileStorage("/tmp")
service := service.NewFirmwareService(repo, fileStorage)
// Insert test data
testRecords := []models.FirmwareMetadata{
{Name: "firmware1", Version: "1.0.0", Labels: map[string]string{"type": "app"}},
{Name: "firmware1", Version: "1.1.0", Labels: map[string]string{"type": "app"}},
{Name: "firmware2", Version: "1.0.0", Labels: map[string]string{"type": "sensor"}},
}
for _, record := range testRecords {
_, err := service.UploadFirmware(record, bytes.NewReader([]byte("test data")))
if err != nil {
t.Fatalf("Failed to store test data: %v", err)
}
}
// Test filtering by name
grouped, err := service.ListFirmware("firmware1", "")
if err != nil {
t.Fatalf("Failed to get records by name: %v", err)
}
if len(grouped) != 1 || len(grouped[0].Firmware) != 2 {
t.Errorf("Expected 1 group with 2 records for firmware1, got %d groups", len(grouped))
}
// Test filtering by version
grouped, err = service.ListFirmware("", "1.0.0")
if err != nil {
t.Fatalf("Failed to get records by version: %v", err)
}
if len(grouped) != 2 {
t.Errorf("Expected 2 groups for version 1.0.0, got %d", len(grouped))
}
// Test filtering by both name and version
grouped, err = service.ListFirmware("firmware1", "1.0.0")
if err != nil {
t.Fatalf("Failed to get records by name and version: %v", err)
}
if len(grouped) != 1 || len(grouped[0].Firmware) != 1 {
t.Errorf("Expected 1 group with 1 record for firmware1/1.0.0, got %d groups", len(grouped))
}
}
func TestStoreFirmwareBinary(t *testing.T) {
db, fileStorage, _ := setupTestDB(t)
defer db.Close()
testData := []byte("test firmware binary data")
reader := bytes.NewReader(testData)
filePath, size, err := fileStorage.StoreFirmwareBinary("test", "1.0.0", reader)
if err != nil {
t.Fatalf("Failed to store firmware binary: %v", err)
}
if size != int64(len(testData)) {
t.Errorf("Expected size %d, got %d", len(testData), size)
}
// Verify file was created
if _, err := os.Stat(filePath); os.IsNotExist(err) {
t.Errorf("Firmware file was not created at %s", filePath)
}
// Verify file contents
storedData, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("Failed to read stored file: %v", err)
}
if !bytes.Equal(testData, storedData) {
t.Error("Stored file contents don't match original data")
}
}
func TestListFirmwareAPI(t *testing.T) {
db, _, handler := setupTestDB(t)
defer db.Close()
// Create a test service to test the repository directly
repo := repository.NewFirmwareRepository(db.GetConnection())
fileStorage := storage.NewFileStorage("/tmp")
service := service.NewFirmwareService(repo, fileStorage)
// Insert test data
metadata := models.FirmwareMetadata{
Name: "test-firmware",
Version: "1.0.0",
Labels: map[string]string{"app": "test"},
}
_, err := service.UploadFirmware(metadata, bytes.NewReader([]byte("test data")))
if err != nil {
t.Fatalf("Failed to store test data: %v", err)
}
// Test GET /firmware
req := httptest.NewRequest("GET", "/firmware", nil)
w := httptest.NewRecorder()
handler.ListFirmware(w, req)
if w.Code != http.StatusOK {
t.Errorf("Expected status 200, got %d", w.Code)
}
var grouped []models.GroupedFirmware
err = json.Unmarshal(w.Body.Bytes(), &grouped)
if err != nil {
t.Fatalf("Failed to parse response: %v", err)
}
if len(grouped) != 1 {
t.Errorf("Expected 1 group, got %d", len(grouped))
}
}
func TestHealthCheckAPI(t *testing.T) {
db, _, handler := setupTestDB(t)
defer db.Close()
req := httptest.NewRequest("GET", "/health", nil)
w := httptest.NewRecorder()
handler.HealthCheck(w, req)
if w.Code != http.StatusOK {
t.Errorf("Expected status 200, got %d", w.Code)
}
var response models.HealthResponse
err := json.Unmarshal(w.Body.Bytes(), &response)
if err != nil {
t.Fatalf("Failed to parse response: %v", err)
}
if response.Status != "healthy" {
t.Errorf("Expected status 'healthy', got '%s'", response.Status)
}
}
func TestInvalidFirmwarePath(t *testing.T) {
db, _, handler := setupTestDB(t)
defer db.Close()
// Test invalid path (too many parts)
req := httptest.NewRequest("GET", "/firmware/invalid/path/extra", nil)
w := httptest.NewRecorder()
handler.DownloadFirmware(w, req)
if w.Code != http.StatusBadRequest {
t.Errorf("Expected status 400, got %d", w.Code)
}
}
func TestFirmwareNotFound(t *testing.T) {
db, _, handler := setupTestDB(t)
defer db.Close()
// Test firmware not found
req := httptest.NewRequest("GET", "/firmware/nonexistent/1.0.0", nil)
w := httptest.NewRecorder()
handler.DownloadFirmware(w, req)
if w.Code != http.StatusNotFound {
t.Errorf("Expected status 404, got %d", w.Code)
}
}