01fd572a89
## Summary Completed Phase 5 refactoring and reached the target architecture. **Architectural milestone achieved:** - Service layer owns all state and is the sole writer - UI is a thin Fyne view, all widget updates marshaled via `fyne.Do` - Core engines are stateless and injectable - Domain types are pure (no `yaml:"-"` fields) - Full module builds and `go vet ./...` clean ## Changes - Bump version: 0.3.6 → 0.4.0 - Update CHANGELOG with Phase 5 summary - Add ROADMAP "Refactoring Follow-Ups" section ## Known follow-up work 1. **Linux test build broken** — `runner_test.go` needs `//go:build windows` tag 2. **File-size limits exceeded** — `operations.go` (486 lines), `jobs_view.go` (415 lines) See ROADMAP.md for details. --------- Co-authored-by: mixeme <mix.public@ya.ru> Reviewed-on: #1
58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package app
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"gitea.mixdep.ru/mix/gosentry/src/domain"
|
|
"gitea.mixdep.ru/mix/gosentry/src/storage"
|
|
)
|
|
|
|
func newTestService(jobs []domain.Job) *Service {
|
|
return NewService(&storage.Store{}, jobs)
|
|
}
|
|
|
|
func TestNewServiceBuildsRuntimePerJob(t *testing.T) {
|
|
jobs := []domain.Job{
|
|
{ID: 1, Name: "Enabled", Enabled: true},
|
|
{ID: 2, Name: "Disabled", Enabled: false},
|
|
}
|
|
svc := newTestService(jobs)
|
|
|
|
if got := svc.Runtime(1); got == nil {
|
|
t.Fatal("expected runtime for enabled job 1")
|
|
} else if got.LastState != "Ready" {
|
|
t.Errorf("enabled job runtime state = %q, want %q", got.LastState, "Ready")
|
|
}
|
|
if got := svc.Runtime(2); got == nil {
|
|
t.Fatal("expected runtime for disabled job 2")
|
|
} else if got.LastState != "Paused" {
|
|
t.Errorf("disabled job runtime state = %q, want %q", got.LastState, "Paused")
|
|
}
|
|
if got := svc.Runtime(99); got != nil {
|
|
t.Errorf("expected nil runtime for unknown job, got %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestJobsReturnsCopy(t *testing.T) {
|
|
jobs := []domain.Job{{ID: 1, Name: "Original"}}
|
|
svc := newTestService(jobs)
|
|
|
|
snapshot := svc.Jobs()
|
|
if len(snapshot) != 1 {
|
|
t.Fatalf("Jobs() len = %d, want 1", len(snapshot))
|
|
}
|
|
// Mutating the returned slice must not affect Service-owned state.
|
|
snapshot[0].Name = "Mutated"
|
|
if again := svc.Jobs(); again[0].Name != "Original" {
|
|
t.Errorf("Service state leaked through Jobs(): name = %q, want %q", again[0].Name, "Original")
|
|
}
|
|
}
|
|
|
|
func TestStoreReturnsWiredStore(t *testing.T) {
|
|
store := &storage.Store{}
|
|
svc := NewService(store, nil)
|
|
if svc.Store() != store {
|
|
t.Error("Store() did not return the wired store")
|
|
}
|
|
}
|