agent/pkg/agentic/status_logic_test.go
Snider 23bb62a116 fix: eliminate path/filepath from all test files
29 test files migrated: filepath.Join→core.JoinPath,
filepath.Dir→core.PathDir, filepath.Base→core.PathBase,
filepath.IsAbs→core.PathIsAbs. Test dogfooding complete for filepath.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:39:41 +00:00

176 lines
4.9 KiB
Go

// SPDX-License-Identifier: EUPL-1.2
package agentic
import (
"encoding/json"
"testing"
"time"
core "dappco.re/go/core"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// --- ReadStatus ---
func TestStatus_ReadStatus_Good_AllFields(t *testing.T) {
dir := t.TempDir()
now := time.Now().Truncate(time.Second)
original := WorkspaceStatus{
Status: "running",
Agent: "claude:opus",
Repo: "go-io",
Org: "core",
Task: "add observability",
Branch: "agent/add-observability",
Issue: 7,
PID: 42100,
StartedAt: now,
UpdatedAt: now,
Question: "",
Runs: 2,
PRURL: "",
}
data, err := json.MarshalIndent(original, "", " ")
require.NoError(t, err)
require.True(t, fs.Write(core.JoinPath(dir, "status.json"), string(data)).OK)
st, err := ReadStatus(dir)
require.NoError(t, err)
assert.Equal(t, original.Status, st.Status)
assert.Equal(t, original.Agent, st.Agent)
assert.Equal(t, original.Repo, st.Repo)
assert.Equal(t, original.Org, st.Org)
assert.Equal(t, original.Task, st.Task)
assert.Equal(t, original.Branch, st.Branch)
assert.Equal(t, original.Issue, st.Issue)
assert.Equal(t, original.PID, st.PID)
assert.Equal(t, original.Runs, st.Runs)
}
func TestStatus_ReadStatus_Bad_MissingFile(t *testing.T) {
dir := t.TempDir()
_, err := ReadStatus(dir)
assert.Error(t, err, "missing status.json must return an error")
}
func TestStatus_ReadStatus_Bad_CorruptJSON(t *testing.T) {
dir := t.TempDir()
require.True(t, fs.Write(core.JoinPath(dir, "status.json"), `{"status": "running", broken`).OK)
_, err := ReadStatus(dir)
assert.Error(t, err, "corrupt JSON must return an error")
}
func TestStatus_ReadStatus_Bad_NullJSON(t *testing.T) {
dir := t.TempDir()
require.True(t, fs.Write(core.JoinPath(dir, "status.json"), "null").OK)
// null is valid JSON — ReadStatus returns a zero-value struct, not an error
st, err := ReadStatus(dir)
require.NoError(t, err)
assert.Equal(t, "", st.Status)
}
// --- writeStatus ---
func TestStatus_WriteStatus_Good_WritesAndReadsBack(t *testing.T) {
dir := t.TempDir()
st := &WorkspaceStatus{
Status: "queued",
Agent: "gemini:pro",
Repo: "go-log",
Task: "improve logging",
Runs: 0,
}
err := writeStatus(dir, st)
require.NoError(t, err)
read, err := ReadStatus(dir)
require.NoError(t, err)
assert.Equal(t, "queued", read.Status)
assert.Equal(t, "gemini:pro", read.Agent)
assert.Equal(t, "go-log", read.Repo)
assert.Equal(t, "improve logging", read.Task)
}
func TestStatus_WriteStatus_Good_SetsUpdatedAt(t *testing.T) {
dir := t.TempDir()
before := time.Now().Add(-time.Millisecond)
st := &WorkspaceStatus{Status: "failed", Agent: "codex"}
err := writeStatus(dir, st)
require.NoError(t, err)
assert.True(t, st.UpdatedAt.After(before), "writeStatus must set UpdatedAt to a recent time")
}
func TestStatus_WriteStatus_Good_Overwrites(t *testing.T) {
dir := t.TempDir()
require.NoError(t, writeStatus(dir, &WorkspaceStatus{Status: "running", Agent: "gemini"}))
require.NoError(t, writeStatus(dir, &WorkspaceStatus{Status: "completed", Agent: "gemini"}))
st, err := ReadStatus(dir)
require.NoError(t, err)
assert.Equal(t, "completed", st.Status)
}
// --- WorkspaceStatus JSON round-trip ---
func TestWorkspaceStatus_Good_JSONRoundTrip(t *testing.T) {
now := time.Now().Truncate(time.Second)
original := WorkspaceStatus{
Status: "blocked",
Agent: "codex:gpt-5.4",
Repo: "agent",
Org: "core",
Task: "write more tests",
Branch: "agent/write-more-tests",
Issue: 15,
PID: 99001,
StartedAt: now,
UpdatedAt: now,
Question: "Which pattern should I use?",
Runs: 3,
PRURL: "https://forge.lthn.ai/core/agent/pulls/10",
}
data, err := json.Marshal(original)
require.NoError(t, err)
var decoded WorkspaceStatus
require.NoError(t, json.Unmarshal(data, &decoded))
assert.Equal(t, original.Status, decoded.Status)
assert.Equal(t, original.Agent, decoded.Agent)
assert.Equal(t, original.Repo, decoded.Repo)
assert.Equal(t, original.Org, decoded.Org)
assert.Equal(t, original.Task, decoded.Task)
assert.Equal(t, original.Branch, decoded.Branch)
assert.Equal(t, original.Issue, decoded.Issue)
assert.Equal(t, original.PID, decoded.PID)
assert.Equal(t, original.Question, decoded.Question)
assert.Equal(t, original.Runs, decoded.Runs)
assert.Equal(t, original.PRURL, decoded.PRURL)
}
func TestWorkspaceStatus_Good_OmitemptyFields(t *testing.T) {
st := WorkspaceStatus{Status: "queued", Agent: "claude"}
data, err := json.Marshal(st)
require.NoError(t, err)
// Optional fields with omitempty must be absent when zero
jsonStr := string(data)
assert.NotContains(t, jsonStr, `"org"`)
assert.NotContains(t, jsonStr, `"branch"`)
assert.NotContains(t, jsonStr, `"question"`)
assert.NotContains(t, jsonStr, `"pr_url"`)
assert.NotContains(t, jsonStr, `"pid"`)
assert.NotContains(t, jsonStr, `"issue"`)
}