Refactored subnet object methods and enhanced related documentation
This commit is contained in:
503
classlib.tests/Helpers/RequestHelperTests.cs
Normal file
503
classlib.tests/Helpers/RequestHelperTests.cs
Normal file
@@ -0,0 +1,503 @@
|
||||
namespace PS.IPAM.Tests.Helpers;
|
||||
|
||||
using System.Net;
|
||||
using FluentAssertions;
|
||||
using PS.IPAM;
|
||||
using PS.IPAM.Helpers;
|
||||
using PS.IPAM.Tests.Mocks;
|
||||
using Xunit;
|
||||
|
||||
[Collection("Sequential")]
|
||||
public class RequestHelperTests : IDisposable
|
||||
{
|
||||
private MockHttpMessageHandler? _mockHandler;
|
||||
|
||||
public RequestHelperTests()
|
||||
{
|
||||
// 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(AuthType authType = AuthType.token)
|
||||
{
|
||||
if (authType == AuthType.token)
|
||||
{
|
||||
SessionManager.CreateSessionWithToken("https://ipam.example.com", "testapp", "test-token");
|
||||
}
|
||||
else
|
||||
{
|
||||
// For credentials auth, we need to set up a session manually with future expiry
|
||||
var session = new Session(
|
||||
AuthType.credentials,
|
||||
"cred-token",
|
||||
"testapp",
|
||||
"https://ipam.example.com",
|
||||
DateTime.Now.AddHours(1),
|
||||
null
|
||||
);
|
||||
SessionManager.CurrentSession = session;
|
||||
}
|
||||
}
|
||||
|
||||
private MockHttpMessageHandler SetupMockHandler()
|
||||
{
|
||||
_mockHandler = new MockHttpMessageHandler();
|
||||
RequestHelper.TestHttpHandler = _mockHandler;
|
||||
return _mockHandler;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithNoSession_ThrowsException()
|
||||
{
|
||||
// Arrange - no session set up
|
||||
|
||||
// Act
|
||||
var action = async () => await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
await action.Should().ThrowAsync<Exception>().WithMessage("No session available!");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithValidSession_BuildsCorrectUri()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{\"id\":1,\"ip\":\"192.168.1.1\"}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
handler.LastRequest.Should().NotBeNull();
|
||||
handler.LastRequest!.RequestUri!.ToString().Should().Be("https://ipam.example.com/api/testapp/addresses/1/");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithSubController_BuildsCorrectUri()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("[]");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("GET", controllers.subnets, null, subcontrollers.tags, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.RequestUri!.ToString().Should().Contain("/subnets/tags/1/");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithTokenAuth_AddsPhpipamTokenHeader()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession(AuthType.token);
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
handler.GetLastRequestHeader("phpipam-token").Should().Be("test-token");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithCredentialsAuth_AddsTokenHeader()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession(AuthType.credentials);
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
handler.GetLastRequestHeader("token").Should().Be("cred-token");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_GetMethod_UsesHttpGet()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Method.Should().Be(HttpMethod.Get);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_PostMethod_UsesHttpPost()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{\"id\":1}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, new { ip = "10.0.0.1" });
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Method.Should().Be(HttpMethod.Post);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_PatchMethod_UsesHttpPatch()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{\"id\":1}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, new { description = "updated" }, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Method.Should().Be(new HttpMethod("PATCH"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_DeleteMethod_UsesHttpDelete()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("DELETE", controllers.addresses, null, null, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Method.Should().Be(HttpMethod.Delete);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_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 InvokeRequest_WithErrorResponse_ThrowsHttpRequestException()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithErrorResponse(HttpStatusCode.InternalServerError, "Server error");
|
||||
|
||||
// Act
|
||||
var action = async () => await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
await action.Should().ThrowAsync<HttpRequestException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithAddressType_ReturnsAddressObject()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
var addressJson = @"{
|
||||
""id"": 1,
|
||||
""subnetId"": 10,
|
||||
""ip"": ""192.168.1.100"",
|
||||
""is_gateway"": false,
|
||||
""description"": ""Test server"",
|
||||
""hostname"": ""server01"",
|
||||
""mac"": ""00:11:22:33:44:55"",
|
||||
""owner"": ""admin"",
|
||||
""tag"": 2,
|
||||
""deviceId"": 0,
|
||||
""location"": """",
|
||||
""port"": """",
|
||||
""note"": """",
|
||||
""lastSeen"": null,
|
||||
""excludePing"": false,
|
||||
""PTRignore"": false,
|
||||
""PTR"": 0,
|
||||
""firewallAddressObject"": """",
|
||||
""editDate"": null,
|
||||
""customer_id"": 0
|
||||
}";
|
||||
handler.WithSuccessResponse(addressJson);
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
result.Should().BeOfType<Address>();
|
||||
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 InvokeRequest_WithAddressArray_ReturnsListOfAddresses()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
var addressArrayJson = @"[
|
||||
{""id"": 1, ""subnetId"": 10, ""ip"": ""192.168.1.1"", ""hostname"": ""host1""},
|
||||
{""id"": 2, ""subnetId"": 10, ""ip"": ""192.168.1.2"", ""hostname"": ""host2""}
|
||||
]";
|
||||
handler.WithSuccessResponse(addressArrayJson);
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.subnets, types.Address, null, null, new[] { "10", "addresses" });
|
||||
|
||||
// Assert
|
||||
result.Should().BeAssignableTo<IEnumerable<object>>();
|
||||
var addresses = ((IEnumerable<object>)result!).ToList();
|
||||
addresses.Should().HaveCount(2);
|
||||
addresses[0].Should().BeOfType<Address>();
|
||||
((Address)addresses[0]).Ip.Should().Be("192.168.1.1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithVlanType_ReturnsVlanObject()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
var vlanJson = @"{
|
||||
""vlanId"": 100,
|
||||
""domainId"": 1,
|
||||
""name"": ""Production"",
|
||||
""number"": 100,
|
||||
""description"": ""Production VLAN"",
|
||||
""editDate"": null,
|
||||
""customer_id"": 0
|
||||
}";
|
||||
handler.WithSuccessResponse(vlanJson);
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.vlan, types.Vlan, null, null, new[] { "100" });
|
||||
|
||||
// Assert
|
||||
result.Should().BeOfType<Vlan>();
|
||||
var vlan = (Vlan)result!;
|
||||
vlan.Name.Should().Be("Production");
|
||||
vlan.Number.Should().Be(100);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithSubnetworkType_ReturnsSubnetworkObject()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
var subnetJson = @"{
|
||||
""id"": 1,
|
||||
""subnet"": ""192.168.1.0"",
|
||||
""mask"": 24,
|
||||
""sectionId"": 1,
|
||||
""description"": ""Test subnet"",
|
||||
""linked_subnet"": """",
|
||||
""firewallAddressObject"": """",
|
||||
""vrfId"": 0,
|
||||
""masterSubnetId"": 0,
|
||||
""allowRequests"": false,
|
||||
""vlanId"": 100,
|
||||
""showName"": false,
|
||||
""deviceId"": 0,
|
||||
""permissions"": """",
|
||||
""pingSubnet"": false,
|
||||
""discoverSubnet"": false,
|
||||
""resolveDNS"": false,
|
||||
""DNSrecursive"": false,
|
||||
""DNSrecords"": false,
|
||||
""nameserverId"": 0,
|
||||
""scanAgent"": false,
|
||||
""isFolder"": false,
|
||||
""isFull"": false,
|
||||
""isPool"": false,
|
||||
""state"": 1,
|
||||
""threshold"": 0,
|
||||
""location"": 0,
|
||||
""editDate"": null,
|
||||
""lastScan"": null,
|
||||
""lastDiscovery"": null,
|
||||
""calculation"": {}
|
||||
}";
|
||||
handler.WithSuccessResponse(subnetJson);
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
result.Should().BeOfType<Subnetwork>();
|
||||
var subnet = (Subnetwork)result!;
|
||||
subnet.Subnet.Should().Be("192.168.1.0");
|
||||
subnet.Mask.Should().Be(24);
|
||||
subnet.GetCIDR().Should().Be("192.168.1.0/24");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithSectionType_ReturnsSectionObject()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
var sectionJson = @"{
|
||||
""id"": 1,
|
||||
""name"": ""Production"",
|
||||
""description"": ""Production section"",
|
||||
""masterSection"": 0,
|
||||
""permissions"": """",
|
||||
""strictMode"": false,
|
||||
""subnetOrdering"": ""default"",
|
||||
""order"": 1,
|
||||
""editDate"": null,
|
||||
""showSubnet"": true,
|
||||
""showVlan"": true,
|
||||
""showVRF"": false,
|
||||
""showSupernetOnly"": false,
|
||||
""DNS"": 0
|
||||
}";
|
||||
handler.WithSuccessResponse(sectionJson);
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
result.Should().BeOfType<Section>();
|
||||
var section = (Section)result!;
|
||||
section.Name.Should().Be("Production");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithCustomFields_ParsesExtendedData()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
var addressJson = @"{
|
||||
""id"": 1,
|
||||
""subnetId"": 10,
|
||||
""ip"": ""192.168.1.100"",
|
||||
""hostname"": ""server01"",
|
||||
""custom_environment"": ""production"",
|
||||
""custom_owner"": ""team-a""
|
||||
}";
|
||||
handler.WithSuccessResponse(addressJson);
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
||||
|
||||
// Assert
|
||||
var address = (Address)result!;
|
||||
address.ExtendedData.Should().NotBeNull();
|
||||
var extendedData = (Dictionary<string, object>)address.ExtendedData!;
|
||||
extendedData.Should().ContainKey("custom_environment");
|
||||
extendedData.Should().ContainKey("custom_owner");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithNoType_ReturnsDynamicData()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse(@"{""some"": ""data""}");
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.tools);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_PostWithParameters_SerializesJsonBody()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse(@"{""id"": 1}");
|
||||
|
||||
var parameters = new { ip = "10.0.0.1", subnetId = 5, description = "New address" };
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, parameters);
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Content.Should().NotBeNull();
|
||||
var content = await handler.LastRequest.Content!.ReadAsStringAsync();
|
||||
content.Should().Contain("10.0.0.1");
|
||||
content.Should().Contain("subnetId");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_SetsAcceptJsonHeader()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithSuccessResponse("{}");
|
||||
|
||||
// Act
|
||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Headers.Accept.Should().Contain(h => h.MediaType == "application/json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithEmptyResponse_ReturnsNull()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithResponse(HttpStatusCode.OK, "", "application/json");
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeRequest_WithNullDataInResponse_ReturnsNull()
|
||||
{
|
||||
// Arrange
|
||||
SetupSession();
|
||||
var handler = SetupMockHandler();
|
||||
handler.WithJsonResponse(@"{""code"": 200, ""success"": true, ""data"": null}");
|
||||
|
||||
// Act
|
||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address);
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull();
|
||||
}
|
||||
}
|
||||
193
classlib.tests/Helpers/SessionManagerTests.cs
Normal file
193
classlib.tests/Helpers/SessionManagerTests.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
namespace PS.IPAM.Tests.Helpers;
|
||||
|
||||
using FluentAssertions;
|
||||
using PS.IPAM;
|
||||
using PS.IPAM.Helpers;
|
||||
using Xunit;
|
||||
|
||||
[Collection("Sequential")]
|
||||
public class SessionManagerTests : IDisposable
|
||||
{
|
||||
public SessionManagerTests()
|
||||
{
|
||||
// Ensure clean state before each test
|
||||
SessionManager.CloseSession();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Clean up after each test
|
||||
SessionManager.CloseSession();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSession_WhenNoSession_ReturnsNoToken()
|
||||
{
|
||||
// Arrange
|
||||
SessionManager.CurrentSession = null;
|
||||
|
||||
// Act
|
||||
var result = SessionManager.TestSession();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("NoToken");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSession_WhenSessionWithNullExpires_ReturnsValid()
|
||||
{
|
||||
// Arrange
|
||||
var session = new Session(AuthType.token, "test-token", "app", "https://test.com", null, null);
|
||||
SessionManager.CurrentSession = session;
|
||||
|
||||
// Act
|
||||
var result = SessionManager.TestSession();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("Valid");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSession_WhenSessionNotExpired_ReturnsValid()
|
||||
{
|
||||
// Arrange
|
||||
var futureExpiry = DateTime.Now.AddHours(1);
|
||||
var session = new Session(AuthType.credentials, "test-token", "app", "https://test.com", futureExpiry, null);
|
||||
SessionManager.CurrentSession = session;
|
||||
|
||||
// Act
|
||||
var result = SessionManager.TestSession();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("Valid");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSession_WhenSessionExpired_ReturnsExpired()
|
||||
{
|
||||
// Arrange
|
||||
var pastExpiry = DateTime.Now.AddHours(-1);
|
||||
var session = new Session(AuthType.credentials, "test-token", "app", "https://test.com", pastExpiry, null);
|
||||
SessionManager.CurrentSession = session;
|
||||
|
||||
// Act
|
||||
var result = SessionManager.TestSession();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("Expired");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSessionWithToken_CreatesValidSession()
|
||||
{
|
||||
// Arrange
|
||||
var url = "https://ipam.example.com";
|
||||
var appId = "myApp";
|
||||
var token = "static-api-token";
|
||||
|
||||
// Act
|
||||
var session = SessionManager.CreateSessionWithToken(url, appId, token);
|
||||
|
||||
// Assert
|
||||
session.Should().NotBeNull();
|
||||
session.URL.Should().Be(url);
|
||||
session.AppID.Should().Be(appId);
|
||||
session.Token.Should().Be(token);
|
||||
session.AuthType.Should().Be(AuthType.token);
|
||||
session.Expires.Should().BeNull();
|
||||
session.Credentials.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSessionWithToken_SetsCurrentSession()
|
||||
{
|
||||
// Arrange
|
||||
var url = "https://ipam.example.com";
|
||||
var appId = "myApp";
|
||||
var token = "api-token";
|
||||
|
||||
// Act
|
||||
var session = SessionManager.CreateSessionWithToken(url, appId, token);
|
||||
|
||||
// Assert
|
||||
SessionManager.CurrentSession.Should().BeSameAs(session);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloseSession_ClearsCurrentSession()
|
||||
{
|
||||
// Arrange
|
||||
SessionManager.CreateSessionWithToken("https://test.com", "app", "token");
|
||||
SessionManager.CurrentSession.Should().NotBeNull();
|
||||
|
||||
// Act
|
||||
SessionManager.CloseSession();
|
||||
|
||||
// Assert
|
||||
SessionManager.CurrentSession.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloseSession_WhenNoSession_DoesNotThrow()
|
||||
{
|
||||
// Arrange
|
||||
SessionManager.CurrentSession = null;
|
||||
|
||||
// Act
|
||||
var action = () => SessionManager.CloseSession();
|
||||
|
||||
// Assert
|
||||
action.Should().NotThrow();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CurrentSession_CanBeSetDirectly()
|
||||
{
|
||||
// Arrange
|
||||
var session = new Session(AuthType.token, "token", "app", "https://test.com", null, null);
|
||||
|
||||
// Act
|
||||
SessionManager.CurrentSession = session;
|
||||
|
||||
// Assert
|
||||
SessionManager.CurrentSession.Should().BeSameAs(session);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHttpClient_WithoutIgnoreSsl_ReturnsHttpClient()
|
||||
{
|
||||
// Act
|
||||
using var client = SessionManager.CreateHttpClient(false);
|
||||
|
||||
// Assert
|
||||
client.Should().NotBeNull();
|
||||
client.Should().BeOfType<HttpClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHttpClient_WithIgnoreSsl_ReturnsHttpClient()
|
||||
{
|
||||
// Act
|
||||
using var client = SessionManager.CreateHttpClient(true);
|
||||
|
||||
// Assert
|
||||
client.Should().NotBeNull();
|
||||
client.Should().BeOfType<HttpClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSessionWithToken_ReplacesExistingSession()
|
||||
{
|
||||
// Arrange
|
||||
SessionManager.CreateSessionWithToken("https://old.com", "oldApp", "oldToken");
|
||||
|
||||
// Act
|
||||
var newSession = SessionManager.CreateSessionWithToken("https://new.com", "newApp", "newToken");
|
||||
|
||||
// Assert
|
||||
SessionManager.CurrentSession.Should().BeSameAs(newSession);
|
||||
SessionManager.CurrentSession!.URL.Should().Be("https://new.com");
|
||||
SessionManager.CurrentSession.AppID.Should().Be("newApp");
|
||||
SessionManager.CurrentSession.Token.Should().Be("newToken");
|
||||
}
|
||||
}
|
||||
32
classlib.tests/TestCollections.cs
Normal file
32
classlib.tests/TestCollections.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace PS.IPAM.Tests;
|
||||
|
||||
using Xunit;
|
||||
|
||||
/// <summary>
|
||||
/// Collection definition for tests that share static state (SessionManager, RequestHelper.TestHttpHandler).
|
||||
/// Tests in this collection will run sequentially, not in parallel.
|
||||
/// </summary>
|
||||
[CollectionDefinition("Sequential")]
|
||||
public class SequentialCollection : ICollectionFixture<SequentialTestFixture>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixture for sequential test collection.
|
||||
/// </summary>
|
||||
public class SequentialTestFixture : IDisposable
|
||||
{
|
||||
public SequentialTestFixture()
|
||||
{
|
||||
// Clean up before tests
|
||||
PS.IPAM.Helpers.SessionManager.CloseSession();
|
||||
PS.IPAM.Helpers.RequestHelper.TestHttpHandler = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Clean up after tests
|
||||
PS.IPAM.Helpers.SessionManager.CloseSession();
|
||||
PS.IPAM.Helpers.RequestHelper.TestHttpHandler = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user