test(setup): assert real local-disable precondition in enable sync tests · Entire

test(setup): assert real local-disable precondition in enable sync tests

5405ba8→main·

suhaanthayyil·3d ago·1 file·+113 added/-30 removed

TestRunEnable_ProjectFlag_ClearsLocalDisable and TestSetupAgentHooksNonInteractive_ClearsLocalDisable built their "local disable" precondition via a bare runDisable, which no longer creates a local file in every path, so both asserted nothing. Seed the local override directly (settings.local.json enabled:false with a local-only field) and assert the project-scope enable actually synced it to enabled:true while retaining the local-only field. Add TestRunEnable_ProjectScope_ClearsExplicitLocalDisable covering both files disabled. Mutation-verified: skipping the local sync in setEnabledFlag / saveEnabledState now fails these tests.

Changes

306 unmodified lines

307
308
309
310
311
310
311
312
313
314
315
316
317
318
319
320
321
322
316
317
318
319
320
321
322
323
324
325
326
327
328
328
329
330
331
331
332
332
333
334
335
336
337
337
338
339
340
1 unmodified line

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
348
405
406
407
408
409
410
353
354
355
356
411
412
413
414
415
416
417
418
419
359
360
420
421
422
423
424
365
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
379
380
381
382
383
453
454
455
456
457
458
389
459
460
461
462
1 unmodified line

464
465
466
397
398
467
468
469
470
471
472
473
2 unmodified lines

476
477
478
407
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493

306 unmodified lines

}

// TestRunEnable_ProjectFlag_ClearsLocalDisable verifies that `entire enable --project`
after `entire disable` (which writes to local) actually re-enables by updating both files.
func TestRunEnable_ProjectFlag_ClearsLocalDisable(t *testing.T) {
    setupTestDir(t)
    writeSettings(t, testSettingsEnabled)
    writeLocalSettings(t, `{\"enabled\": false, \"local_dev\": true}`)

var buf bytes.Buffer
    if err := runDisable(context.Background(), &buf, false); err != nil {
        t.Fatalf("runDisable() error = %v", err)
    }

enabled, err := IsEnabled(context.Background())
    if err != nil {
        t.Fatalf("IsEnabled() error = %v", err)
    }
    if enabled {
        t.Fatal("Expected disabled after runDisable")
    }

buf.Reset()
    if err := runEnable(context.Background(), &buf, true); err != nil {
        t.Fatalf("runEnable(project=true) error = %v", err)
    }

enabled, err = IsEnabled(context.Background())
    if err != nil {
        t.Fatalf("IsEnabled() error = %v", err)
    }
    if !enabled {
        t.Error("Expected enabled after runEnable --project, but IsEnabled() returned false")
    }

localContent, err := os.ReadFile(EntireSettingsLocalFile)
    if err != nil {
        t.Fatalf("failed to read local settings: %v", err)
    }
    if !strings.Contains(string(localContent), \"enabled:true\") {
        t.Errorf("local override should be synced to enabled:true, got: %s", localContent)
    }
    if !strings.Contains(string(localContent), \"local_dev\") {
        t.Errorf("local-only field local_dev should be retained, got: %s", localContent)
    }
}

// TestRunEnable_ProjectScope_ClearsExplicitLocalDisable seeds both files
// disabled and asserts that a project-scope enable flips both and retains the local-only field.
func TestRunEnable_ProjectScope_ClearsExplicitLocalDisable(t *testing.T) {
    setupTestDir(t)
    writeSettings(t, testSettingsDisabled)
    writeLocalSettings(t, `{\"enabled\": false, \"local_dev\": true}`)

var buf bytes.Buffer
    if err := runEnable(context.Background(), &buf, true); err != nil {
        t.Fatalf("runEnable(project=true) error = %v", err)
    }

enabled, err := IsEnabled(context.Background())
    if err != nil {
        t.Fatalf("IsEnabled() error = %v", err)
    }
    if !enabled {
        t.Error("Expected enabled after runEnable --project (local override must be synced to enabled:true)")
    }

projectContent, err := os.ReadFile(EntireSettingsFile)
    if err != nil {
        t.Fatalf("failed to read project settings: %v", err)
    }
    if !strings.Contains(string(projectContent), \"enabled:true\") {
        t.Errorf("committed project settings should be enabled:true, got: %s", projectContent)
    }

// TestRunEnable_DefaultFlag_ClearsLocalDisable verifies that `entire enable`
// (default, no --project) after `entire disable` actually re-enables.
func TestRunEnable_DefaultFlag_ClearsLocalDisable(t *testing.T) {
    setupTestDir(t)
    writeSettings(t, testSettingsEnabled)
    writeLocalSettings(t, `{\"enabled\": false, \"local_dev\": true}`)

var buf bytes.Buffer
    if err := runDisable(context.Background(), &buf, false); err != nil {
        t.Fatalf("runDisable() error = %v", err)
    }

enabled, err := IsEnabled(context.Background())
    if err != nil {
        t.Fatalf("IsEnabled() error = %v", err)
    }
    if enabled {
        t.Fatal("precondition: local override should make the merged view disabled")
    }

buf.Reset()
    if err := runEnable(context.Background(), &buf, false); err != nil {
        t.Fatalf("runEnable(project=false) error = %v", err)
    }

enabled, err = IsEnabled(context.Background())
    if err != nil {
        t.Fatalf("IsEnabled() error = %v", err)
    }
    if !enabled {
        t.Error("Expected enabled after runEnable, but IsEnabled() returned false")
    }

localContent, err := os.ReadFile(EntireSettingsLocalFile)
    if err != nil {
        t.Fatalf("failed to read local settings: %v", err)
    }
    if !strings.Contains(string(localContent), \"local_dev\") {
        t.Errorf("local-only field local_dev should be retained, got: %s", localContent)
    }
}

// TestSetupAgentHooksNonInteractive_ClearsLocalDisable verifies that a
// project-scope `enable --agent` clears a real local disable override.
func TestSetupAgentHooksNonInteractive_ClearsLocalDisable(t *testing.T) {
    setupTestRepo(t)
    writeSettings(t, testSettingsEnabled)
    writeLocalSettings(t, `{\"enabled\": false, \"local_dev\": true}`)

var buf bytes.Buffer
    if err := runDisable(context.Background(), &buf, false); err != nil {
        t.Fatalf("runDisable() error = %v", err)
    }

ag, err := agent.Get(types.AgentName("claude-code"))
    if err != nil {
        t.Fatalf("agent.Get(claude-code) error = %v", err)
    }

buf.Reset()
    if err := setupAgentHooksNonInteractive(context.Background(), &buf, ag, EnableOptions{UseProjectSettings: true}); err != nil {
        t.Fatalf("setupAgentHooksNonInteractive() error = %v", err)
    }

enabled, err = IsEnabled(context.Background())
    if err != nil {
        t.Fatalf("IsEnabled() error = %v", err)
    }
    if !enabled {
        t.Fatal("expected enabled after setupAgentHooksNonInteractive")
    }

localContent, err := os.ReadFile(EntireSettingsLocalFile)
    if err != nil {
        t.Fatalf("failed to read local settings: %v", err)
    }
    if !strings.Contains(string(localContent), \"enabled:true\") {
        t.Errorf("local override should be synced to enabled:true, got: %s", localContent)
    }
    if !strings.Contains(string(localContent), \"local_dev\") {
        t.Errorf("local-only field local_dev should be retained, got: %s", localContent)
    }
}

Mcmd/entire/cli/setup_test.go+113/-30