using System.Net; using System.Net.Http.Json; using System.Text.Json; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using NSubstitute; using Xunit; using XiangYi.AdminApi; using XiangYi.Application.DTOs.Requests; using XiangYi.Application.DTOs.Responses; using XiangYi.Application.Interfaces; namespace XiangYi.Api.Tests.AdminApi; /// /// 后台数据备份控制器集成测�? /// public class AdminBackupControllerIntegrationTests : IClassFixture> { private readonly WebApplicationFactory _factory; private readonly IAdminBackupService _mockAdminBackupService; public AdminBackupControllerIntegrationTests(WebApplicationFactory factory) { _mockAdminBackupService = Substitute.For(); _factory = factory.WithWebHostBuilder(builder => { builder.UseEnvironment("Testing"); builder.ConfigureServices(services => { services.RemoveAll(); services.AddSingleton(_mockAdminBackupService); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme; options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme; }) .AddScheme( AdminTestAuthHandler.AuthenticationScheme, options => { }); }); }); } /// /// 测试获取备份记录列表 - 未授权返�?01 /// [Fact] public async Task GetBackupList_WithoutAuth_ReturnsUnauthorized() { var client = _factory.CreateClient(); var response = await client.GetAsync("/api/admin/backups"); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } /// /// 测试获取备份记录列表 - 授权后成�? /// [Fact] public async Task GetBackupList_WithAuth_ReturnsSuccess() { var expectedResult = new PagedResult { Items = new List { new AdminBackupListDto { BackupId = 1, BackupType = 1, BackupTypeText = "自动备份", FileName = "backup_20231231_020000.bak", FileSize = 1024 * 1024 * 100, FileSizeText = "100 MB", Status = 1, StatusText = "成功", CreateTime = DateTime.Now.AddHours(-2) } }, Total = 1, PageIndex = 1, PageSize = 10 }; _mockAdminBackupService.GetBackupListAsync(Arg.Any()) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.GetAsync("/api/admin/backups"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); Assert.NotNull(result.Data); Assert.Single(result.Data.Items); } /// /// 测试获取备份记录详情 - 成功 /// [Fact] public async Task GetBackupDetail_WithAuth_ReturnsSuccess() { var expectedResult = new AdminBackupDetailDto { BackupId = 1, BackupType = 1, BackupTypeText = "自动备份", FileName = "backup_20231231_020000.bak", FileSize = 1024 * 1024 * 100, FileSizeText = "100 MB", StorageUrl = "https://cos.example.com/backups/backup_20231231_020000.bak", Status = 1, StatusText = "成功", CreateTime = DateTime.Now.AddHours(-2) }; _mockAdminBackupService.GetBackupDetailAsync(1) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.GetAsync("/api/admin/backups/1"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); Assert.NotNull(result.Data); Assert.Equal(expectedResult.BackupId, result.Data.BackupId); } /// /// 测试执行手动备份 - 成功 /// [Fact] public async Task ExecuteManualBackup_WithAuth_ReturnsSuccess() { var expectedResult = new AdminBackupDetailDto { BackupId = 100, BackupType = 2, BackupTypeText = "手动备份", FileName = "backup_20231231_150000.bak", FileSize = 1024 * 1024 * 100, FileSizeText = "100 MB", StorageUrl = "https://cos.example.com/backups/backup_20231231_150000.bak", Status = 1, StatusText = "成功", AdminId = 1, CreateTime = DateTime.Now }; _mockAdminBackupService.ExecuteManualBackupAsync(1) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.PostAsync("/api/admin/backups", null); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); Assert.NotNull(result.Data); Assert.Equal(2, result.Data.BackupType); // 手动备份 } /// /// 测试恢复数据 - 成功 /// [Fact] public async Task RestoreData_WithAuth_ReturnsSuccess() { _mockAdminBackupService.RestoreDataAsync(1, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.PostAsync("/api/admin/backups/1/restore", null); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); } /// /// 测试删除备份记录 - 成功 /// [Fact] public async Task DeleteBackup_WithAuth_ReturnsSuccess() { _mockAdminBackupService.DeleteBackupAsync(1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.DeleteAsync("/api/admin/backups/1"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); } /// /// 测试获取备份统计信息 - 成功 /// [Fact] public async Task GetBackupStatistics_WithAuth_ReturnsSuccess() { var expectedResult = new AdminBackupStatisticsDto { TotalCount = 100, SuccessCount = 98, FailedCount = 2, AutoCount = 90, ManualCount = 10, TotalSize = 1024L * 1024 * 1024 * 10, // 10 GB TotalSizeText = "10 GB", LastBackupTime = DateTime.Now.AddHours(-2), LastSuccessBackupTime = DateTime.Now.AddHours(-2) }; _mockAdminBackupService.GetBackupStatisticsAsync() .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.GetAsync("/api/admin/backups/statistics"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); Assert.NotNull(result.Data); Assert.Equal(expectedResult.TotalCount, result.Data.TotalCount); Assert.Equal(expectedResult.SuccessCount, result.Data.SuccessCount); } /// /// 测试清理过期备份 - 成功 /// [Fact] public async Task CleanupExpiredBackups_WithAuth_ReturnsSuccess() { _mockAdminBackupService.CleanupExpiredBackupsAsync() .Returns(Task.FromResult(5)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.PostAsync("/api/admin/backups/cleanup", null); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); Assert.Equal(5, result.Data); } /// /// 测试备份流程 - 手动备份并恢�? /// [Fact] public async Task BackupFlow_ManualBackupAndRestore_Success() { var backupId = 100L; var backupResult = new AdminBackupDetailDto { BackupId = backupId, BackupType = 2, BackupTypeText = "手动备份", FileName = "backup_20231231_150000.bak", FileSize = 1024 * 1024 * 100, Status = 1, StatusText = "成功" }; _mockAdminBackupService.ExecuteManualBackupAsync(1) .Returns(Task.FromResult(backupResult)); _mockAdminBackupService.GetBackupDetailAsync(backupId) .Returns(Task.FromResult(backupResult)); _mockAdminBackupService.RestoreDataAsync(backupId, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Execute manual backup var backupResponse = await client.PostAsync("/api/admin/backups", null); Assert.Equal(HttpStatusCode.OK, backupResponse.StatusCode); // Get backup detail var detailResponse = await client.GetAsync($"/api/admin/backups/{backupId}"); Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode); // Restore data var restoreResponse = await client.PostAsync($"/api/admin/backups/{backupId}/restore", null); Assert.Equal(HttpStatusCode.OK, restoreResponse.StatusCode); } /// /// 测试恢复数据失败 - 返回错误 /// [Fact] public async Task RestoreData_WhenFails_ReturnsError() { _mockAdminBackupService.RestoreDataAsync(1, 1) .Returns(Task.FromResult(false)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.PostAsync("/api/admin/backups/1/restore", null); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(40001, result.Code); } /// /// 测试备份列表按类型筛�?- 成功 /// [Fact] public async Task GetBackupList_WithTypeFilter_ReturnsFilteredResults() { var expectedResult = new PagedResult { Items = new List { new AdminBackupListDto { BackupId = 1, BackupType = 2, BackupTypeText = "手动备份", Status = 1 } }, Total = 1, PageIndex = 1, PageSize = 10 }; _mockAdminBackupService.GetBackupListAsync(Arg.Is(r => r.BackupType == 2)) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.GetAsync("/api/admin/backups?backupType=2"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); Assert.NotNull(result); Assert.Equal(0, result.Code); Assert.NotNull(result.Data); Assert.All(result.Data.Items, item => Assert.Equal(2, item.BackupType)); } }