using PnvPanel.Domain.Inbounds; using Xunit; namespace PnvPanel.Domain.Tests.Inbounds; public class InboundTests { [Fact] public void FromRemote_CreatesUnpublishedInbound() { var nodeId = Guid.NewGuid(); var inbound = Inbound.FromRemote(nodeId, "12", VpnProtocol.Vless, "Germany", 443); Assert.Equal(nodeId, inbound.NodeId); Assert.Equal("12", inbound.RemoteInboundId); Assert.Equal(VpnProtocol.Vless, inbound.Protocol); Assert.Equal(443, inbound.Port); Assert.False(inbound.IsPublished); Assert.Empty(inbound.AllowedRoleIds); } [Fact] public void UpdateFromRemote_UpdatesFieldsAndLastSyncAt() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Old", 443); var before = inbound.LastSyncAt; inbound.UpdateFromRemote(VpnProtocol.Trojan, "New", 8443); Assert.Equal(VpnProtocol.Trojan, inbound.Protocol); Assert.Equal("New", inbound.Remark); Assert.Equal(8443, inbound.Port); Assert.NotNull(inbound.LastSyncAt); } [Fact] public void Publish_SetsDisplayNameAndRoles() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Germany", 443); var roleId = Guid.NewGuid(); inbound.Publish("Germany (VLESS)", [roleId, roleId]); Assert.True(inbound.IsPublished); Assert.Equal("Germany (VLESS)", inbound.DisplayName); Assert.Single(inbound.AllowedRoleIds); Assert.Contains(roleId, inbound.AllowedRoleIds); } [Fact] public void Unpublish_SetsIsPublishedFalseButKeepsRoles() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Germany", 443); var roleId = Guid.NewGuid(); inbound.Publish("Germany", [roleId]); inbound.Unpublish(); Assert.False(inbound.IsPublished); Assert.Contains(roleId, inbound.AllowedRoleIds); } [Fact] public void FromRemote_CreatesAvailableInbound() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Germany", 443); Assert.True(inbound.IsAvailable); } [Fact] public void MarkUnavailable_SetsIsAvailableAndIsPublishedFalse() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Germany", 443); inbound.Publish("Germany", [Guid.NewGuid()]); inbound.MarkUnavailable(); Assert.False(inbound.IsAvailable); Assert.False(inbound.IsPublished); } [Fact] public void UpdateFromRemote_AfterMarkUnavailable_RestoresIsAvailable() { // Инбаунд пропадал с ноды, потом снова появился при следующей синхронизации — без сброса // IsAvailable оставался бы недоступным навсегда, хотя реально снова опубликован на панели. var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Old", 443); inbound.MarkUnavailable(); inbound.UpdateFromRemote(VpnProtocol.Vless, "New", 443); Assert.True(inbound.IsAvailable); } [Fact] public void Publish_AfterMarkUnavailable_RestoresIsAvailable() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Germany", 443); inbound.MarkUnavailable(); inbound.Publish("Germany", [Guid.NewGuid()]); Assert.True(inbound.IsAvailable); } [Fact] public void RemoveAllowedRole_RemovesOnlyMatchingRole() { var inbound = Inbound.FromRemote(Guid.NewGuid(), "12", VpnProtocol.Vless, "Germany", 443); var roleId = Guid.NewGuid(); var otherRoleId = Guid.NewGuid(); inbound.Publish("Germany", [roleId, otherRoleId]); inbound.RemoveAllowedRole(roleId); Assert.DoesNotContain(roleId, inbound.AllowedRoleIds); Assert.Contains(otherRoleId, inbound.AllowedRoleIds); } }