Tau.Acuvim/console/tests/Tau.Acuvim.Console.Tests/AlertServiceTests.cs
Renier Forster 84a0668c54 Initial commit: Tau Acuvim IoT monitoring system
Complete IoT monitoring platform for Acuvim II power meters via ESP32.

Firmware (Phases 1-7):
- ESP32-WROVER-B (TTGO T-Call v1.4) with RS485 Modbus RTU
- WiFi STA+AP concurrent mode with GSM/GPRS failover
- Transport abstraction layer with 4 priority modes
- MQTT protocol with 20 commands, LWT, QoS, exponential backoff
- SD card offline buffering with JSONL rotation and non-blocking drain
- OTA firmware updates with dual partition rollback protection
- Watchdog timer, crash loop detection, Acuvim health monitoring
- Captive portal provisioning with AP mode

Console backend (Phase 8):
- .NET 10 minimal API with PostgreSQL + EF Core
- JWT authentication, SignalR real-time updates
- MQTTnet 5.x bridge service with health monitoring
- Device, telemetry, firmware, alert, group management
- Rate limiting, security headers, Swagger/OpenAPI

Frontend (Phase 9):
- React 18 + TypeScript + Vite with Ant Design 5
- ECharts telemetry visualization, TanStack Query
- SignalR live updates, device management UI
- Dashboard, fleet management, firmware deployment

Testing & Production (Phase 10):
- 28 firmware unit tests (Modbus, JSON, config, version)
- 23 xUnit backend tests (device, telemetry, command, alert)
- Docker Compose with nginx, TLS MQTT, PostgreSQL
- Production deployment, commissioning, and troubleshooting docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-16 19:05:32 +02:00

120 lines
4.0 KiB
C#

using System.Text.Json;
using Tau.Acuvim.Console.Models;
using Tau.Acuvim.Console.Services;
namespace Tau.Acuvim.Console.Tests;
public class AlertServiceTests
{
private AlertService CreateService(Data.AppDbContext db)
=> new(db, TestHelpers.CreateLogger<AlertService>());
[Fact]
public async Task ProcessAlertAsync_CreatesAlert()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
var payload = JsonSerializer.Serialize(new
{
alert = "overvoltage",
severity = "critical",
message = "Voltage exceeded 250V",
value = 255.3,
threshold = 250.0
});
await svc.ProcessAlertAsync("DEV-A1", payload);
Assert.Single(db.Alerts);
var alert = db.Alerts.First();
Assert.Equal("DEV-A1", alert.DeviceId);
Assert.Equal("overvoltage", alert.AlertType);
Assert.Equal("critical", alert.Severity);
Assert.Equal("Voltage exceeded 250V", alert.Message);
Assert.Equal(255.3, alert.Value);
Assert.Equal(250.0, alert.Threshold);
Assert.False(alert.Acknowledged);
}
[Fact]
public async Task GetAllAsync_FiltersBySeverity()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
db.Alerts.AddRange(
new Alert { DeviceId = "D1", AlertType = "temp", Severity = "critical", Message = "hot" },
new Alert { DeviceId = "D1", AlertType = "voltage", Severity = "warning", Message = "low" },
new Alert { DeviceId = "D2", AlertType = "temp", Severity = "critical", Message = "hot2" }
);
await db.SaveChangesAsync();
var result = await svc.GetAllAsync(
deviceId: null, severity: "critical", acknowledged: null, page: 1, pageSize: 10);
Assert.Equal(2, result.Count);
Assert.All(result, a => Assert.Equal("critical", a.Severity));
}
[Fact]
public async Task AcknowledgeAsync_MarksAlertAcknowledged()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
var alert = new Alert
{
DeviceId = "D1",
AlertType = "temp",
Severity = "warning",
Message = "test"
};
db.Alerts.Add(alert);
await db.SaveChangesAsync();
var result = await svc.AcknowledgeAsync(alert.Id, "operator1");
Assert.True(result);
var updated = db.Alerts.First(a => a.Id == alert.Id);
Assert.True(updated.Acknowledged);
Assert.Equal("operator1", updated.AcknowledgedBy);
Assert.NotNull(updated.AcknowledgedAt);
}
[Fact]
public async Task AcknowledgeAsync_ReturnsFalse_WhenNotFound()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
var result = await svc.AcknowledgeAsync(999, "operator1");
Assert.False(result);
}
[Fact]
public async Task GetActiveCountAsync_CountsUnacknowledged()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
db.Alerts.AddRange(
new Alert { DeviceId = "D1", AlertType = "a", Severity = "info", Message = "m1",
Acknowledged = false, ResolvedAt = null },
new Alert { DeviceId = "D1", AlertType = "b", Severity = "info", Message = "m2",
Acknowledged = true, AcknowledgedBy = "op" },
new Alert { DeviceId = "D2", AlertType = "c", Severity = "info", Message = "m3",
Acknowledged = false, ResolvedAt = DateTime.UtcNow },
new Alert { DeviceId = "D2", AlertType = "d", Severity = "info", Message = "m4",
Acknowledged = false, ResolvedAt = null }
);
await db.SaveChangesAsync();
var count = await svc.GetActiveCountAsync();
// Only alerts where Acknowledged == false AND ResolvedAt == null
Assert.Equal(2, count);
}
}