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 _mockStatisticsService; private readonly StatisticsController _controller; public StatisticsControllerTests() { _mockStatisticsService = new Mock(); _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() }; _mockStatisticsService.Setup(service => service.CalculateProductionTrendsAsync(deviceId, startDate, endDate)) .ReturnsAsync(trendAnalysis); // Act var result = await _controller.GetProductionTrends(deviceId, startDate, endDate); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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(result); var response = Assert.IsType>(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 { 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(), Metadata = ReportMetadata.GeneratedAt }; _mockStatisticsService.Setup(service => service.GenerateProductionReportAsync(filter)) .ReturnsAsync(productionReport); // Act var result = await _controller.GetProductionReport(filter); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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 { 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(), ActiveAlerts = new List() }; _mockStatisticsService.Setup(service => service.GetDashboardSummaryAsync(filter)) .ReturnsAsync(dashboardSummary); // Act var result = await _controller.GetDashboardSummary(filter); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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 { 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() }; _mockStatisticsService.Setup(service => service.CalculateEfficiencyMetricsAsync(filter)) .ReturnsAsync(efficiencyMetrics); // Act var result = await _controller.GetEfficiencyMetrics(filter); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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(result); var response = Assert.IsType>(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(), 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(result); var response = Assert.IsType>(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 { 1 }, StartDate = DateTime.Now.AddDays(-7), EndDate = DateTime.Now, MinSeverity = AnomalySeverity.Medium }; var anomalyAnalysis = new AnomalyAnalysis { DeviceIds = new List { 1 }, DeviceNames = new List { "Test Device" }, AnalysisStartDate = DateTime.Now.AddDays(-7), AnalysisEndDate = DateTime.Now, Anomalies = new List(), OverallSeverity = AnomalySeverity.Low }; _mockStatisticsService.Setup(service => service.DetectProductionAnomaliesAsync(filter)) .ReturnsAsync(anomalyAnalysis); // Act var result = await _controller.DetectProductionAnomalies(filter); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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() }; _mockStatisticsService.Setup(service => service.GenerateProductionReportAsync(It.IsAny())) .ReturnsAsync(new ProductionReport { SummaryItems = new List() }); // 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(result); var response = Assert.IsType>(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(result); var response = Assert.IsType>(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() }; _mockStatisticsService.Setup(service => service.CalculateEfficiencyMetricsAsync(It.IsAny())) .ReturnsAsync(new EfficiencyMetrics { HourlyData = new List() }); // Act var result = await _controller.GetEfficiencyTrends(deviceId, startDate, endDate, metric); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(okResult.Value); Assert.True(response.Success); Assert.Equal(deviceId, response.Data.DeviceId); } [Fact] public async Task GetMultiDeviceSummaryAsync_ValidDevices_ReturnsOk() { // Arrange var deviceIds = new List { 1, 2, 3 }; _mockStatisticsService.Setup(service => service.GetDashboardSummaryAsync(It.IsAny())) .ReturnsAsync(new DashboardSummary { TotalDevices = 3, ActiveDevices = 2, OfflineDevices = 1, TotalProductionToday = 1000, TotalProductionThisWeek = 7000, TotalProductionThisMonth = 30000, OverallEfficiency = 85.5m, QualityRate = 98.2m, DeviceSummaries = new List() }); // Act var result = await _controller.GetMultiDeviceSummary(deviceIds); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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 _mockSystemService; private readonly Mock _mockTemplateService; private readonly Mock _mockRulesService; private readonly Mock _mockStatisticsService; private readonly ConfigController _controller; public ConfigControllerTests() { _mockSystemService = new Mock(); _mockTemplateService = new Mock(); _mockRulesService = new Mock(); _mockStatisticsService = new Mock(); _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 { { "production_drop", 30 }, { "quality_rate", 90 } } }; _mockSystemService.Setup(service => service.GetSystemConfigurationAsync()) .ReturnsAsync(systemConfig); // Act var result = await _controller.GetSystemConfiguration(); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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(result); var response = Assert.IsType>(okResult.Value); Assert.True(response.Success); Assert.True(response.Data); } [Fact] public async Task GetProductionTargetsAsync_ValidRequest_ReturnsOk() { // Arrange var targets = new List { 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(result); var response = Assert.IsType>>(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.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }, WorkingHours = TimeSpan.FromHours(8), StartHour = 9, EndHour = 17, BreakIntervals = new List { TimeSpan.FromHours(12) // Lunch break } }; _mockSystemService.Setup(service => service.GetWorkingHoursConfigAsync()) .ReturnsAsync(workingHoursConfig); // Act var result = await _controller.GetWorkingHoursConfig(); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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 { "production_drop", "quality_rate", "device_error" }, AlertThresholds = new Dictionary { { "production_drop", 30 }, { "quality_rate", 90 }, { "device_error", 5 } }, NotificationChannels = new List { "email", "sms", "webhook" } }; _mockSystemService.Setup(service => service.GetAlertConfigurationAsync()) .ReturnsAsync(alertConfig); // Act var result = await _controller.GetAlertConfiguration(); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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 { 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(result); var response = Assert.IsType>>(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(result); var response = Assert.IsType>(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(result); var response = Assert.IsType>(okResult.Value); Assert.True(response.Success); Assert.True(response.Data); } [Fact] public async Task GetStatisticsRulesAsync_ValidRequest_ReturnsOk() { // Arrange var rules = new List { 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(result); var response = Assert.IsType>>(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(result); var response = Assert.IsType>(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 { "1d", "7d", "30d", "90d" }, AvailableWidgets = new List { "production_chart", "efficiency_chart", "device_status" } }; _mockSystemService.Setup(service => service.GetDashboardConfigAsync()) .ReturnsAsync(dashboardConfig); // Act var result = await _controller.GetDashboardConfig(); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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(), Warnings = new List() }; _mockSystemService.Setup(service => service.ValidateConfigurationAsync(config)) .ReturnsAsync(validationResult); // Act var result = await _controller.ValidateConfiguration(config); // Assert var okResult = Assert.IsType(result); var response = Assert.IsType>(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(result); Assert.Contains("system-configuration.json", fileResult.FileDownloadName); } } }