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) }