You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.9 KiB
C#
166 lines
5.9 KiB
C#
using Xunit;
|
|
using Moq;
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.Logging;
|
|
using Haoliang.Core.Services;
|
|
using Haoliang.Models.Device;
|
|
using Haoliang.Data.Repositories;
|
|
using DeviceStatus = Haoliang.Models.Device.DeviceCurrentStatus;
|
|
|
|
namespace Haoliang.Tests;
|
|
|
|
public class DeviceCollectionServiceTests
|
|
{
|
|
private readonly Mock<ILogger<DeviceCollectionService>> _mockLogger;
|
|
private readonly Mock<IPingService> _mockPingService;
|
|
private readonly Mock<IDataParserService> _mockDataParserService;
|
|
private readonly Mock<IDeviceRepository> _mockDeviceRepository;
|
|
private readonly DeviceCollectionService _deviceCollectionService;
|
|
|
|
public DeviceCollectionServiceTests()
|
|
{
|
|
_mockLogger = new Mock<ILogger<DeviceCollectionService>>();
|
|
_mockPingService = new Mock<IPingService>();
|
|
_mockDataParserService = new Mock<IDataParserService>();
|
|
_mockDeviceRepository = new Mock<IDeviceRepository>();
|
|
|
|
_deviceCollectionService = new DeviceCollectionService(
|
|
_mockLogger.Object,
|
|
_mockPingService.Object,
|
|
_mockDataParserService.Object,
|
|
_mockDeviceRepository.Object);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetAllDevicesAsync_ReturnsDevicesFromRepository()
|
|
{
|
|
var devices = new List<CNCDevice>
|
|
{
|
|
new CNCDevice { Id = 1, DeviceCode = "CNC001", DeviceName = "Device 1" },
|
|
new CNCDevice { Id = 2, DeviceCode = "CNC002", DeviceName = "Device 2" }
|
|
};
|
|
_mockDeviceRepository.Setup(r => r.GetAllAsync()).ReturnsAsync(devices);
|
|
|
|
var result = await _deviceCollectionService.GetAllDevicesAsync();
|
|
|
|
result.Should().HaveCount(2);
|
|
result.Should().BeEquivalentTo(devices);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDeviceByIdAsync_ReturnsDevice_WhenExists()
|
|
{
|
|
var device = new CNCDevice { Id = 1, DeviceCode = "CNC001", DeviceName = "Device 1" };
|
|
_mockDeviceRepository.Setup(r => r.GetByIdAsync(1)).ReturnsAsync(device);
|
|
|
|
var result = await _deviceCollectionService.GetDeviceByIdAsync(1);
|
|
|
|
result.Should().NotBeNull();
|
|
result!.Id.Should().Be(1);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDeviceByIdAsync_ReturnsNull_WhenNotExists()
|
|
{
|
|
_mockDeviceRepository.Setup(r => r.GetByIdAsync(999)).ReturnsAsync((CNCDevice?)null);
|
|
|
|
var result = await _deviceCollectionService.GetDeviceByIdAsync(999);
|
|
|
|
result.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateDeviceAsync_SetsCreatedAtAndUpdatedAt()
|
|
{
|
|
var device = new CNCDevice { DeviceCode = "CNC003", DeviceName = "New Device" };
|
|
_mockDeviceRepository.Setup(r => r.AddAsync(It.IsAny<CNCDevice>())).Returns(Task.CompletedTask);
|
|
_mockDeviceRepository.Setup(r => r.SaveAsync()).ReturnsAsync(1);
|
|
|
|
var beforeCreate = DateTime.UtcNow;
|
|
var result = await _deviceCollectionService.CreateDeviceAsync(device);
|
|
var afterCreate = DateTime.UtcNow;
|
|
|
|
result.CreatedAt.Should().BeOnOrAfter(beforeCreate);
|
|
result.CreatedAt.Should().BeOnOrBefore(afterCreate);
|
|
result.UpdatedAt.Should().BeOnOrAfter(beforeCreate);
|
|
result.UpdatedAt.Should().BeOnOrBefore(afterCreate);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateDeviceAsync_UpdatesDevice_WhenExists()
|
|
{
|
|
var device = new CNCDevice { Id = 1, DeviceCode = "CNC001", DeviceName = "Updated Device" };
|
|
_mockDeviceRepository.Setup(r => r.Update(It.IsAny<CNCDevice>())).Verifiable();
|
|
_mockDeviceRepository.Setup(r => r.SaveAsync()).ReturnsAsync(1);
|
|
|
|
var result = await _deviceCollectionService.UpdateDeviceAsync(device);
|
|
|
|
result.Should().NotBeNull();
|
|
result!.DeviceName.Should().Be("Updated Device");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateDeviceAsync_ReturnsNull_WhenNotExists()
|
|
{
|
|
var device = new CNCDevice { Id = 999 };
|
|
_mockDeviceRepository.Setup(r => r.SaveAsync()).ReturnsAsync(0);
|
|
|
|
var result = await _deviceCollectionService.UpdateDeviceAsync(device);
|
|
|
|
result.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteDeviceAsync_ReturnsTrue_WhenDeviceExists()
|
|
{
|
|
var device = new CNCDevice { Id = 1 };
|
|
_mockDeviceRepository.Setup(r => r.GetByIdAsync(1)).ReturnsAsync(device);
|
|
_mockDeviceRepository.Setup(r => r.Remove(device)).Verifiable();
|
|
_mockDeviceRepository.Setup(r => r.SaveAsync()).ReturnsAsync(1);
|
|
|
|
var result = await _deviceCollectionService.DeleteDeviceAsync(1);
|
|
|
|
result.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteDeviceAsync_ReturnsFalse_WhenDeviceNotExists()
|
|
{
|
|
_mockDeviceRepository.Setup(r => r.GetByIdAsync(999)).ReturnsAsync((CNCDevice?)null);
|
|
|
|
var result = await _deviceCollectionService.DeleteDeviceAsync(999);
|
|
|
|
result.Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectDeviceAsync_Skips_WhenDeviceNotExists()
|
|
{
|
|
_mockDeviceRepository.Setup(r => r.GetByIdAsync(999)).ReturnsAsync((CNCDevice?)null);
|
|
|
|
await _deviceCollectionService.CollectDeviceAsync(999);
|
|
|
|
_mockPingService.Verify(p => p.PingAsync(It.IsAny<int>(), It.IsAny<string>()), Times.Never);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectDeviceAsync_Skips_WhenDeviceNotAvailable()
|
|
{
|
|
var device = new CNCDevice { Id = 1, IsAvailable = false };
|
|
_mockDeviceRepository.Setup(r => r.GetByIdAsync(1)).ReturnsAsync(device);
|
|
|
|
await _deviceCollectionService.CollectDeviceAsync(1);
|
|
|
|
_mockPingService.Verify(p => p.PingAsync(It.IsAny<int>(), It.IsAny<string>()), Times.Never);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDeviceStatusAsync_ReturnsDeviceStatus()
|
|
{
|
|
var result = await _deviceCollectionService.GetDeviceStatusAsync(1);
|
|
|
|
result.Should().NotBeNull();
|
|
result.DeviceId.Should().Be(1);
|
|
result.Timestamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
|
}
|
|
} |