Initial commit
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RobotNet10.FleetManager.Data;
|
||||
using RobotNet10.FleetManager.Services;
|
||||
using RobotNet10.FleetManager.Shared.DTOs.RobotModel;
|
||||
using RobotNet10.FleetManager.Shared.Enums;
|
||||
using RobotNet10.RobotManager.Test.Helpers;
|
||||
|
||||
namespace RobotNet10.RobotManager.Test.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for RobotModelService
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class RobotModelServiceTests
|
||||
{
|
||||
private ApplicationDbContext _context = null!;
|
||||
private RobotModelService _service = null!;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
||||
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
|
||||
.Options;
|
||||
|
||||
_context = new ApplicationDbContext(options);
|
||||
var logger = new LoggerFactory().CreateLogger<RobotModelService>();
|
||||
var _logger = new FleetManager.Services.Logger<RobotModelService>(logger);
|
||||
_service = new RobotModelService(_context, _logger);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateAsync_ValidData_ReturnsCreatedRobotModel()
|
||||
{
|
||||
// Arrange
|
||||
var request = new CreateRobotModelRequest
|
||||
{
|
||||
ModelName = "TestModel",
|
||||
Length = 1.2,
|
||||
Width = 0.8,
|
||||
ImageWidth = 800,
|
||||
ImageHeight = 600,
|
||||
NavigationPointX = 0.0,
|
||||
NavigationPointY = 0.0,
|
||||
NavigationType = NavigationType.Differential
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _service.CreateAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.ModelName, Is.EqualTo(request.ModelName));
|
||||
Assert.That(result.Length, Is.EqualTo(request.Length));
|
||||
Assert.That(result.Width, Is.EqualTo(request.Width));
|
||||
Assert.That(result.NavigationType, Is.EqualTo(request.NavigationType));
|
||||
Assert.That(result.Id, Is.Not.EqualTo(Guid.Empty));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateAsync_DuplicateModelName_ThrowsInvalidOperationException()
|
||||
{
|
||||
// Arrange
|
||||
var existingModel = TestHelpers.CreateTestRobotModel(modelName: "ExistingModel");
|
||||
_context.RobotModels.Add(existingModel);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var request = new CreateRobotModelRequest
|
||||
{
|
||||
ModelName = "ExistingModel",
|
||||
Length = 1.0,
|
||||
Width = 0.5,
|
||||
ImageWidth = 800,
|
||||
ImageHeight = 600,
|
||||
NavigationPointX = 0.0,
|
||||
NavigationPointY = 0.0,
|
||||
NavigationType = NavigationType.Differential
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsAsync<InvalidOperationException>(async () => await _service.CreateAsync(request));
|
||||
Assert.That(ex!.Message, Does.Contain("already exists"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetAllAsync_ReturnsAllRobotModels()
|
||||
{
|
||||
// Arrange
|
||||
TestHelpers.SeedTestData(_context);
|
||||
|
||||
// Act
|
||||
var result = await _service.GetAllAsync();
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.Count, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetByIdAsync_ExistingId_ReturnsRobotModel()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel();
|
||||
_context.RobotModels.Add(model);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Act
|
||||
var result = await _service.GetByIdAsync(model.Id);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result!.Id, Is.EqualTo(model.Id));
|
||||
Assert.That(result.ModelName, Is.EqualTo(model.ModelName));
|
||||
}
|
||||
|
||||
[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 UpdateAsync_ValidData_UpdatesRobotModel()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel();
|
||||
_context.RobotModels.Add(model);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var request = new UpdateRobotModelRequest
|
||||
{
|
||||
ModelName = "UpdatedModel",
|
||||
Length = 2.0,
|
||||
Width = 1.0,
|
||||
ImageWidth = 1000,
|
||||
ImageHeight = 800,
|
||||
NavigationPointX = 0.1,
|
||||
NavigationPointY = 0.2,
|
||||
NavigationType = NavigationType.OmniDrive
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _service.UpdateAsync(model.Id, request);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.ModelName, Is.EqualTo(request.ModelName));
|
||||
Assert.That(result.Length, Is.EqualTo(request.Length));
|
||||
Assert.That(result.NavigationType, Is.EqualTo(request.NavigationType));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdateAsync_NonExistentId_ThrowsKeyNotFoundException()
|
||||
{
|
||||
// Arrange
|
||||
var nonExistentId = Guid.NewGuid();
|
||||
var request = new UpdateRobotModelRequest
|
||||
{
|
||||
ModelName = "Test",
|
||||
Length = 1.0,
|
||||
Width = 0.5,
|
||||
ImageWidth = 800,
|
||||
ImageHeight = 600,
|
||||
NavigationPointX = 0.0,
|
||||
NavigationPointY = 0.0,
|
||||
NavigationType = NavigationType.Differential
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.ThrowsAsync<KeyNotFoundException>(async () => await _service.UpdateAsync(nonExistentId, request));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DeleteAsync_ExistingId_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel();
|
||||
_context.RobotModels.Add(model);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Act
|
||||
var result = await _service.DeleteAsync(model.Id);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.True);
|
||||
var deleted = await _context.RobotModels.FindAsync(model.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 DeleteAsync_ModelWithRobots_ThrowsInvalidOperationException()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel();
|
||||
_context.RobotModels.Add(model);
|
||||
|
||||
var robot = TestHelpers.CreateTestRobot(modelId: model.Id);
|
||||
_context.Robots.Add(robot);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsAsync<InvalidOperationException>(async () => await _service.DeleteAsync(model.Id));
|
||||
Assert.That(ex, Is.Not.Null);
|
||||
Assert.That(ex!.Message, Does.Contain("Cannot delete").Or.Contain("cannot be deleted").Or.Contain("being used"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SearchAsync_WithQuery_ReturnsMatchingModels()
|
||||
{
|
||||
// Arrange
|
||||
TestHelpers.SeedTestData(_context);
|
||||
|
||||
// Act
|
||||
var result = await _service.SearchAsync("AMR-T800");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.Count, Is.EqualTo(1));
|
||||
Assert.That(result[0].ModelName, Is.EqualTo("AMR-T800"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SearchAsync_EmptyQuery_ReturnsAllModels()
|
||||
{
|
||||
// Arrange
|
||||
TestHelpers.SeedTestData(_context);
|
||||
|
||||
// Act
|
||||
var result = await _service.SearchAsync("");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.Count, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistsAsync_ExistingModelName_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel(modelName: "ExistingModel");
|
||||
_context.RobotModels.Add(model);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Act
|
||||
var result = await _service.ExistsAsync("ExistingModel");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistsAsync_NonExistentModelName_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
// No models in database
|
||||
|
||||
// Act
|
||||
var result = await _service.ExistsAsync("NonExistentModel");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUsageInfoAsync_ModelWithRobots_ReturnsUsageInfo()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel();
|
||||
_context.RobotModels.Add(model);
|
||||
|
||||
var robot1 = TestHelpers.CreateTestRobot(modelId: model.Id);
|
||||
var robot2 = TestHelpers.CreateTestRobot(robotId: "ROBOT-002", modelId: model.Id);
|
||||
_context.Robots.AddRange(robot1, robot2);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Act
|
||||
var result = await _service.GetUsageInfoAsync(model.Id);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.RobotCount, Is.EqualTo(2));
|
||||
Assert.That(result.CanDelete, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUsageInfoAsync_ModelWithoutRobots_ReturnsZeroCount()
|
||||
{
|
||||
// Arrange
|
||||
var model = TestHelpers.CreateTestRobotModel();
|
||||
_context.RobotModels.Add(model);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Act
|
||||
var result = await _service.GetUsageInfoAsync(model.Id);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result.RobotCount, Is.EqualTo(0));
|
||||
Assert.That(result.CanDelete, Is.True);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user