tarakan/test/tarakan_web/controllers/api/work_controller_test.exs
Maxfield Luke af6077b9c3
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s
Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
2026-07-29 04:43:40 -04:00

601 lines
18 KiB
Elixir

defmodule TarakanWeb.API.WorkControllerTest do
use TarakanWeb.ConnCase, async: true
alias Tarakan.Accounts
alias Tarakan.Accounts.ApiCredentials
alias Tarakan.Repositories.Repository
alias Tarakan.Repo
alias Tarakan.Work
setup %{conn: conn} do
creator = github_account_fixture()
repository = listed_github_repository_fixture(creator)
worker = account_fixture()
worker_token = client_token(worker)
creator_token = client_token(creator)
%{
conn: conn,
creator: creator,
creator_token: creator_token,
repository: repository,
worker: worker,
worker_token: worker_token
}
end
defp authed(conn, token), do: put_req_header(conn, "authorization", "Bearer #{token}")
defp client_token(account) do
{:ok, token, _credential} =
ApiCredentials.create(account, %{
name: "work controller test",
scopes: ["tasks:read", "tasks:claim", "contributions:write"]
})
token
end
test "all work queue endpoints require an API token", %{conn: conn} do
conn = get(conn, ~p"/api/github.com/openai/codex/jobs")
assert json_response(conn, 401)["error"] =~ "API token"
end
test "lists the global open jobs queue", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn = conn |> authed(token) |> get(~p"/api/jobs")
assert %{"jobs" => jobs} = json_response(conn, 200)
assert Enum.any?(jobs, &(&1["id"] == task.id))
match = Enum.find(jobs, &(&1["id"] == task.id))
assert match["status"] == "open"
assert match["repository"]["owner"] == repository.owner
assert match["repository"]["name"] == repository.name
assert match["repository"]["primary_language"] == repository.primary_language
assert match["repository"]["stars_count"] == repository.stars_count
end
test "global jobs queue filters by language and min stars", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
# Fixture repo is Rust with 42000 stars (GitHub stub).
conn =
conn
|> authed(token)
|> get(~p"/api/jobs", %{"language" => "Rust", "min_stars" => "1000"})
assert %{"jobs" => jobs} = json_response(conn, 200)
assert Enum.any?(jobs, &(&1["id"] == task.id))
conn =
build_conn()
|> authed(token)
|> get(~p"/api/jobs", %{"language" => "Elixir"})
assert %{"jobs" => jobs} = json_response(conn, 200)
refute Enum.any?(jobs, &(&1["id"] == task.id))
conn =
build_conn()
|> authed(token)
|> get(~p"/api/jobs", %{"min_stars" => "999999"})
assert %{"jobs" => jobs} = json_response(conn, 200)
refute Enum.any?(jobs, &(&1["id"] == task.id))
end
# A worker declares what it can run so it never claims a kind it does not
# implement and then holds the lease until it expires.
test "global jobs queue filters by the kinds a worker can run", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn =
conn
|> authed(token)
|> get(~p"/api/jobs", %{"kinds" => "#{task.kind},refute_finding"})
assert %{"jobs" => jobs} = json_response(conn, 200)
assert Enum.any?(jobs, &(&1["id"] == task.id))
conn =
build_conn()
|> authed(token)
|> get(~p"/api/jobs", %{"kinds" => "reproduce_finding"})
assert %{"jobs" => jobs} = json_response(conn, 200)
refute Enum.any?(jobs, &(&1["id"] == task.id))
end
# An old client and a new server must still be able to talk, so a name the
# server does not know is dropped rather than erroring or filtering to empty.
test "unknown kind names are ignored rather than rejected", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn =
conn
|> authed(token)
|> get(~p"/api/jobs", %{"kinds" => "not_a_real_kind"})
assert %{"jobs" => jobs} = json_response(conn, 200)
assert Enum.any?(jobs, &(&1["id"] == task.id))
end
test "global jobs queue includes the caller's active claims", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: token
} do
task =
review_task_fixture(repository, creator, %{"kind" => "code_review", "capability" => "agent"})
{:ok, claimed} = Work.claim_task(task, worker)
assert claimed.status == "claimed"
conn = conn |> authed(token) |> get(~p"/api/jobs")
assert %{"jobs" => jobs} = json_response(conn, 200)
match = Enum.find(jobs, &(&1["id"] == claimed.id))
assert match
assert match["status"] == "claimed"
assert match["lease"]["active"] == true
end
test "lists a repository's tasks with client-ready relationships", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn = conn |> authed(token) |> get(~p"/api/github.com/openai/codex/jobs")
assert %{"jobs" => [response]} = json_response(conn, 200)
assert response["id"] == task.id
assert response["kind"] == "threat_model"
assert response["capability"] == "human"
assert response["status"] == "open"
assert response["visibility"] == "public"
assert response["commit_sha"] == task.commit_sha
assert response["commit_committed_at"] == "2026-07-01T12:00:00.000000Z"
assert response["repository"]["canonical_url"] == "https://github.com/openai/codex"
assert response["repository"]["host"] == "github.com"
assert response["repository"]["id"] == repository.id
assert response["repository"]["name"] == "codex"
assert response["repository"]["owner"] == "openai"
assert response["repository"]["participation_mode"] == repository.participation_mode
assert response["repository"]["record_url"] =~ "/github.com/openai/codex"
assert response["creator"]["id"] == creator.id
assert response["creator"]["handle"] == creator.handle
assert response["creator"] |> Map.keys() |> Enum.sort() == ["handle", "id"]
assert response["claimant"] == nil
assert response["lease"] == nil
assert response["contribution"] == nil
assert response["job_url"] =~ "/jobs/#{task.id}"
end
test "returns an empty list and 404s an unregistered repository", %{
conn: conn,
worker_token: token
} do
conn1 = conn |> authed(token) |> get(~p"/api/github.com/openai/codex/jobs")
assert json_response(conn1, 200) == %{"jobs" => []}
conn2 =
conn
|> recycle()
|> authed(token)
|> get(~p"/api/github.com/unknown/repository/jobs")
assert json_response(conn2, 404)["error"] =~ "not registered"
end
test "does not disclose a quarantined repository to an unrelated credential", %{
conn: conn,
repository: repository,
worker_token: token
} do
_contained =
repository
|> Repository.listing_changeset(%{listing_status: "quarantined"})
|> Repo.update!()
conn = conn |> authed(token) |> get(~p"/api/github.com/openai/codex/jobs")
assert json_response(conn, 404)["error"] =~ "not registered"
end
test "shows a task and returns 404 for missing or malformed ids", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn1 = conn |> authed(token) |> get(~p"/api/jobs/#{task.id}")
assert json_response(conn1, 200)["id"] == task.id
conn2 = conn |> recycle() |> authed(token) |> get("/api/jobs/not-an-id")
assert json_response(conn2, 404)["error"] == "job not found"
conn3 = conn |> recycle() |> authed(token) |> get("/api/jobs/999999999")
assert json_response(conn3, 404)["error"] == "job not found"
end
test "claims a task and exposes the active lease", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn = conn |> authed(token) |> post(~p"/api/jobs/#{task.id}/claim")
response = json_response(conn, 200)
assert response["status"] == "claimed"
assert response["claimant"]["id"] == worker.id
assert response["lease"]["active"] == true
assert response["lease"]["claimed_at"]
assert response["lease"]["expires_at"]
original_expiry = response["lease"]["expires_at"]
conn =
conn
|> recycle()
|> authed(token)
|> post(~p"/api/jobs/#{task.id}/claim")
repeated = json_response(conn, 200)
assert repeated["claimant"]["id"] == worker.id
assert repeated["lease"]["expires_at"] == original_expiry
end
test "creators may claim their own jobs; active claims conflict for others", %{
conn: conn,
creator: creator,
creator_token: creator_token,
repository: repository,
worker_token: worker_token
} do
task = review_task_fixture(repository, creator)
# Solo/hosted workflow: job creators may claim and perform their own Jobs.
conn1 = conn |> authed(creator_token) |> post(~p"/api/jobs/#{task.id}/claim")
assert json_response(conn1, 200)["claimant"]["id"] == creator.id
conn_release =
conn |> recycle() |> authed(creator_token) |> delete(~p"/api/jobs/#{task.id}/claim")
assert json_response(conn_release, 200)["status"] == "open"
conn2 = conn |> recycle() |> authed(worker_token) |> post(~p"/api/jobs/#{task.id}/claim")
assert json_response(conn2, 200)
outsider = account_fixture()
outsider_token = client_token(outsider)
conn3 = conn |> recycle() |> authed(outsider_token) |> post(~p"/api/jobs/#{task.id}/claim")
assert json_response(conn3, 409)["error"] =~ "active claim"
end
test "only the claimant can release a task", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: worker_token
} do
task = review_task_fixture(repository, creator)
{:ok, task} = Work.claim_task(task, worker)
outsider_token = client_token(account_fixture())
conn1 = conn |> authed(outsider_token) |> delete(~p"/api/jobs/#{task.id}/claim")
assert json_response(conn1, 403)["error"] =~ "current claimant"
conn2 =
conn
|> recycle()
|> authed(worker_token)
|> delete(~p"/api/jobs/#{task.id}/claim")
response = json_response(conn2, 200)
assert response["status"] == "open"
assert response["claimant"] == nil
assert response["lease"] == nil
end
test "claimant can renew an active lease", %{
conn: conn,
creator: creator,
repository: repository,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn = conn |> authed(token) |> post(~p"/api/jobs/#{task.id}/claim")
first = json_response(conn, 200)
conn =
conn
|> recycle()
|> authed(token)
|> post(~p"/api/jobs/#{task.id}/claim/renew")
renewed = json_response(conn, 200)
assert renewed["lease"]["active"]
assert renewed["lease"]["expires_at"] >= first["lease"]["expires_at"]
end
test "completion path submits a claimed task for independent review", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: token
} do
task = review_task_fixture(repository, creator)
{:ok, task} = Work.claim_task(task, worker)
body = %{
"provenance" => "hybrid",
"summary" => "The authorization boundary is enforced.",
"evidence" => "Reviewed both entry points and ran the focused regression test."
}
conn = conn |> authed(token) |> post(~p"/api/jobs/#{task.id}/complete", body)
response = json_response(conn, 200)
assert response["status"] == "submitted"
assert response["visibility"] == "public"
assert response["submitted_at"]
assert response["completed_at"] == nil
assert response["lease"]["active"] == false
assert response["contribution"] == %{
"contributor" => %{
"handle" => worker.handle,
"id" => worker.id
},
"evidence" => body["evidence"],
"id" => response["contribution"]["id"],
"version" => 1,
"provenance" => "hybrid",
"submitted_at" => response["contribution"]["submitted_at"],
"summary" => body["summary"]
}
conn2 =
conn
|> recycle()
|> authed(token)
|> delete(~p"/api/jobs/#{task.id}/claim")
assert json_response(conn2, 403)["error"] =~ "current claimant"
end
test "completion requires the active claimant and valid evidence metadata", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: token
} do
task = review_task_fixture(repository, creator)
conn1 =
conn
|> authed(token)
|> post(~p"/api/jobs/#{task.id}/complete", %{
"provenance" => "human",
"summary" => "Completed",
"evidence" => "Attempted submission without first holding the task's active claim."
})
assert json_response(conn1, 403)["error"] =~ "current claimant"
{:ok, _task} = Work.claim_task(task, worker)
conn2 =
conn
|> recycle()
|> authed(token)
|> post(~p"/api/jobs/#{task.id}/complete", %{
"provenance" => "unverifiable",
"summary" => ""
})
errors = json_response(conn2, 422)["errors"]
assert errors["provenance"] == ["is invalid"]
assert errors["summary"] == ["can't be blank"]
end
test "completion provenance must satisfy the requested capability", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: token
} do
task = review_task_fixture(repository, creator, %{"capability" => "hybrid"})
{:ok, _task} = Work.claim_task(task, worker)
conn =
conn
|> authed(token)
|> post(~p"/api/jobs/#{task.id}/complete", %{
"provenance" => "human",
"summary" => "Manual review completed.",
"evidence" => "Manually traced the requested paths and recorded reproducible notes."
})
assert json_response(conn, 422)["errors"]["provenance"] == [
"does not satisfy this task's required capability"
]
end
test "proposals are publicly listed and publishing is not exposed to client credentials", %{
conn: conn,
creator: creator,
repository: repository,
creator_token: creator_token,
worker_token: worker_token
} do
proposal = proposed_review_task_fixture(repository, creator)
conn1 =
conn
|> authed(worker_token)
|> get(~p"/api/github.com/openai/codex/jobs")
assert [listed] = json_response(conn1, 200)["jobs"]
assert listed["id"] == proposal.id
assert listed["status"] == "proposed"
assert listed["visibility"] == "public"
conn2 =
conn
|> recycle()
|> authed(creator_token)
|> get(~p"/api/jobs/#{proposal.id}")
assert json_response(conn2, 200)["status"] == "proposed"
moderator = moderator_account_fixture()
moderator_token = Accounts.create_account_api_token(moderator)
conn3 =
conn
|> recycle()
|> authed(moderator_token)
|> post("/api/jobs/#{proposal.id}/publish", %{
"reason" => "The task scope is safe, bounded, and useful to contributors."
})
assert response(conn3, 404) == "Not Found"
assert {:ok, open} =
Work.publish_task(proposal, moderator, %{
"reason" => "The task scope is safe, bounded, and useful to contributors."
})
assert open.status == "open"
end
test "acceptance is not exposed to client credentials", %{
conn: conn,
creator: creator,
repository: repository,
worker: worker,
worker_token: worker_token
} do
task = review_task_fixture(repository, creator)
{:ok, task} = Work.claim_task(task, worker)
{:ok, submitted} =
Work.submit_task(task, worker, %{
"provenance" => "human",
"summary" => "The requested boundary was independently traced.",
"evidence" => "Ran the negative authorization suite against both repository entry points."
})
conn1 =
conn
|> authed(worker_token)
|> post("/api/jobs/#{submitted.id}/accept", %{
"reason" => "I should not be allowed to approve my own contribution.",
"evidence" => "This evidence comes from the original contributor and is not independent."
})
assert response(conn1, 404) == "Not Found"
reviewer = moderator_account_fixture()
reviewer_token = Accounts.create_account_api_token(reviewer)
assert Work.get_visible_task(submitted.id, Tarakan.Accounts.Scope.for_account(reviewer))
conn2 =
conn
|> recycle()
|> authed(reviewer_token)
|> post("/api/jobs/#{submitted.id}/accept", %{
"reason" => "The result was independently reproduced at the pinned commit.",
"evidence" => "Checked out the pinned SHA and ran the documented negative-path tests."
})
assert response(conn2, 404) == "Not Found"
assert {:ok, accepted} =
Work.accept_task(submitted, reviewer, %{
"reason" => "The result was independently reproduced at the pinned commit.",
"evidence" =>
"Checked out the pinned SHA and ran the documented negative-path tests."
})
assert accepted.status == "accepted"
assert accepted.visibility == "public"
outsider = account_fixture()
outsider_token = Accounts.create_account_api_token(outsider)
conn3 =
conn
|> recycle()
|> authed(outsider_token)
|> get(~p"/api/jobs/#{accepted.id}")
response = json_response(conn3, 200)
assert response["status"] == "accepted"
assert response["visibility"] == "public"
assert response["contribution"]["summary"] =~ "boundary"
assert response["contribution"]["evidence"] =~ "negative authorization suite"
assert {:ok, redacted} =
Work.disclose_task(accepted, reviewer, "public_summary", %{
"reason" =>
"The redacted result is safe and useful without publishing raw evidence."
})
conn4 =
conn
|> recycle()
|> authed(outsider_token)
|> get(~p"/api/jobs/#{redacted.id}")
response = json_response(conn4, 200)
assert response["visibility"] == "public_summary"
assert response["contribution"]["summary"] =~ "boundary"
assert response["contribution"]["evidence"] == nil
assert response["decisions"] == []
assert response["disclosed_at"]
assert response["sensitive_data_reviewed"] == false
end
end