refactor: Refactor tests read-side

This commit is contained in:
Pc 2023-05-08 18:37:10 +03:30
parent 95ac22d3b8
commit 607d72eef7
31 changed files with 128 additions and 102 deletions

View File

@ -14,7 +14,7 @@ using MediatR;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
public record CreateAircraftMongo(Guid Id, string Name, string Model, int ManufacturingYear, bool IsDeleted) : InternalCommand;
public record CreateAircraftMongo(Guid Id, string Name, string Model, int ManufacturingYear, bool IsDeleted = false) : InternalCommand;
public class CreateAircraftMongoHandler : ICommandHandler<CreateAircraftMongo>
{

View File

@ -14,7 +14,7 @@ using MediatR;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
public record CreateAirportMongo(Guid Id, string Name, string Address, string Code, bool IsDeleted) : InternalCommand;
public record CreateAirportMongo(Guid Id, string Name, string Address, string Code, bool IsDeleted = false) : InternalCommand;
internal class CreateAirportMongoHandler : ICommandHandler<CreateAirportMongo>
{

View File

@ -16,7 +16,7 @@ using MongoDB.Driver.Linq;
public record CreateFlightMongo(Guid Id, string FlightNumber, Guid AircraftId, DateTime DepartureDate,
Guid DepartureAirportId, DateTime ArriveDate, Guid ArriveAirportId, decimal DurationMinutes, DateTime FlightDate,
Enums.FlightStatus Status, decimal Price, bool IsDeleted) : InternalCommand;
Enums.FlightStatus Status, decimal Price, bool IsDeleted = false) : InternalCommand;
internal class CreateFlightMongoHandler : ICommandHandler<CreateFlightMongo>
{

View File

@ -16,7 +16,7 @@ using MongoDB.Driver.Linq;
public record DeleteFlightMongo(Guid Id, string FlightNumber, Guid AircraftId, DateTime DepartureDate,
Guid DepartureAirportId, DateTime ArriveDate, Guid ArriveAirportId, decimal DurationMinutes, DateTime FlightDate,
Enums.FlightStatus Status, decimal Price, bool IsDeleted) : InternalCommand;
Enums.FlightStatus Status, decimal Price, bool IsDeleted = false) : InternalCommand;
internal class DeleteFlightMongoCommandHandler : ICommandHandler<DeleteFlightMongo>
{

View File

@ -16,7 +16,7 @@ using MongoDB.Driver.Linq;
public record UpdateFlightMongo(Guid Id, string FlightNumber, Guid AircraftId, DateTime DepartureDate,
Guid DepartureAirportId, DateTime ArriveDate, Guid ArriveAirportId, decimal DurationMinutes, DateTime FlightDate,
Enums.FlightStatus Status, decimal Price, bool IsDeleted) : InternalCommand;
Enums.FlightStatus Status, decimal Price, bool IsDeleted = false) : InternalCommand;
internal class UpdateFlightMongoCommandHandler : ICommandHandler<UpdateFlightMongo>

View File

@ -15,7 +15,7 @@ using MongoDB.Driver;
using MongoDB.Driver.Linq;
public record CreateSeatMongo(Guid Id, string SeatNumber, Enums.SeatType Type,
Enums.SeatClass Class, Guid FlightId, bool IsDeleted) : InternalCommand;
Enums.SeatClass Class, Guid FlightId, bool IsDeleted = false) : InternalCommand;
public class CreateSeatMongoHandler : ICommandHandler<CreateSeatMongo>
{

View File

@ -13,7 +13,7 @@ using MediatR;
using MongoDB.Driver;
public record ReserveSeatMongo(Guid Id, string SeatNumber, Enums.SeatType Type,
Enums.SeatClass Class, Guid FlightId, bool IsDeleted) : InternalCommand;
Enums.SeatClass Class, Guid FlightId, bool IsDeleted = false) : InternalCommand;
internal class ReserveSeatMongoHandler : ICommandHandler<ReserveSeatMongo>
{

View File

@ -24,8 +24,4 @@
<ProjectReference Include="..\..\src\Flight.Api\Flight.Api.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Fakes" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,22 @@
namespace EndToEnd.Test.Fakes;
using AutoBogus;
using global::Flight.Data.Seed;
using global::Flight.Flights.Features.CreatingFlight.V1;
using global::Flight.Flights.Enums;
using MassTransit;
public sealed class FakeCreateFlightMongoCommand : AutoFaker<CreateFlightMongo>
{
public FakeCreateFlightMongoCommand()
{
RuleFor(r => r.Id, _ => NewId.NextGuid());
RuleFor(r => r.FlightNumber, r => "12FF");
RuleFor(r => r.DepartureAirportId, _ => InitialData.Airports.First().Id);
RuleFor(r => r.ArriveAirportId, _ => InitialData.Airports.Last().Id);
RuleFor(r => r.Status, _ => FlightStatus.Flying);
RuleFor(r => r.AircraftId, _ => InitialData.Aircrafts.First().Id);
RuleFor(r => r.IsDeleted, _ => false);
}
}

View File

@ -9,8 +9,6 @@ using Xunit;
namespace EndToEnd.Test.Flight.Features;
using global::Flight.Flights.Features.CreatingFlight.V1;
public class GetFlightByIdTests: FlightEndToEndTestBase
{
public GetFlightByIdTests(TestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
@ -22,9 +20,9 @@ public class GetFlightByIdTests: FlightEndToEndTestBase
public async Task should_retrive_a_flight_by_id_currectly()
{
//Arrange
var command = new FakeCreateFlightCommand().Generate();
var command = new FakeCreateFlightMongoCommand().Generate();
await Fixture.SendAsync(command);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
// Act
var route = ApiRoutes.Flight.GetFlightById.Replace(ApiRoutes.Flight.Id, command.Id.ToString());

View File

@ -31,7 +31,5 @@ public class CreateAircraftTests : FlightIntegrationTestBase
response?.Id.Should().Be(command.Id);
(await Fixture.WaitForPublishing<AircraftCreated>()).Should().Be(true);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateAircraftMongo>()).Should().Be(true);
}
}

View File

@ -31,7 +31,5 @@ public class CreateAirportTests : FlightIntegrationTestBase
response?.Id.Should().Be(command.Id);
(await Fixture.WaitForPublishing<AirportCreated>()).Should().Be(true);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateAirportMongo>()).Should().Be(true);
}
}

View File

@ -0,0 +1,23 @@
namespace Integration.Test.Fakes;
using System.Linq;
using AutoBogus;
using global::Flight.Data.Seed;
using global::Flight.Flights.Enums;
using global::Flight.Flights.Features.CreatingFlight.V1;
using MassTransit;
public sealed class FakeCreateFlightMongoCommand : AutoFaker<CreateFlightMongo>
{
public FakeCreateFlightMongoCommand()
{
RuleFor(r => r.Id, _ => NewId.NextGuid());
RuleFor(r => r.FlightNumber, r => "12FF");
RuleFor(r => r.DepartureAirportId, _ => InitialData.Airports.First().Id);
RuleFor(r => r.ArriveAirportId, _ => InitialData.Airports.Last().Id);
RuleFor(r => r.Status, _ => FlightStatus.Flying);
RuleFor(r => r.AircraftId, _ => InitialData.Aircrafts.First().Id);
RuleFor(r => r.IsDeleted, _ => false);
}
}

View File

@ -0,0 +1,19 @@
namespace Integration.Test.Fakes;
using System;
using AutoBogus;
using global::Flight.Seats.Enums;
using global::Flight.Seats.Features.CreatingSeat.V1;
using MassTransit;
public class FakeCreateSeatMongoCommand : AutoFaker<CreateSeatMongo>
{
public FakeCreateSeatMongoCommand(Guid flightId)
{
RuleFor(r => r.Id, _ => NewId.NextGuid());
RuleFor(r => r.FlightId, _ => flightId);
RuleFor(r => r.Class, _ => SeatClass.Economy);
RuleFor(r => r.Type, _ => SeatType.Middle);
RuleFor(r => r.IsDeleted, _ => false);
}
}

View File

@ -33,7 +33,5 @@ public class CreateFlightTests : FlightIntegrationTestBase
(await Fixture.WaitForPublishing<FlightCreated>()).Should().Be(true);
(await Fixture.WaitForConsuming<FlightCreated>()).Should().Be(true);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
}
}

View File

@ -41,7 +41,5 @@ public class DeleteFlightTests : FlightIntegrationTestBase
deletedFlight?.IsDeleted.Should().BeTrue();
(await Fixture.WaitForPublishing<FlightDeleted>()).Should().Be(true);
(await Fixture.ShouldProcessedPersistInternalCommand<DeleteFlightMongo>()).Should().Be(true);
}
}

View File

@ -23,11 +23,9 @@ public class GetAvailableFlightsTests : FlightIntegrationTestBase
public async Task should_return_available_flights()
{
// Arrange
var flightCommand = new FakeCreateFlightCommand().Generate();
var command = new FakeCreateFlightMongoCommand().Generate();
await Fixture.SendAsync(flightCommand);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
await Fixture.SendAsync(command);
var query = new GetAvailableFlights();

View File

@ -24,10 +24,9 @@ public class GetFlightByIdTests : FlightIntegrationTestBase
public async Task should_retrive_a_flight_by_id_currectly()
{
//Arrange
var command = new FakeCreateFlightCommand().Generate();
await Fixture.SendAsync(command);
var command = new FakeCreateFlightMongoCommand().Generate();
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
await Fixture.SendAsync(command);
var query = new GetFlightById(command.Id);
@ -36,17 +35,16 @@ public class GetFlightByIdTests : FlightIntegrationTestBase
// Assert
response.Should().NotBeNull();
// response?.FlightDto?.Id.Should().Be(command.Id);
response?.FlightDto?.Id.Should().Be(command.Id);
}
[Fact]
public async Task should_retrive_a_flight_by_id_from_grpc_service()
{
//Arrange
var command = new FakeCreateFlightCommand().Generate();
await Fixture.SendAsync(command);
var command = new FakeCreateFlightMongoCommand().Generate();
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
await Fixture.SendAsync(command);
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel);

View File

@ -37,7 +37,5 @@ public class UpdateFlightTests : FlightIntegrationTestBase
response?.Id.Should().Be(flightEntity.Id);
(await Fixture.WaitForPublishing<FlightUpdated>()).Should().Be(true);
(await Fixture.ShouldProcessedPersistInternalCommand<UpdateFlightMongo>()).Should().Be(true);
}
}

View File

@ -23,18 +23,14 @@ public class GetAvailableSeatsTests : FlightIntegrationTestBase
public async Task should_return_available_seats_from_grpc_service()
{
// Arrange
var flightCommand = new FakeCreateFlightCommand().Generate();
var flightCommand = new FakeCreateFlightMongoCommand().Generate();
await Fixture.SendAsync(flightCommand);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate();
var seatCommand = new FakeCreateSeatMongoCommand(flightCommand.Id).Generate();
await Fixture.SendAsync(seatCommand);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateSeatMongo>()).Should().Be(true);
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel);
// Act

View File

@ -27,14 +27,10 @@ public class ReserveSeatTests : FlightIntegrationTestBase
await Fixture.SendAsync(flightCommand);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongo>()).Should().Be(true);
var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate();
await Fixture.SendAsync(seatCommand);
(await Fixture.ShouldProcessedPersistInternalCommand<CreateSeatMongo>()).Should().Be(true);
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel);
// Act

View File

@ -1,10 +1,3 @@
namespace Passenger.Passengers.Dtos;
public record PassengerDto
{
public Guid Id { get; init; }
public string Name { get; init; }
public string PassportNumber { get; init; }
public Enums.PassengerType PassengerType { get; init; }
public int Age { get; init; }
}
public record PassengerDto(Guid Id, string Name, string PassportNumber, Enums.PassengerType PassengerType, int Age);

View File

@ -11,7 +11,7 @@ using MongoDB.Driver.Linq;
using Data;
public record CompleteRegisterPassengerMongoCommand(Guid Id, string PassportNumber, string Name,
Enums.PassengerType PassengerType, int Age, bool IsDeleted) : InternalCommand;
Enums.PassengerType PassengerType, int Age, bool IsDeleted = false) : InternalCommand;
internal class CompleteRegisterPassengerMongoHandler : ICommandHandler<CompleteRegisterPassengerMongoCommand>

View File

@ -5,7 +5,6 @@ using Data;
using Dtos;
using FluentValidation;
using MapsterMapper;
using Microsoft.EntityFrameworkCore;
using Ardalis.GuardClauses;
using BuildingBlocks.Web;
using Exceptions;
@ -13,6 +12,8 @@ using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
public record GetPassengerById(Guid Id) : IQuery<GetPassengerByIdResult>;
@ -57,13 +58,13 @@ internal class GetPassengerByIdValidator : AbstractValidator<GetPassengerById>
internal class GetPassengerByIdHandler : IQueryHandler<GetPassengerById, GetPassengerByIdResult>
{
private readonly PassengerDbContext _passengerDbContext;
private readonly IMapper _mapper;
private readonly PassengerReadDbContext _passengerReadDbContext;
public GetPassengerByIdHandler(IMapper mapper, PassengerDbContext passengerDbContext)
public GetPassengerByIdHandler(IMapper mapper, PassengerReadDbContext passengerReadDbContext)
{
_mapper = mapper;
_passengerDbContext = passengerDbContext;
_passengerReadDbContext = passengerReadDbContext;
}
public async Task<GetPassengerByIdResult> Handle(GetPassengerById query, CancellationToken cancellationToken)
@ -71,7 +72,8 @@ internal class GetPassengerByIdHandler : IQueryHandler<GetPassengerById, GetPass
Guard.Against.Null(query, nameof(query));
var passenger =
await _passengerDbContext.Passengers.SingleOrDefaultAsync(x => x.Id == query.Id, cancellationToken);
await _passengerReadDbContext.Passenger.AsQueryable()
.SingleOrDefaultAsync(x => x.PassengerId == query.Id && x.IsDeleted == false, cancellationToken);
if (passenger is null)
{

View File

@ -3,6 +3,7 @@ using Mapster;
namespace Passenger.Passengers.Features;
using CompletingRegisterPassenger.V1;
using Dtos;
using MassTransit;
using Models;
@ -16,5 +17,8 @@ public class PassengerMappings : IRegister
config.NewConfig<CompleteRegisterPassengerRequestDto, CompleteRegisterPassenger>()
.ConstructUsing(x => new CompleteRegisterPassenger(x.PassportNumber, x.PassengerType, x.Age));
config.NewConfig<PassengerReadModel, PassengerDto>()
.ConstructUsing(x => new PassengerDto(x.PassengerId, x.Name, x.PassportNumber, x.PassengerType, x.Age));
}
}

View File

@ -0,0 +1,19 @@
namespace Integration.Test.Fakes;
using AutoBogus;
using global::Passenger.Passengers.Enums;
using global::Passenger.Passengers.Features.CompletingRegisterPassenger.V1;
using MassTransit;
public class FakeCompleteRegisterPassengerMongoCommand: AutoFaker<CompleteRegisterPassengerMongoCommand>
{
public FakeCompleteRegisterPassengerMongoCommand()
{
RuleFor(r => r.Id, _ => NewId.NextGuid());
RuleFor(r => r.Name, _ => "Sam");
RuleFor(r => r.PassportNumber, _ => "123456789");
RuleFor(r => r.Age, _ => 30);
RuleFor(r => r.IsDeleted, _ => false);
RuleFor(r => r.PassengerType, _ => PassengerType.Male);
}
}

View File

@ -1,13 +0,0 @@
using BuildingBlocks.Contracts.EventBus.Messages;
namespace Integration.Test.Fakes;
using MassTransit;
public static class FakePassengerCreated
{
public static global::Passenger.Passengers.Models.Passenger Generate(UserCreated userCreated)
{
return global::Passenger.Passengers.Models.Passenger.Create(NewId.NextGuid(), userCreated.Name, userCreated.PassportNumber);
}
}

View File

@ -1,14 +0,0 @@
using AutoBogus;
namespace Integration.Test.Fakes;
using global::Passenger;
using MassTransit;
public class FakePassengerResponse : AutoFaker<PassengerResponse>
{
public FakePassengerResponse()
{
RuleFor(r => r.Id, _ => NewId.NextGuid().ToString());
}
}

View File

@ -12,7 +12,7 @@ namespace Integration.Test.Passenger.Features;
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
{
public CompleteRegisterPassengerTests(
TestWriteFixture<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory) : base(integrationTestFactory)
{
}

View File

@ -10,12 +10,13 @@ using Xunit;
namespace Integration.Test.Passenger.Features;
using global::Passenger.Passengers.Features.GettingPassengerById.Queries.V1;
using Humanizer;
using Thrift.Protocol;
public class GetPassengerByIdTests : PassengerIntegrationTestBase
{
public GetPassengerByIdTests(
TestWriteFixture<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory) : base(integrationTestFactory)
{
}
@ -23,37 +24,35 @@ public class GetPassengerByIdTests : PassengerIntegrationTestBase
public async Task should_retrive_a_passenger_by_id_currectly()
{
// Arrange
var userCreated = new FakeUserCreated().Generate();
var command = new FakeCompleteRegisterPassengerMongoCommand().Generate();
var passengerEntity = FakePassengerCreated.Generate(userCreated);
await Fixture.InsertAsync(passengerEntity);
await Fixture.SendAsync(command);
var query = new GetPassengerById(passengerEntity.Id);
var query = new GetPassengerById(command.Id);
// Act
var response = await Fixture.SendAsync(query);
// Assert
response.Should().NotBeNull();
response?.PassengerDto?.Id.Should().Be(passengerEntity.Id);
response?.PassengerDto?.Id.Should().Be(command.Id);
}
[Fact]
public async Task should_retrive_a_passenger_by_id_from_grpc_service()
{
// Arrange
var userCreated = new FakeUserCreated().Generate();
var command = new FakeCompleteRegisterPassengerMongoCommand().Generate();
var passengerEntity = FakePassengerCreated.Generate(userCreated);
await Fixture.InsertAsync(passengerEntity);
await Fixture.SendAsync(command);
var passengerGrpcClient = new PassengerGrpcService.PassengerGrpcServiceClient(Fixture.Channel);
// Act
var response = await passengerGrpcClient.GetByIdAsync(new GetByIdRequest {Id = passengerEntity.Id.ToString()});
var response = await passengerGrpcClient.GetByIdAsync(new GetByIdRequest {Id = command.Id.ToString()});
// Assert
response?.Should().NotBeNull();
response?.PassengerDto?.Id.Should().Be(passengerEntity.Id.ToString());
response?.PassengerDto?.Id.Should().Be(command.Id.ToString());
}
}

View File

@ -6,16 +6,16 @@ using Xunit;
namespace Integration.Test;
[Collection(IntegrationTestCollection.Name)]
public class PassengerIntegrationTestBase: TestWriteBase<Program, PassengerDbContext>
public class PassengerIntegrationTestBase: TestBase<Program, PassengerDbContext, PassengerReadDbContext>
{
public PassengerIntegrationTestBase(TestWriteFixture<Program, PassengerDbContext> integrationTestFactory)
public PassengerIntegrationTestBase(TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory)
: base(integrationTestFactory)
{
}
}
[CollectionDefinition(Name)]
public class IntegrationTestCollection : ICollectionFixture<TestWriteFixture<Program, PassengerDbContext>>
public class IntegrationTestCollection : ICollectionFixture<TestFixture<Program, PassengerDbContext, PassengerReadDbContext>>
{
public const string Name = "Passenger Integration Test";
}