Browse Source

Add flash-sale order canceled event handler

pull/220/head
Jadyn 4 years ago
parent
commit
587b57d83d
  1. 86
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCanceledEventHandler.cs
  2. 33
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs
  3. 11
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/IProductCache.cs
  4. 55
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCache.cs
  5. 18
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs
  6. 1
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj
  7. 1
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs
  8. 4
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs
  9. 207
      plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCanceledEventHandlerTests.cs
  10. 22
      plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs

86
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCanceledEventHandler.cs

@ -0,0 +1,86 @@
using System.Threading.Tasks;
using EasyAbp.Eshop.Products.Products;
using EasyAbp.EShop.Orders.Orders;
using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults;
using EasyAbp.EShop.Products.Products;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Uow;
namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans;
public class FlashSaleOrderCanceledEventHandler : IDistributedEventHandler<OrderCanceledEto>, ITransientDependency
{
protected IFlashSaleResultRepository FlashSaleResultRepository { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IAbpApplication AbpApplication { get; }
protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; }
protected IProductCache ProductCache { get; }
protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; }
protected ILogger<FlashSaleOrderCanceledEventHandler> Logger { get; }
public FlashSaleOrderCanceledEventHandler(
IFlashSaleResultRepository flashSaleResultRepository,
IUnitOfWorkManager unitOfWorkManager,
IAbpApplication abpApplication,
IFlashSaleInventoryManager flashSaleInventoryManager,
IProductCache productCache,
IFlashSaleCurrentResultCache flashSaleCurrentResultCache,
ILogger<FlashSaleOrderCanceledEventHandler> logger)
{
FlashSaleResultRepository = flashSaleResultRepository;
UnitOfWorkManager = unitOfWorkManager;
AbpApplication = abpApplication;
FlashSaleInventoryManager = flashSaleInventoryManager;
ProductCache = productCache;
FlashSaleCurrentResultCache = flashSaleCurrentResultCache;
Logger = logger;
}
[UnitOfWork(true)]
public virtual async Task HandleEventAsync(OrderCanceledEto eventData)
{
var flashSaleResult = await FlashSaleResultRepository
.SingleOrDefaultAsync(x => x.Status != FlashSaleResultStatus.Failed && x.StoreId == eventData.Order.StoreId && x.OrderId == eventData.Order.Id);
if (flashSaleResult == null)
{
return;
}
flashSaleResult.MarkAsFailed(FlashSaleResultFailedReason.OrderCanceled);
await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true);
UnitOfWorkManager.Current.OnCompleted(async () =>
{
if (eventData.Order.OrderLines.Count == 0)
{
Logger.LogWarning("OrderCanceled order {orderId} orderLines is empty.", eventData.Order.Id);
return;
}
var productId = eventData.Order.OrderLines[0].ProductId;
var productSkuId = eventData.Order.OrderLines[0].ProductSkuId;
var product = await ProductCache.GetAsync(productId);
// try to roll back the inventory.
if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(
eventData.TenantId, product.InventoryProviderName, eventData.Order.StoreId,
productId, productSkuId))
{
Logger.LogWarning("Failed to roll back the flash sale inventory.");
return; // avoid to remove cache if the rollback failed.
}
// remove the cache so the user can try to order again.
await FlashSaleCurrentResultCache.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId);
});
}
}

33
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs

@ -50,13 +50,11 @@ public class FlashSalePlanAppService :
protected IFlashSalePlanRepository FlashSalePlanRepository { get; }
protected IProductAppService ProductAppService { get; }
protected IDistributedCache<FlashSalePlanPreOrderCacheItem> PreOrderDistributedCache { get; }
protected IDistributedCache<FlashSalePlanCacheItem, Guid> PlanDistributedCache { get; }
protected IDistributedCache<ProductCacheItem, Guid> ProductDistributedCache { get; }
protected IProductCache ProductCache { get; }
protected IDistributedEventBus DistributedEventBus { get; }
@ -74,10 +72,9 @@ public class FlashSalePlanAppService :
public FlashSalePlanAppService(
IFlashSalePlanRepository flashSalePlanRepository,
IProductAppService productAppService,
IDistributedCache<FlashSalePlanPreOrderCacheItem> tokenDistributedCache,
IDistributedCache<FlashSalePlanCacheItem, Guid> planDistributedCache,
IDistributedCache<ProductCacheItem, Guid> productDistributedCache,
IProductCache productCache,
IDistributedEventBus distributedEventBus,
IFlashSaleResultRepository flashSaleResultRepository,
IAbpDistributedLock distributedLock,
@ -88,10 +85,9 @@ public class FlashSalePlanAppService :
: base(flashSalePlanRepository)
{
FlashSalePlanRepository = flashSalePlanRepository;
ProductAppService = productAppService;
PreOrderDistributedCache = tokenDistributedCache;
PlanDistributedCache = planDistributedCache;
ProductDistributedCache = productDistributedCache;
ProductCache = productCache;
DistributedEventBus = distributedEventBus;
FlashSaleResultRepository = flashSaleResultRepository;
DistributedLock = distributedLock;
@ -131,7 +127,7 @@ public class FlashSalePlanAppService :
{
await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName);
var product = await ProductAppService.GetAsync(input.ProductId);
var product = await ProductCache.GetAsync(input.ProductId);
var productSku = product.GetSkuById(input.ProductSkuId);
await ValidateProductAsync(input.ProductId, product, input.StoreId);
@ -155,7 +151,7 @@ public class FlashSalePlanAppService :
public override async Task<FlashSalePlanDto> UpdateAsync(Guid id, FlashSalePlanUpdateDto input)
{
var flashSalePlan = await GetEntityByIdAsync(id);
var product = await ProductAppService.GetAsync(input.ProductId);
var product = await ProductCache.GetAsync(input.ProductId);
var productSku = product.GetSkuById(input.ProductSkuId);
await CheckMultiStorePolicyAsync(product.StoreId, UpdatePolicyName);
@ -210,7 +206,7 @@ public class FlashSalePlanAppService :
await CheckPolicyAsync(PreOrderPolicyName);
var plan = await GetFlashSalePlanCacheAsync(id);
var product = await GetProductCacheAsync(plan.ProductId);
var product = await ProductCache.GetAsync(plan.ProductId);
var productSku = product.GetSkuById(plan.ProductSkuId);
var expiresTime = DateTimeOffset.Now.Add(Options.PreOrderExpires);
@ -432,21 +428,4 @@ public class FlashSalePlanAppService :
return Task.FromResult(eto);
}
protected virtual async Task<ProductCacheItem> GetProductCacheAsync(Guid productId)
{
return await ProductDistributedCache.GetOrAddAsync(productId, async () =>
{
var productDto = await ProductAppService.GetAsync(productId);
var cacheItem = ObjectMapper.Map<ProductDto, ProductCacheItem>(productDto);
if (cacheItem != null)
{
cacheItem.TenantId = CurrentTenant.Id;
}
return cacheItem;
});
}
}

11
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/IProductCache.cs

@ -0,0 +1,11 @@
using System;
using System.Threading.Tasks;
namespace EasyAbp.EShop.Products.Products;
public interface IProductCache
{
Task<ProductCacheItem> GetAsync(Guid productId);
Task RemoveAsync(Guid productId);
}

55
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCache.cs

@ -0,0 +1,55 @@
using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Products.Products.Dtos;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
namespace EasyAbp.EShop.Products.Products;
public class ProductCache : IProductCache, ITransientDependency
{
protected IDistributedCache<ProductCacheItem, Guid> DistributedCache { get; }
protected IProductAppService ProductAppService { get; }
protected IObjectMapper ObjectMapper { get; }
protected ICurrentTenant CurrentTenant { get; }
public ProductCache(
IDistributedCache<ProductCacheItem, Guid> productDistributedCache,
IProductAppService productAppService,
IObjectMapper objectMapper,
ICurrentTenant currentTenant)
{
DistributedCache = productDistributedCache;
ProductAppService = productAppService;
ObjectMapper = objectMapper;
CurrentTenant = currentTenant;
}
public virtual async Task<ProductCacheItem> GetAsync(Guid productId)
{
return await DistributedCache.GetOrAddAsync(productId, async () =>
{
var productDto = await ProductAppService.GetAsync(productId);
var cacheItem = ObjectMapper.Map<ProductDto, ProductCacheItem>(productDto);
if (cacheItem != null)
{
cacheItem.TenantId = CurrentTenant.Id;
}
return cacheItem;
});
}
public virtual async Task RemoveAsync(Guid productId)
{
await DistributedCache.RemoveAsync(productId);
}
}

18
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs

@ -1,6 +1,4 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
@ -13,34 +11,34 @@ public class ProductCacheInvalidator :
IDistributedEventHandler<EntityDeletedEto<ProductEto>>,
ITransientDependency
{
protected IDistributedCache<ProductCacheItem, Guid> DistributedCache { get; }
protected IProductCache ProductCache { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
public ProductCacheInvalidator(
IDistributedCache<ProductCacheItem, Guid> distributedCache,
IProductCache productCache,
IUnitOfWorkManager unitOfWorkManager)
{
DistributedCache = distributedCache;
ProductCache = productCache;
UnitOfWorkManager = unitOfWorkManager;
}
public virtual async Task HandleEventAsync(EntityUpdatedEto<ProductEto> eventData)
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
await ProductCache.RemoveAsync(eventData.Entity.Id);
UnitOfWorkManager.Current?.OnCompleted(async () =>
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
await ProductCache.RemoveAsync(eventData.Entity.Id);
});
}
public virtual async Task HandleEventAsync(EntityDeletedEto<ProductEto> eventData)
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
await ProductCache.RemoveAsync(eventData.Entity.Id);
UnitOfWorkManager.Current?.OnCompleted(async () =>
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
await ProductCache.RemoveAsync(eventData.Entity.Id);
});
}
}

1
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj

@ -22,6 +22,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Orders\src\EasyAbp.EShop.Orders.Domain.Shared\EasyAbp.EShop.Orders.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Products\src\EasyAbp.EShop.Products.Domain.Shared\EasyAbp.EShop.Products.Domain.Shared.csproj" />
</ItemGroup>

1
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs

@ -3,4 +3,5 @@
public static class FlashSaleResultFailedReason
{
public const string InvalidHashToken = "InvalidHashToken";
public const string OrderCanceled = "OrderCanceled";
}

4
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs

@ -49,10 +49,6 @@ public class FlashSaleResult : FullAuditedAggregateRoot<Guid>, IFlashSaleResult,
public void MarkAsFailed([NotNull] string reason)
{
if (Status != FlashSaleResultStatus.Pending)
{
throw new FlashSaleResultStatusNotPendingException(Id);
}
Status = FlashSaleResultStatus.Failed;
Reason = Check.NotNullOrEmpty(reason, nameof(reason));
}

207
plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCanceledEventHandlerTests.cs

@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyAbp.Eshop.Products.Products;
using EasyAbp.EShop.Orders.Orders;
using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NSubstitute;
using Shouldly;
using Volo.Abp.Users;
using Xunit;
namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans;
public class FlashSaleOrderCanceledEventHandlerTests : FlashSalesApplicationTestBase
{
protected FlashSaleOrderCanceledEventHandler ResultMarkAsFailedOrderCanceledEventHandler { get; }
protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; }
protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; }
private ProductDto Product1 { get; set; }
public FlashSaleOrderCanceledEventHandlerTests()
{
ResultMarkAsFailedOrderCanceledEventHandler = GetRequiredService<FlashSaleOrderCanceledEventHandler>();
FlashSaleCurrentResultCache = GetRequiredService<IFlashSaleCurrentResultCache>();
FlashSaleInventoryManager = GetRequiredService<IFlashSaleInventoryManager>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
Product1 = CreateMockProductDto();
var productAppService = Substitute.For<IProductAppService>();
productAppService.GetAsync(FlashSalesTestData.Product1Id).Returns(Task.FromResult(Product1));
services.Replace(ServiceDescriptor.Singleton(productAppService));
var flashSaleInventoryManager = Substitute.For<IFlashSaleInventoryManager>();
services.Replace(ServiceDescriptor.Singleton(flashSaleInventoryManager));
var flashSaleCurrentResultCache = Substitute.For<IFlashSaleCurrentResultCache>();
services.Replace(ServiceDescriptor.Singleton(flashSaleCurrentResultCache));
}
[Fact]
public async Task HandleEventAsync()
{
var flashSaleResult = await CreateFlashSaleResultAsync();
var orderCanceledEto = new OrderCanceledEto(new OrderEto()
{
Id = Guid.NewGuid(),
StoreId = flashSaleResult.StoreId,
OrderLines = new List<OrderLineEto>()
{
new OrderLineEto()
{
ProductId = FlashSalesTestData.Product1Id,
ProductSkuId = FlashSalesTestData.ProductSku1Id
}
}
});
flashSaleResult = await MarkAsSuccessfulAsync(flashSaleResult.Id, orderCanceledEto.Order.Id);
FlashSaleInventoryManager
.TryRollBackInventoryAsync(flashSaleResult.TenantId,
Product1.InventoryProviderName, flashSaleResult.StoreId,
FlashSalesTestData.Product1Id, FlashSalesTestData.ProductSku1Id)
.Returns(Task.FromResult(true));
await ResultMarkAsFailedOrderCanceledEventHandler.HandleEventAsync(orderCanceledEto);
var existFlashSaleResult = await FlashSaleResultRepository.GetAsync(flashSaleResult.Id);
existFlashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Failed);
existFlashSaleResult.Reason.ShouldBe(FlashSaleResultFailedReason.OrderCanceled);
await FlashSaleInventoryManager.Received()
.TryRollBackInventoryAsync(flashSaleResult.TenantId,
Product1.InventoryProviderName, flashSaleResult.StoreId,
FlashSalesTestData.Product1Id, FlashSalesTestData.ProductSku1Id);
await FlashSaleCurrentResultCache.Received()
.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId);
}
[Fact]
public async Task HandleEventAsync_Should_Do_Not_RemoveResultCache_When_TryRollBackInventory_Failed()
{
var flashSaleResult = await CreateFlashSaleResultAsync();
var orderCanceledEto = new OrderCanceledEto(new OrderEto()
{
Id = Guid.NewGuid(),
StoreId = flashSaleResult.StoreId,
OrderLines = new List<OrderLineEto>()
{
new OrderLineEto()
{
ProductId = FlashSalesTestData.Product1Id,
ProductSkuId = FlashSalesTestData.ProductSku1Id
}
}
});
flashSaleResult = await MarkAsSuccessfulAsync(flashSaleResult.Id, orderCanceledEto.Order.Id);
FlashSaleInventoryManager
.TryRollBackInventoryAsync(flashSaleResult.TenantId,
Product1.InventoryProviderName, flashSaleResult.StoreId,
FlashSalesTestData.Product1Id, FlashSalesTestData.ProductSku1Id)
.Returns(Task.FromResult(false));
await ResultMarkAsFailedOrderCanceledEventHandler.HandleEventAsync(orderCanceledEto);
var existFlashSaleResult = await FlashSaleResultRepository.GetAsync(flashSaleResult.Id);
existFlashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Failed);
existFlashSaleResult.Reason.ShouldBe(FlashSaleResultFailedReason.OrderCanceled);
await FlashSaleInventoryManager.Received()
.TryRollBackInventoryAsync(flashSaleResult.TenantId,
Product1.InventoryProviderName, flashSaleResult.StoreId,
FlashSalesTestData.Product1Id, FlashSalesTestData.ProductSku1Id);
await FlashSaleCurrentResultCache.DidNotReceive()
.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId);
}
[Fact]
public async Task HandleEventAsync_Should_Do_Not_Something_When_Result_Not_Exists()
{
var flashSaleResult = await CreateFlashSaleResultAsync();
var orderCanceledEto = new OrderCanceledEto(new OrderEto()
{
Id = Guid.NewGuid(),
StoreId = flashSaleResult.StoreId,
OrderLines = new List<OrderLineEto>()
{
new OrderLineEto()
{
ProductId = FlashSalesTestData.Product1Id,
ProductSkuId = FlashSalesTestData.ProductSku1Id
}
}
});
flashSaleResult = await MarkAsSuccessfulAsync(flashSaleResult.Id, orderCanceledEto.Order.Id);
flashSaleResult = await MarkAsFailedAsync(flashSaleResult.Id, "UT");
FlashSaleInventoryManager
.TryRollBackInventoryAsync(flashSaleResult.TenantId,
Product1.InventoryProviderName, flashSaleResult.StoreId,
FlashSalesTestData.Product1Id, FlashSalesTestData.ProductSku1Id)
.Returns(Task.FromResult(true));
await ResultMarkAsFailedOrderCanceledEventHandler.HandleEventAsync(orderCanceledEto);
var existFlashSaleResult = await FlashSaleResultRepository.GetAsync(flashSaleResult.Id);
existFlashSaleResult.Status.ShouldBe(flashSaleResult.Status);
existFlashSaleResult.Reason.ShouldBe(flashSaleResult.Reason);
await FlashSaleInventoryManager.DidNotReceive()
.TryRollBackInventoryAsync(flashSaleResult.TenantId,
Product1.InventoryProviderName, flashSaleResult.StoreId,
FlashSalesTestData.Product1Id, FlashSalesTestData.ProductSku1Id);
await FlashSaleCurrentResultCache.DidNotReceive()
.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId);
}
protected async Task<FlashSaleResult> MarkAsSuccessfulAsync(Guid resultId, Guid orderId)
{
return await WithUnitOfWorkAsync(async () =>
{
var flashSaleResult = await FlashSaleResultRepository.GetAsync(resultId);
flashSaleResult.MarkAsSuccessful(orderId);
await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true);
return flashSaleResult;
});
}
protected async Task<FlashSaleResult> MarkAsFailedAsync(Guid resultId, string reason)
{
return await WithUnitOfWorkAsync(async () =>
{
var flashSaleResult = await FlashSaleResultRepository.GetAsync(resultId);
flashSaleResult.MarkAsFailed(reason);
await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true);
return flashSaleResult;
});
}
protected async Task<FlashSaleResult> CreateFlashSaleResultAsync()
{
return await WithUnitOfWorkAsync(async () =>
{
var flashSaleResult = new FlashSaleResult(
GuidGenerator.Create(),
null,
FlashSalesTestData.Store1Id,
FlashSalesTestData.Plan1Id,
CurrentUser.GetId(),
DateTime.Now);
await FlashSaleResultRepository.InsertAsync(flashSaleResult, autoSave: true);
return flashSaleResult;
});
}
}

22
plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs

@ -75,26 +75,4 @@ public class FlashSaleResultTests
flashSaleResult.OrderId.ShouldBe(null);
flashSaleResult.Reason.ShouldBe("reason");
}
[Fact]
public void MarkAsFailed_Should_Throw_FlashSaleResultStatusNotPendingException_When_Status_Not_Pending()
{
var flashSaleResult = new FlashSaleResult(
id: Guid.NewGuid(),
tenantId: null,
storeId: Guid.NewGuid(),
planId: Guid.NewGuid(),
userId: Guid.NewGuid(),
DateTime.Now
);
flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending);
flashSaleResult.MarkAsFailed("reason");
Assert.Throws<FlashSaleResultStatusNotPendingException>(() =>
{
flashSaleResult.MarkAsFailed("reason");
});
}
}

Loading…
Cancel
Save