From f8f240e31326208d5837c5d54cfda80c70f3a6c4 Mon Sep 17 00:00:00 2001 From: Nikolay Tatarinov Date: Mon, 19 Jan 2026 14:44:10 +0300 Subject: [PATCH] Updated subnet object handling and improved documentation --- .../Cmdlets/GetAddressCmdletTests.cs | 323 ++++++++++++++++++ .../Cmdlets/NewSessionCmdletTests.cs | 103 ++++++ 2 files changed, 426 insertions(+) create mode 100644 classlib.tests/Cmdlets/GetAddressCmdletTests.cs create mode 100644 classlib.tests/Cmdlets/NewSessionCmdletTests.cs diff --git a/classlib.tests/Cmdlets/GetAddressCmdletTests.cs b/classlib.tests/Cmdlets/GetAddressCmdletTests.cs new file mode 100644 index 0000000..8ca88e5 --- /dev/null +++ b/classlib.tests/Cmdlets/GetAddressCmdletTests.cs @@ -0,0 +1,323 @@ +namespace PS.IPAM.Tests.Cmdlets; + +using System.Net; +using FluentAssertions; +using PS.IPAM; +using PS.IPAM.Cmdlets; +using PS.IPAM.Helpers; +using PS.IPAM.Tests.Mocks; +using Xunit; + +/// +/// Tests for the GetAddressCmdlet. +/// Note: Full cmdlet testing with parameter sets requires a PowerShell runspace. +/// These tests focus on verifying the cmdlet structure and the underlying RequestHelper functionality. +/// +[Collection("Sequential")] +public class GetAddressCmdletTests : IDisposable +{ + private MockHttpMessageHandler? _mockHandler; + + public GetAddressCmdletTests() + { + // Clean state before each test + SessionManager.CloseSession(); + RequestHelper.TestHttpHandler = null; + } + + public void Dispose() + { + // Clean up after each test + SessionManager.CloseSession(); + RequestHelper.TestHttpHandler = null; + _mockHandler?.ForceDispose(); + } + + private void SetupSession() + { + SessionManager.CreateSessionWithToken("https://ipam.example.com", "testapp", "test-token"); + } + + private MockHttpMessageHandler SetupMockHandler() + { + _mockHandler = new MockHttpMessageHandler(); + RequestHelper.TestHttpHandler = _mockHandler; + return _mockHandler; + } + + [Fact] + public void GetAddressCmdlet_Exists() + { + // Verify the cmdlet class exists and can be instantiated + var cmdlet = new GetAddressCmdlet(); + cmdlet.Should().NotBeNull(); + } + + [Fact] + public void GetAddressCmdlet_IdProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.Id = 42; + cmdlet.Id.Should().Be(42); + } + + [Fact] + public void GetAddressCmdlet_IPProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.IP = IPAddress.Parse("192.168.1.100"); + cmdlet.IP.Should().Be(IPAddress.Parse("192.168.1.100")); + } + + [Fact] + public void GetAddressCmdlet_HostNameProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.HostName = "server01.example.com"; + cmdlet.HostName.Should().Be("server01.example.com"); + } + + [Fact] + public void GetAddressCmdlet_HostBaseProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.HostBase = "server"; + cmdlet.HostBase.Should().Be("server"); + } + + [Fact] + public void GetAddressCmdlet_TagIdProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.TagId = 2; + cmdlet.TagId.Should().Be(2); + } + + [Fact] + public void GetAddressCmdlet_SubnetIdProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.SubnetId = 10; + cmdlet.SubnetId.Should().Be(10); + } + + [Fact] + public void GetAddressCmdlet_SubnetCIDRProperty_Exists() + { + var cmdlet = new GetAddressCmdlet(); + cmdlet.SubnetCIDR = "192.168.1.0/24"; + cmdlet.SubnetCIDR.Should().Be("192.168.1.0/24"); + } + + // Test the underlying RequestHelper functionality that the cmdlet uses + + [Fact] + public async Task RequestHelper_GetAddressById_ReturnsAddress() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + var addressJson = @"{ + ""id"": 1, + ""subnetId"": 10, + ""ip"": ""192.168.1.100"", + ""hostname"": ""server01"", + ""description"": ""Test server"" + }"; + handler.WithSuccessResponse(addressJson); + + // Act + var result = await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address, + null, + null, + new[] { "1" } + ); + + // Assert + result.Should().BeOfType
(); + var address = (Address)result!; + address.Id.Should().Be(1); + address.Ip.Should().Be("192.168.1.100"); + address.Hostname.Should().Be("server01"); + } + + [Fact] + public async Task RequestHelper_GetAddressById_BuildsCorrectUri() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithSuccessResponse(@"{""id"": 42, ""ip"": ""10.0.0.1""}"); + + // Act + await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address, + null, + null, + new[] { "42" } + ); + + // Assert + handler.LastRequest!.RequestUri!.ToString().Should().Contain("/addresses/42/"); + } + + [Fact] + public async Task RequestHelper_SearchByIP_BuildsCorrectUri() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithSuccessResponse(@"{""id"": 1, ""ip"": ""192.168.1.50""}"); + + // Act + await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address, + null, + null, + new[] { "search", "192.168.1.50" } + ); + + // Assert + handler.LastRequest!.RequestUri!.ToString().Should().Contain("/addresses/search/192.168.1.50/"); + } + + [Fact] + public async Task RequestHelper_SearchByHostname_BuildsCorrectUri() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithSuccessResponse(@"{""id"": 1, ""ip"": ""10.0.0.5"", ""hostname"": ""myserver.example.com""}"); + + // Act + await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address, + null, + null, + new[] { "search_hostname", "myserver.example.com" } + ); + + // Assert + handler.LastRequest!.RequestUri!.ToString().Should().Contain("/addresses/search_hostname/myserver.example.com/"); + } + + [Fact] + public async Task RequestHelper_GetSubnetAddresses_BuildsCorrectUri() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithSuccessResponse(@"[{""id"": 1, ""ip"": ""192.168.1.1""}]"); + + // Act + await RequestHelper.InvokeRequest( + "GET", + controllers.subnets, + types.Address, + null, + null, + new[] { "10", "addresses" } + ); + + // Assert + handler.LastRequest!.RequestUri!.ToString().Should().Contain("/subnets/10/addresses/"); + } + + [Fact] + public async Task RequestHelper_GetAddressesByTag_BuildsCorrectUri() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithSuccessResponse(@"[{""id"": 1, ""ip"": ""10.0.0.1"", ""tag"": 2}]"); + + // Act + await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address, + null, + null, + new[] { "tags", "2", "addresses" } + ); + + // Assert + handler.LastRequest!.RequestUri!.ToString().Should().Contain("/addresses/tags/2/addresses/"); + } + + [Fact] + public async Task RequestHelper_ReturnsMultipleAddresses() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithSuccessResponse(@"[ + {""id"": 1, ""ip"": ""192.168.1.1""}, + {""id"": 2, ""ip"": ""192.168.1.2""}, + {""id"": 3, ""ip"": ""192.168.1.3""} + ]"); + + // Act + var result = await RequestHelper.InvokeRequest( + "GET", + controllers.subnets, + types.Address, + null, + null, + new[] { "10", "addresses" } + ); + + // Assert + result.Should().BeAssignableTo(); + var addresses = ((System.Collections.IEnumerable)result!).Cast().ToList(); + addresses.Should().HaveCount(3); + addresses.Should().AllBeOfType
(); + } + + [Fact] + public async Task RequestHelper_With404Response_ReturnsNull() + { + // Arrange + SetupSession(); + var handler = SetupMockHandler(); + handler.WithNotFoundResponse(); + + // Act + var result = await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address, + null, + null, + new[] { "999" } + ); + + // Assert + result.Should().BeNull(); + } + + [Fact] + public async Task RequestHelper_WithNoSession_ThrowsException() + { + // Arrange - no session set up + + // Act + var action = async () => await RequestHelper.InvokeRequest( + "GET", + controllers.addresses, + types.Address + ); + + // Assert + await action.Should().ThrowAsync().WithMessage("No session available!"); + } +} diff --git a/classlib.tests/Cmdlets/NewSessionCmdletTests.cs b/classlib.tests/Cmdlets/NewSessionCmdletTests.cs new file mode 100644 index 0000000..64c8f71 --- /dev/null +++ b/classlib.tests/Cmdlets/NewSessionCmdletTests.cs @@ -0,0 +1,103 @@ +namespace PS.IPAM.Tests.Cmdlets; + +using FluentAssertions; +using PS.IPAM; +using PS.IPAM.Cmdlets; +using PS.IPAM.Helpers; +using Xunit; + +/// +/// Tests for the NewSessionCmdlet. +/// Note: Full cmdlet testing with parameter sets requires a PowerShell runspace. +/// These tests focus on verifying the cmdlet structure and basic functionality. +/// +[Collection("Sequential")] +public class NewSessionCmdletTests : IDisposable +{ + public NewSessionCmdletTests() + { + // Clean state before each test + SessionManager.CloseSession(); + } + + public void Dispose() + { + // Clean up after each test + SessionManager.CloseSession(); + } + + [Fact] + public void NewSessionCmdlet_Exists() + { + // Verify the cmdlet class exists and can be instantiated + var cmdlet = new NewSessionCmdlet(); + cmdlet.Should().NotBeNull(); + } + + [Fact] + public void NewSessionCmdlet_URLProperty_Exists() + { + var cmdlet = new NewSessionCmdlet(); + cmdlet.URL = "https://ipam.example.com"; + cmdlet.URL.Should().Be("https://ipam.example.com"); + } + + [Fact] + public void NewSessionCmdlet_AppIDProperty_Exists() + { + var cmdlet = new NewSessionCmdlet(); + cmdlet.AppID = "testapp"; + cmdlet.AppID.Should().Be("testapp"); + } + + [Fact] + public void NewSessionCmdlet_TokenProperty_Exists() + { + var cmdlet = new NewSessionCmdlet(); + cmdlet.Token = "my-api-token"; + cmdlet.Token.Should().Be("my-api-token"); + } + + [Fact] + public void NewSessionCmdlet_CredentialsProperty_Exists() + { + var cmdlet = new NewSessionCmdlet(); + cmdlet.Credentials = null; + cmdlet.Credentials.Should().BeNull(); + } + + [Fact] + public void NewSessionCmdlet_IgnoreSSLProperty_Exists() + { + var cmdlet = new NewSessionCmdlet(); + // SwitchParameter defaults to false + cmdlet.IgnoreSSL.IsPresent.Should().BeFalse(); + // Setting it to true + var switchParam = new System.Management.Automation.SwitchParameter(true); + cmdlet.IgnoreSSL = switchParam; + // Note: SwitchParameter is a struct, so getting the value back may not work as expected + // Just verify the property exists and can be set + } + + [Fact] + public void SessionManager_CreateSessionWithToken_WorksCorrectly() + { + // This tests the underlying functionality that the cmdlet uses + var session = SessionManager.CreateSessionWithToken( + "https://ipam.example.com", + "testapp", + "my-api-token" + ); + + session.Should().NotBeNull(); + session.URL.Should().Be("https://ipam.example.com"); + session.AppID.Should().Be("testapp"); + session.Token.Should().Be("my-api-token"); + session.AuthType.Should().Be(AuthType.token); + session.Expires.Should().BeNull(); + session.Credentials.Should().BeNull(); + + // Verify it was set as current session + SessionManager.CurrentSession.Should().BeSameAs(session); + } +}