refactor(test): fold enable-scope e2e into setup_cmd_test and drop issue-number references · Entire
refactor(test): fold enable-scope e2e into setup_cmd_test and drop issue-number references
a243ac2→main
Move TestIssue1140_ReenableAfterProjectDisable_EnablesProjectFile into setup_cmd_test.go as TestEnableReenablesProjectScopeAfterProjectDisable and remove issue-number references from comments.
Changes
4
cmd/entire/cli
integration_test
Dissue_1140_enable_state_e2e_test.go-99
Msetup_cmd_test.go+90
Msetup.go+11/-10
Msetup_test.go+9/-9
//go:build integration
package integration
import (
"encoding/json"
"os"
"path/filepath"
"testing"
)
// TestIssue1140_ReenableAfterProjectDisable_EnablesProjectFile is a full-flow
// reproduction of #1140: after `entire disable --project`, running
// `entire enable --checkpoint-remote ...` with no --project/--local reported
// success but wrote the enabled flag to .entire/settings.local.json, leaving the
// project .entire/settings.json the user disabled still enabled=false.
//
// Because settings.local.json (enabled:true) overrides settings.json in the
// merged view that both `entire status` and IsEnabled read, status actually
// reported ENABLED — the effective state was correct and only the committed
// file was stale. That still bites anyone without the local file (a fresh
// clone, a teammate) and leaves the committed source of truth wrong.
//
// This drives the real entire binary end-to-end — enable, disable --project,
// then a setup-flag re-enable — and asserts the PROJECT settings.json (the file
// the user actually disabled) is enabled again.
func TestIssue1140_ReenableAfterProjectDisable_EnablesProjectFile(t *testing.T) {
t.Parallel()
env := NewTestEnv(t)
defer env.Cleanup()
env.InitRepo()
// First-time setup via the real binary; a plain enable writes the project
// .entire/settings.json.
env.RunCLI("enable", "--agent", "claude-code", "--telemetry=false")
assertProjectSettingsEnabled(t, env, true)
// Disable at the project scope → settings.json enabled=false.
env.RunCLI("disable", "--project")
assertProjectSettingsEnabled(t, env, false)
// Re-enable with a setup flag but WITHOUT --project/--local. Pre-fix the
// enabled flag landed in settings.local.json, so the project file the user
// disabled stayed enabled=false (#1140).
env.RunCLI("enable", "--checkpoint-remote", "github:org/repo", "--skip-push-sessions", "--telemetry=false")
assertProjectSettingsEnabled(t, env, true)
// And no local override may contradict it: settings.local.json must be
// absent or itself enabled:true, so the merged view can't silently flip
// back to disabled by accident of the flow.
assertLocalSettingsAbsentOrEnabled(t, env)
}
// assertLocalSettingsAbsentOrEnabled asserts that .entire/settings.local.json,
// if present, does not carry an enabled:false override that would mask the
// committed project scope.
func assertLocalSettingsAbsentOrEnabled(t *testing.T, env *TestEnv) {
t.Helper()
localPath := filepath.Join(env.RepoDir, ".entire", "settings.local.json")
data, err := os.ReadFile(localPath)
if os.IsNotExist(err) {
return
}
if err != nil {
t.Fatalf("read .entire/settings.local.json: %v", err)
}
var s struct {
Enabled *bool `json:"enabled"`
}
if err := json.Unmarshal(data, &s); err != nil {
t.Fatalf("parse .entire/settings.local.json: %v\ncontent: %s", err, data)
}
if s.Enabled != nil && !*s.Enabled {
t.Fatalf("settings.local.json carries enabled:false, which would mask the re-enabled project scope\ncontent: %s", data)
}
}
// assertProjectSettingsEnabled reads .entire/settings.json (the project scope,
// never settings.local.json) and asserts its enabled flag matches want.
func assertProjectSettingsEnabled(t *testing.T, env *TestEnv, want bool) {
t.Helper()
settingsPath := filepath.Join(env.RepoDir, ".entire", "settings.json")
data, err := os.ReadFile(settingsPath)
if err != nil {
t.Fatalf("read .entire/settings.json: %v", err)
}
var s struct {
Enabled bool `json:"enabled"`
}
if err := json.Unmarshal(data, &s); err != nil {
t.Fatalf("parse .entire/settings.json: %v\ncontent: %s", err, data)
}
if s.Enabled != want {
t.Fatalf("project settings.json enabled=%v, want %v — enabled flag written to the wrong scope (#1140)\ncontent: %s",
s.Enabled, want, data)
}
}
Mcmd/entire/cli/integration_test/issue_1140_enable_state_e2e_test.go-99
// TestEnableReenablesProjectScopeAfterProjectDisable is a full-flow
// reproduction of a re-enable regression: after `entire disable --project`,
// running `entire enable --checkpoint-remote ...` with no --project/--local
// reported success but wrote the enabled flag to .entire/settings.local.json,
// leaving the project .entire/settings.json the user disabled still
// enabled=false.
//
// Because settings.local.json (enabled:true) overrides settings.json in the
// merged view that both `entire status` and IsEnabled read, status actually
// reported ENABLED — the effective state was correct and only the committed
// file was stale. That still bites anyone without the local file (a fresh
// clone, a teammate) and leaves the committed source of truth wrong.
//
// This drives the real entire binary end-to-end — enable, disable --project,
// then a setup-flag re-enable — and asserts the PROJECT settings.json (the file
// the user actually disabled) is enabled again.
func TestEnableReenablesProjectScopeAfterProjectDisable(t *testing.T) {
t.Parallel()
env := NewTestEnv(t)
defer env.Cleanup()
env.InitRepo()
// Disable at the project scope → settings.json enabled=false.
env.RunCLI("disable", "--project")
assertProjectSettingsEnabled(t, env, false)
// Re-enable with a setup flag but WITHOUT --project/--local. Pre-fix the
// enabled flag landed in settings.local.json, so the project file the user
// disabled stayed enabled=false.
env.RunCLI("enable", "--checkpoint-remote", "github:org/repo", "--skip-push-sessions", "--telemetry=false")
assertProjectSettingsEnabled(t, env, true)
Mcmd/entire/cli/integration_test/setup_cmd_test.go+90
```go
// TestRunEnableOnConfiguredRepo_RecoversLegacySplitState covers issue #1140
// step 4: recovering the split state a pre-fix binary left on disk — committed
// settings.json enabled:false, settings.local.json enabled:true. The local
// override wins in the merged view, so IsEnabled reports true; a bare early
// return on the merged view would leave the committed project file disabled
// detect that the target scope is itself disabled and flip it.
func TestRunEnableOnConfiguredRepo_RecoversLegacySplitState(t *testing.T) {
setupTestRepo(t)
// Legacy #1140 split state.
writeSettings(t, testSettingsDisabled)
writeLocalSettings(t, `{"enabled": true}`)
// The committed project file must now be enabled — the state #1140 could
// not recover before this fix.
projectS, err := settings.LoadFromFile(EntireSettingsFile)
if err != nil {
t.Fatalf("load project settings: %v", err)
}
if !projectS.Enabled {
t.Errorf("settings.json still enabled=false after enable; the enabled flag went to the wrong file (#1140)")
}
}