Files

72 lines
2.5 KiB
C#

using ClawdDotNet.App.Services;
using ClawdDotNet.Core.Runtimes;
using Shouldly;
namespace ClawdDotNet.App.Tests;
/// <summary>
/// #712: A runtime setting is checked when it is saved — not at the next run, where a list
/// of hosts that does not parse would only show as a failed run at night.
/// </summary>
public sealed class RuntimeSettingsTests
{
[Fact]
public void A_sound_runtime_passes()
=> AgentAdministration.ValidateRuntime(new AgentRuntimeConfig
{
Kind = "claude-code", AllowedTools = ["Read", "Bash(npm test)"], Egress = ["pypi.org", "*.pythonhosted.org"]
}).ShouldBeNull();
[Theory]
[InlineData("codex")]
[InlineData("http")]
public void A_runtime_that_is_not_built_is_refused(string kind)
=> AgentAdministration.ValidateRuntime(new AgentRuntimeConfig { Kind = kind })!.ShouldContain("Unknown runtime");
[Fact]
public void An_option_in_disguise_is_not_a_tool_name()
=> AgentAdministration.ValidateRuntime(new AgentRuntimeConfig
{
Kind = "claude-code", AllowedTools = ["--dangerously-skip-permissions"]
}).ShouldNotBeNull();
[Fact]
public void A_host_that_is_not_one_is_refused()
=> AgentAdministration.ValidateRuntime(new AgentRuntimeConfig
{
Kind = "claude-code", Egress = ["https://example.org/path"]
}).ShouldNotBeNull();
[Fact]
public void The_command_runtime_needs_a_command()
=> AgentAdministration.ValidateRuntime(new AgentRuntimeConfig { Kind = "command" })!.ShouldContain("command");
[Theory]
[InlineData(0, 30)]
[InlineData(501, 30)]
[InlineData(30, 0)]
[InlineData(30, 241)]
public void Turns_and_time_stay_in_bounds(int turns, int minutes)
=> AgentAdministration.ValidateRuntime(new AgentRuntimeConfig
{
Kind = "claude-code", MaxTurns = turns, TimeoutMinutes = minutes
}).ShouldNotBeNull();
[Fact]
public void The_claude_code_keys_are_stored_protected()
{
var config = new Core.Config.InstanceConfig
{
ClaudeCode = new ClaudeCodeSettings { ApiKey = "sk-ant-plain", OAuthToken = "sk-ant-oat-plain" }
};
Core.Security.ConfigSecrets.Protect(config);
config.ClaudeCode.ApiKey.ShouldNotBe("sk-ant-plain");
config.ClaudeCode.OAuthToken.ShouldNotBe("sk-ant-oat-plain");
Core.Security.ConfigSecrets.Unprotect(config);
config.ClaudeCode.ApiKey.ShouldBe("sk-ant-plain");
config.ClaudeCode.OAuthToken.ShouldBe("sk-ant-oat-plain");
}
}