admin/src/SimpleAdmin.Api.IntegrationTests/WarehouseApiIntegrationTests.cs
2026-04-29 09:38:07 +08:00

204 lines
8.6 KiB
C#

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<IWarehouseAddressRepository>(MockBehavior.Strict);
repository
.Setup(x => x.GetPagedListAsync(
It.IsAny<System.Linq.Expressions.Expression<Func<WarehouseAddress, bool>>>(),
It.IsAny<int>(),
It.IsAny<int>(),
It.IsAny<Dictionary<string, bool>>(),
It.IsAny<CancellationToken>()))
.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<System.Linq.Expressions.Expression<Func<WarehouseAddress, bool>>>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(1);
await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services =>
{
services.RemoveAll<IWarehouseAddressRepository>();
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<OmsPageResult<WarehousePaginatedOutput>>();
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<IWarehouseAddressRepository>(MockBehavior.Strict);
repository
.Setup(x => x.FirstOrDefaultAsync(
It.IsAny<System.Linq.Expressions.Expression<Func<WarehouseAddress, bool>>>(),
It.IsAny<CancellationToken>()))
.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<IWarehouseAddressRepository>();
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<WarehouseOutput>();
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<IWarehouseAddressRepository>(MockBehavior.Strict);
repository
.Setup(x => x.GetByWarehouseNameAsync("New Warehouse", It.IsAny<CancellationToken>()))
.ReturnsAsync((WarehouseAddress?)null);
repository
.Setup(x => x.InsertAsync(It.IsAny<WarehouseAddress>(), It.IsAny<CancellationToken>()))
.Callback<WarehouseAddress, CancellationToken>((entity, _) => insertedEntity = entity)
.ReturnsAsync((WarehouseAddress entity, CancellationToken _) => entity);
await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services =>
{
services.RemoveAll<IWarehouseAddressRepository>();
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<IWarehouseAddressRepository>(MockBehavior.Strict);
repository
.Setup(x => x.FirstOrDefaultAsync(
It.IsAny<System.Linq.Expressions.Expression<Func<WarehouseAddress, bool>>>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(currentEntity);
repository
.Setup(x => x.GetByWarehouseNameAsync("Updated Warehouse", It.IsAny<CancellationToken>()))
.ReturnsAsync((WarehouseAddress?)null);
repository
.Setup(x => x.UpdateAsync(It.IsAny<WarehouseAddress>(), It.IsAny<CancellationToken>()))
.Callback<WarehouseAddress, CancellationToken>((entity, _) => updatedEntity = entity)
.Returns(Task.CompletedTask);
await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: services =>
{
services.RemoveAll<IWarehouseAddressRepository>();
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\"]");
}
}