Tau.Acuvim/console/tests/Tau.Acuvim.Console.Tests/TelemetryServiceTests.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

123 lines
3.8 KiB
C#

using System.Text.Json;
using Tau.Acuvim.Console.Models;
using Tau.Acuvim.Console.Services;
namespace Tau.Acuvim.Console.Tests;
public class TelemetryServiceTests
{
private TelemetryService CreateService(Data.AppDbContext db)
=> new(db, TestHelpers.CreateLogger<TelemetryService>());
[Fact]
public async Task IngestAsync_CreatesTelemetryRecord()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
db.Devices.Add(new Device { Id = Guid.NewGuid(), DeviceId = "DEV-T1" });
await db.SaveChangesAsync();
var payload = JsonSerializer.Serialize(new { ts = 1700000000L, conn = "wifi", voltage = 3.3 });
await svc.IngestAsync("DEV-T1", payload);
Assert.Single(db.TelemetryRecords);
var record = db.TelemetryRecords.First();
Assert.Equal("DEV-T1", record.DeviceId);
Assert.Equal("live", record.Source);
Assert.Equal("wifi", record.Connection);
}
[Fact]
public async Task IngestAsync_UpdatesDeviceLastTelemetry()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
var device = new Device { Id = Guid.NewGuid(), DeviceId = "DEV-T2", LastTelemetry = null };
db.Devices.Add(device);
await db.SaveChangesAsync();
var payload = JsonSerializer.Serialize(new { ts = 1700000000L });
await svc.IngestAsync("DEV-T2", payload);
var updated = db.Devices.First(d => d.DeviceId == "DEV-T2");
Assert.NotNull(updated.LastTelemetry);
}
[Fact]
public async Task IngestAsync_ThrowsOnInvalidJson()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
await Assert.ThrowsAnyAsync<JsonException>(() => svc.IngestAsync("DEV-X", "not-json!!!"));
}
[Fact]
public async Task GetLatestAsync_ReturnsLatestRecord()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
db.TelemetryRecords.AddRange(
new TelemetryRecord
{
DeviceId = "DEV-T3",
Timestamp = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
Data = JsonDocument.Parse("{\"v\":1}"),
ReceivedAt = DateTime.UtcNow
},
new TelemetryRecord
{
DeviceId = "DEV-T3",
Timestamp = new DateTime(2025, 6, 1, 0, 0, 0, DateTimeKind.Utc),
Data = JsonDocument.Parse("{\"v\":2}"),
ReceivedAt = DateTime.UtcNow
}
);
await db.SaveChangesAsync();
var latest = await svc.GetLatestAsync("DEV-T3");
Assert.NotNull(latest);
Assert.Equal(new DateTime(2025, 6, 1, 0, 0, 0, DateTimeKind.Utc), latest.Timestamp);
}
[Fact]
public async Task GetCountTodayAsync_CountsRecordsFromToday()
{
using var db = TestHelpers.CreateDbContext();
var svc = CreateService(db);
db.TelemetryRecords.AddRange(
new TelemetryRecord
{
DeviceId = "DEV-T4",
Timestamp = DateTime.UtcNow,
Data = JsonDocument.Parse("{}"),
ReceivedAt = DateTime.UtcNow
},
new TelemetryRecord
{
DeviceId = "DEV-T4",
Timestamp = DateTime.UtcNow,
Data = JsonDocument.Parse("{}"),
ReceivedAt = DateTime.UtcNow
},
new TelemetryRecord
{
DeviceId = "DEV-T4",
Timestamp = DateTime.UtcNow.AddDays(-2),
Data = JsonDocument.Parse("{}"),
ReceivedAt = DateTime.UtcNow.AddDays(-2)
}
);
await db.SaveChangesAsync();
var count = await svc.GetCountTodayAsync();
Assert.Equal(2, count);
}
}