AddNewOrder in Ordering.FunctionalTests is not properly tested
- Dominant language
- C#
- Stars
- 10.9k
- Forks
- 3.8k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 4
Description
`eshop.Ordering.FunctionalTests.OrderingApiTests.AddNewOrder` in the `Ordering.FunctionalTest` project cannot be considered properly tested for the following reasons.
### 1. Parameters that cause validation errors are being passed
The `POST api/orders` API receives a `CreateOrderRequest`.
An instance of this class is converted into `IdentifiedCommand` and passed to `mediator.Send`.
However, due to `eShop.Ordering.API.Application.Validations.CreateOrderCommandValidator`, a validation error occurs when the command is sent.
Because of the following code in `IdentifiedCommandHandler`, validation errors for `CreateOrderCommand` are caught by exception handling, and the return value of the `Handle` method becomes `false` (since the method returns `default` for a `bool` return type).
https://github.com/dotnet/eShop/blob/b832741187b7a1d6c993d5a0321a622d31e75203/src/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs#L87
```cs
var result = await _mediator.Send(command, cancellationToken);
_logger.LogInformation(
"Command result: {@Result} - {CommandName} - {IdProperty}: {CommandId} ({@Command})",
result,
commandName,
idProperty,
commandId,
command);
return result;
}
catch
{
return default;
}
```
As a result, even when `mediator.Send` returns `false`, the `POST api/orders` API still returns `200 OK`, causing the test to pass incorrectly.
```cs
var result = await services.Mediator.Send(requestCreateOrder);
if (result)
{
services.Logger.LogInformation("CreateOrderCommand succeeded - RequestId: {RequestId}", requestId);
}
else
{
services.Logger.LogWarning("CreateOrderCommand failed - RequestId: {RequestId}", requestId);
}
return TypedResults.Ok();
```
---
### 2. A `Microsoft.EntityFrameworkCore.DbUpdateException` occurs because `cardExpirationDate.Kind` is `Kind.Local`
(This issue may be environment-dependent.)
If issue 1 is fixed so that validation succeeds, `AddNewOrder` fails due to an exception.
```cs
var cardExpirationDate = Convert.ToDateTime("2123-12-22T12:34:24.334Z");
var OrderRequest = new CreateOrderRequest(
UserId: "1",
UserName: "TestUser",
City: "test city",
Street: "test street",
State: "test state",
Country: "test country",
ZipCode: "00001",
CardNumber: "XXXXXXXXXXXX0005",
CardHolderName: "Test User",
CardExpiration: cardExpirationDate,
CardSecurityNumber: "000",
CardTypeId: 1,
Buyer: "TestBuyer",
Items: new List { item });
```
When writing `DateTime` values to PostgreSQL, the `Kind` must be `Kind.Utc`.
However, since `cardExpirationDate` is initialized as shown above, its `Kind` becomes `Kind.Local`, which is presumed to be the cause of the exception.
If the code is changed as follows, the exception does not occur:
```cs
var cardExpirationDate = DateTime.Parse(
"2123-12-22T12:34:24Z",
null,
System.Globalization.DateTimeStyles.AdjustToUniversal);
```
---
### 3. `IntegrationEventLogService` fails to deserialize `EventLogEntry` when publishing `OrderStartedIntegrationEvent`
After fixing issue 2, another issue arises.
This may be better handled as a separate issue.
Because derived classes of `IntegrationEvent` are not included in the FunctionalTest assembly, the following code in
`eshop.IntegrationEventLogEF.Services.IntegrationEventLogService` results in an empty array:
https://github.com/dotnet/eShop/blob/b832741187b7a1d6c993d5a0321a622d31e75203/src/IntegrationEventLogEF/Services/IntegrationEventLogService.cs#L13
````cs
// In FunctionalTests, the Entry Assembly is the DLL built from the test project.
// Derived IntegrationEvent classes do not exist there.
_eventTypes = Assembly.Load(Assembly.GetEntryAssembly().FullName)
.GetTypes()
.Where(t => t.Name.EndsWith(nameof(IntegrationEvent)))
.ToArray();
````
Since `_eventTypes` is an empty array, `RetrieveEventLogsPendingToPublishAsync` in the same class fails at the following code:
https://github.com/dotnet/eShop/blob/b832741187b7a1d6c993d5a0321a622d31e75203/src/IntegrationEventLogEF/Services/IntegrationEventLogService.cs#L28
````cs
// Since _eventTypes is empty, a NullReferenceException occurs
return result.OrderBy(o => o.CreationTime)
.Select(e => e.DeserializeJsonContent(
_eventTypes.FirstOrDefault(t => t.Name == e.EventTypeShortName)));
````
I checked other tests but could not find any others that publish `IntegrationEvent`s.
Therefore, it is fair to say that tests involving the publication of integration events are not properly covered by FunctionalTests.
Contributor guide
Assessment
This issue has not been assessed yet.