From 6838ac0fa1ae0578cf84a451ed628cd8ded31562 Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Sun, 25 Jan 2026 20:05:58 -0500 Subject: [PATCH] test(uninstall): add hook cleanup tests - add Section 7: SETTINGS.JSON HOOK CLEANUP tests - test CCS hook removal from settings.json - test user-defined hooks preserved - test mixed CCS and user hooks handling - test missing settings.json handling - update special-commands.test.js expectations --- tests/native/unix/uninstall.sh | 78 +++++++++++++++++++++ tests/native/windows/uninstall.ps1 | 108 +++++++++++++++++++++++++++++ tests/npm/special-commands.test.js | 5 +- 3 files changed, 188 insertions(+), 3 deletions(-) diff --git a/tests/native/unix/uninstall.sh b/tests/native/unix/uninstall.sh index b4f5273e..13d34b48 100755 --- a/tests/native/unix/uninstall.sh +++ b/tests/native/unix/uninstall.sh @@ -281,6 +281,84 @@ test_case "Edge case: Missing parent directories" "Handles missing .claude direc [[ \$exit_code -eq 0 ]] " +# ============================================================================ +# TEST SECTION 7: SETTINGS.JSON HOOK CLEANUP +# ============================================================================ + +echo "" +echo "========================================" +echo "SECTION 7: SETTINGS.JSON HOOK CLEANUP" +echo "========================================" + +test_case "Hook cleanup: Removes CCS WebSearch hook from settings.json" "Hook removed" bash -c " + # Setup: Create settings.json with CCS hook + mkdir -p '$TEST_CLAUDE_DIR' + cat > '$TEST_CLAUDE_DIR/settings.json' << 'EOFINNER' +{ + \"hooks\": { + \"PreToolUse\": [ + { \"matcher\": \"WebSearch\", \"hooks\": [{ \"command\": \"node ~/.ccs/hooks/websearch-transformer.cjs\" }] } + ] + } +} +EOFINNER + # Install then uninstall + HOME='$TEST_HOME' '$CCS_PATH' --install > /dev/null 2>&1 + HOME='$TEST_HOME' '$CCS_PATH' --uninstall > /dev/null 2>&1 + # Check hook removed + ! grep -q 'websearch-transformer' '$TEST_CLAUDE_DIR/settings.json' +" + +test_case "Hook cleanup: Preserves user-defined WebSearch hooks" "User hooks kept" bash -c " + # Setup: Create settings.json with user hook + mkdir -p '$TEST_CLAUDE_DIR' + cat > '$TEST_CLAUDE_DIR/settings.json' << 'EOFINNER' +{ + \"hooks\": { + \"PreToolUse\": [ + { \"matcher\": \"WebSearch\", \"hooks\": [{ \"command\": \"my-custom-hook.sh\" }] } + ] + } +} +EOFINNER + # Uninstall + HOME='$TEST_HOME' '$CCS_PATH' --uninstall > /dev/null 2>&1 + # Check user hook preserved + grep -q 'my-custom-hook' '$TEST_CLAUDE_DIR/settings.json' +" + +test_case "Hook cleanup: Handles mixed CCS and user hooks" "Only CCS hook removed" bash -c " + # Setup: Create settings.json with both CCS and user hooks + mkdir -p '$TEST_CLAUDE_DIR' + cat > '$TEST_CLAUDE_DIR/settings.json' << 'EOFINNER' +{ + \"hooks\": { + \"PreToolUse\": [ + { \"matcher\": \"WebSearch\", \"hooks\": [{ \"command\": \"node ~/.ccs/hooks/websearch-transformer.cjs\" }] }, + { \"matcher\": \"WebSearch\", \"hooks\": [{ \"command\": \"my-custom-hook.sh\" }] }, + { \"matcher\": \"Bash\", \"hooks\": [{ \"command\": \"bash-hook.sh\" }] } + ] + } +} +EOFINNER + # Uninstall + HOME='$TEST_HOME' '$CCS_PATH' --uninstall > /dev/null 2>&1 + # Check CCS hook removed + ! grep -q 'websearch-transformer' '$TEST_CLAUDE_DIR/settings.json' && + # Check user WebSearch hook preserved + grep -q 'my-custom-hook' '$TEST_CLAUDE_DIR/settings.json' && + # Check other hooks preserved + grep -q 'bash-hook' '$TEST_CLAUDE_DIR/settings.json' +" + +test_case "Hook cleanup: Handles missing settings.json" "No error when settings.json missing" bash -c " + # Ensure settings.json doesn't exist + rm -f '$TEST_CLAUDE_DIR/settings.json' + HOME='$TEST_HOME' '$CCS_PATH' --uninstall > /dev/null 2>&1 + exit_code=\$? + [[ \$exit_code -eq 0 ]] +" + # ============================================================================ # SUMMARY # ============================================================================ diff --git a/tests/native/windows/uninstall.ps1 b/tests/native/windows/uninstall.ps1 index 978c8b24..82f79348 100644 --- a/tests/native/windows/uninstall.ps1 +++ b/tests/native/windows/uninstall.ps1 @@ -425,6 +425,114 @@ Test-Case "Edge case: Missing parent directories" "Handles missing .claude direc } } +# ============================================================================ +# TEST SECTION 7: SETTINGS.JSON HOOK CLEANUP +# ============================================================================ + +Write-Host "" +Write-ColorOutput "========================================" "Yellow" +Write-ColorOutput "SECTION 7: SETTINGS.JSON HOOK CLEANUP" "Yellow" +Write-ColorOutput "========================================" "Yellow" + +Test-Case "Hook cleanup: Removes CCS WebSearch hook from settings.json" "Hook removed" { + # Setup: Create settings.json with CCS hook + New-Item -ItemType Directory -Path $TestClaudeDir -Force | Out-Null + $settingsPath = Join-Path $TestClaudeDir "settings.json" + $settingsContent = @' +{ + "hooks": { + "PreToolUse": [ + { "matcher": "WebSearch", "hooks": [{ "command": "node ~/.ccs/hooks/websearch-transformer.cjs" }] } + ] + } +} +'@ + Set-Content -Path $settingsPath -Value $settingsContent + + # Install then uninstall + $env:HOME = $TestHome + try { + & $CcsPath --install | Out-Null + & $CcsPath --uninstall | Out-Null + } catch { } + + # Check hook removed + $content = Get-Content -Path $settingsPath -Raw + -not ($content -match "websearch-transformer") +} + +Test-Case "Hook cleanup: Preserves user-defined WebSearch hooks" "User hooks kept" { + # Setup: Create settings.json with user hook + New-Item -ItemType Directory -Path $TestClaudeDir -Force | Out-Null + $settingsPath = Join-Path $TestClaudeDir "settings.json" + $settingsContent = @' +{ + "hooks": { + "PreToolUse": [ + { "matcher": "WebSearch", "hooks": [{ "command": "my-custom-hook.sh" }] } + ] + } +} +'@ + Set-Content -Path $settingsPath -Value $settingsContent + + # Uninstall + $env:HOME = $TestHome + try { + & $CcsPath --uninstall | Out-Null + } catch { } + + # Check user hook preserved + $content = Get-Content -Path $settingsPath -Raw + $content -match "my-custom-hook" +} + +Test-Case "Hook cleanup: Handles mixed CCS and user hooks" "Only CCS hook removed" { + # Setup: Create settings.json with both CCS and user hooks + New-Item -ItemType Directory -Path $TestClaudeDir -Force | Out-Null + $settingsPath = Join-Path $TestClaudeDir "settings.json" + $settingsContent = @' +{ + "hooks": { + "PreToolUse": [ + { "matcher": "WebSearch", "hooks": [{ "command": "node ~/.ccs/hooks/websearch-transformer.cjs" }] }, + { "matcher": "WebSearch", "hooks": [{ "command": "my-custom-hook.sh" }] }, + { "matcher": "Bash", "hooks": [{ "command": "bash-hook.sh" }] } + ] + } +} +'@ + Set-Content -Path $settingsPath -Value $settingsContent + + # Uninstall + $env:HOME = $TestHome + try { + & $CcsPath --uninstall | Out-Null + } catch { } + + # Check CCS hook removed, user hooks preserved + $content = Get-Content -Path $settingsPath -Raw + (-not ($content -match "websearch-transformer")) -and + ($content -match "my-custom-hook") -and + ($content -match "bash-hook") +} + +Test-Case "Hook cleanup: Handles missing settings.json" "No error when settings.json missing" { + # Ensure settings.json doesn't exist + $settingsPath = Join-Path $TestClaudeDir "settings.json" + if (Test-Path $settingsPath) { + Remove-Item $settingsPath -Force + } + + $env:HOME = $TestHome + try { + & $CcsPath --uninstall | Out-Null + return $true + } catch { + return $false + } +} + # ============================================================================ # SUMMARY # ============================================================================ diff --git a/tests/npm/special-commands.test.js b/tests/npm/special-commands.test.js index 601612eb..84f3f4d6 100644 --- a/tests/npm/special-commands.test.js +++ b/tests/npm/special-commands.test.js @@ -39,9 +39,8 @@ describe('integration: special commands', () => { it('handles --uninstall command', () => { const output = execSync(`node ${ccsPath} --uninstall`, { encoding: 'utf8' }); - assert(output.includes('Feature not available')); - assert(output.includes('under development')); - assert(output.includes('.claude/ integration testing')); + assert(output.includes('Uninstalling CCS')); + assert(output.includes('[OK] Uninstall complete!') || output.includes('Nothing to uninstall')); }); describe('ccs update command flags', () => {