Remove Jenkinsfile and add unit tests for various models including Address, Domain, Nameserver, Section, Session, Subnetwork, Tag, Vlan, and Vrf. Introduce mock classes for HTTP requests and cmdlet testing.
This commit is contained in:
172
classlib.tests/Mocks/MockHttpMessageHandler.cs
Normal file
172
classlib.tests/Mocks/MockHttpMessageHandler.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
namespace PS.IPAM.Tests.Mocks;
|
||||
|
||||
using System.Net;
|
||||
|
||||
/// <summary>
|
||||
/// A mock HTTP message handler for testing HTTP requests without making actual network calls.
|
||||
/// This handler does not dispose itself when the HttpClient is disposed, allowing reuse in tests.
|
||||
/// </summary>
|
||||
public class MockHttpMessageHandler : HttpMessageHandler
|
||||
{
|
||||
private readonly Queue<MockResponse> _responses = new();
|
||||
private readonly List<HttpRequestMessage> _requests = new();
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets all requests that were sent through this handler.
|
||||
/// </summary>
|
||||
public IReadOnlyList<HttpRequestMessage> Requests => _requests.AsReadOnly();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last request that was sent through this handler.
|
||||
/// </summary>
|
||||
public HttpRequestMessage? LastRequest => _requests.LastOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Queues a response to be returned for the next request.
|
||||
/// </summary>
|
||||
public MockHttpMessageHandler WithResponse(HttpStatusCode statusCode, string content, string contentType = "application/json")
|
||||
{
|
||||
_responses.Enqueue(new MockResponse(statusCode, content, contentType));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a successful JSON response.
|
||||
/// </summary>
|
||||
public MockHttpMessageHandler WithJsonResponse(string jsonContent)
|
||||
{
|
||||
return WithResponse(HttpStatusCode.OK, jsonContent, "application/json");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a successful response with phpIPAM-style wrapper.
|
||||
/// </summary>
|
||||
public MockHttpMessageHandler WithSuccessResponse(string dataJson)
|
||||
{
|
||||
var response = $"{{\"code\":200,\"success\":true,\"data\":{dataJson}}}";
|
||||
return WithJsonResponse(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a 404 Not Found response.
|
||||
/// </summary>
|
||||
public MockHttpMessageHandler WithNotFoundResponse()
|
||||
{
|
||||
return WithResponse(HttpStatusCode.NotFound, "{\"code\":404,\"success\":false,\"message\":\"Not found\"}", "application/json");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues an error response.
|
||||
/// </summary>
|
||||
public MockHttpMessageHandler WithErrorResponse(HttpStatusCode statusCode, string message)
|
||||
{
|
||||
var response = $"{{\"code\":{(int)statusCode},\"success\":false,\"message\":\"{message}\"}}";
|
||||
return WithResponse(statusCode, response, "application/json");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues an exception to be thrown on the next request.
|
||||
/// </summary>
|
||||
public MockHttpMessageHandler WithException(Exception exception)
|
||||
{
|
||||
_responses.Enqueue(new MockResponse(exception));
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(nameof(MockHttpMessageHandler));
|
||||
}
|
||||
|
||||
_requests.Add(request);
|
||||
|
||||
if (_responses.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No mock response configured. Call WithResponse() before making requests.");
|
||||
}
|
||||
|
||||
var mockResponse = _responses.Dequeue();
|
||||
|
||||
if (mockResponse.Exception != null)
|
||||
{
|
||||
throw mockResponse.Exception;
|
||||
}
|
||||
|
||||
var response = new HttpResponseMessage(mockResponse.StatusCode)
|
||||
{
|
||||
Content = new StringContent(mockResponse.Content, System.Text.Encoding.UTF8, mockResponse.ContentType),
|
||||
RequestMessage = request
|
||||
};
|
||||
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
// Don't actually dispose - allow reuse in tests
|
||||
// The test itself is responsible for cleanup
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually disposes the handler. Call this in test cleanup.
|
||||
/// </summary>
|
||||
public void ForceDispose()
|
||||
{
|
||||
_disposed = true;
|
||||
base.Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that a request was made to the expected URL.
|
||||
/// </summary>
|
||||
public bool WasRequestMadeTo(string urlContains)
|
||||
{
|
||||
return _requests.Any(r => r.RequestUri?.ToString().Contains(urlContains) == true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that a request with the expected method was made.
|
||||
/// </summary>
|
||||
public bool WasRequestMadeWithMethod(HttpMethod method)
|
||||
{
|
||||
return _requests.Any(r => r.Method == method);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a header from the last request.
|
||||
/// </summary>
|
||||
public string? GetLastRequestHeader(string headerName)
|
||||
{
|
||||
if (LastRequest?.Headers.TryGetValues(headerName, out var values) == true)
|
||||
{
|
||||
return values.FirstOrDefault();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class MockResponse
|
||||
{
|
||||
public HttpStatusCode StatusCode { get; }
|
||||
public string Content { get; }
|
||||
public string ContentType { get; }
|
||||
public Exception? Exception { get; }
|
||||
|
||||
public MockResponse(HttpStatusCode statusCode, string content, string contentType)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
Content = content;
|
||||
ContentType = contentType;
|
||||
}
|
||||
|
||||
public MockResponse(Exception exception)
|
||||
{
|
||||
Exception = exception;
|
||||
StatusCode = HttpStatusCode.InternalServerError;
|
||||
Content = string.Empty;
|
||||
ContentType = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user