summaryrefslogtreecommitdiff
path: root/internal/api/server_test.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-16 04:24:19 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-16 04:24:19 +0000
commitd75a231d8865d9b14fbe3d608c9aa1bffb7ed386 (patch)
tree1875147811c1cbf5b85260dc5fc5be8986902f68 /internal/api/server_test.go
parent16ff7ca46bfb4af44af488fa95bd3f8e981f4db2 (diff)
feat: add deployment status endpoint for tasks
Adds GET /api/tasks/{id}/deployment-status which checks whether the currently-deployed server binary includes the fix commits from the task's latest execution. Uses git merge-base --is-ancestor to compare commit hashes against the running version. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/api/server_test.go')
-rw-r--r--internal/api/server_test.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/internal/api/server_test.go b/internal/api/server_test.go
index 4899a5c..5c0deba 100644
--- a/internal/api/server_test.go
+++ b/internal/api/server_test.go
@@ -1704,3 +1704,80 @@ func TestListExecutions_IncludesChangestats(t *testing.T) {
t.Errorf("lines_removed: want 20, got %v", csMap["lines_removed"])
}
}
+
+// TestDeploymentStatus_ReturnsStatusForReadyTask verifies that
+// GET /api/tasks/{id}/deployment-status returns a valid deployment status
+// with deployed_commit, fix_commits, and includes_fix fields.
+func TestDeploymentStatus_ReturnsStatusForReadyTask(t *testing.T) {
+ srv, store := testServer(t)
+
+ // Create a READY task using the walk-path helper.
+ tk := createTaskWithState(t, store, "deploy-status-task-1", task.StateReady)
+
+ // Create an execution with commits.
+ exec := &storage.Execution{
+ ID: "deploy-exec-1",
+ TaskID: tk.ID,
+ StartTime: time.Now(),
+ EndTime: time.Now(),
+ Status: "COMPLETED",
+ Commits: []task.GitCommit{
+ {Hash: "abc123def456", Message: "fix: resolve the bug"},
+ },
+ }
+ if err := store.CreateExecution(exec); err != nil {
+ t.Fatal(err)
+ }
+
+ // GET /api/tasks/{id}/deployment-status
+ req := httptest.NewRequest("GET", "/api/tasks/deploy-status-task-1/deployment-status", nil)
+ w := httptest.NewRecorder()
+ srv.Handler().ServeHTTP(w, req)
+
+ if w.Code != http.StatusOK {
+ t.Fatalf("want 200, got %d; body: %s", w.Code, w.Body.String())
+ }
+
+ var resp map[string]interface{}
+ if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
+ t.Fatalf("decode response: %v", err)
+ }
+
+ // deployed_commit must be present (will be "dev" in test environment).
+ if _, ok := resp["deployed_commit"]; !ok {
+ t.Error("response missing deployed_commit field")
+ }
+ // fix_commits must be an array.
+ fixCommits, ok := resp["fix_commits"]
+ if !ok {
+ t.Fatal("response missing fix_commits field")
+ }
+ commits, ok := fixCommits.([]interface{})
+ if !ok {
+ t.Fatalf("fix_commits is not an array: %T", fixCommits)
+ }
+ if len(commits) != 1 {
+ t.Fatalf("fix_commits length: want 1, got %d", len(commits))
+ }
+ commit := commits[0].(map[string]interface{})
+ if commit["hash"] != "abc123def456" {
+ t.Errorf("fix_commits[0].hash: want abc123def456, got %v", commit["hash"])
+ }
+ // includes_fix must be present (false in test env since version is "dev").
+ if _, ok := resp["includes_fix"]; !ok {
+ t.Error("response missing includes_fix field")
+ }
+}
+
+// TestDeploymentStatus_NotFound returns 404 for unknown task.
+func TestDeploymentStatus_NotFound(t *testing.T) {
+ srv, _ := testServer(t)
+
+ req := httptest.NewRequest("GET", "/api/tasks/nonexistent-task/deployment-status", nil)
+ w := httptest.NewRecorder()
+ srv.Handler().ServeHTTP(w, req)
+
+ if w.Code != http.StatusNotFound {
+ t.Fatalf("want 404, got %d", w.Code)
+ }
+}