2026-03-30 00:54:20 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
2026-03-30 00:19:43 +00:00
|
|
|
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
package repos
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
2026-03-21 23:54:23 +00:00
|
|
|
"dappco.re/go/core/io"
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ── DefaultWorkConfig ──────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
func TestDefaultWorkConfig_Good(t *testing.T) {
|
|
|
|
|
wc := DefaultWorkConfig()
|
|
|
|
|
assert.Equal(t, 1, wc.Version)
|
|
|
|
|
assert.Equal(t, 5*time.Minute, wc.Sync.Interval)
|
|
|
|
|
assert.True(t, wc.Sync.AutoPull)
|
|
|
|
|
assert.False(t, wc.Sync.AutoPush)
|
|
|
|
|
assert.True(t, wc.Sync.CloneMissing)
|
|
|
|
|
assert.Equal(t, 2*time.Minute, wc.Agents.Heartbeat)
|
|
|
|
|
assert.Equal(t, 10*time.Minute, wc.Agents.StaleAfter)
|
|
|
|
|
assert.True(t, wc.Agents.WarnOnOverlap)
|
|
|
|
|
assert.Contains(t, wc.Triggers, "on_activate")
|
|
|
|
|
assert.Contains(t, wc.Triggers, "on_commit")
|
|
|
|
|
assert.Contains(t, wc.Triggers, "scheduled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Load / Save round-trip ─────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
func TestWorkConfig_LoadSave_Good(t *testing.T) {
|
|
|
|
|
m := io.NewMockMedium()
|
|
|
|
|
_ = m.EnsureDir("/workspace/.core")
|
|
|
|
|
|
|
|
|
|
wc := DefaultWorkConfig()
|
|
|
|
|
wc.Sync.Interval = 10 * time.Minute
|
|
|
|
|
wc.Sync.AutoPush = true
|
|
|
|
|
|
|
|
|
|
err := SaveWorkConfig(m, "/workspace", wc)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
loaded, err := LoadWorkConfig(m, "/workspace")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, 1, loaded.Version)
|
|
|
|
|
assert.Equal(t, 10*time.Minute, loaded.Sync.Interval)
|
|
|
|
|
assert.True(t, loaded.Sync.AutoPush)
|
|
|
|
|
assert.True(t, loaded.Sync.AutoPull)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 06:37:20 +00:00
|
|
|
func TestWorkConfig_Load_Good_NoFile_Good(t *testing.T) {
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
m := io.NewMockMedium()
|
|
|
|
|
_ = m.EnsureDir("/workspace/.core")
|
|
|
|
|
|
|
|
|
|
wc, err := LoadWorkConfig(m, "/workspace")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Equal(t, DefaultWorkConfig().Sync.Interval, wc.Sync.Interval)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 06:37:20 +00:00
|
|
|
func TestWorkConfig_Load_Good_PartialOverride_Good(t *testing.T) {
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
m := io.NewMockMedium()
|
|
|
|
|
_ = m.Write("/workspace/.core/work.yaml", `
|
|
|
|
|
version: 1
|
|
|
|
|
sync:
|
|
|
|
|
interval: 30s
|
|
|
|
|
auto_push: true
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
wc, err := LoadWorkConfig(m, "/workspace")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, 30*time.Second, wc.Sync.Interval)
|
|
|
|
|
assert.True(t, wc.Sync.AutoPush)
|
|
|
|
|
// Defaults preserved for unset fields
|
|
|
|
|
assert.True(t, wc.Sync.AutoPull)
|
|
|
|
|
assert.True(t, wc.Sync.CloneMissing)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 06:37:20 +00:00
|
|
|
func TestWorkConfig_Load_Bad_InvalidYAML_Good(t *testing.T) {
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
m := io.NewMockMedium()
|
|
|
|
|
_ = m.Write("/workspace/.core/work.yaml", "{{{{broken")
|
|
|
|
|
|
|
|
|
|
_, err := LoadWorkConfig(m, "/workspace")
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "failed to parse")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── HasTrigger ─────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
func TestWorkConfig_HasTrigger_Good(t *testing.T) {
|
|
|
|
|
wc := DefaultWorkConfig()
|
|
|
|
|
assert.True(t, wc.HasTrigger("on_activate"))
|
|
|
|
|
assert.True(t, wc.HasTrigger("on_commit"))
|
|
|
|
|
assert.True(t, wc.HasTrigger("scheduled"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 06:37:20 +00:00
|
|
|
func TestWorkConfig_HasTrigger_Bad_NotFound_Good(t *testing.T) {
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
wc := DefaultWorkConfig()
|
|
|
|
|
assert.False(t, wc.HasTrigger("on_deploy"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 06:37:20 +00:00
|
|
|
func TestWorkConfig_HasTrigger_Good_CustomTriggers_Good(t *testing.T) {
|
feat(repos): add git.yaml state tracking and work.yaml sync config
GitState (.core/git.yaml, .gitignored):
- Per-repo sync timestamps (last pull/push), branch, ahead/behind
- Agent heartbeats with active package lists
- Stale agent detection, overlap queries, NeedsPull check
WorkConfig (.core/work.yaml, checked in):
- Sync policy: interval, auto_pull, auto_push, clone_missing
- Agent policy: heartbeat interval, stale timeout, overlap warnings
- Trigger list: on_activate, on_commit, scheduled
Both use io.Medium for testability (MockMedium in all tests).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:44:31 +00:00
|
|
|
wc := &WorkConfig{
|
|
|
|
|
Version: 1,
|
|
|
|
|
Triggers: []string{"on_pr", "manual"},
|
|
|
|
|
}
|
|
|
|
|
assert.True(t, wc.HasTrigger("on_pr"))
|
|
|
|
|
assert.True(t, wc.HasTrigger("manual"))
|
|
|
|
|
assert.False(t, wc.HasTrigger("on_commit"))
|
|
|
|
|
}
|