diff --git a/backend/api.test/Database/DatabaseUtilities.cs b/backend/api.test/Database/DatabaseUtilities.cs index 0df4cbc1..a410d4f6 100644 --- a/backend/api.test/Database/DatabaseUtilities.cs +++ b/backend/api.test/Database/DatabaseUtilities.cs @@ -103,13 +103,13 @@ public async Task NewPlant(string installationCode) return await _plantService.Create(createPlantQuery); } - public async Task NewDeck(string installationCode, string plantCode) + public async Task NewDeck(string installationCode, string plantCode, string deckName = "testDeck") { var createDeckQuery = new CreateDeckQuery { InstallationCode = installationCode, PlantCode = plantCode, - Name = "testDeck", + Name = deckName, DefaultLocalizationPose = new Pose() }; diff --git a/backend/api.test/EventHandlers/TestMissionEventHandler.cs b/backend/api.test/EventHandlers/TestMissionEventHandler.cs index 1f6618c4..4d496ee7 100644 --- a/backend/api.test/EventHandlers/TestMissionEventHandler.cs +++ b/backend/api.test/EventHandlers/TestMissionEventHandler.cs @@ -35,6 +35,7 @@ public class TestMissionEventHandler : IDisposable private readonly RobotService _robotService; private readonly LocalizationService _localizationService; private readonly EmergencyActionService _emergencyActionService; + private readonly MissionSchedulingService _missionSchedulingService; public TestMissionEventHandler(DatabaseFixture fixture) { @@ -79,7 +80,7 @@ public TestMissionEventHandler(DatabaseFixture fixture) _localizationService = new LocalizationService(localizationServiceLogger, _robotService, _missionRunService, installationService, areaService, mapServiceMock); var returnToHomeService = new ReturnToHomeService(returnToHomeServiceLogger, _robotService, _missionRunService, mapServiceMock); - var missionSchedulingService = new MissionSchedulingService(missionSchedulingServiceLogger, _missionRunService, _robotService, areaService, + _missionSchedulingService = new MissionSchedulingService(missionSchedulingServiceLogger, _missionRunService, _robotService, areaService, isarServiceMock, _localizationService, returnToHomeService, signalRService); var lastMissionRunService = new LastMissionRunService(lastMissionRunServiceLogger, missionDefinitionService, _missionRunService); @@ -97,7 +98,7 @@ public TestMissionEventHandler(DatabaseFixture fixture) .Returns(_robotService); mockServiceProvider .Setup(p => p.GetService(typeof(IMissionSchedulingService))) - .Returns(missionSchedulingService); + .Returns(_missionSchedulingService); mockServiceProvider .Setup(p => p.GetService(typeof(FlotillaDbContext))) .Returns(context); @@ -265,7 +266,7 @@ public async void ReturnToHomeMissionIsStartedIfQueueIsEmptyWhenRobotBecomesAvai OrderBy = "DesiredStartTime", PageSize = 100 }); - Assert.False(ongoingMission.Any()); + Assert.True(ongoingMission.Any()); } [Fact] @@ -371,7 +372,7 @@ public async void ReturnHomeMissionNotScheduledIfRobotIsNotLocalized() // Act var eventArgs = new RobotAvailableEventArgs(robot.Id); - _missionEventHandler.RaiseEvent(nameof(MissionSchedulingService.RobotAvailable), eventArgs); + _missionSchedulingService.RaiseEvent(nameof(MissionSchedulingService.RobotAvailable), eventArgs); Thread.Sleep(100); @@ -381,5 +382,58 @@ public async void ReturnHomeMissionNotScheduledIfRobotIsNotLocalized() Assert.False(await _missionRunService.PendingOrOngoingReturnToHomeMissionRunExists(robot.Id)); } + + [Fact] + public async void ReturnHomeMissionCancelledIfNewMissionScheduled() + { + // Arrange + var installation = await _databaseUtilities.NewInstallation(); + var plant = await _databaseUtilities.NewPlant(installation.InstallationCode); + var deck = await _databaseUtilities.NewDeck(installation.InstallationCode, plant.PlantCode); + var area = await _databaseUtilities.NewArea(installation.InstallationCode, plant.PlantCode, deck.Name); + var robot = await _databaseUtilities.NewRobot(RobotStatus.Busy, installation, area); + var returnToHomeMission = await _databaseUtilities.NewMissionRun(installation.InstallationCode, robot, area, true, MissionRunType.ReturnHome, MissionStatus.Ongoing, Guid.NewGuid().ToString()); + var missionRun = await _databaseUtilities.NewMissionRun(installation.InstallationCode, robot, area, true, MissionRunType.Normal, MissionStatus.Pending, Guid.NewGuid().ToString()); + + Thread.Sleep(100); + + // Act + var eventArgs = new MissionRunCreatedEventArgs(missionRun.Id); + _missionRunService.RaiseEvent(nameof(MissionRunService.MissionRunCreated), eventArgs); + + Thread.Sleep(500); + + // Assert + var updatedReturnHomeMission = await _missionRunService.ReadById(returnToHomeMission.Id); + Assert.True(updatedReturnHomeMission?.Status.Equals(MissionStatus.Cancelled)); + Assert.True(updatedReturnHomeMission?.Tasks.FirstOrDefault()?.Status.Equals(TaskStatus.Cancelled)); + } + + [Fact] + public async void ReturnHomeMissionNotCancelledIfNewMissionScheduledInDifferentDeck() + { + // Arrange + var installation = await _databaseUtilities.NewInstallation(); + var plant = await _databaseUtilities.NewPlant(installation.InstallationCode); + var deck1 = await _databaseUtilities.NewDeck(installation.InstallationCode, plant.PlantCode); + var area1 = await _databaseUtilities.NewArea(installation.InstallationCode, plant.PlantCode, deck1.Name); + var robot = await _databaseUtilities.NewRobot(RobotStatus.Busy, installation, area1); + var deck2 = await _databaseUtilities.NewDeck(installation.InstallationCode, plant.PlantCode, "testDeck2"); + var area2 = await _databaseUtilities.NewArea(installation.InstallationCode, plant.PlantCode, deck2.Name); + var returnToHomeMission = await _databaseUtilities.NewMissionRun(installation.InstallationCode, robot, area1, true, MissionRunType.ReturnHome, MissionStatus.Ongoing, Guid.NewGuid().ToString()); + var missionRun = await _databaseUtilities.NewMissionRun(installation.InstallationCode, robot, area2, true, MissionRunType.Normal, MissionStatus.Pending, Guid.NewGuid().ToString()); + + Thread.Sleep(100); + + // Act + var eventArgs = new MissionRunCreatedEventArgs(missionRun.Id); + _missionRunService.RaiseEvent(nameof(MissionRunService.MissionRunCreated), eventArgs); + + Thread.Sleep(500); + + // Assert + var updatedReturnHomeMission = await _missionRunService.ReadById(returnToHomeMission.Id); + Assert.True(updatedReturnHomeMission?.Status.Equals(MissionStatus.Ongoing)); + } } } diff --git a/backend/api/EventHandlers/MqttEventHandler.cs b/backend/api/EventHandlers/MqttEventHandler.cs index 3be7d54a..bfbcad14 100644 --- a/backend/api/EventHandlers/MqttEventHandler.cs +++ b/backend/api/EventHandlers/MqttEventHandler.cs @@ -85,7 +85,8 @@ private async void OnIsarRobotStatus(object? sender, MqttReceivedArgs mqttArgs) return; } - await robotService.UpdateRobotStatus(robot.Id, isarRobotStatus.RobotStatus); + robot.Status = isarRobotStatus.RobotStatus; + await robotService.Update(robot); _logger.LogInformation("Updated status for robot {Name} to {Status}", robot.Name, isarRobotStatus.RobotStatus); if (isarRobotStatus.RobotStatus == RobotStatus.Available) missionSchedulingService.TriggerRobotAvailable(new RobotAvailableEventArgs(robot.Id));