test: batch 4 — fill 36 testable gaps, 802 tests, AX-7 89%
- commands.go: factory wrapper Good/Bad/Ugly - dispatch.go: containerCommand Bad - queue.go: UnmarshalYAML/loadAgentsConfig Good/Bad/Ugly - remote.go: resolveHost/remoteToken Bad/Ugly - remote_client.go: setHeaders Bad - prep.go: TestPrepWorkspace/TestBuildPrompt public API GBU - prep.go: sanitise Good tests (collapseRepeatedRune, sanitisePlanSlug, trimRuneEdges) - ingest.go: ingestFindings/createIssueViaAPI Ugly - scan.go: scan Good - runner.go: Poke Ugly, StartRunner Bad/Ugly - process_register.go: ProcessRegister Good/Bad/Ugly AX-7: 462/516 filled (89%), 152/172 functions complete Coverage: 77.2%, 802 tests Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
eeaed52256
commit
c0bc7675a1
11 changed files with 541 additions and 0 deletions
|
|
@ -757,6 +757,68 @@ func TestCommands_CmdRunTask_Ugly_MixedIssueString(t *testing.T) {
|
|||
assert.False(t, r.OK)
|
||||
}
|
||||
|
||||
// --- CmdRunTaskFactory Good/Bad/Ugly ---
|
||||
|
||||
func TestCommands_CmdRunTaskFactory_Good(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fn := s.cmdRunTaskFactory(ctx)
|
||||
assert.NotNil(t, fn, "factory should return a non-nil func")
|
||||
}
|
||||
|
||||
func TestCommands_CmdRunTaskFactory_Bad(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel() // cancelled ctx
|
||||
|
||||
fn := s.cmdRunTaskFactory(ctx)
|
||||
assert.NotNil(t, fn, "factory should return a func even with cancelled ctx")
|
||||
}
|
||||
|
||||
func TestCommands_CmdRunTaskFactory_Ugly(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fn := s.cmdRunTaskFactory(ctx)
|
||||
// Call with empty options — should fail gracefully (missing repo+task)
|
||||
r := fn(core.NewOptions())
|
||||
assert.False(t, r.OK)
|
||||
}
|
||||
|
||||
// --- CmdOrchestratorFactory Good/Bad/Ugly ---
|
||||
|
||||
func TestCommands_CmdOrchestratorFactory_Good(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fn := s.cmdOrchestratorFactory(ctx)
|
||||
assert.NotNil(t, fn, "factory should return a non-nil func")
|
||||
}
|
||||
|
||||
func TestCommands_CmdOrchestratorFactory_Bad(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel() // cancelled ctx
|
||||
|
||||
fn := s.cmdOrchestratorFactory(ctx)
|
||||
assert.NotNil(t, fn, "factory should return a func even with cancelled ctx")
|
||||
}
|
||||
|
||||
func TestCommands_CmdOrchestratorFactory_Ugly(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel() // pre-cancelled
|
||||
|
||||
fn := s.cmdOrchestratorFactory(ctx)
|
||||
// Calling the factory result with a cancelled ctx should return OK (exits immediately)
|
||||
r := fn(core.NewOptions())
|
||||
assert.True(t, r.OK)
|
||||
}
|
||||
|
||||
// --- CmdStatus Bad/Ugly ---
|
||||
|
||||
func TestCommands_CmdStatus_Bad_NoWorkspaceDir(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -485,6 +485,20 @@ func TestDispatch_WorkspaceDir_Ugly(t *testing.T) {
|
|||
assert.Contains(t, dir, "pr-3")
|
||||
}
|
||||
|
||||
// --- containerCommand ---
|
||||
|
||||
func TestDispatch_ContainerCommand_Bad(t *testing.T) {
|
||||
t.Setenv("AGENT_DOCKER_IMAGE", "")
|
||||
t.Setenv("DIR_HOME", "/home/dev")
|
||||
|
||||
// Empty command string — docker still runs, just with no command after image
|
||||
cmd, args := containerCommand("codex", "", []string{}, "/ws/repo", "/ws/.meta")
|
||||
assert.Equal(t, "docker", cmd)
|
||||
assert.Contains(t, args, "run")
|
||||
// The image should still be present in args
|
||||
assert.Contains(t, args, defaultDockerImage)
|
||||
}
|
||||
|
||||
// --- canDispatchAgent ---
|
||||
// Good: tested in queue_test.go
|
||||
// Bad: tested in queue_test.go
|
||||
|
|
|
|||
|
|
@ -276,6 +276,62 @@ func TestIngest_CountFileRefs_Good_SecurityFindings(t *testing.T) {
|
|||
assert.Equal(t, 2, countFileRefs(body))
|
||||
}
|
||||
|
||||
// --- IngestFindings Ugly ---
|
||||
|
||||
func TestIngest_IngestFindings_Ugly(t *testing.T) {
|
||||
// Workspace with no findings file (completed but empty meta dir)
|
||||
wsDir := t.TempDir()
|
||||
require.NoError(t, writeStatus(wsDir, &WorkspaceStatus{
|
||||
Status: "completed",
|
||||
Repo: "go-io",
|
||||
Agent: "codex",
|
||||
}))
|
||||
// No agent-*.log files at all
|
||||
|
||||
s := &PrepSubsystem{
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Should return early without panic — no log files
|
||||
assert.NotPanics(t, func() {
|
||||
s.ingestFindings(wsDir)
|
||||
})
|
||||
}
|
||||
|
||||
// --- CreateIssueViaAPI Ugly ---
|
||||
|
||||
func TestIngest_CreateIssueViaAPI_Ugly(t *testing.T) {
|
||||
// Issue body with HTML injection chars — should be passed as-is without panic
|
||||
called := false
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
called = true
|
||||
var body map[string]string
|
||||
json.NewDecoder(r.Body).Decode(&body)
|
||||
// Verify the body preserved HTML chars
|
||||
assert.Contains(t, body["description"], "<script>")
|
||||
assert.Contains(t, body["description"], "alert('xss')")
|
||||
w.WriteHeader(201)
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
home := t.TempDir()
|
||||
t.Setenv("DIR_HOME", home)
|
||||
require.True(t, fs.EnsureDir(filepath.Join(home, ".claude")).OK)
|
||||
require.True(t, fs.Write(filepath.Join(home, ".claude", "agent-api.key"), "test-key").OK)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
brainURL: srv.URL,
|
||||
brainKey: "test-brain-key",
|
||||
client: srv.Client(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
s.createIssueViaAPI("go-io", "XSS Test", "<script>alert('xss')</script><b>bold</b>&", "bug", "high", "scan")
|
||||
assert.True(t, called)
|
||||
}
|
||||
|
||||
func TestIngest_CountFileRefs_Good_PHPSecurityFindings(t *testing.T) {
|
||||
body := "PHP audit:\n" +
|
||||
"- `src/Controller/Api.php:42` SQL injection risk\n" +
|
||||
|
|
|
|||
|
|
@ -472,6 +472,35 @@ func TestPrep_BrainRecall_Ugly(t *testing.T) {
|
|||
assert.Equal(t, 0, count)
|
||||
}
|
||||
|
||||
// --- PrepWorkspace Ugly ---
|
||||
|
||||
func TestPrep_PrepWorkspace_Ugly(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Repo name "." — should be rejected as invalid
|
||||
_, _, err := s.prepWorkspace(context.Background(), nil, PrepInput{
|
||||
Repo: ".",
|
||||
Issue: 1,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "invalid repo name")
|
||||
|
||||
// Repo name ".." — should be rejected as invalid
|
||||
_, _, err2 := s.prepWorkspace(context.Background(), nil, PrepInput{
|
||||
Repo: "..",
|
||||
Issue: 1,
|
||||
})
|
||||
assert.Error(t, err2)
|
||||
assert.Contains(t, err2.Error(), "invalid repo name")
|
||||
}
|
||||
|
||||
// --- findConsumersList Ugly ---
|
||||
|
||||
func TestPrep_FindConsumersList_Ugly(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -513,6 +513,134 @@ func TestPrep_DetectBuildCmd_Ugly(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
// --- TestPrepWorkspace (public API wrapper) ---
|
||||
|
||||
func TestPrep_TestPrepWorkspace_Good(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Valid input but repo won't exist — still exercises the public wrapper delegation
|
||||
_, _, err := s.TestPrepWorkspace(context.Background(), PrepInput{
|
||||
Repo: "go-io",
|
||||
Issue: 1,
|
||||
})
|
||||
// Error expected (no local clone) but we verified it delegates to prepWorkspace
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestPrep_TestPrepWorkspace_Bad(t *testing.T) {
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Missing repo — should return error
|
||||
_, _, err := s.TestPrepWorkspace(context.Background(), PrepInput{})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "repo is required")
|
||||
}
|
||||
|
||||
func TestPrep_TestPrepWorkspace_Ugly(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Bare ".." is caught as invalid repo name by PathBase check
|
||||
_, _, err := s.TestPrepWorkspace(context.Background(), PrepInput{
|
||||
Repo: "..",
|
||||
Issue: 1,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "invalid repo name")
|
||||
}
|
||||
|
||||
// --- TestBuildPrompt (public API wrapper) ---
|
||||
|
||||
func TestPrep_TestBuildPrompt_Good(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
require.True(t, fs.Write(filepath.Join(dir, "go.mod"), "module test").OK)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
prompt, memories, consumers := s.TestBuildPrompt(context.Background(), PrepInput{
|
||||
Task: "Review code",
|
||||
Org: "core",
|
||||
Repo: "go-io",
|
||||
}, "dev", dir)
|
||||
|
||||
assert.NotEmpty(t, prompt)
|
||||
assert.Contains(t, prompt, "TASK: Review code")
|
||||
assert.Contains(t, prompt, "REPO: core/go-io on branch dev")
|
||||
assert.Equal(t, 0, memories)
|
||||
assert.Equal(t, 0, consumers)
|
||||
}
|
||||
|
||||
func TestPrep_TestBuildPrompt_Bad(t *testing.T) {
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Empty inputs — should still return a prompt string without panicking
|
||||
prompt, memories, consumers := s.TestBuildPrompt(context.Background(), PrepInput{}, "", "")
|
||||
assert.NotEmpty(t, prompt)
|
||||
assert.Contains(t, prompt, "TASK:")
|
||||
assert.Contains(t, prompt, "CONSTRAINTS:")
|
||||
assert.Equal(t, 0, memories)
|
||||
assert.Equal(t, 0, consumers)
|
||||
}
|
||||
|
||||
func TestPrep_TestBuildPrompt_Ugly(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Unicode in all fields — should not panic
|
||||
prompt, _, _ := s.TestBuildPrompt(context.Background(), PrepInput{
|
||||
Task: "\u00e9nchantr\u00efx \u2603 \U0001f600",
|
||||
Org: "c\u00f6re",
|
||||
Repo: "g\u00f6-i\u00f6",
|
||||
}, "\u00e9-branch", dir)
|
||||
|
||||
assert.NotEmpty(t, prompt)
|
||||
assert.Contains(t, prompt, "\u00e9nchantr\u00efx")
|
||||
}
|
||||
|
||||
// --- collapseRepeatedRune / sanitisePlanSlug / trimRuneEdges Good ---
|
||||
|
||||
func TestPrep_CollapseRepeatedRune_Good(t *testing.T) {
|
||||
assert.Equal(t, "hello-world", collapseRepeatedRune("hello---world", '-'))
|
||||
}
|
||||
|
||||
func TestPrep_SanitisePlanSlug_Good(t *testing.T) {
|
||||
assert.Equal(t, "my-cool-plan", sanitisePlanSlug("My Cool Plan"))
|
||||
}
|
||||
|
||||
func TestPrep_TrimRuneEdges_Good(t *testing.T) {
|
||||
assert.Equal(t, "hello", trimRuneEdges("--hello--", '-'))
|
||||
}
|
||||
|
||||
// --- DetectTestCmd Bad/Ugly ---
|
||||
|
||||
func TestPrep_DetectTestCmd_Bad(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -491,6 +491,106 @@ func TestQueue_DrainOne_Ugly_QueuedButInBackoffWindow(t *testing.T) {
|
|||
|
||||
// --- DrainQueue Bad ---
|
||||
|
||||
// --- UnmarshalYAML (renamed convention) ---
|
||||
|
||||
func TestQueue_UnmarshalYAML_Good(t *testing.T) {
|
||||
var cfg struct {
|
||||
Limit ConcurrencyLimit `yaml:"limit"`
|
||||
}
|
||||
err := yaml.Unmarshal([]byte("limit: 5"), &cfg)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, cfg.Limit.Total)
|
||||
assert.Nil(t, cfg.Limit.Models)
|
||||
}
|
||||
|
||||
func TestQueue_UnmarshalYAML_Bad(t *testing.T) {
|
||||
var cfg struct {
|
||||
Limit ConcurrencyLimit `yaml:"limit"`
|
||||
}
|
||||
// Invalid YAML — nested map with bad types
|
||||
err := yaml.Unmarshal([]byte("limit: [1, 2, 3]"), &cfg)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestQueue_UnmarshalYAML_Ugly(t *testing.T) {
|
||||
var cfg struct {
|
||||
Limit ConcurrencyLimit `yaml:"limit"`
|
||||
}
|
||||
// Float value — YAML truncates to int, so 3.5 becomes 3
|
||||
err := yaml.Unmarshal([]byte("limit: 3.5"), &cfg)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 3, cfg.Limit.Total)
|
||||
assert.Nil(t, cfg.Limit.Models)
|
||||
}
|
||||
|
||||
// --- loadAgentsConfig ---
|
||||
|
||||
func TestQueue_LoadAgentsConfig_Good(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
|
||||
cfg := `version: 1
|
||||
concurrency:
|
||||
claude: 1
|
||||
codex: 2
|
||||
rates:
|
||||
codex:
|
||||
sustained_delay: 60`
|
||||
require.True(t, fs.Write(core.JoinPath(root, "agents.yaml"), cfg).OK)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
loaded := s.loadAgentsConfig()
|
||||
assert.NotNil(t, loaded)
|
||||
assert.Equal(t, 1, loaded.Version)
|
||||
assert.Equal(t, 1, loaded.Concurrency["claude"].Total)
|
||||
assert.Equal(t, 2, loaded.Concurrency["codex"].Total)
|
||||
assert.Equal(t, 60, loaded.Rates["codex"].SustainedDelay)
|
||||
}
|
||||
|
||||
func TestQueue_LoadAgentsConfig_Bad(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
|
||||
// Corrupt YAML file
|
||||
require.True(t, fs.Write(core.JoinPath(root, "agents.yaml"), "{{{not yaml!!!").OK)
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
// Should return defaults when YAML is corrupt
|
||||
loaded := s.loadAgentsConfig()
|
||||
assert.NotNil(t, loaded)
|
||||
assert.Equal(t, "claude", loaded.Dispatch.DefaultAgent)
|
||||
}
|
||||
|
||||
func TestQueue_LoadAgentsConfig_Ugly(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
// No agents.yaml file at all — should return defaults
|
||||
|
||||
s := &PrepSubsystem{
|
||||
codePath: t.TempDir(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
loaded := s.loadAgentsConfig()
|
||||
assert.NotNil(t, loaded)
|
||||
assert.Equal(t, "claude", loaded.Dispatch.DefaultAgent)
|
||||
assert.Equal(t, "coding", loaded.Dispatch.DefaultTemplate)
|
||||
assert.NotNil(t, loaded.Concurrency)
|
||||
}
|
||||
|
||||
// --- DrainQueue Bad ---
|
||||
|
||||
func TestQueue_DrainQueue_Bad_FrozenQueueDoesNothing(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
|
|
|
|||
|
|
@ -162,6 +162,57 @@ func TestRunner_StartRunner_Good_AutoStartEnvVar(t *testing.T) {
|
|||
assert.False(t, s.frozen, "CORE_AGENT_DISPATCH=1 should unfreeze the queue")
|
||||
}
|
||||
|
||||
// --- Poke Ugly ---
|
||||
|
||||
func TestRunner_Poke_Ugly(t *testing.T) {
|
||||
// Poke on a closed channel — the select with default protects against panic
|
||||
// but closing + sending would panic. However, Poke uses non-blocking send,
|
||||
// so we test that pokeCh=nil is safe (already tested), and that
|
||||
// double-filling is safe (already tested). Here we test rapid multi-poke.
|
||||
s := &PrepSubsystem{}
|
||||
s.pokeCh = make(chan struct{}, 1)
|
||||
|
||||
// Rapid-fire pokes — should all be safe
|
||||
for i := 0; i < 100; i++ {
|
||||
assert.NotPanics(t, func() { s.Poke() })
|
||||
}
|
||||
// Channel should have at most 1 signal
|
||||
assert.LessOrEqual(t, len(s.pokeCh), 1)
|
||||
}
|
||||
|
||||
// --- StartRunner Bad/Ugly ---
|
||||
|
||||
func TestRunner_StartRunner_Bad(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
t.Setenv("CORE_AGENT_DISPATCH", "")
|
||||
|
||||
s := NewPrep()
|
||||
s.StartRunner()
|
||||
// Without CORE_AGENT_DISPATCH=1, queue should be frozen
|
||||
assert.True(t, s.frozen, "queue must be frozen when CORE_AGENT_DISPATCH is not set")
|
||||
assert.NotNil(t, s.pokeCh)
|
||||
}
|
||||
|
||||
func TestRunner_StartRunner_Ugly(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
t.Setenv("CORE_WORKSPACE", root)
|
||||
t.Setenv("CORE_AGENT_DISPATCH", "1")
|
||||
|
||||
s := NewPrep()
|
||||
|
||||
// Start twice — second call overwrites pokeCh
|
||||
s.StartRunner()
|
||||
firstCh := s.pokeCh
|
||||
assert.NotNil(t, firstCh)
|
||||
|
||||
s.StartRunner()
|
||||
secondCh := s.pokeCh
|
||||
assert.NotNil(t, secondCh)
|
||||
// The channels should be different objects (new make each time)
|
||||
assert.NotSame(t, &firstCh, &secondCh)
|
||||
}
|
||||
|
||||
// --- DefaultBranch ---
|
||||
|
||||
func TestPaths_DefaultBranch_Good_DefaultsToMain(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,36 @@ func TestRegister_Good_AgentsConfigLoaded(t *testing.T) {
|
|||
assert.NotNil(t, concurrency, "Register must store agents.concurrency in Core Config")
|
||||
}
|
||||
|
||||
// --- ProcessRegister ---
|
||||
|
||||
func TestProcessRegister_ProcessRegister_Good(t *testing.T) {
|
||||
t.Setenv("CORE_WORKSPACE", t.TempDir())
|
||||
|
||||
c := core.New()
|
||||
result := ProcessRegister(c)
|
||||
assert.True(t, result.OK, "ProcessRegister should succeed with a real Core instance")
|
||||
assert.NotNil(t, result.Value)
|
||||
}
|
||||
|
||||
func TestProcessRegister_ProcessRegister_Bad(t *testing.T) {
|
||||
// nil Core — the process.NewService factory tolerates nil Core, returns a result
|
||||
result := ProcessRegister(nil)
|
||||
// Either OK (service created without Core) or not OK (error) — must not panic
|
||||
_ = result
|
||||
}
|
||||
|
||||
func TestProcessRegister_ProcessRegister_Ugly(t *testing.T) {
|
||||
// Call twice with same Core — second call should still succeed
|
||||
t.Setenv("CORE_WORKSPACE", t.TempDir())
|
||||
|
||||
c := core.New()
|
||||
r1 := ProcessRegister(c)
|
||||
assert.True(t, r1.OK)
|
||||
|
||||
r2 := ProcessRegister(c)
|
||||
assert.True(t, r2.OK, "second ProcessRegister call should not fail")
|
||||
}
|
||||
|
||||
// --- OnStartup ---
|
||||
|
||||
func TestPrep_OnStartup_Good_CreatesPokeCh(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -125,6 +125,19 @@ func TestRemoteClient_SetHeaders_Good_NoToken(t *testing.T) {
|
|||
assert.Empty(t, req.Header.Get("Mcp-Session-Id"))
|
||||
}
|
||||
|
||||
// --- setHeaders Bad ---
|
||||
|
||||
func TestRemoteClient_SetHeaders_Bad(t *testing.T) {
|
||||
// Both token and session empty — only Content-Type and Accept are set
|
||||
req, _ := http.NewRequest("POST", "http://example.com", nil)
|
||||
setHeaders(req, "", "")
|
||||
|
||||
assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
|
||||
assert.Equal(t, "application/json, text/event-stream", req.Header.Get("Accept"))
|
||||
assert.Empty(t, req.Header.Get("Authorization"), "no auth header when token is empty")
|
||||
assert.Empty(t, req.Header.Get("Mcp-Session-Id"), "no session header when session is empty")
|
||||
}
|
||||
|
||||
// --- readSSEData ---
|
||||
|
||||
func TestRemoteClient_ReadSSEData_Good(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -43,3 +43,38 @@ func TestRemote_RemoteToken_Good_EnvPrecedence(t *testing.T) {
|
|||
token := remoteToken("PRIO")
|
||||
assert.Equal(t, "specific-token", token, "host-specific env should take precedence")
|
||||
}
|
||||
|
||||
// --- resolveHost Bad/Ugly ---
|
||||
|
||||
func TestRemote_ResolveHost_Bad(t *testing.T) {
|
||||
// Empty string — returns empty host with default port appended
|
||||
result := resolveHost("")
|
||||
assert.Equal(t, ":9101", result)
|
||||
}
|
||||
|
||||
func TestRemote_ResolveHost_Ugly(t *testing.T) {
|
||||
// Unicode host name — not an alias, no colon, so default port appended
|
||||
result := resolveHost("\u00e9nchantr\u00efx")
|
||||
assert.Equal(t, "\u00e9nchantr\u00efx:9101", result)
|
||||
}
|
||||
|
||||
// --- remoteToken Bad/Ugly ---
|
||||
|
||||
func TestRemote_RemoteToken_Bad(t *testing.T) {
|
||||
// Host with no matching env var and no file — returns empty
|
||||
t.Setenv("AGENT_TOKEN_NOHOST", "")
|
||||
t.Setenv("MCP_AUTH_TOKEN", "")
|
||||
t.Setenv("DIR_HOME", t.TempDir()) // no token files
|
||||
token := remoteToken("nohost")
|
||||
assert.Equal(t, "", token)
|
||||
}
|
||||
|
||||
func TestRemote_RemoteToken_Ugly(t *testing.T) {
|
||||
// Host name with dashes and dots — creates odd env key like AGENT_TOKEN_MY-HOST.LOCAL
|
||||
// Env lookup will use the exact uppercased key
|
||||
t.Setenv("AGENT_TOKEN_MY-HOST.LOCAL", "")
|
||||
t.Setenv("MCP_AUTH_TOKEN", "")
|
||||
t.Setenv("DIR_HOME", t.TempDir())
|
||||
token := remoteToken("my-host.local")
|
||||
assert.Equal(t, "", token)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,29 @@ func mockScanServer(t *testing.T) *httptest.Server {
|
|||
|
||||
// --- scan ---
|
||||
|
||||
func TestScan_Scan_Good(t *testing.T) {
|
||||
srv := mockScanServer(t)
|
||||
s := &PrepSubsystem{
|
||||
forge: forge.NewForge(srv.URL, "test-token"),
|
||||
forgeURL: srv.URL,
|
||||
forgeToken: "test-token",
|
||||
client: srv.Client(),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
_, out, err := s.scan(context.Background(), nil, ScanInput{Org: "core"})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, out.Success)
|
||||
assert.Greater(t, out.Count, 0)
|
||||
// Verify issues contain repos from mock server
|
||||
repos := make(map[string]bool)
|
||||
for _, iss := range out.Issues {
|
||||
repos[iss.Repo] = true
|
||||
}
|
||||
assert.True(t, repos["go-io"] || repos["go-log"], "should contain issues from mock repos")
|
||||
}
|
||||
|
||||
func TestScan_Good_AllRepos(t *testing.T) {
|
||||
srv := mockScanServer(t)
|
||||
s := &PrepSubsystem{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue