using System.Net; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Moq; using Oms.Application.Dtos.Shared; using Oms.Application.Dtos.System; using Oms.Domain.SystemAggregate.Consts; using Oms.Domain.SystemAggregate.Entities; using Oms.Domain.SystemAggregate.Repositories; using SimpleAdmin.Api.IntegrationTests.Support; namespace SimpleAdmin.Api.IntegrationTests; public class WarehouseApiIntegrationTests { [Fact] public async Task GetWarehouseList_ShouldReturnPagedItemsWithMappedFields() { var repository = new Mock(MockBehavior.Strict); repository .Setup(x => x.GetPagedListAsync( It.IsAny>>(), It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) .ReturnsAsync([ new WarehouseAddress { Id = 12, WarehouseName = "UK Transit", WarehouseType = WarehouseTypeCodes.Transit, Recipient = "Alice", ContactPhone = "13800138000", ShippingAddress = "London", ServicePhone = "020-123456", ServiceWechat = "oms-warehouse", ServiceWechatFiles = "[\"wx-1.png\",\"wx-2.png\"]", CreateTime = new DateTime(2026, 4, 29, 9, 0, 0), UpdateTime = new DateTime(2026, 4, 29, 10, 0, 0) } ]); repository .Setup(x => x.CountAsync( It.IsAny>>(), It.IsAny())) .ReturnsAsync(1); await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services => { services.RemoveAll(); services.AddSingleton(repository.Object); }); var response = await host.Client.GetAsync("/system/warehouse/list?Page=1&PageSize=20&WarehouseType=transit&Keyword=UK"); response.StatusCode.Should().Be(HttpStatusCode.OK); var payload = await response.Content.ReadFromJsonAsync>(); payload.Should().NotBeNull(); payload!.Total.Should().Be(1); payload.Items.Should().ContainSingle(); payload.Items[0].WarehouseTypeName.Should().Be("中转仓"); payload.Items[0].ServiceWechatFiles.Should().ContainInOrder("wx-1.png", "wx-2.png"); } [Fact] public async Task GetWarehouseDetail_ShouldReturnMappedAuditAndFileFields() { var repository = new Mock(MockBehavior.Strict); repository .Setup(x => x.FirstOrDefaultAsync( It.IsAny>>(), It.IsAny())) .ReturnsAsync(new WarehouseAddress { Id = 8, WarehouseName = "Main Hub", WarehouseType = WarehouseTypeCodes.Main, Recipient = "Bob", ContactPhone = "13900139000", ShippingAddress = "Shenzhen", ServicePhone = "0755-123456", ServiceWechat = "main-hub", ServiceWechatFiles = "[\"main.png\"]", CreateTime = new DateTime(2026, 4, 20, 9, 30, 0), CreateUserId = 66, UpdateTime = new DateTime(2026, 4, 21, 14, 0, 0), UpdateUserId = 88 }); await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services => { services.RemoveAll(); services.AddSingleton(repository.Object); }); var response = await host.Client.GetAsync("/system/warehouse/detail?id=8"); response.StatusCode.Should().Be(HttpStatusCode.OK); var payload = await response.Content.ReadFromJsonAsync(); payload.Should().NotBeNull(); payload!.CreateBy.Should().Be("66"); payload.UpdateBy.Should().Be("88"); payload.ServiceWechatFiles.Should().ContainSingle().Which.Should().Be("main.png"); } [Fact] public async Task CreateWarehouse_ShouldSerializeFilesBeforePersisting() { WarehouseAddress? insertedEntity = null; var repository = new Mock(MockBehavior.Strict); repository .Setup(x => x.GetByWarehouseNameAsync("New Warehouse", It.IsAny())) .ReturnsAsync((WarehouseAddress?)null); repository .Setup(x => x.InsertAsync(It.IsAny(), It.IsAny())) .Callback((entity, _) => insertedEntity = entity) .ReturnsAsync((WarehouseAddress entity, CancellationToken _) => entity); await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services => { services.RemoveAll(); services.AddSingleton(repository.Object); }); var response = await host.Client.PostAsJsonAsync("/system/warehouse/create", new CreateWarehouseInput { WarehouseName = "New Warehouse", WarehouseType = WarehouseTypeCodes.Return, Recipient = "Cindy", ContactPhone = "13700137000", ShippingAddress = "Guangzhou", ServicePhone = "020-888888", ServiceWechat = "return-hub", ServiceWechatFiles = ["qr-a.png", "qr-b.png"] }); response.IsSuccessStatusCode.Should().BeTrue(); insertedEntity.Should().NotBeNull(); insertedEntity!.WarehouseName.Should().Be("New Warehouse"); insertedEntity.WarehouseType.Should().Be(WarehouseTypeCodes.Return); insertedEntity.ServiceWechatFiles.Should().Be("[\"qr-a.png\",\"qr-b.png\"]"); } [Fact] public async Task UpdateWarehouse_ShouldPersistMutatedEntity() { WarehouseAddress? updatedEntity = null; var currentEntity = new WarehouseAddress { Id = 18, WarehouseName = "Old Warehouse", WarehouseType = WarehouseTypeCodes.Other, Recipient = "Old", ContactPhone = "13600136000", ShippingAddress = "Old Address", ServicePhone = "010-111111", ServiceWechat = "old-wechat", ServiceWechatFiles = "[\"old.png\"]" }; var repository = new Mock(MockBehavior.Strict); repository .Setup(x => x.FirstOrDefaultAsync( It.IsAny>>(), It.IsAny())) .ReturnsAsync(currentEntity); repository .Setup(x => x.GetByWarehouseNameAsync("Updated Warehouse", It.IsAny())) .ReturnsAsync((WarehouseAddress?)null); repository .Setup(x => x.UpdateAsync(It.IsAny(), It.IsAny())) .Callback((entity, _) => updatedEntity = entity) .Returns(Task.CompletedTask); await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services => { services.RemoveAll(); services.AddSingleton(repository.Object); }); var response = await host.Client.PostAsJsonAsync("/system/warehouse/update", new UpdateWarehouseInput { Id = 18, WarehouseName = "Updated Warehouse", WarehouseType = WarehouseTypeCodes.Main, Recipient = "Daisy", ContactPhone = "13500135000", ShippingAddress = "New Address", ServicePhone = "0755-999999", ServiceWechat = "new-wechat", ServiceWechatFiles = ["new-a.png", "new-b.png"] }); response.IsSuccessStatusCode.Should().BeTrue(); updatedEntity.Should().NotBeNull(); updatedEntity!.WarehouseName.Should().Be("Updated Warehouse"); updatedEntity.WarehouseType.Should().Be(WarehouseTypeCodes.Main); updatedEntity.Recipient.Should().Be("Daisy"); updatedEntity.ServiceWechatFiles.Should().Be("[\"new-a.png\",\"new-b.png\"]"); } }