using PnvPanel.Domain.Exceptions; using PnvPanel.Domain.Nodes; using Xunit; namespace PnvPanel.Domain.Tests.Nodes; public class NodeTests { private static NodeCredentials Credentials => new("admin", "protected-secret"); [Fact] public void Register_WithAbsoluteUri_CreatesEnabledUnknownStatusNode() { var node = Node.Register( "Germany-1", new Uri("https://de1.example.com:2053"), Credentials, "Germany" ); Assert.Equal("Germany-1", node.Name); Assert.Equal("Germany", node.Location); Assert.Equal(NodeStatus.Unknown, node.Status); Assert.True(node.IsEnabled); Assert.NotEqual(Guid.Empty, node.Id); } [Fact] public void Register_WithRelativeUri_Throws() { var relativeUri = new Uri("de1.example.com", UriKind.Relative); Assert.Throws(() => Node.Register("Germany-1", relativeUri, Credentials, null) ); } [Theory] [InlineData("https://host.example.com/benis", "https://host.example.com/benis/")] [InlineData("https://host.example.com/benis/", "https://host.example.com/benis/")] [InlineData("https://host.example.com", "https://host.example.com/")] public void Register_NormalizesBaseAddressToTrailingSlash(string input, string expected) { var node = Node.Register("Node", new Uri(input), Credentials, null); Assert.Equal(expected, node.BaseAddress.ToString()); } [Theory] [InlineData("https://host.example.com/benis", "https://host.example.com/benis/")] [InlineData("https://host.example.com/benis/", "https://host.example.com/benis/")] public void UpdateAddress_NormalizesBaseAddressToTrailingSlash(string input, string expected) { var node = Node.Register("Node", new Uri("https://old.example.com"), Credentials, null); node.UpdateAddress(new Uri(input)); Assert.Equal(expected, node.BaseAddress.ToString()); } [Fact] public void UpdateDetails_ChangesNameAndLocation() { var node = Node.Register( "Old", new Uri("https://example.com"), Credentials, "Old location" ); node.UpdateDetails("New", "New location"); Assert.Equal("New", node.Name); Assert.Equal("New location", node.Location); } [Fact] public void UpdateCredentials_ReplacesCredentials() { var node = Node.Register("Node", new Uri("https://example.com"), Credentials, null); var newCredentials = new NodeCredentials("root", "new-protected-secret"); node.UpdateCredentials(newCredentials); Assert.Equal(newCredentials, node.Credentials); } [Fact] public void Disable_ThenEnable_TogglesIsEnabled() { var node = Node.Register("Node", new Uri("https://example.com"), Credentials, null); node.Disable(); Assert.False(node.IsEnabled); node.Enable(); Assert.True(node.IsEnabled); } [Fact] public void SetNotifyOnStatusChange_DefaultsFalse_AndCanBeToggled() { var node = Node.Register("Node", new Uri("https://example.com"), Credentials, null); Assert.False(node.NotifyOnStatusChange); node.SetNotifyOnStatusChange(true); Assert.True(node.NotifyOnStatusChange); node.SetNotifyOnStatusChange(false); Assert.False(node.NotifyOnStatusChange); } [Fact] public void UpdateStatus_SetsStatus() { var node = Node.Register("Node", new Uri("https://example.com"), Credentials, null); node.UpdateStatus(NodeStatus.Online); Assert.Equal(NodeStatus.Online, node.Status); } [Fact] public void MarkSynced_SetsLastSyncAt() { var node = Node.Register("Node", new Uri("https://example.com"), Credentials, null); Assert.Null(node.LastSyncAt); node.MarkSynced(); Assert.NotNull(node.LastSyncAt); } [Fact] public void NodeCredentials_ToString_RedactsPassword() { var text = Credentials.ToString(); Assert.DoesNotContain("protected-secret", text); Assert.Contains("REDACTED", text); } }