using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using RobotNet10.FleetManager.Data; using RobotNet10.FleetManager.Services; using RobotNet10.FleetManager.Shared.DTOs.Robot; using RobotNet10.RobotManager.Test.Helpers; namespace RobotNet10.RobotManager.Test.Services; /// /// Unit tests for RobotService /// [TestFixture] public class RobotServiceTests { private ApplicationDbContext _context = null!; private RobotService _service = null!; [SetUp] public void Setup() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) .Options; _context = new ApplicationDbContext(options); var logger = new LoggerFactory().CreateLogger(); var _logger = new FleetManager.Services.Logger(logger); _service = new RobotService(_context, _logger); } [TearDown] public void TearDown() { _context.Dispose(); } [Test] public async Task CreateAsync_ValidData_ReturnsCreatedRobot() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); await _context.SaveChangesAsync(); var request = new CreateRobotRequest { RobotId = "ROBOT-001", Name = "Test Robot", ModelId = model.Id, MapId = null }; // Act var result = await _service.CreateAsync(request); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.RobotId, Is.EqualTo(request.RobotId)); Assert.That(result.Name, Is.EqualTo(request.Name)); Assert.That(result.ModelId, Is.EqualTo(request.ModelId)); Assert.That(result.Id, Is.Not.EqualTo(Guid.Empty)); } [Test] public async Task CreateAsync_DuplicateRobotId_ThrowsInvalidOperationException() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); var existingRobot = TestHelpers.CreateTestRobot(robotId: "ROBOT-001", modelId: model.Id); _context.Robots.Add(existingRobot); await _context.SaveChangesAsync(); var request = new CreateRobotRequest { RobotId = "ROBOT-001", Name = "Another Robot", ModelId = model.Id }; // Act & Assert var ex = Assert.ThrowsAsync(async () => await _service.CreateAsync(request)); Assert.That(ex!.Message, Does.Contain("already exists")); } [Test] public async Task CreateAsync_NonExistentModelId_ThrowsKeyNotFoundException() { // Arrange var request = new CreateRobotRequest { RobotId = "ROBOT-001", Name = "Test Robot", ModelId = Guid.NewGuid() // Non-existent model }; // Act & Assert Assert.ThrowsAsync(async () => await _service.CreateAsync(request)); } [Test] public async Task GetAllAsync_ReturnsAllRobots() { // Arrange TestHelpers.SeedTestData(_context); // Act var result = await _service.GetAllAsync(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(3)); } [Test] public async Task GetAllAsync_WithModelIdFilter_ReturnsFilteredRobots() { // Arrange TestHelpers.SeedTestData(_context); var modelId = Guid.Parse("11111111-1111-1111-1111-111111111111"); // Act var result = await _service.GetAllAsync(modelId, null); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(2)); // 2 robots use model1 Assert.That(result.All(r => r.ModelId == modelId), Is.True); } [Test] public async Task GetByIdAsync_ExistingId_ReturnsRobot() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); var robot = TestHelpers.CreateTestRobot(modelId: model.Id); _context.Robots.Add(robot); await _context.SaveChangesAsync(); // Act var result = await _service.GetByIdAsync(robot.Id); // Assert Assert.That(result, Is.Not.Null); Assert.That(result!.Id, Is.EqualTo(robot.Id)); Assert.That(result.RobotId, Is.EqualTo(robot.RobotId)); } [Test] public async Task GetByIdAsync_NonExistentId_ReturnsNull() { // Arrange var nonExistentId = Guid.NewGuid(); // Act var result = await _service.GetByIdAsync(nonExistentId); // Assert Assert.That(result, Is.Null); } [Test] public async Task GetByRobotIdAsync_ExistingRobotId_ReturnsRobot() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); var robot = TestHelpers.CreateTestRobot(robotId: "ROBOT-001", modelId: model.Id); _context.Robots.Add(robot); await _context.SaveChangesAsync(); // Act var result = await _service.GetByRobotIdAsync("ROBOT-001"); // Assert Assert.That(result, Is.Not.Null); Assert.That(result!.RobotId, Is.EqualTo("ROBOT-001")); } [Test] public async Task GetByRobotIdAsync_NonExistentRobotId_ReturnsNull() { // Arrange // No robots in database // Act var result = await _service.GetByRobotIdAsync("NON-EXISTENT"); // Assert Assert.That(result, Is.Null); } [Test] public async Task UpdateAsync_ValidData_UpdatesRobot() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); var robot = TestHelpers.CreateTestRobot(modelId: model.Id); _context.Robots.Add(robot); await _context.SaveChangesAsync(); var request = new UpdateRobotRequest { RobotId = "UPDATED-001", Name = "Updated Robot", ModelId = model.Id, MapId = null }; // Act var result = await _service.UpdateAsync(robot.Id, request); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.RobotId, Is.EqualTo(request.RobotId)); Assert.That(result.Name, Is.EqualTo(request.Name)); } [Test] public async Task UpdateAsync_NonExistentId_ThrowsKeyNotFoundException() { // Arrange var nonExistentId = Guid.NewGuid(); var request = new UpdateRobotRequest { RobotId = "ROBOT-001", Name = "Test", ModelId = Guid.NewGuid() }; // Act & Assert Assert.ThrowsAsync(async () => await _service.UpdateAsync(nonExistentId, request)); } [Test] public async Task DeleteAsync_ExistingId_ReturnsTrue() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); var robot = TestHelpers.CreateTestRobot(modelId: model.Id); _context.Robots.Add(robot); await _context.SaveChangesAsync(); // Act var result = await _service.DeleteAsync(robot.Id); // Assert Assert.That(result, Is.True); var deleted = await _context.Robots.FindAsync(robot.Id); Assert.That(deleted, Is.Null); } [Test] public async Task DeleteAsync_NonExistentId_ReturnsFalse() { // Arrange var nonExistentId = Guid.NewGuid(); // Act var result = await _service.DeleteAsync(nonExistentId); // Assert Assert.That(result, Is.False); } [Test] public async Task GetByModelIdAsync_ReturnsRobotsForModel() { // Arrange TestHelpers.SeedTestData(_context); var modelId = Guid.Parse("11111111-1111-1111-1111-111111111111"); // Act var result = await _service.GetByModelIdAsync(modelId); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(2)); Assert.That(result.All(r => r.ModelId == modelId), Is.True); } [Test] public async Task SearchAsync_WithQuery_ReturnsMatchingRobots() { // Arrange TestHelpers.SeedTestData(_context); // Act var result = await _service.SearchAsync("ROBOT-001"); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(1)); Assert.That(result[0].RobotId, Is.EqualTo("ROBOT-001")); } [Test] public async Task SearchAsync_EmptyQuery_ReturnsAllRobots() { // Arrange TestHelpers.SeedTestData(_context); // Act var result = await _service.SearchAsync(""); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(3)); } [Test] public async Task ExistsAsync_ExistingRobotId_ReturnsTrue() { // Arrange var model = TestHelpers.CreateTestRobotModel(); _context.RobotModels.Add(model); var robot = TestHelpers.CreateTestRobot(robotId: "ROBOT-001", modelId: model.Id); _context.Robots.Add(robot); await _context.SaveChangesAsync(); // Act var result = await _service.ExistsAsync("ROBOT-001"); // Assert Assert.That(result, Is.True); } [Test] public async Task ExistsAsync_NonExistentRobotId_ReturnsFalse() { // Arrange // No robots in database // Act var result = await _service.ExistsAsync("NON-EXISTENT"); // Assert Assert.That(result, Is.False); } }