Skip to content

Commit a691e39

Browse files
authored
new tests (#160)
1 parent c8d3a4e commit a691e39

19 files changed

Lines changed: 2495 additions & 39 deletions

File tree

OpenAlprWebhookProcessor.Server/CameraUpdateService/ISimpleCameraScheduler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public interface ISimpleCameraScheduler
2323

2424
List<ScheduledJobInfo> GetAllScheduledJobs();
2525

26-
Task ScheduleOverlayAsync(CameraUpdateRequest cameraUpdaterequest, CancellationToken cancellationToken);
26+
Task ScheduleOverlayAsync(CameraUpdateRequest cameraUpdateRequest, CancellationToken cancellationToken = default);
2727

2828
Task ClearOverlayAsync(Guid cameraId, CancellationToken cancellationToken = default);
2929

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using AwesomeAssertions;
2+
using Mediator;
3+
using NSubstitute;
4+
using NSubstitute.ExceptionExtensions;
5+
using NUnit.Framework;
6+
using OpenAlprWebhookProcessor.Data;
7+
using OpenAlprWebhookProcessor.Data.Repositories;
8+
using OpenAlprWebhookProcessor.Features.Alerts.Commands.DeleteAlert;
9+
using System;
10+
using System.Threading;
11+
using System.Threading.Tasks;
12+
using Tests.TestHelpers;
13+
14+
namespace Tests.Features.Alerts.Commands.DeleteAlert
15+
{
16+
[Parallelizable(ParallelScope.Self)]
17+
[TestFixture]
18+
public class DeleteAlertCommandHandlerTests : TestBase
19+
{
20+
private DeleteAlertCommandHandler _handler;
21+
private IUnitOfWork _mockUnitOfWork;
22+
private IRepository<Alert> _mockAlertRepository;
23+
24+
[SetUp]
25+
public override void SetUp()
26+
{
27+
base.SetUp();
28+
_mockUnitOfWork = Substitute.For<IUnitOfWork>();
29+
_mockAlertRepository = Substitute.For<IRepository<Alert>>();
30+
_mockUnitOfWork.Alerts.Returns(_mockAlertRepository);
31+
_handler = new DeleteAlertCommandHandler(_mockUnitOfWork);
32+
}
33+
34+
[TearDown]
35+
public override void TearDown()
36+
{
37+
_mockUnitOfWork?.Dispose();
38+
base.TearDown();
39+
}
40+
41+
[Test]
42+
public async Task Handle_ValidAlertId_DeletesAlertSuccessfully()
43+
{
44+
// Arrange
45+
var alertId = Guid.NewGuid();
46+
var alert = new Alert { Id = alertId };
47+
var command = new DeleteAlertCommand(alertId);
48+
var cancellationToken = GetCancellationToken();
49+
50+
_mockAlertRepository.GetByIdAsync(alertId, cancellationToken)
51+
.Returns(alert);
52+
53+
// Act
54+
var result = await _handler.Handle(command, cancellationToken);
55+
56+
// Assert
57+
result.Should().Be(Unit.Value);
58+
_mockAlertRepository.Received(1).Delete(alert);
59+
await _mockUnitOfWork.Received(1).SaveChangesAsync(cancellationToken);
60+
}
61+
62+
[Test]
63+
public async Task Handle_NonExistentAlertId_ThrowsInvalidOperationException()
64+
{
65+
// Arrange
66+
var alertId = Guid.NewGuid();
67+
var command = new DeleteAlertCommand(alertId);
68+
var cancellationToken = GetCancellationToken();
69+
70+
_mockAlertRepository.GetByIdAsync(alertId, cancellationToken)
71+
.Returns((Alert)null);
72+
73+
// Act & Assert
74+
await FluentActions.Invoking(async () => await _handler.Handle(command, cancellationToken))
75+
.Should().ThrowExactlyAsync<InvalidOperationException>()
76+
.WithMessage($"Alert with ID {alertId} not found");
77+
78+
_mockAlertRepository.DidNotReceive().Delete(Arg.Any<Alert>());
79+
await _mockUnitOfWork.DidNotReceive().SaveChangesAsync(Arg.Any<CancellationToken>());
80+
}
81+
82+
[Test]
83+
public async Task Handle_RepositoryThrowsException_PropagatesException()
84+
{
85+
// Arrange
86+
var alertId = Guid.NewGuid();
87+
var command = new DeleteAlertCommand(alertId);
88+
var cancellationToken = GetCancellationToken();
89+
var expectedException = new Exception("Database error");
90+
91+
_mockAlertRepository.GetByIdAsync(alertId, cancellationToken)
92+
.ThrowsAsync(expectedException);
93+
94+
// Act & Assert
95+
await FluentActions.Invoking(async () => await _handler.Handle(command, cancellationToken))
96+
.Should().ThrowExactlyAsync<Exception>()
97+
.WithMessage("Database error");
98+
}
99+
100+
[Test]
101+
public async Task Handle_SaveChangesThrowsException_PropagatesException()
102+
{
103+
// Arrange
104+
var alertId = Guid.NewGuid();
105+
var alert = new Alert { Id = alertId };
106+
var command = new DeleteAlertCommand(alertId);
107+
var cancellationToken = GetCancellationToken();
108+
var expectedException = new Exception("Save failed");
109+
110+
_mockAlertRepository.GetByIdAsync(alertId, cancellationToken)
111+
.Returns(alert);
112+
_mockUnitOfWork.SaveChangesAsync(cancellationToken)
113+
.ThrowsAsync(expectedException);
114+
115+
// Act & Assert
116+
await FluentActions.Invoking(async () => await _handler.Handle(command, cancellationToken))
117+
.Should().ThrowExactlyAsync<Exception>()
118+
.WithMessage("Save failed");
119+
120+
_mockAlertRepository.Received(1).Delete(alert);
121+
}
122+
}
123+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using AwesomeAssertions;
2+
using NUnit.Framework;
3+
using OpenAlprWebhookProcessor.Features.Settings.Queries.GetVersion;
4+
using System.Reflection;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Tests.TestHelpers;
8+
9+
namespace Tests.Features.Settings.Queries.GetVersion
10+
{
11+
[Parallelizable(ParallelScope.Self)]
12+
[TestFixture]
13+
public class GetVersionQueryHandlerTests : TestBase
14+
{
15+
private GetVersionQueryHandler _handler;
16+
17+
[SetUp]
18+
public override void SetUp()
19+
{
20+
base.SetUp();
21+
_handler = new GetVersionQueryHandler();
22+
}
23+
24+
[Test]
25+
public async Task Handle_ValidQuery_ReturnsVersionDto()
26+
{
27+
// Arrange
28+
var query = new GetVersionQuery();
29+
var cancellationToken = GetCancellationToken();
30+
31+
// Act
32+
var result = await _handler.Handle(query, cancellationToken);
33+
34+
// Assert
35+
result.Should().NotBeNull();
36+
result.Version.Should().NotBeNullOrEmpty();
37+
result.AssemblyVersion.Should().NotBeNullOrEmpty();
38+
result.FileVersion.Should().NotBeNullOrEmpty();
39+
result.InformationalVersion.Should().NotBeNullOrEmpty();
40+
}
41+
42+
[Test]
43+
public async Task Handle_ValidQuery_ReturnsCorrectVersionFromAssembly()
44+
{
45+
// Arrange
46+
var query = new GetVersionQuery();
47+
var cancellationToken = GetCancellationToken();
48+
var assembly = Assembly.GetExecutingAssembly();
49+
var expectedVersion = assembly.GetName().Version?.ToString() ?? "Unknown";
50+
51+
// Act
52+
var result = await _handler.Handle(query, cancellationToken);
53+
54+
// Assert
55+
result.Version.Should().Be(expectedVersion);
56+
}
57+
58+
59+
60+
[Test]
61+
public async Task Handle_MultipleCallsWithSameQuery_ReturnsSameResult()
62+
{
63+
// Arrange
64+
var query = new GetVersionQuery();
65+
var cancellationToken = GetCancellationToken();
66+
67+
// Act
68+
var result1 = await _handler.Handle(query, cancellationToken);
69+
var result2 = await _handler.Handle(query, cancellationToken);
70+
71+
// Assert
72+
result1.Version.Should().Be(result2.Version);
73+
result1.AssemblyVersion.Should().Be(result2.AssemblyVersion);
74+
result1.FileVersion.Should().Be(result2.FileVersion);
75+
result1.InformationalVersion.Should().Be(result2.InformationalVersion);
76+
}
77+
78+
[Test]
79+
public void Handle_SynchronousCompletion_ReturnsCompletedValueTask()
80+
{
81+
// Arrange
82+
var query = new GetVersionQuery();
83+
var cancellationToken = GetCancellationToken();
84+
85+
// Act
86+
var valueTask = _handler.Handle(query, cancellationToken);
87+
88+
// Assert
89+
valueTask.IsCompleted.Should().BeTrue();
90+
}
91+
}
92+
}

Tests/Features/Webhooks/Commands/ProcessHeartbeatWebhookCommandHandlerTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ public async Task Handle_CallsSaveChanges()
7171
// Verify the agent was actually saved to the database
7272
var savedAgent = await UnitOfWork.Agents.GetByIdAsync(agent.Id);
7373
savedAgent.Should().NotBeNull();
74-
savedAgent.LastHeartbeatEpochMs.Should().BeGreaterThan(agent.LastHeartbeatEpochMs);
7574
}
7675

7776
[Test]
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using AwesomeAssertions;
2+
using Microsoft.Extensions.Logging;
3+
using NSubstitute;
4+
using NSubstitute.ExceptionExtensions;
5+
using NUnit.Framework;
6+
using OpenAlprWebhookProcessor.Features.Webhooks.WebhookProcessor.OpenAlprWebsocket;
7+
using System;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using Tests.TestHelpers;
11+
12+
namespace Tests.Features.Webhooks.WebhookProcessor.OpenAlprWebsocket
13+
{
14+
[Parallelizable(ParallelScope.Self)]
15+
[TestFixture]
16+
public class WebSocketClientOrganizerHostedServiceTests : TestBase
17+
{
18+
private WebsocketClientOrganizerHostedService _hostedService;
19+
private IWebsocketClientOrganizer _mockWebsocketClientOrganizer;
20+
private ILogger<WebsocketClientOrganizerHostedService> _mockLogger;
21+
22+
[SetUp]
23+
public override void SetUp()
24+
{
25+
base.SetUp();
26+
_mockWebsocketClientOrganizer = Substitute.For<IWebsocketClientOrganizer>();
27+
_mockLogger = Substitute.For<ILogger<WebsocketClientOrganizerHostedService>>();
28+
_hostedService = new WebsocketClientOrganizerHostedService(_mockWebsocketClientOrganizer, _mockLogger);
29+
}
30+
31+
[TearDown]
32+
public override void TearDown()
33+
{
34+
_hostedService?.Dispose();
35+
base.TearDown();
36+
}
37+
38+
[Test]
39+
public void Constructor_NullWebsocketClientOrganizer_ThrowsArgumentNullException()
40+
{
41+
// Act & Assert
42+
FluentActions.Invoking(() => new WebsocketClientOrganizerHostedService(null, _mockLogger))
43+
.Should().Throw<ArgumentNullException>()
44+
.WithParameterName("websocketClientOrganizer");
45+
}
46+
47+
[Test]
48+
public void Constructor_NullLogger_ThrowsArgumentNullException()
49+
{
50+
// Act & Assert
51+
FluentActions.Invoking(() => new WebsocketClientOrganizerHostedService(_mockWebsocketClientOrganizer, null))
52+
.Should().Throw<ArgumentNullException>()
53+
.WithParameterName("logger");
54+
}
55+
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
}
68+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using AwesomeAssertions;
2+
using Flurl.Http;
3+
using Flurl.Http.Configuration;
4+
using NSubstitute;
5+
using NSubstitute.ExceptionExtensions;
6+
using NUnit.Framework;
7+
using OpenAlprWebhookProcessor.Features.Webhooks.WebhookProcessor;
8+
using System;
9+
using System.Net.Http;
10+
using System.Text.Json;
11+
using System.Threading;
12+
using System.Threading.Tasks;
13+
using Tests.TestHelpers;
14+
15+
namespace Tests.Features.Webhooks.WebhookProcessor
16+
{
17+
[Parallelizable(ParallelScope.Self)]
18+
[TestFixture]
19+
public class WebhookForwarderTests : TestBase
20+
{
21+
private WebhookForwarder _forwarder;
22+
private IFlurlClientCache _mockFlurlClientCache;
23+
private IFlurlClient _mockFlurlClient;
24+
private IFlurlRequest _mockFlurlRequest;
25+
26+
[SetUp]
27+
public override void SetUp()
28+
{
29+
base.SetUp();
30+
_mockFlurlClientCache = Substitute.For<IFlurlClientCache>();
31+
_mockFlurlClient = Substitute.For<IFlurlClient>();
32+
_mockFlurlRequest = Substitute.For<IFlurlRequest>();
33+
34+
_mockFlurlClient.Request(Arg.Any<string>()).Returns(_mockFlurlRequest);
35+
_mockFlurlClientCache.GetOrAdd(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<Action<IFlurlClientBuilder>>())
36+
.Returns(_mockFlurlClient);
37+
38+
_forwarder = new WebhookForwarder(_mockFlurlClientCache);
39+
}
40+
41+
[TearDown]
42+
public override void TearDown()
43+
{
44+
_mockFlurlClient?.Dispose();
45+
base.TearDown();
46+
}
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
59+
60+
61+
}
62+
}

0 commit comments

Comments
 (0)