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.
765 lines
28 KiB
C#
765 lines
28 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Xunit;
|
|
using Moq;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Haoliang.Api.Controllers;
|
|
using Haoliang.Core.Services;
|
|
using Haoliang.Models.Models.System;
|
|
using Haoliang.Models.Models.Production;
|
|
using Haoliang.Models.Common;
|
|
|
|
namespace Haoliang.Tests.Controllers
|
|
{
|
|
public class StatisticsControllerTests
|
|
{
|
|
private readonly Mock<IProductionStatisticsService> _mockStatisticsService;
|
|
private readonly StatisticsController _controller;
|
|
|
|
public StatisticsControllerTests()
|
|
{
|
|
_mockStatisticsService = new Mock<IProductionStatisticsService>();
|
|
_controller = new StatisticsController(_mockStatisticsService.Object);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetProductionTrendsAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var deviceId = 1;
|
|
var startDate = DateTime.Now.AddDays(-7);
|
|
var endDate = DateTime.Now;
|
|
|
|
var trendAnalysis = new ProductionTrendAnalysis
|
|
{
|
|
DeviceId = deviceId,
|
|
DeviceName = "Test Device",
|
|
PeriodStart = startDate,
|
|
PeriodEnd = endDate,
|
|
TotalProduction = 1000,
|
|
AverageDailyProduction = 142.86m,
|
|
TrendCoefficient = 0.5m,
|
|
TrendDirection = ProductionTrendDirection.Increasing,
|
|
DailyData = new List<DailyProduction>()
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.CalculateProductionTrendsAsync(deviceId, startDate, endDate))
|
|
.ReturnsAsync(trendAnalysis);
|
|
|
|
// Act
|
|
var result = await _controller.GetProductionTrends(deviceId, startDate, endDate);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<ProductionTrendAnalysis>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(trendAnalysis, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetProductionTrendsAsync_InvalidDevice_ReturnsNotFound()
|
|
{
|
|
// Arrange
|
|
var deviceId = 999;
|
|
var startDate = DateTime.Now.AddDays(-7);
|
|
var endDate = DateTime.Now;
|
|
|
|
_mockStatisticsService.Setup(service => service.CalculateProductionTrendsAsync(deviceId, startDate, endDate))
|
|
.ThrowsAsync(new KeyNotFoundException("Device not found"));
|
|
|
|
// Act
|
|
var result = await _controller.GetProductionTrends(deviceId, startDate, endDate);
|
|
|
|
// Assert
|
|
var notFoundResult = Assert.IsType<NotFoundObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<ProductionTrendAnalysis>>(notFoundResult.Value);
|
|
Assert.False(response.Success);
|
|
Assert.Contains("Device not found", response.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetProductionReportAsync_ValidFilter_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var filter = new ReportFilter
|
|
{
|
|
DeviceIds = new List<int> { 1 },
|
|
StartDate = DateTime.Now.AddDays(-7),
|
|
EndDate = DateTime.Now,
|
|
ReportType = ReportType.Daily
|
|
};
|
|
|
|
var productionReport = new ProductionReport
|
|
{
|
|
ReportDate = DateTime.Now,
|
|
ReportType = ReportType.Daily,
|
|
SummaryItems = new List<ProductionSummaryItem>(),
|
|
Metadata = ReportMetadata.GeneratedAt
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.GenerateProductionReportAsync(filter))
|
|
.ReturnsAsync(productionReport);
|
|
|
|
// Act
|
|
var result = await _controller.GetProductionReport(filter);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<ProductionReport>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(productionReport, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDashboardSummaryAsync_ValidFilter_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var filter = new DashboardFilter
|
|
{
|
|
DeviceIds = new List<int> { 1 },
|
|
Date = DateTime.Today,
|
|
IncludeAlerts = true
|
|
};
|
|
|
|
var dashboardSummary = new DashboardSummary
|
|
{
|
|
GeneratedAt = DateTime.Now,
|
|
TotalDevices = 10,
|
|
ActiveDevices = 8,
|
|
OfflineDevices = 2,
|
|
TotalProductionToday = 1000,
|
|
TotalProductionThisWeek = 7000,
|
|
TotalProductionThisMonth = 30000,
|
|
OverallEfficiency = 85.5m,
|
|
QualityRate = 98.2m,
|
|
DeviceSummaries = new List<DeviceSummary>(),
|
|
ActiveAlerts = new List<AlertSummary>()
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.GetDashboardSummaryAsync(filter))
|
|
.ReturnsAsync(dashboardSummary);
|
|
|
|
// Act
|
|
var result = await _controller.GetDashboardSummary(filter);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<DashboardSummary>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(dashboardSummary, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetEfficiencyMetricsAsync_ValidFilter_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var filter = new EfficiencyFilter
|
|
{
|
|
DeviceIds = new List<int> { 1 },
|
|
StartDate = DateTime.Now.AddDays(-7),
|
|
EndDate = DateTime.Now,
|
|
Metrics = EfficiencyMetric.Oee
|
|
};
|
|
|
|
var efficiencyMetrics = new EfficiencyMetrics
|
|
{
|
|
DeviceId = 1,
|
|
DeviceName = "Test Device",
|
|
PeriodStart = DateTime.Now.AddDays(-7),
|
|
PeriodEnd = DateTime.Now,
|
|
Availability = 95m,
|
|
Performance = 90m,
|
|
Quality = 98m,
|
|
Oee = 83.79m,
|
|
Utilization = EquipmentUtilization.Optimal,
|
|
HourlyData = new List<HourlyEfficiency>()
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.CalculateEfficiencyMetricsAsync(filter))
|
|
.ReturnsAsync(efficiencyMetrics);
|
|
|
|
// Act
|
|
var result = await _controller.GetEfficiencyMetrics(filter);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<EfficiencyMetrics>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(efficiencyMetrics, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetOeeMetricsAsync_ValidDeviceAndDate_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var deviceId = 1;
|
|
var date = DateTime.Today;
|
|
|
|
var oeeMetrics = new OeeMetrics
|
|
{
|
|
DeviceId = deviceId,
|
|
DeviceName = "Test Device",
|
|
Date = date,
|
|
Availability = 95m,
|
|
Performance = 90m,
|
|
Quality = 98m,
|
|
Oee = 83.79m,
|
|
PlannedProductionTime = TimeSpan.FromHours(8),
|
|
ActualProductionTime = TimeSpan.FromHours(7.6),
|
|
Downtime = TimeSpan.FromMinutes(24),
|
|
IdealCycleTime = 2,
|
|
TotalCycleTime = 500,
|
|
TotalPieces = 250,
|
|
GoodPieces = 245
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.CalculateOeeAsync(deviceId, date))
|
|
.ReturnsAsync(oeeMetrics);
|
|
|
|
// Act
|
|
var result = await _controller.GetOeeMetrics(deviceId, date);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<OeeMetrics>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(oeeMetrics, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetProductionForecastAsync_ValidFilter_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var filter = new ForecastFilter
|
|
{
|
|
DeviceId = 1,
|
|
DaysToForecast = 7,
|
|
Model = ForecastModel.Linear,
|
|
HistoricalDataStart = DateTime.Now.AddDays(-30),
|
|
HistoricalDataEnd = DateTime.Now
|
|
};
|
|
|
|
var productionForecast = new ProductionForecast
|
|
{
|
|
DeviceId = 1,
|
|
DeviceName = "Test Device",
|
|
ForecastStartDate = DateTime.Today,
|
|
ForecastEndDate = DateTime.Today.AddDays(6),
|
|
DailyForecasts = new List<ForecastItem>(),
|
|
ForecastAccuracy = 85.5m,
|
|
ModelUsed = ForecastModel.Linear
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.GenerateProductionForecastAsync(filter))
|
|
.ReturnsAsync(productionForecast);
|
|
|
|
// Act
|
|
var result = await _controller.GetProductionForecast(filter);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<ProductionForecast>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(productionForecast, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DetectProductionAnomaliesAsync_ValidFilter_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var filter = new AnomalyFilter
|
|
{
|
|
DeviceIds = new List<int> { 1 },
|
|
StartDate = DateTime.Now.AddDays(-7),
|
|
EndDate = DateTime.Now,
|
|
MinSeverity = AnomalySeverity.Medium
|
|
};
|
|
|
|
var anomalyAnalysis = new AnomalyAnalysis
|
|
{
|
|
DeviceIds = new List<int> { 1 },
|
|
DeviceNames = new List<string> { "Test Device" },
|
|
AnalysisStartDate = DateTime.Now.AddDays(-7),
|
|
AnalysisEndDate = DateTime.Now,
|
|
Anomalies = new List<ProductionAnomaly>(),
|
|
OverallSeverity = AnomalySeverity.Low
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.DetectProductionAnomaliesAsync(filter))
|
|
.ReturnsAsync(anomalyAnalysis);
|
|
|
|
// Act
|
|
var result = await _controller.DetectProductionAnomalies(filter);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<AnomalyAnalysis>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(anomalyAnalysis, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetHistoricalProductionDataAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var deviceId = 1;
|
|
var startDate = DateTime.Now.AddDays(-7);
|
|
var endDate = DateTime.Now;
|
|
var groupBy = GroupBy.Date;
|
|
|
|
var historicalData = new HistoricalProductionData
|
|
{
|
|
DeviceId = deviceId,
|
|
PeriodStart = startDate,
|
|
PeriodEnd = endDate,
|
|
GroupBy = groupBy,
|
|
DataPoints = new List<DataPoint>()
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.GenerateProductionReportAsync(It.IsAny<ReportFilter>()))
|
|
.ReturnsAsync(new ProductionReport { SummaryItems = new List<ProductionSummaryItem>() });
|
|
|
|
// Mock the conversion in the controller
|
|
// This would normally be done by the controller logic
|
|
|
|
// Act
|
|
var result = await _controller.GetHistoricalProductionData(deviceId, startDate, endDate, groupBy);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<HistoricalProductionData>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(deviceId, response.Data.DeviceId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetHistoricalProductionDataAsync_InvalidDevice_ReturnsBadRequest()
|
|
{
|
|
// Arrange
|
|
var deviceId = 0; // Invalid device ID
|
|
var startDate = DateTime.Now.AddDays(-7);
|
|
var endDate = DateTime.Now;
|
|
|
|
// Act
|
|
var result = await _controller.GetHistoricalProductionData(deviceId, startDate, endDate);
|
|
|
|
// Assert
|
|
var badRequestResult = Assert.IsType<BadRequestObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<HistoricalProductionData>>(badRequestResult.Value);
|
|
Assert.False(response.Success);
|
|
Assert.Contains("Invalid device ID", response.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetEfficiencyTrendsAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var deviceId = 1;
|
|
var startDate = DateTime.Now.AddDays(-7);
|
|
var endDate = DateTime.Now;
|
|
var metric = EfficiencyMetric.Oee;
|
|
|
|
var efficiencyTrendData = new EfficiencyTrendData
|
|
{
|
|
DeviceId = deviceId,
|
|
Metric = metric,
|
|
PeriodStart = startDate,
|
|
PeriodEnd = endDate,
|
|
DataPoints = new List<EfficiencyDataPoint>()
|
|
};
|
|
|
|
_mockStatisticsService.Setup(service => service.CalculateEfficiencyMetricsAsync(It.IsAny<EfficiencyFilter>()))
|
|
.ReturnsAsync(new EfficiencyMetrics { HourlyData = new List<HourlyEfficiency>() });
|
|
|
|
// Act
|
|
var result = await _controller.GetEfficiencyTrends(deviceId, startDate, endDate, metric);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<EfficiencyTrendData>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(deviceId, response.Data.DeviceId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetMultiDeviceSummaryAsync_ValidDevices_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var deviceIds = new List<int> { 1, 2, 3 };
|
|
|
|
_mockStatisticsService.Setup(service => service.GetDashboardSummaryAsync(It.IsAny<DashboardFilter>()))
|
|
.ReturnsAsync(new DashboardSummary
|
|
{
|
|
TotalDevices = 3,
|
|
ActiveDevices = 2,
|
|
OfflineDevices = 1,
|
|
TotalProductionToday = 1000,
|
|
TotalProductionThisWeek = 7000,
|
|
TotalProductionThisMonth = 30000,
|
|
OverallEfficiency = 85.5m,
|
|
QualityRate = 98.2m,
|
|
DeviceSummaries = new List<DeviceSummary>()
|
|
});
|
|
|
|
// Act
|
|
var result = await _controller.GetMultiDeviceSummary(deviceIds);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<MultiDeviceSummary>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(3, response.Data.DeviceCount);
|
|
Assert.Equal(2, response.Data.ActiveDeviceCount);
|
|
Assert.Equal(1, response.Data.OfflineDeviceCount);
|
|
}
|
|
}
|
|
|
|
public class ConfigControllerTests
|
|
{
|
|
private readonly Mock<ISystemService> _mockSystemService;
|
|
private readonly Mock<ITemplateService> _mockTemplateService;
|
|
private readonly Mock<IRulesService> _mockRulesService;
|
|
private readonly Mock<IProductionStatisticsService> _mockStatisticsService;
|
|
private readonly ConfigController _controller;
|
|
|
|
public ConfigControllerTests()
|
|
{
|
|
_mockSystemService = new Mock<ISystemService>();
|
|
_mockTemplateService = new Mock<ITemplateService>();
|
|
_mockRulesService = new Mock<IRulesService>();
|
|
_mockStatisticsService = new Mock<IProductionStatisticsService>();
|
|
_controller = new ConfigController(
|
|
_mockSystemService.Object,
|
|
_mockTemplateService.Object,
|
|
_mockRulesService.Object,
|
|
_mockStatisticsService.Object
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetSystemConfigurationAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var systemConfig = new SystemConfiguration
|
|
{
|
|
DailyProductionTarget = 100,
|
|
EnableProduction = true,
|
|
EnableAlerts = true,
|
|
AlertThresholds = new Dictionary<string, decimal>
|
|
{
|
|
{ "production_drop", 30 },
|
|
{ "quality_rate", 90 }
|
|
}
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetSystemConfigurationAsync())
|
|
.ReturnsAsync(systemConfig);
|
|
|
|
// Act
|
|
var result = await _controller.GetSystemConfiguration();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<SystemConfiguration>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(systemConfig, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateSystemConfigurationAsync_ValidConfig_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var config = new SystemConfiguration
|
|
{
|
|
DailyProductionTarget = 150,
|
|
EnableProduction = true,
|
|
EnableAlerts = true
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.UpdateSystemConfigurationAsync(config))
|
|
.ReturnsAsync(true);
|
|
|
|
// Act
|
|
var result = await _controller.UpdateSystemConfiguration(config);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<bool>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.True(response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetProductionTargetsAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var targets = new List<ProductionTargetConfig>
|
|
{
|
|
new ProductionTargetConfig { DeviceId = 1, ProgramName = "Program1", DailyTarget = 100 },
|
|
new ProductionTargetConfig { DeviceId = 2, ProgramName = "Program2", DailyTarget = 150 }
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetProductionTargetsAsync())
|
|
.ReturnsAsync(targets);
|
|
|
|
// Act
|
|
var result = await _controller.GetProductionTargets();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<List<ProductionTargetConfig>>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(2, response.Data.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetWorkingHoursConfigAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var workingHoursConfig = new WorkingHoursConfig
|
|
{
|
|
WorkingDays = new List<DayOfWeek> { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday },
|
|
WorkingHours = TimeSpan.FromHours(8),
|
|
StartHour = 9,
|
|
EndHour = 17,
|
|
BreakIntervals = new List<TimeSpan>
|
|
{
|
|
TimeSpan.FromHours(12) // Lunch break
|
|
}
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetWorkingHoursConfigAsync())
|
|
.ReturnsAsync(workingHoursConfig);
|
|
|
|
// Act
|
|
var result = await _controller.GetWorkingHoursConfig();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<WorkingHoursConfig>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(5, response.Data.WorkingDays.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetAlertConfigurationAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var alertConfig = new AlertConfiguration
|
|
{
|
|
EnableAlerts = true,
|
|
AlertTypes = new List<string> { "production_drop", "quality_rate", "device_error" },
|
|
AlertThresholds = new Dictionary<string, decimal>
|
|
{
|
|
{ "production_drop", 30 },
|
|
{ "quality_rate", 90 },
|
|
{ "device_error", 5 }
|
|
},
|
|
NotificationChannels = new List<string> { "email", "sms", "webhook" }
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetAlertConfigurationAsync())
|
|
.ReturnsAsync(alertConfig);
|
|
|
|
// Act
|
|
var result = await _controller.GetAlertConfiguration();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<AlertConfiguration>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(3, response.Data.AlertTypes.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetBusinessRulesAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var rules = new List<BusinessRuleConfig>
|
|
{
|
|
new BusinessRuleConfig { RuleId = 1, RuleName = "Production Target", Enabled = true },
|
|
new BusinessRuleConfig { RuleId = 2, RuleName = "Quality Control", Enabled = false }
|
|
};
|
|
|
|
_mockRulesService.Setup(service => service.GetAllRulesAsync())
|
|
.ReturnsAsync(rules);
|
|
|
|
// Act
|
|
var result = await _controller.GetBusinessRules();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<List<BusinessRuleConfig>>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(2, response.Data.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrUpdateBusinessRuleAsync_ValidRule_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var rule = new BusinessRuleConfig
|
|
{
|
|
RuleId = 1,
|
|
RuleName = "Production Target",
|
|
Enabled = true,
|
|
RuleExpression = "production > target * 0.9"
|
|
};
|
|
|
|
_mockRulesService.Setup(service => service.CreateOrUpdateRuleAsync(rule))
|
|
.ReturnsAsync(rule);
|
|
|
|
// Act
|
|
var result = await _controller.CreateOrUpdateBusinessRule(rule);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<BusinessRuleConfig>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(rule, response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteBusinessRuleAsync_ValidRuleId_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var ruleId = 1;
|
|
|
|
_mockRulesService.Setup(service => service.DeleteRuleAsync(ruleId))
|
|
.ReturnsAsync(true);
|
|
|
|
// Act
|
|
var result = await _controller.DeleteBusinessRule(ruleId);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<bool>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.True(response.Data);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetStatisticsRulesAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var rules = new List<StatisticsRuleConfig>
|
|
{
|
|
new StatisticsRuleConfig { RuleId = 1, RuleName = "Production Trend", Enabled = true },
|
|
new StatisticsRuleConfig { RuleId = 2, RuleName = "Efficiency Analysis", Enabled = true }
|
|
};
|
|
|
|
_mockRulesService.Setup(service => service.GetStatisticsRulesAsync())
|
|
.ReturnsAsync(rules);
|
|
|
|
// Act
|
|
var result = await _controller.GetStatisticsRules();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<List<StatisticsRuleConfig>>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(2, response.Data.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDataRetentionConfigAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var retentionConfig = new DataRetentionConfig
|
|
{
|
|
BusinessDataRetentionDays = 365,
|
|
LogDataRetentionDays = 90,
|
|
StatisticsDataRetentionDays = 180,
|
|
AutoCleanupEnabled = true,
|
|
CleanupSchedule = "0 2 * * *" // Daily at 2 AM
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetDataRetentionConfigAsync())
|
|
.ReturnsAsync(retentionConfig);
|
|
|
|
// Act
|
|
var result = await _controller.GetDataRetentionConfig();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<DataRetentionConfig>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(365, response.Data.BusinessDataRetentionDays);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDashboardConfigAsync_ValidRequest_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var dashboardConfig = new DashboardConfig
|
|
{
|
|
RefreshInterval = 30,
|
|
EnableRealTimeUpdates = true,
|
|
DefaultTimeRange = "7d",
|
|
AvailableTimeRanges = new List<string> { "1d", "7d", "30d", "90d" },
|
|
AvailableWidgets = new List<string> { "production_chart", "efficiency_chart", "device_status" }
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetDashboardConfigAsync())
|
|
.ReturnsAsync(dashboardConfig);
|
|
|
|
// Act
|
|
var result = await _controller.GetDashboardConfig();
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<DashboardConfig>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.Equal(30, response.Data.RefreshInterval);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ValidateConfigurationAsync_ValidConfig_ReturnsOk()
|
|
{
|
|
// Arrange
|
|
var config = new SystemConfiguration { DailyProductionTarget = 100 };
|
|
|
|
var validationResult = new ValidationResult
|
|
{
|
|
IsValid = true,
|
|
Errors = new List<string>(),
|
|
Warnings = new List<string>()
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.ValidateConfigurationAsync(config))
|
|
.ReturnsAsync(validationResult);
|
|
|
|
// Act
|
|
var result = await _controller.ValidateConfiguration(config);
|
|
|
|
// Assert
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
var response = Assert.IsType<ApiResponse<ValidationResult>>(okResult.Value);
|
|
Assert.True(response.Success);
|
|
Assert.True(response.Data.IsValid);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExportConfigurationAsync_ValidRequest_ReturnsFile()
|
|
{
|
|
// Arrange
|
|
var config = new SystemConfiguration
|
|
{
|
|
DailyProductionTarget = 100,
|
|
EnableProduction = true,
|
|
EnableAlerts = true
|
|
};
|
|
|
|
_mockSystemService.Setup(service => service.GetSystemConfigurationAsync())
|
|
.ReturnsAsync(config);
|
|
|
|
// Act
|
|
var result = await _controller.ExportConfiguration();
|
|
|
|
// Assert
|
|
var fileResult = Assert.IsType<FileContentResult>(result);
|
|
Assert.Contains("system-configuration.json", fileResult.FileDownloadName);
|
|
}
|
|
}
|
|
} |