Browse Source

add ordering completed process

pull/2130/head
Emre Pehlivan 1 year ago
parent
commit
1baca5bdec
19 changed files with 266 additions and 15 deletions
  1. +13
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommand.cs
  2. +48
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommandHandler.cs
  3. +5
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs
  4. +29
    -0
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCompletedDomainEventHandler.cs
  5. +15
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToCompletedIntegrationEvent.cs
  6. +5
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs
  7. +11
    -0
      src/Services/Ordering/Ordering.API/Application/Validations/CompleteOrderCommandValidator.cs
  8. +40
    -7
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  9. +3
    -0
      src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs
  10. +14
    -1
      src/Services/Ordering/Ordering.API/GlobalUsings.cs
  11. +1
    -0
      src/Services/Ordering/Ordering.API/Program.cs
  12. +2
    -1
      src/Services/Ordering/Ordering.API/Setup/OrderStatus.csv
  13. +12
    -0
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  14. +1
    -0
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs
  15. +11
    -0
      src/Services/Ordering/Ordering.Domain/Events/OrderCompletedDomainEvent.cs
  16. +8
    -3
      src/Services/Ordering/Ordering.Domain/GlobalUsings.cs
  17. +1
    -0
      src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs
  18. +14
    -0
      src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs
  19. +33
    -2
      src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs

+ 13
- 0
src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommand.cs View File

@ -0,0 +1,13 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
public class CompleteOrderCommand : IRequest<bool>
{
[DataMember]
public int OrderNumber { get; private set; }
public CompleteOrderCommand(int orderNumber)
{
OrderNumber = orderNumber;
}
}

+ 48
- 0
src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommandHandler.cs View File

@ -0,0 +1,48 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
// Regular CommandHandler
public class CompleteOrderCommandHandler : IRequestHandler<CompleteOrderCommand, bool>
{
private readonly IOrderRepository _orderRepository;
public CompleteOrderCommandHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
/// <summary>
/// Handler which processes the command when
/// administrator executes complete order from app
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public async Task<bool> Handle(CompleteOrderCommand command, CancellationToken cancellationToken)
{
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
if (orderToUpdate == null)
{
return false;
}
orderToUpdate.SetCompletedStatus();
return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
}
}
// Use for Idempotency in Command process
public class CompleteOrderIdentifiedCommandHandler : IdentifiedCommandHandler<CompleteOrderCommand, bool>
{
public CompleteOrderIdentifiedCommandHandler(
IMediator mediator,
IRequestManager requestManager,
ILogger<IdentifiedCommandHandler<CompleteOrderCommand, bool>> logger)
: base(mediator, requestManager, logger)
{
}
protected override bool CreateResultForDuplicateRequest()
{
return true; // Ignore duplicate requests for processing order.
}
}

+ 5
- 0
src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs View File

@ -70,6 +70,11 @@ public abstract class IdentifiedCommandHandler<T, R> : IRequestHandler<Identifie
commandId = $"{shipOrderCommand.OrderNumber}"; commandId = $"{shipOrderCommand.OrderNumber}";
break; break;
case CompleteOrderCommand completeOrderCommand:
idProperty = nameof(completeOrderCommand.OrderNumber);
commandId = $"{completeOrderCommand.OrderNumber}";
break;
default: default:
idProperty = "Id?"; idProperty = "Id?";
commandId = "n/a"; commandId = "n/a";


+ 29
- 0
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCompletedDomainEventHandler.cs View File

@ -0,0 +1,29 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
public partial class OrderCompletedDomainEventHandler : INotificationHandler<OrderCompletedDomainEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly IBuyerRepository _buyerRepository;
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
private readonly ILogger _logger;
public OrderCompletedDomainEventHandler(IOrderRepository orderRepository, ILogger<OrderCompletedDomainEventHandler> logger, IBuyerRepository buyerRepository, IOrderingIntegrationEventService orderingIntegrationEventService)
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
_orderingIntegrationEventService = orderingIntegrationEventService;
}
public async Task Handle(OrderCompletedDomainEvent domainEvent, CancellationToken cancellationToken)
{
OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.Order.Id, nameof(OrderStatus.Completed), OrderStatus.Completed.Id);
var order = await _orderRepository.GetAsync(domainEvent.Order.Id);
var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
var integrationEvent = new OrderStatusChangedToCompletedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name);
await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent);
}
}

+ 15
- 0
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToCompletedIntegrationEvent.cs View File

@ -0,0 +1,15 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
public record OrderStatusChangedToCompletedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public string OrderStatus { get; }
public string BuyerName { get; }
public OrderStatusChangedToCompletedIntegrationEvent(int orderId, string orderStatus, string buyerName)
{
OrderId = orderId;
OrderStatus = orderStatus;
BuyerName = buyerName;
}
}

+ 5
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs View File

@ -1,4 +1,8 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents;
public class OrderingIntegrationEventService : IOrderingIntegrationEventService public class OrderingIntegrationEventService : IOrderingIntegrationEventService
{ {


+ 11
- 0
src/Services/Ordering/Ordering.API/Application/Validations/CompleteOrderCommandValidator.cs View File

@ -0,0 +1,11 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Validations;
public class CompleteOrderCommandValidator : AbstractValidator<CompleteOrderCommand>
{
public CompleteOrderCommandValidator(ILogger<CompleteOrderCommandValidator> logger)
{
RuleFor(order => order.OrderNumber).NotEmpty().WithMessage("No orderId found");
logger.LogTrace("INSTANCE CREATED - {ClassName}", GetType().Name);
}
}

+ 40
- 7
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -1,7 +1,9 @@
using CardType = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries.CardType;
using Order = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries.Order;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
[Route("api/v1/[controller]")] [Route("api/v1/[controller]")]
[Authorize] [Authorize]
@ -85,11 +87,42 @@ public class OrdersController : ControllerBase
return Ok(); return Ok();
} }
[Route("complete")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CompleteOrderAsync([FromBody] CompleteOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId)
{
bool commandResult = false;
if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
{
var requestCompleteOrder = new IdentifiedCommand<CompleteOrderCommand, bool>(command, guid);
_logger.LogInformation(
"Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
requestCompleteOrder.GetGenericTypeName(),
nameof(requestCompleteOrder.Command.OrderNumber),
requestCompleteOrder.Command.OrderNumber,
requestCompleteOrder);
commandResult = await _mediator.Send(requestCompleteOrder);
}
if (!commandResult)
{
return BadRequest();
}
return Ok();
}
[Route("{orderId:int}")] [Route("{orderId:int}")]
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(Order), StatusCodes.Status200OK)] [ProducesResponseType(typeof(Order), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<Order>> GetOrderAsync(int orderId)
public async Task<ActionResult> GetOrderAsync(int orderId)
{ {
try try
{ {
@ -97,7 +130,7 @@ public class OrdersController : ControllerBase
//var order customer = await _mediator.Send(new GetOrderByIdQuery(orderId)); //var order customer = await _mediator.Send(new GetOrderByIdQuery(orderId));
var order = await _orderQueries.GetOrderAsync(orderId); var order = await _orderQueries.GetOrderAsync(orderId);
return order;
return Ok(order);
} }
catch catch
{ {
@ -106,7 +139,7 @@ public class OrdersController : ControllerBase
} }
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(IEnumerable<OrderSummary>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(IEnumerable<OrderSummary>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<OrderSummary>>> GetOrdersAsync() public async Task<ActionResult<IEnumerable<OrderSummary>>> GetOrdersAsync()
{ {
var userid = _identityService.GetUserIdentity(); var userid = _identityService.GetUserIdentity();
@ -117,7 +150,7 @@ public class OrdersController : ControllerBase
[Route("cardtypes")] [Route("cardtypes")]
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(IEnumerable<CardType>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(IEnumerable<CardType>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<CardType>>> GetCardTypesAsync() public async Task<ActionResult<IEnumerable<CardType>>> GetCardTypesAsync()
{ {
var cardTypes = await _orderQueries.GetCardTypesAsync(); var cardTypes = await _orderQueries.GetCardTypesAsync();


+ 3
- 0
src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs View File

@ -1,5 +1,8 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Extensions; namespace Microsoft.eShopOnContainers.Services.Ordering.API.Extensions;
using System.Collections.Generic;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models;
public static class BasketItemExtensions public static class BasketItemExtensions
{ {
public static IEnumerable<OrderItemDTO> ToOrderItemsDTO(this IEnumerable<BasketItem> basketItems) public static IEnumerable<OrderItemDTO> ToOrderItemsDTO(this IEnumerable<BasketItem> basketItems)


+ 14
- 1
src/Services/Ordering/Ordering.API/GlobalUsings.cs View File

@ -1,6 +1,13 @@
global using System.Data.Common;
global using System;
global using System.Collections.Generic;
global using System.Data.Common;
global using System.Data.SqlClient; global using System.Data.SqlClient;
global using System.IO;
global using System.Linq;
global using System.Net;
global using System.Runtime.Serialization; global using System.Runtime.Serialization;
global using System.Threading;
global using System.Threading.Tasks;
global using Azure.Identity; global using Azure.Identity;
global using Dapper; global using Dapper;
global using FluentValidation; global using FluentValidation;
@ -8,6 +15,9 @@ global using Google.Protobuf.Collections;
global using Grpc.Core; global using Grpc.Core;
global using MediatR; global using MediatR;
global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Mvc; global using Microsoft.AspNetCore.Mvc;
global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore;
global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.EntityFrameworkCore.Design;
@ -36,6 +46,9 @@ global using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories; global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Options;
global using Polly; global using Polly;
global using Polly.Retry; global using Polly.Retry;


+ 1
- 0
src/Services/Ordering/Ordering.API/Program.cs View File

@ -26,6 +26,7 @@ services.AddSingleton<IValidator<CancelOrderCommand>, CancelOrderCommandValidato
services.AddSingleton<IValidator<CreateOrderCommand>, CreateOrderCommandValidator>(); services.AddSingleton<IValidator<CreateOrderCommand>, CreateOrderCommandValidator>();
services.AddSingleton<IValidator<IdentifiedCommand<CreateOrderCommand, bool>>, IdentifiedCommandValidator>(); services.AddSingleton<IValidator<IdentifiedCommand<CreateOrderCommand, bool>>, IdentifiedCommandValidator>();
services.AddSingleton<IValidator<ShipOrderCommand>, ShipOrderCommandValidator>(); services.AddSingleton<IValidator<ShipOrderCommand>, ShipOrderCommandValidator>();
services.AddSingleton<IValidator<CompleteOrderCommand>, CompleteOrderCommandValidator>();
services.AddScoped<IOrderQueries>(sp => new OrderQueries(builder.Configuration.GetConnectionString("OrderingDB"))); services.AddScoped<IOrderQueries>(sp => new OrderQueries(builder.Configuration.GetConnectionString("OrderingDB")));
services.AddScoped<IBuyerRepository, BuyerRepository>(); services.AddScoped<IBuyerRepository, BuyerRepository>();


+ 2
- 1
src/Services/Ordering/Ordering.API/Setup/OrderStatus.csv View File

@ -4,4 +4,5 @@ AwaitingValidation
StockConfirmed StockConfirmed
Paid Paid
Shipped Shipped
Cancelled
Cancelled
Completed

+ 12
- 0
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -156,6 +156,18 @@ public class Order
AddDomainEvent(new OrderCancelledDomainEvent(this)); AddDomainEvent(new OrderCancelledDomainEvent(this));
} }
public void SetCompletedStatus()
{
if (_orderStatusId != OrderStatus.Paid.Id)
{
StatusChangeException(OrderStatus.Completed);
}
_orderStatusId = OrderStatus.Completed.Id;
_description = "The order was completed.";
AddDomainEvent(new OrderCompletedDomainEvent(this));
}
public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems) public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems)
{ {
if (_orderStatusId == OrderStatus.AwaitingValidation.Id) if (_orderStatusId == OrderStatus.AwaitingValidation.Id)


+ 1
- 0
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs View File

@ -11,6 +11,7 @@ public class OrderStatus
public static OrderStatus Paid = new OrderStatus(4, nameof(Paid).ToLowerInvariant()); public static OrderStatus Paid = new OrderStatus(4, nameof(Paid).ToLowerInvariant());
public static OrderStatus Shipped = new OrderStatus(5, nameof(Shipped).ToLowerInvariant()); public static OrderStatus Shipped = new OrderStatus(5, nameof(Shipped).ToLowerInvariant());
public static OrderStatus Cancelled = new OrderStatus(6, nameof(Cancelled).ToLowerInvariant()); public static OrderStatus Cancelled = new OrderStatus(6, nameof(Cancelled).ToLowerInvariant());
public static OrderStatus Completed = new OrderStatus(7, nameof(Completed).ToLowerInvariant());
public OrderStatus(int id, string name) public OrderStatus(int id, string name)
: base(id, name) : base(id, name)


+ 11
- 0
src/Services/Ordering/Ordering.Domain/Events/OrderCompletedDomainEvent.cs View File

@ -0,0 +1,11 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Events;
public class OrderCompletedDomainEvent : INotification
{
public Order Order { get; }
public OrderCompletedDomainEvent(Order order)
{
Order = order;
}
}

+ 8
- 3
src/Services/Ordering/Ordering.Domain/GlobalUsings.cs View File

@ -1,7 +1,12 @@
global using System.Reflection;
global using global::Microsoft.eShopOnContainers.Services.Ordering.Domain.Exceptions;
global using global::Microsoft.eShopOnContainers.Services.Ordering.Domain.Exceptions;
global using MediatR; global using MediatR;
global using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
global using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
global using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
global using Microsoft.eShopOnContainers.Services.Ordering.Domain.Events; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.Events;
global using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
global using System.Collections.Generic;
global using System.Linq;
global using System.Reflection;
global using System.Threading.Tasks;
global using System.Threading;
global using System;

+ 1
- 0
src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs View File

@ -50,6 +50,7 @@ public class OrderingScenarioBase
{ {
public static string CancelOrder = "api/v1/orders/cancel"; public static string CancelOrder = "api/v1/orders/cancel";
public static string ShipOrder = "api/v1/orders/ship"; public static string ShipOrder = "api/v1/orders/ship";
public static string CompleteOrder = "api/v1/orders/complete";
} }
private class AuthStartupFilter : IStartupFilter private class AuthStartupFilter : IStartupFilter


+ 14
- 0
src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs View File

@ -48,6 +48,20 @@ namespace Ordering.FunctionalTests
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
} }
[Fact]
public async Task Complete_order_no_order_created_bad_request_response()
{
using var server = CreateServer();
var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json")
{
Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
};
var response = await server.CreateClient()
.PutAsync(Put.CompleteOrder, content);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
string BuildOrder() string BuildOrder()
{ {
var order = new var order = new


+ 33
- 2
src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs View File

@ -79,6 +79,37 @@ public class OrdersWebApiTest
Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode); Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode);
} }
[Fact]
public async Task Complete_order_with_requestId_success()
{
//Arrange
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CompleteOrderCommand, bool>>(), default))
.Returns(Task.FromResult(true));
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object);
var actionResult = await orderController.CompleteOrderAsync(new CompleteOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
//Assert
Assert.Equal((int)System.Net.HttpStatusCode.OK, actionResult.StatusCode);
}
[Fact]
public async Task Complete_order_bad_request()
{
//Arrange
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CreateOrderCommand, bool>>(), default))
.Returns(Task.FromResult(true));
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object);
var actionResult = await orderController.CompleteOrderAsync(new CompleteOrderCommand(1), string.Empty) as BadRequestResult;
//Assert
Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode);
}
[Fact] [Fact]
public async Task Get_orders_success() public async Task Get_orders_success()
{ {
@ -110,10 +141,10 @@ public class OrdersWebApiTest
//Act //Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object); var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object);
var actionResult = await orderController.GetOrderAsync(fakeOrderId);
var actionResult = await orderController.GetOrderAsync(fakeOrderId) as OkObjectResult;
//Assert //Assert
Assert.Same(actionResult.Value, fakeDynamicResult);
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
} }
[Fact] [Fact]


Loading…
Cancel
Save