Skip to content

Commit f9ba086

Browse files
committed
fix Claude auth probe for real integration tests
1 parent 903d2b6 commit f9ba086

File tree

1 file changed

+9
-36
lines changed

1 file changed

+9
-36
lines changed

ClaudeCodeSharpSDK.Tests/Shared/RealClaudeTestSupport.cs

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,18 @@ namespace ManagedCode.ClaudeCodeSharpSDK.Tests.Shared;
99

1010
internal static class RealClaudeTestSupport
1111
{
12+
private const string AuthCommandName = "auth";
13+
private const string StatusCommandName = "status";
1214
private const string ClaudeDirectoryName = ".claude";
13-
private const string DangerouslySkipPermissionsFlag = "--dangerously-skip-permissions";
14-
private const string LoginGuidanceFragment = "Please run /login";
15-
private const string MaxBudgetFlag = "--max-budget-usd";
16-
private const string MaxBudgetValue = "0.05";
17-
private const string UnauthorizedStatusCodeFragment = "401";
1815
private const string AuthenticationRequiredMessage =
1916
"Authenticated Claude Code session is required for this test. Start Claude Code and complete '/login' first.";
2017
private const string ClaudeExecutableNotFoundMessage =
2118
"Claude Code executable could not be resolved for authenticated integration tests.";
2219
private const string CouldNotLocateRepositoryRootMessage = "Could not locate repository root from test execution directory.";
2320
private const string JsonLinesFileExtension = ".jsonl";
21+
private const string LoggedInPropertyName = "loggedIn";
2422
private const string ModelEnvironmentVariable = "CLAUDE_TEST_MODEL";
25-
private const string NoSessionPersistenceFlag = "--no-session-persistence";
26-
private const string OutputFormatFlag = "--output-format";
2723
private const string ProjectsDirectoryName = "projects";
28-
private const string JsonOutputFormat = "json";
29-
private const string PrintFlag = "-p";
30-
private const string ProbePrompt = "Reply with ok only.";
31-
private const string ResultPropertyName = "result";
32-
private const string IsErrorPropertyName = "is_error";
3324
private const int AuthenticationProbeTimeoutMilliseconds = 60000;
3425
private const string TerminateFailureMessagePrefix = "Failed to terminate timed-out Claude auth probe process: ";
3526
private static readonly Lazy<AuthenticationProbeResult> CachedAuthenticationProbe = new(ProbeAuthentication);
@@ -163,28 +154,20 @@ private static AuthenticationProbeResult ProbeAuthentication()
163154

164155
var startInfo = new ProcessStartInfo(executablePath)
165156
{
166-
RedirectStandardInput = true,
167157
RedirectStandardOutput = true,
168158
RedirectStandardError = true,
169159
UseShellExecute = false,
170160
CreateNoWindow = true,
171161
};
172-
startInfo.ArgumentList.Add(PrintFlag);
173-
startInfo.ArgumentList.Add(OutputFormatFlag);
174-
startInfo.ArgumentList.Add(JsonOutputFormat);
175-
startInfo.ArgumentList.Add(DangerouslySkipPermissionsFlag);
176-
startInfo.ArgumentList.Add(NoSessionPersistenceFlag);
177-
startInfo.ArgumentList.Add(MaxBudgetFlag);
178-
startInfo.ArgumentList.Add(MaxBudgetValue);
179-
startInfo.ArgumentList.Add(ProbePrompt);
162+
startInfo.ArgumentList.Add(AuthCommandName);
163+
startInfo.ArgumentList.Add(StatusCommandName);
180164

181165
using var process = Process.Start(startInfo);
182166
if (process is null)
183167
{
184168
return new AuthenticationProbeResult(executablePath, false);
185169
}
186170

187-
process.StandardInput.Close();
188171
var standardOutputTask = process.StandardOutput.ReadToEndAsync();
189172
var standardErrorTask = process.StandardError.ReadToEndAsync();
190173

@@ -205,23 +188,13 @@ private static AuthenticationProbeResult ProbeAuthentication()
205188
return new AuthenticationProbeResult(executablePath, false);
206189
}
207190

208-
if (combinedOutput.Contains(LoginGuidanceFragment, StringComparison.OrdinalIgnoreCase)
209-
|| combinedOutput.Contains(UnauthorizedStatusCodeFragment, StringComparison.OrdinalIgnoreCase))
210-
{
211-
return new AuthenticationProbeResult(executablePath, false);
212-
}
213-
214191
try
215192
{
216-
using var document = JsonDocument.Parse(standardOutput);
193+
using var document = JsonDocument.Parse(string.IsNullOrWhiteSpace(standardOutput) ? combinedOutput : standardOutput);
217194
var root = document.RootElement;
218-
var isError = root.TryGetProperty(IsErrorPropertyName, out var isErrorElement)
219-
&& isErrorElement.ValueKind is JsonValueKind.True or JsonValueKind.False
220-
&& isErrorElement.GetBoolean();
221-
var result = root.TryGetProperty(ResultPropertyName, out var resultElement)
222-
? resultElement.GetString()
223-
: null;
224-
var isAuthenticated = !isError && !string.IsNullOrWhiteSpace(result);
195+
var isAuthenticated = root.TryGetProperty(LoggedInPropertyName, out var loggedInElement)
196+
&& loggedInElement.ValueKind is JsonValueKind.True or JsonValueKind.False
197+
&& loggedInElement.GetBoolean();
225198
return new AuthenticationProbeResult(executablePath, isAuthenticated);
226199
}
227200
catch (JsonException)

0 commit comments

Comments
 (0)