using Xunit; namespace Robotico.Nexus.Client.Tests; [Collection("NexusTlsEnvironment")] public class NexusTlsMaterialTests : IDisposable { private const string CaVar = "NEXUS_TLS_CA_FILE"; private const string CertVar = "NEXUS_TLS_CLIENT_CERT_FILE"; private const string KeyVar = "NEXUS_TLS_CLIENT_KEY_FILE"; private const string ModeVar = "NEXUS_TLS_MODE"; public void Dispose() { Environment.SetEnvironmentVariable(CaVar, null); Environment.SetEnvironmentVariable(CertVar, null); Environment.SetEnvironmentVariable(KeyVar, null); Environment.SetEnvironmentVariable(ModeVar, null); } [Fact] public void Constructor_ThrowsOnBlankArguments() { Assert.Throws(() => new NexusTlsMaterial(string.Empty, "cert", "key")); Assert.Throws(() => new NexusTlsMaterial("ca", string.Empty, "key")); Assert.Throws(() => new NexusTlsMaterial("ca", "cert", string.Empty)); } [Fact] public void Constructor_ResolvesFullPaths_AndDefaultsToHttps() { NexusTlsMaterial material = new("ca.pem", "cert.pem", "key.pem"); Assert.EndsWith("ca.pem", material.CaCertificateFile, StringComparison.Ordinal); Assert.True(Path.IsPathRooted(material.CaCertificateFile)); Assert.True(material.UseHttps); } [Fact] public void TryFromEnvironment_ReturnsNull_WhenVariablesUnset() { Assert.Null(NexusTlsMaterial.TryFromEnvironment()); } [Fact] public void TryFromEnvironment_ReturnsNull_WhenFilesDoNotExist() { Environment.SetEnvironmentVariable(CaVar, "/nonexistent/ca.pem"); Environment.SetEnvironmentVariable(CertVar, "/nonexistent/cert.pem"); Environment.SetEnvironmentVariable(KeyVar, "/nonexistent/key.pem"); Assert.Null(NexusTlsMaterial.TryFromEnvironment()); } [Fact] public void TryFromEnvironment_ReturnsMaterial_WhenFilesExist() { string dir = Directory.CreateTempSubdirectory("nexus-tls-test-").FullName; try { string ca = Path.Combine(dir, "ca.pem"); string cert = Path.Combine(dir, "cert.pem"); string key = Path.Combine(dir, "key.pem"); File.WriteAllText(ca, "ca"); File.WriteAllText(cert, "cert"); File.WriteAllText(key, "key"); Environment.SetEnvironmentVariable(CaVar, ca); Environment.SetEnvironmentVariable(CertVar, cert); Environment.SetEnvironmentVariable(KeyVar, key); Environment.SetEnvironmentVariable(ModeVar, "insecure"); NexusTlsMaterial? material = NexusTlsMaterial.TryFromEnvironment(); Assert.NotNull(material); Assert.False(material!.UseHttps); } finally { Directory.Delete(dir, recursive: true); } } [Fact] public void EnsureFilesExist_Throws_WhenAnyFileMissing() { NexusTlsMaterial material = new("/nonexistent/ca.pem", "/nonexistent/cert.pem", "/nonexistent/key.pem"); Assert.Throws(material.EnsureFilesExist); } [Fact] public void EnsureFilesExist_Succeeds_WhenAllFilesPresent() { string dir = Directory.CreateTempSubdirectory("nexus-tls-test-").FullName; try { string ca = Path.Combine(dir, "ca.pem"); string cert = Path.Combine(dir, "cert.pem"); string key = Path.Combine(dir, "key.pem"); File.WriteAllText(ca, "ca"); File.WriteAllText(cert, "cert"); File.WriteAllText(key, "key"); NexusTlsMaterial material = new(ca, cert, key); material.EnsureFilesExist(); } finally { Directory.Delete(dir, recursive: true); } } }