dotnet / dotnet/eShop

AddNewOrder in Ordering.FunctionalTests is not properly tested

Open
#943 1 comment 1 reaction 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.