@ -40,22 +40,27 @@ namespace EasyAbp.EShop.Payments.Refunds
{
{
var paymentType = typeof ( Payment ) ;
var paymentType = typeof ( Payment ) ;
var paymentItemType = typeof ( PaymentItem ) ;
var paymentItemType = typeof ( PaymentItem ) ;
var paymentItem = Activator . CreateInstance ( paymentItemType , true ) as PaymentItem ;
var paymentItem = Activator . CreateInstance ( paymentItemType , true ) as PaymentItem ;
paymentItem . ShouldNotBeNull ( ) ;
paymentItem . ShouldNotBeNull ( ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . Id ) ) ? . SetValue ( paymentItem , PaymentsTestData . PaymentItem1 ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . Id ) )
paymentItemType . GetProperty ( nameof ( PaymentItem . ActualPaymentAmount ) ) ? . SetValue ( paymentItem , 1 m ) ;
? . SetValue ( paymentItem , PaymentsTestData . PaymentItem1 ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . ItemType ) ) ? . SetValue ( paymentItem , PaymentsConsts . PaymentItemType ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . ActualPaymentAmount ) ) ? . SetValue ( paymentItem , 5 m ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . ItemKey ) ) ? . SetValue ( paymentItem , PaymentsTestData . Order1 . ToString ( ) ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . ItemType ) )
paymentItemType . GetProperty ( nameof ( PaymentItem . StoreId ) ) ? . SetValue ( paymentItem , PaymentsTestData . Store1 ) ;
? . SetValue ( paymentItem , PaymentsConsts . PaymentItemType ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . ItemKey ) )
? . SetValue ( paymentItem , PaymentsTestData . Order1 . ToString ( ) ) ;
paymentItemType . GetProperty ( nameof ( PaymentItem . StoreId ) )
? . SetValue ( paymentItem , PaymentsTestData . Store1 ) ;
// paymentItem.ExtraProperties.Add(nameof(paymentItem.StoreId), PaymentsTestData.Store1);
// paymentItem.ExtraProperties.Add(nameof(paymentItem.StoreId), PaymentsTestData.Store1);
var payment = Activator . CreateInstance ( paymentType , true ) as Payment ;
var payment = Activator . CreateInstance ( paymentType , true ) as Payment ;
payment . ShouldNotBeNull ( ) ;
payment . ShouldNotBeNull ( ) ;
paymentType . GetProperty ( nameof ( Payment . Id ) ) ? . SetValue ( payment , PaymentsTestData . Payment1 ) ;
paymentType . GetProperty ( nameof ( Payment . Id ) ) ? . SetValue ( payment , PaymentsTestData . Payment1 ) ;
paymentType . GetProperty ( nameof ( Payment . Currency ) ) ? . SetValue ( payment , "USD" ) ;
paymentType . GetProperty ( nameof ( Payment . Currency ) ) ? . SetValue ( payment , "USD" ) ;
paymentType . GetProperty ( nameof ( Payment . ActualPaymentAmount ) ) ? . SetValue ( payment , 1 m ) ;
paymentType . GetProperty ( nameof ( Payment . ActualPaymentAmount ) ) ? . SetValue ( payment , 5 m ) ;
paymentType . GetProperty ( nameof ( Payment . PaymentItems ) ) ? . SetValue ( payment , new List < PaymentItem > { paymentItem } ) ;
paymentType . GetProperty ( nameof ( Payment . PaymentItems ) )
? . SetValue ( payment , new List < PaymentItem > { paymentItem } ) ;
return payment ;
return payment ;
} ;
} ;
@ -95,13 +100,13 @@ namespace EasyAbp.EShop.Payments.Refunds
paymentRepository . GetAsync ( PaymentsTestData . Payment1 ) . Returns ( payment1Returns ) ;
paymentRepository . GetAsync ( PaymentsTestData . Payment1 ) . Returns ( payment1Returns ) ;
paymentRepository . FindAsync ( PaymentsTestData . Payment1 ) . Returns ( payment1Returns ) ;
paymentRepository . FindAsync ( PaymentsTestData . Payment1 ) . Returns ( payment1Returns ) ;
paymentRepository . GetAsync ( PaymentsTestData . Payment2 ) . Returns ( payment2Returns ) ;
paymentRepository . GetAsync ( PaymentsTestData . Payment2 ) . Returns ( payment2Returns ) ;
paymentRepository . FindAsync ( PaymentsTestData . Payment2 ) . Returns ( payment2Returns ) ;
paymentRepository . FindAsync ( PaymentsTestData . Payment2 ) . Returns ( payment2Returns ) ;
services . AddTransient ( _ = > paymentRepository ) ;
services . AddTransient ( _ = > paymentRepository ) ;
}
}
private void MockOrderService ( IServiceCollection services )
private void MockOrderService ( IServiceCollection services )
{
{
var orderService = Substitute . For < IOrderAppService > ( ) ;
var orderService = Substitute . For < IOrderAppService > ( ) ;
@ -109,7 +114,8 @@ namespace EasyAbp.EShop.Payments.Refunds
{
{
Id = PaymentsTestData . Order1 ,
Id = PaymentsTestData . Order1 ,
Currency = "USD" ,
Currency = "USD" ,
ActualTotalPrice = 0 ,
ActualTotalPrice = 6 m ,
PaymentAmount = 5 m ,
StoreId = PaymentsTestData . Store1 ,
StoreId = PaymentsTestData . Store1 ,
OrderLines = new List < OrderLineDto >
OrderLines = new List < OrderLineDto >
{
{
@ -118,6 +124,7 @@ namespace EasyAbp.EShop.Payments.Refunds
Id = PaymentsTestData . OrderLine1 ,
Id = PaymentsTestData . OrderLine1 ,
Currency = "USD" ,
Currency = "USD" ,
ActualTotalPrice = 1 m ,
ActualTotalPrice = 1 m ,
PaymentAmount = 0.83 m ,
Quantity = 1
Quantity = 1
}
}
} ,
} ,
@ -127,15 +134,17 @@ namespace EasyAbp.EShop.Payments.Refunds
{
{
Name = "Name" ,
Name = "Name" ,
Key = "Key" ,
Key = "Key" ,
Fee = 5 m
DisplayName = "DisplayName" ,
Fee = 5 m ,
PaymentAmount = 4.17 m
}
}
} ,
} ,
PaymentId = PaymentsTestData . Payment1
PaymentId = PaymentsTestData . Payment1
} ) ) ;
} ) ) ;
services . AddTransient ( _ = > orderService ) ;
services . AddTransient ( _ = > orderService ) ;
}
}
public RefundAppServiceTests ( )
public RefundAppServiceTests ( )
{
{
_ jsonSerializer = GetRequiredService < IJsonSerializer > ( ) ;
_ jsonSerializer = GetRequiredService < IJsonSerializer > ( ) ;
@ -176,6 +185,7 @@ namespace EasyAbp.EShop.Payments.Refunds
{
{
Name = "Name" ,
Name = "Name" ,
Key = "Key" ,
Key = "Key" ,
DisplayName = "DisplayName" ,
TotalAmount = 0.6 m
TotalAmount = 0.6 m
}
}
}
}
@ -190,7 +200,7 @@ namespace EasyAbp.EShop.Payments.Refunds
TestRefundPaymentEventHandler . LastEto = null ;
TestRefundPaymentEventHandler . LastEto = null ;
eventData . ShouldNotBeNull ( ) ;
eventData . ShouldNotBeNull ( ) ;
eventData . CreateRefundInput . RefundItems . Count . ShouldBe ( 1 ) ;
eventData . CreateRefundInput . RefundItems . Count . ShouldBe ( 1 ) ;
var refundItem = eventData . CreateRefundInput . RefundItems [ 0 ] ;
var refundItem = eventData . CreateRefundInput . RefundItems [ 0 ] ;
refundItem . GetProperty < Guid ? > ( nameof ( RefundItem . OrderId ) ) . ShouldBe ( PaymentsTestData . Order1 ) ;
refundItem . GetProperty < Guid ? > ( nameof ( RefundItem . OrderId ) ) . ShouldBe ( PaymentsTestData . Order1 ) ;
@ -202,14 +212,15 @@ namespace EasyAbp.EShop.Payments.Refunds
orderLines [ 0 ] . OrderLineId . ShouldBe ( PaymentsTestData . OrderLine1 ) ;
orderLines [ 0 ] . OrderLineId . ShouldBe ( PaymentsTestData . OrderLine1 ) ;
orderLines [ 0 ] . Quantity . ShouldBe ( 1 ) ;
orderLines [ 0 ] . Quantity . ShouldBe ( 1 ) ;
orderLines [ 0 ] . TotalAmount . ShouldBe ( 0.4 m ) ;
orderLines [ 0 ] . TotalAmount . ShouldBe ( 0.4 m ) ;
var orderExtraFees =
var orderExtraFees =
_ jsonSerializer . Deserialize < List < OrderExtraFeeRefundInfoModel > > (
_ jsonSerializer . Deserialize < List < OrderExtraFeeRefundInfoModel > > (
refundItem . GetProperty < string > ( nameof ( RefundItem . OrderExtraFees ) ) ) ;
refundItem . GetProperty < string > ( nameof ( RefundItem . OrderExtraFees ) ) ) ;
orderExtraFees . Count . ShouldBe ( 1 ) ;
orderExtraFees . Count . ShouldBe ( 1 ) ;
orderExtraFees [ 0 ] . Name . ShouldBe ( "Name" ) ;
orderExtraFees [ 0 ] . Name . ShouldBe ( "Name" ) ;
orderExtraFees [ 0 ] . Key . ShouldBe ( "Key" ) ;
orderExtraFees [ 0 ] . Key . ShouldBe ( "Key" ) ;
orderExtraFees [ 0 ] . DisplayName . ShouldBe ( "DisplayName" ) ;
orderExtraFees [ 0 ] . TotalAmount . ShouldBe ( 0.6 m ) ;
orderExtraFees [ 0 ] . TotalAmount . ShouldBe ( 0.6 m ) ;
}
}
@ -230,24 +241,25 @@ namespace EasyAbp.EShop.Payments.Refunds
CustomerRemark = "CustomerRemark" ,
CustomerRemark = "CustomerRemark" ,
OrderId = PaymentsTestData . Order1 ,
OrderId = PaymentsTestData . Order1 ,
StaffRemark = "StaffRemark" ,
StaffRemark = "StaffRemark" ,
OrderLines = new List < OrderLineRefundInfoModel > ( ) , // empty
OrderLines = new List < OrderLineRefundInfoModel > ( ) , // empty
OrderExtraFees = new List < OrderExtraFeeRefundInfoModel > ( ) // empty
OrderExtraFees = new List < OrderExtraFeeRefundInfoModel > ( ) // empty
}
}
}
}
} ;
} ;
// Act & Assert
// Act & Assert
await Should . ThrowAsync < AbpValidationException > ( async ( ) = >
( await Should . ThrowAsync < AbpValidationException > ( async ( ) = >
{
{
await _ refundAppService . CreateAsync ( request ) ;
await _ refundAppService . CreateAsync ( request ) ;
} , "RefundItem.OrderLines and RefundItem.OrderExtraFees should not both be empty!" ) ;
} ) ) . ValidationErrors [ 0 ] . ErrorMessage
. ShouldBe ( "RefundItem.OrderLines and RefundItem.OrderExtraFees should not both be empty!" ) ;
}
}
[Fact]
[Fact]
public async Task Should_Avoid_Over_Refund ( )
public async Task Should_Avoid_Over_Amount_ Refund ( )
{
{
// Arrange
// Arrange
var request = new CreateEShopRefundInput
var request1 = new CreateEShopRefundInput
{
{
DisplayReason = "Reason" ,
DisplayReason = "Reason" ,
CustomerRemark = "Customer Remark" ,
CustomerRemark = "Customer Remark" ,
@ -266,16 +278,108 @@ namespace EasyAbp.EShop.Payments.Refunds
{
{
OrderLineId = PaymentsTestData . OrderLine1 ,
OrderLineId = PaymentsTestData . OrderLine1 ,
Quantity = 1 ,
Quantity = 1 ,
TotalAmount = 1 m
TotalAmount = 0.84 m // 0.84m > 0.83m
}
}
} ,
}
}
}
} ;
// Arrange
var request2 = new CreateEShopRefundInput
{
DisplayReason = "Reason" ,
CustomerRemark = "Customer Remark" ,
PaymentId = PaymentsTestData . Payment1 ,
StaffRemark = "StaffRemark" ,
RefundItems = new List < CreateEShopRefundItemInput >
{
new ( )
{
CustomerRemark = "CustomerRemark" ,
OrderId = PaymentsTestData . Order1 ,
StaffRemark = "StaffRemark" ,
OrderExtraFees = new List < OrderExtraFeeRefundInfoModel >
OrderExtraFees = new List < OrderExtraFeeRefundInfoModel >
{
{
new ( )
new ( )
{
{
Name = "Name" ,
Name = "Name" ,
Key = "Key" ,
Key = "Key" ,
TotalAmount = 0.1 m
DisplayName = "DisplayName" ,
TotalAmount = 4.18 m // 4.18m > 4.17m
}
}
}
}
} ;
var request3 = new CreateEShopRefundInput
{
DisplayReason = "Reason" ,
CustomerRemark = "Customer Remark" ,
PaymentId = PaymentsTestData . Payment1 ,
StaffRemark = "StaffRemark" ,
RefundItems = new List < CreateEShopRefundItemInput >
{
new ( )
{
CustomerRemark = "CustomerRemark" ,
OrderId = PaymentsTestData . Order1 ,
StaffRemark = "StaffRemark" ,
OrderLines = new List < OrderLineRefundInfoModel >
{
new ( )
{
OrderLineId = PaymentsTestData . OrderLine1 ,
Quantity = 1 ,
TotalAmount = 1 0 0 m // 100m >>> 5m (the order payment amount)
}
}
}
}
} ;
// Act & Assert
await Should . ThrowAsync < InvalidOrderLineRefundAmountException > ( async ( ) = >
{
await _ refundAppService . CreateAsync ( request1 ) ;
} ) ;
await Should . ThrowAsync < InvalidOrderExtraFeeRefundAmountException > ( async ( ) = >
{
await _ refundAppService . CreateAsync ( request2 ) ;
} ) ;
await Should . ThrowAsync < InvalidOrderRefundAmountException > ( async ( ) = >
{
await _ refundAppService . CreateAsync ( request3 ) ;
} ) ;
}
[Fact]
public async Task Should_Avoid_Over_Quantity_Refund ( )
{
// Arrange
var request = new CreateEShopRefundInput
{
DisplayReason = "Reason" ,
CustomerRemark = "Customer Remark" ,
PaymentId = PaymentsTestData . Payment1 ,
StaffRemark = "StaffRemark" ,
RefundItems = new List < CreateEShopRefundItemInput >
{
new ( )
{
CustomerRemark = "CustomerRemark" ,
OrderId = PaymentsTestData . Order1 ,
StaffRemark = "StaffRemark" ,
OrderLines = new List < OrderLineRefundInfoModel >
{
new ( )
{
OrderLineId = PaymentsTestData . OrderLine1 ,
Quantity = 2 , // 2 > 1
TotalAmount = 0.83 m
}
}
}
}
}
}
@ -283,7 +387,7 @@ namespace EasyAbp.EShop.Payments.Refunds
} ;
} ;
// Act & Assert
// Act & Assert
await Should . ThrowAsync < InvalidRefundAmount Exception > ( async ( ) = >
await Should . ThrowAsync < InvalidRefundQuantity Exception > ( async ( ) = >
{
{
await _ refundAppService . CreateAsync ( request ) ;
await _ refundAppService . CreateAsync ( request ) ;
} ) ;
} ) ;
@ -308,7 +412,7 @@ namespace EasyAbp.EShop.Payments.Refunds
StaffRemark = "StaffRemark" ,
StaffRemark = "StaffRemark" ,
OrderLines = new List < OrderLineRefundInfoModel >
OrderLines = new List < OrderLineRefundInfoModel >
{
{
new OrderLineRefundInfoModel
new ( )
{
{
OrderLineId = PaymentsTestData . OrderLine1 ,
OrderLineId = PaymentsTestData . OrderLine1 ,
Quantity = 1 ,
Quantity = 1 ,
@ -327,7 +431,7 @@ namespace EasyAbp.EShop.Payments.Refunds
}
}
[Fact]
[Fact]
public async Task Should_Check_OrderLines_Exist_When_Refunding ( )
public Task Should_Check_OrderLines_Exist_When_Refunding ( )
{
{
// Arrange
// Arrange
var request = new CreateEShopRefundInput
var request = new CreateEShopRefundInput
@ -355,6 +459,8 @@ namespace EasyAbp.EShop.Payments.Refunds
}
}
}
}
} ;
} ;
return Task . CompletedTask ;
}
}
[Fact]
[Fact]
@ -380,6 +486,7 @@ namespace EasyAbp.EShop.Payments.Refunds
{
{
Name = "FakeName" ,
Name = "FakeName" ,
Key = "FakeKey" ,
Key = "FakeKey" ,
DisplayName = "FakeDisplayName" ,
TotalAmount = 0.6 m
TotalAmount = 0.6 m
}
}
}
}
@ -393,7 +500,7 @@ namespace EasyAbp.EShop.Payments.Refunds
await _ refundAppService . CreateAsync ( request ) ;
await _ refundAppService . CreateAsync ( request ) ;
} ) ;
} ) ;
}
}
[Fact]
[Fact]
public async Task Should_Avoid_Non_Positive_Refund_Amount ( )
public async Task Should_Avoid_Non_Positive_Refund_Amount ( )
{
{
@ -413,7 +520,7 @@ namespace EasyAbp.EShop.Payments.Refunds
StaffRemark = "StaffRemark" ,
StaffRemark = "StaffRemark" ,
OrderLines = new List < OrderLineRefundInfoModel >
OrderLines = new List < OrderLineRefundInfoModel >
{
{
new OrderLineRefundInfoModel
new ( )
{
{
OrderLineId = PaymentsTestData . OrderLine1 ,
OrderLineId = PaymentsTestData . OrderLine1 ,
Quantity = 1 ,
Quantity = 1 ,
@ -425,10 +532,10 @@ namespace EasyAbp.EShop.Payments.Refunds
} ;
} ;
// Act & Assert
// Act & Assert
await Should . ThrowAsync < AbpValidationException > ( async ( ) = >
( await Should . ThrowAsync < AbpValidationException > ( async ( ) = >
{
{
await _ refundAppService . CreateAsync ( request ) ;
await _ refundAppService . CreateAsync ( request ) ;
} , "RefundAmount should be greater than 0." ) ;
} ) ) . ValidationErrors [ 0 ] . ErrorMessage . ShouldBe ( "RefundAmount should be greater than 0." ) ;
}
}
[Fact]
[Fact]
@ -447,27 +554,30 @@ namespace EasyAbp.EShop.Payments.Refunds
} ;
} ;
var now = DateTime . Now ;
var now = DateTime . Now ;
refundItem . SetProperty ( nameof ( RefundItem . StoreId ) , PaymentsTestData . Store1 ) ;
refundItem . SetProperty ( nameof ( RefundItem . StoreId ) , PaymentsTestData . Store1 ) ;
refundItem . SetProperty ( nameof ( RefundItem . OrderId ) , PaymentsTestData . Order1 ) ;
refundItem . SetProperty ( nameof ( RefundItem . OrderId ) , PaymentsTestData . Order1 ) ;
refundItem . SetProperty ( nameof ( RefundItem . OrderLines ) , _ jsonSerializer . Serialize ( new List < OrderLineRefundInfoModel >
refundItem . SetProperty ( nameof ( RefundItem . OrderLines ) , _ jsonSerializer . Serialize (
{
new List < OrderLineRefundInfoModel >
new ( )
{
{
OrderLineId = PaymentsTestData . OrderLine1 ,
new ( )
Quantity = 2 ,
{
TotalAmount = 1 m
OrderLineId = PaymentsTestData . OrderLine1 ,
}
Quantity = 2 ,
} ) ) ;
TotalAmount = 1 m
refundItem . SetProperty ( nameof ( RefundItem . OrderExtraFees ) , _ jsonSerializer . Serialize ( new List < OrderExtraFeeRefundInfoModel >
}
{
} ) ) ;
new ( )
refundItem . SetProperty ( nameof ( RefundItem . OrderExtraFees ) , _ jsonSerializer . Serialize (
new List < OrderExtraFeeRefundInfoModel >
{
{
Name = "Name" ,
new ( )
Key = "Key" ,
{
TotalAmount = 0.5 m
Name = "Name" ,
}
Key = "Key" ,
} ) ) ;
DisplayName = "DisplayName" ,
TotalAmount = 0.5 m
}
} ) ) ;
await synchronizer . HandleEventAsync ( new EntityCreatedEto < RefundEto > ( new RefundEto
await synchronizer . HandleEventAsync ( new EntityCreatedEto < RefundEto > ( new RefundEto
{
{
@ -487,7 +597,7 @@ namespace EasyAbp.EShop.Payments.Refunds
} ) ) ;
} ) ) ;
var refundDto = await _ refundAppService . GetAsync ( PaymentsTestData . Refund1 ) ;
var refundDto = await _ refundAppService . GetAsync ( PaymentsTestData . Refund1 ) ;
refundDto . PaymentId . ShouldBe ( PaymentsTestData . Payment1 ) ;
refundDto . PaymentId . ShouldBe ( PaymentsTestData . Payment1 ) ;
refundDto . ExternalTradingCode . ShouldBe ( "testcode" ) ;
refundDto . ExternalTradingCode . ShouldBe ( "testcode" ) ;
refundDto . Currency . ShouldBe ( "USD" ) ;
refundDto . Currency . ShouldBe ( "USD" ) ;
@ -517,7 +627,8 @@ namespace EasyAbp.EShop.Payments.Refunds
var orderExtraFee = refundItemDto . OrderExtraFees . First ( ) ;
var orderExtraFee = refundItemDto . OrderExtraFees . First ( ) ;
orderExtraFee . Name . ShouldBe ( "Name" ) ;
orderExtraFee . Name . ShouldBe ( "Name" ) ;
orderExtraFee . Key . ShouldBe ( "Key" ) ;
orderExtraFee . Key . ShouldBe ( "Key" ) ;
orderExtraFee . DisplayName . ShouldBe ( "DisplayName" ) ;
orderExtraFee . RefundAmount . ShouldBe ( 0.5 m ) ;
orderExtraFee . RefundAmount . ShouldBe ( 0.5 m ) ;
}
}
}
}
}
}