Problem: Tests were calling `defer setup.Close()` which was interfering with the library cleanup added in the previous commit. The execution order was: 1. setupTestServer() registers t.Cleanup() with library deletion code 2. Test calls defer setup.Close() 3. Test finishes: - defer setup.Close() runs FIRST → closes DB pool - t.Cleanup() runs SECOND → tries to delete libraries but DB is closed! This prevented "Job Status Test Library" and other test libraries from being cleaned up, leaving residual data in the database after tests. Root Cause: The setupTestServer() function already handles cleanup via t.Cleanup(), which calls setup.Close() at the end. The explicit defer calls were redundant and caused the database pool to close before library cleanup could execute. Solution: Removed all 17 occurrences of `defer setup.Close()` from test files: - worker_test.go: 4 tests - jobs_test.go: 7 tests - scan_settings_integration_test.go: 3 tests - library_browse_test.go: 1 test - goroutine_leak_test.go: 1 test - fsnotify_integration_test.go: 1 test Now setupTestServer()'s t.Cleanup() function properly: 1. Deletes "test" libraries (while DB is still connected) 2. Then calls setup.Close() to close connections This ensures all test libraries are cleaned up, leaving a clean database after `make test-integration` completes. Files changed: - cmd/server/tests/worker_test.go: Removed 4 defer calls - cmd/server/tests/jobs_test.go: Removed 7 defer calls - cmd/server/tests/scan_settings_integration_test.go: Removed 3 defer calls - cmd/server/tests/library_browse_test.go: Removed 1 defer call - cmd/server/tests/goroutine_leak_test.go: Removed 1 defer call - cmd/server/tests/fsnotify_integration_test.go: Removed 1 defer call
225 lines
5.9 KiB
Go
225 lines
5.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestJobsHandler_CreateJob(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
token := setup.Token
|
|
|
|
jobReq := map[string]interface{}{
|
|
"type": "import",
|
|
"params": map[string]interface{}{
|
|
"test": "data",
|
|
},
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", setup.Server.URL+"/api/jobs", bytes.NewBuffer(jsonMarshal(jobReq)))
|
|
require.NoError(t, err)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(t, err)
|
|
defer resp.Body.Close()
|
|
|
|
require.Equal(t, http.StatusAccepted, resp.StatusCode)
|
|
|
|
var response map[string]interface{}
|
|
err = json.NewDecoder(resp.Body).Decode(&response)
|
|
require.NoError(t, err)
|
|
|
|
assert.NotEmpty(t, response["job_id"])
|
|
assert.Equal(t, "Job created", response["message"])
|
|
assert.Equal(t, "import", response["type"])
|
|
assert.Equal(t, "pending", response["status"])
|
|
}
|
|
|
|
func TestJobsHandler_CreateJob_InvalidType(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
token := setup.Token
|
|
|
|
jobReq := map[string]interface{}{
|
|
"type": "invalid_job_type",
|
|
"params": map[string]interface{}{},
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", setup.Server.URL+"/api/jobs", bytes.NewBuffer(jsonMarshal(jobReq)))
|
|
require.NoError(t, err)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(t, err)
|
|
defer resp.Body.Close()
|
|
|
|
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
}
|
|
|
|
func TestJobsHandler_GetJobStatus(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
token := setup.Token
|
|
|
|
jobReq := map[string]interface{}{
|
|
"type": "import",
|
|
"params": map[string]interface{}{},
|
|
}
|
|
|
|
createReq, err := http.NewRequest("POST", setup.Server.URL+"/api/jobs", bytes.NewBuffer(jsonMarshal(jobReq)))
|
|
require.NoError(t, err)
|
|
createReq.Header.Set("Content-Type", "application/json")
|
|
createReq.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
createResp, err := client.Do(createReq)
|
|
require.NoError(t, err)
|
|
defer createResp.Body.Close()
|
|
|
|
var createResponse map[string]interface{}
|
|
err = json.NewDecoder(createResp.Body).Decode(&createResponse)
|
|
require.NoError(t, err)
|
|
|
|
jobID := createResponse["job_id"].(string)
|
|
require.NotEmpty(t, jobID)
|
|
|
|
getReq, err := http.NewRequest("GET", fmt.Sprintf("%s/api/jobs/%s", setup.Server.URL, jobID), nil)
|
|
require.NoError(t, err)
|
|
getReq.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
getResp, err := client.Do(getReq)
|
|
require.NoError(t, err)
|
|
defer getResp.Body.Close()
|
|
|
|
require.Equal(t, http.StatusOK, getResp.StatusCode)
|
|
|
|
var statusResponse map[string]interface{}
|
|
err = json.NewDecoder(getResp.Body).Decode(&statusResponse)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, jobID, statusResponse["job_id"])
|
|
}
|
|
|
|
func TestJobsHandler_GetJobStatus_NotFound(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
token := setup.Token
|
|
|
|
fakeJobID := uuid.New().String()
|
|
|
|
req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/jobs/%s", setup.Server.URL, fakeJobID), nil)
|
|
require.NoError(t, err)
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(t, err)
|
|
defer resp.Body.Close()
|
|
|
|
require.Equal(t, http.StatusNotFound, resp.StatusCode)
|
|
}
|
|
|
|
func TestJobsHandler_CreateAndTrackJob(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
token := setup.Token
|
|
|
|
jobReq := map[string]interface{}{
|
|
"type": "import",
|
|
"params": map[string]interface{}{},
|
|
}
|
|
|
|
createReq, err := http.NewRequest("POST", setup.Server.URL+"/api/jobs", bytes.NewBuffer(jsonMarshal(jobReq)))
|
|
require.NoError(t, err)
|
|
createReq.Header.Set("Content-Type", "application/json")
|
|
createReq.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
createResp, err := client.Do(createReq)
|
|
require.NoError(t, err)
|
|
defer createResp.Body.Close()
|
|
|
|
var createResponse map[string]interface{}
|
|
err = json.NewDecoder(createResp.Body).Decode(&createResponse)
|
|
require.NoError(t, err)
|
|
|
|
jobID := createResponse["job_id"].(string)
|
|
|
|
var finalStatus string
|
|
for i := 0; i < 20; i++ {
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
getReq, err := http.NewRequest("GET", fmt.Sprintf("%s/api/jobs/%s", setup.Server.URL, jobID), nil)
|
|
require.NoError(t, err)
|
|
getReq.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
getResp, err := client.Do(getReq)
|
|
require.NoError(t, err)
|
|
|
|
var statusResponse map[string]interface{}
|
|
err = json.NewDecoder(getResp.Body).Decode(&statusResponse)
|
|
getResp.Body.Close()
|
|
require.NoError(t, err)
|
|
|
|
if statusResponse["status"] != nil {
|
|
finalStatus = statusResponse["status"].(string)
|
|
if finalStatus == "completed" || finalStatus == "failed" {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
assert.True(t, finalStatus == "completed" || finalStatus == "failed",
|
|
fmt.Sprintf("Job should complete, got status: %s", finalStatus))
|
|
}
|
|
|
|
func TestJobsHandler_CreateJob_Unauthorized(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
jobReq := map[string]interface{}{
|
|
"type": "import",
|
|
"params": map[string]interface{}{},
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", setup.Server.URL+"/api/jobs", bytes.NewBuffer(jsonMarshal(jobReq)))
|
|
require.NoError(t, err)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(t, err)
|
|
defer resp.Body.Close()
|
|
|
|
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
}
|
|
|
|
func TestJobsHandler_GetJobStatus_Unauthorized(t *testing.T) {
|
|
setup := setupTestServer(t)
|
|
|
|
jobID := uuid.New().String()
|
|
|
|
req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/jobs/%s", setup.Server.URL, jobID), nil)
|
|
require.NoError(t, err)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(t, err)
|
|
defer resp.Body.Close()
|
|
|
|
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
}
|