This commit is contained in:
82
test-aspnetcore/src/Core/Jobs/JobApi.Test.cs
Normal file
82
test-aspnetcore/src/Core/Jobs/JobApi.Test.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using TestAspNetCore.Infra;
|
||||
|
||||
namespace TestAspNetCore.Core.Jobs;
|
||||
|
||||
public class JobApiTests : IClassFixture<TestFixture>
|
||||
{
|
||||
private readonly HttpClient client;
|
||||
|
||||
public JobApiTests(TestFixture fixture)
|
||||
{
|
||||
client = fixture.Client;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Base()
|
||||
{
|
||||
// Create
|
||||
var createRequest = new CreateJobEndpoint.Request(
|
||||
"Client name", "Pickup", "Dropoff"
|
||||
);
|
||||
var createCall = await client.PostAsJsonAsync(
|
||||
JobApi.Prefix,
|
||||
createRequest,
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, createCall.StatusCode);
|
||||
|
||||
var createResponse = await createCall.Content
|
||||
.ReadFromJsonAsync<CreateJobEndpoint.Response>(
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.NotNull(createResponse);
|
||||
|
||||
// Get
|
||||
var getListCall = await client.GetAsync(
|
||||
JobApi.Prefix,
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getListCall.StatusCode);
|
||||
|
||||
var getCall = await client.GetAsync(
|
||||
$"{JobApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getCall.StatusCode);
|
||||
|
||||
// Update
|
||||
var updateRequest = new UpdateJobEndpoint.Request(
|
||||
"Client name", "Pickup update", "Dropoff update");
|
||||
var updateCall = await client.PutAsJsonAsync(
|
||||
$"{JobApi.Prefix}/{createResponse.Id}", updateRequest,
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, updateCall.StatusCode);
|
||||
|
||||
// Delete
|
||||
var deleteCall = await client.DeleteAsync(
|
||||
$"{JobApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, deleteCall.StatusCode);
|
||||
|
||||
// Not found
|
||||
var deleteCallNotFound = await client.DeleteAsync(
|
||||
$"{JobApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.NotFound, deleteCallNotFound.StatusCode);
|
||||
|
||||
var getCallNotFound = await client.GetAsync(
|
||||
$"{JobApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.NotFound, getCallNotFound.StatusCode);
|
||||
}
|
||||
}
|
||||
150
test-aspnetcore/src/Core/Jobs/JobApi.cs
Executable file
150
test-aspnetcore/src/Core/Jobs/JobApi.cs
Executable file
@@ -0,0 +1,150 @@
|
||||
using TestAspNetCore.Infra;
|
||||
using TestAspNetCore.Utils;
|
||||
|
||||
namespace TestAspNetCore.Core.Jobs;
|
||||
|
||||
public static class JobApi
|
||||
{
|
||||
public const string Prefix = "/api/jobs";
|
||||
|
||||
public static void MapEndpoints(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var group = endpoints.MapGroup(Prefix)
|
||||
.WithTags("Jobs");
|
||||
group.MapPost("/", CreateJobEndpoint.Handle)
|
||||
.WithSummary("Create a job")
|
||||
.WithRequestValidation<CreateJobEndpoint.Request>();
|
||||
group.MapGet("/", GetJobListEndpoint.Handle)
|
||||
.WithSummary("Get job list");
|
||||
group.MapGet("/{id}", GetJobEndpoint.Handle)
|
||||
.WithSummary("Get job by id");
|
||||
group.MapPut("/{id}", UpdateJobEndpoint.Handle)
|
||||
.WithSummary("Update job by id")
|
||||
.WithRequestValidation<UpdateJobEndpoint.Request>();
|
||||
group.MapDelete("/{id}", DeleteJobEndpoint.Handle)
|
||||
.WithSummary("Delete job by id");
|
||||
}
|
||||
}
|
||||
|
||||
public static class CreateJobEndpoint
|
||||
{
|
||||
public record Request(
|
||||
string ClientName,
|
||||
string Pickup,
|
||||
string Dropoff
|
||||
);
|
||||
|
||||
public record Response(int Id);
|
||||
|
||||
public class RequestValidator : AbstractValidator<Request>
|
||||
{
|
||||
public RequestValidator()
|
||||
{
|
||||
RuleFor(x => x.ClientName).NotEmpty().MaximumLength(250);
|
||||
RuleFor(x => x.Pickup).NotEmpty().MaximumLength(120);
|
||||
RuleFor(x => x.Dropoff).NotEmpty().MaximumLength(120);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Ok<Response>> Handle(Request request, AppDbContext db, CancellationToken ct)
|
||||
{
|
||||
var row = new Job
|
||||
{
|
||||
ClientName = request.ClientName,
|
||||
Pickup = request.Pickup,
|
||||
Dropoff = request.Dropoff,
|
||||
};
|
||||
|
||||
await db.Jobs.AddAsync(row, ct);
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
var response = new Response(row.Id);
|
||||
return TypedResults.Ok(response);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetJobListEndpoint
|
||||
{
|
||||
public static async Task<Ok<Job[]>> Handle(AppDbContext db, CancellationToken ct)
|
||||
{
|
||||
var results = await db.Jobs.ToArrayAsync(ct);
|
||||
return TypedResults.Ok(results);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetJobEndpoint
|
||||
{
|
||||
public static async Task<Results<Ok<Job>, NotFound>> Handle(
|
||||
int id,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var result = await db.Jobs
|
||||
.Where(x => x.Id == id)
|
||||
.SingleOrDefaultAsync(ct);
|
||||
|
||||
return result is null
|
||||
? TypedResults.NotFound()
|
||||
: TypedResults.Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UpdateJobEndpoint
|
||||
{
|
||||
public record Request(
|
||||
string ClientName,
|
||||
string Pickup,
|
||||
string Dropoff
|
||||
);
|
||||
|
||||
public class RequestValidator : AbstractValidator<Request>
|
||||
{
|
||||
public RequestValidator()
|
||||
{
|
||||
RuleFor(x => x.ClientName).NotEmpty().MaximumLength(250);
|
||||
RuleFor(x => x.Pickup).NotEmpty().MaximumLength(120);
|
||||
RuleFor(x => x.Dropoff).NotEmpty().MaximumLength(120);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Results<Ok, NotFound>> Handle(
|
||||
int id,
|
||||
Request request,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var result = await db.Jobs
|
||||
.Where(x => x.Id == id)
|
||||
.SingleOrDefaultAsync(ct);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
result.ClientName = request.ClientName;
|
||||
result.Pickup = request.Pickup;
|
||||
result.Dropoff = request.Dropoff;
|
||||
result.LastUpdatedAtUtc = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DeleteJobEndpoint
|
||||
{
|
||||
public static async Task<Results<Ok, NotFound>> Handle(
|
||||
int id,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var rowsDeleted = await db.Jobs
|
||||
.Where(x => x.Id == id)
|
||||
.ExecuteDeleteAsync(ct);
|
||||
|
||||
return rowsDeleted == 1
|
||||
? TypedResults.Ok()
|
||||
: TypedResults.NotFound();
|
||||
}
|
||||
}
|
||||
78
test-aspnetcore/src/Core/Users/UserApi.Test.cs
Normal file
78
test-aspnetcore/src/Core/Users/UserApi.Test.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using TestAspNetCore.Infra;
|
||||
|
||||
namespace TestAspNetCore.Core.Users;
|
||||
|
||||
public class UserApiTests : IClassFixture<TestFixture>
|
||||
{
|
||||
private readonly HttpClient client;
|
||||
|
||||
public UserApiTests(TestFixture fixture)
|
||||
{
|
||||
client = fixture.Client;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Base()
|
||||
{
|
||||
// Create
|
||||
var createRequest = new CreateUserEndpoint.Request("Test");
|
||||
var createCall = await client.PostAsJsonAsync(
|
||||
UserApi.Prefix,
|
||||
createRequest,
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, createCall.StatusCode);
|
||||
|
||||
var createResponse = await createCall.Content
|
||||
.ReadFromJsonAsync<CreateUserEndpoint.Response>(cancellationToken: TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(createResponse);
|
||||
|
||||
// Get
|
||||
var getListCall = await client.GetAsync(
|
||||
UserApi.Prefix,
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getListCall.StatusCode);
|
||||
|
||||
var getCall = await client.GetAsync(
|
||||
$"{UserApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getCall.StatusCode);
|
||||
|
||||
// Update
|
||||
var updateRequest = new UpdateUserEndpoint.Request("Test");
|
||||
var updateCall = await client.PutAsJsonAsync(
|
||||
$"{UserApi.Prefix}/{createResponse.Id}",
|
||||
updateRequest,
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, updateCall.StatusCode);
|
||||
|
||||
// Delete
|
||||
var deleteCall = await client.DeleteAsync(
|
||||
$"{UserApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, deleteCall.StatusCode);
|
||||
|
||||
// Not found
|
||||
var deleteCallNotFound = await client.DeleteAsync(
|
||||
$"{UserApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.NotFound, deleteCallNotFound.StatusCode);
|
||||
|
||||
var getCallNotFound = await client.GetAsync(
|
||||
$"{UserApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.NotFound, getCallNotFound.StatusCode);
|
||||
}
|
||||
}
|
||||
136
test-aspnetcore/src/Core/Users/UserApi.cs
Executable file
136
test-aspnetcore/src/Core/Users/UserApi.cs
Executable file
@@ -0,0 +1,136 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using TestAspNetCore.Infra;
|
||||
using TestAspNetCore.Utils;
|
||||
|
||||
namespace TestAspNetCore.Core.Users;
|
||||
|
||||
public static class UserApi
|
||||
{
|
||||
public const string Prefix = "/api/users";
|
||||
|
||||
public static void MapEndpoints(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var group = endpoints.MapGroup(Prefix)
|
||||
.WithTags("Users");
|
||||
group.MapPost("/", CreateUserEndpoint.Handle)
|
||||
.WithSummary("Create a user")
|
||||
.WithRequestValidation<CreateUserEndpoint.Request>();
|
||||
group.MapGet("/", GetUserListEndpoint.Handle)
|
||||
.WithSummary("Get user list");
|
||||
group.MapGet("/{id}", GetUserEndpoint.Handle)
|
||||
.WithSummary("Get user by id");
|
||||
group.MapPut("/{id}", UpdateUserEndpoint.Handle)
|
||||
.WithSummary("Update user by id")
|
||||
.WithRequestValidation<UpdateUserEndpoint.Request>();
|
||||
group.MapDelete("/{id}", DeleteUserEndpoint.Handle)
|
||||
.WithSummary("Delete user by id");
|
||||
}
|
||||
}
|
||||
|
||||
public static class CreateUserEndpoint
|
||||
{
|
||||
public record Request(string UserName);
|
||||
|
||||
public class RequestValidator : AbstractValidator<Request>
|
||||
{
|
||||
public RequestValidator()
|
||||
{
|
||||
RuleFor(x => x.UserName).NotEmpty().MaximumLength(250);
|
||||
}
|
||||
}
|
||||
|
||||
public record Response(int Id);
|
||||
|
||||
public static async Task<Ok<Response>> Handle(Request request, AppDbContext db, CancellationToken ct)
|
||||
{
|
||||
var row = new User
|
||||
{
|
||||
Username = request.UserName,
|
||||
DisplayName = request.UserName,
|
||||
Password = string.Empty
|
||||
};
|
||||
|
||||
await db.Users.AddAsync(row, ct);
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
var response = new Response(row.Id);
|
||||
return TypedResults.Ok(response);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetUserListEndpoint
|
||||
{
|
||||
public static async Task<Ok<User[]>> Handle(AppDbContext db, CancellationToken ct)
|
||||
{
|
||||
var results = await db.Users.ToArrayAsync(ct);
|
||||
return TypedResults.Ok(results);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetUserEndpoint
|
||||
{
|
||||
public static async Task<Results<Ok<User>, NotFound>> Handle(
|
||||
int id,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var result = await db.Users
|
||||
.Where(x => x.Id == id)
|
||||
.SingleOrDefaultAsync(ct);
|
||||
|
||||
return result is null
|
||||
? TypedResults.NotFound()
|
||||
: TypedResults.Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UpdateUserEndpoint
|
||||
{
|
||||
public record Request(string DisplayName);
|
||||
|
||||
public class RequestValidator : AbstractValidator<Request>
|
||||
{
|
||||
public RequestValidator()
|
||||
{
|
||||
RuleFor(x => x.DisplayName).NotEmpty().MaximumLength(250);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Results<Ok, NotFound>> Handle(
|
||||
int id,
|
||||
Request request,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var result = await db.Users
|
||||
.Where(x => x.Id == id)
|
||||
.SingleOrDefaultAsync(ct);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
result.DisplayName = request.DisplayName;
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DeleteUserEndpoint
|
||||
{
|
||||
public static async Task<Results<Ok, NotFound>> Handle(
|
||||
int id,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var rowsDeleted = await db.Users
|
||||
.Where(x => x.Id == id)
|
||||
.ExecuteDeleteAsync(ct);
|
||||
|
||||
return rowsDeleted == 1
|
||||
? TypedResults.Ok()
|
||||
: TypedResults.NotFound();
|
||||
}
|
||||
}
|
||||
80
test-aspnetcore/src/Core/Vehicles/VehicleApi.Test.cs
Normal file
80
test-aspnetcore/src/Core/Vehicles/VehicleApi.Test.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using TestAspNetCore.Infra;
|
||||
|
||||
namespace TestAspNetCore.Core.Vehicles;
|
||||
|
||||
public class VehicleApiTests : IClassFixture<TestFixture>
|
||||
{
|
||||
private readonly HttpClient client;
|
||||
|
||||
public VehicleApiTests(TestFixture fixture)
|
||||
{
|
||||
client = fixture.Client;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Base()
|
||||
{
|
||||
// Create
|
||||
var createRequest = new CreateVehicleEndpoint.Request("Test");
|
||||
var createCall = await client.PostAsJsonAsync(
|
||||
VehicleApi.Prefix,
|
||||
createRequest,
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, createCall.StatusCode);
|
||||
|
||||
var createResponse = await createCall.Content
|
||||
.ReadFromJsonAsync<CreateVehicleEndpoint.Response>(
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.NotNull(createResponse);
|
||||
|
||||
// Get
|
||||
var getListCall = await client.GetAsync(
|
||||
VehicleApi.Prefix,
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getListCall.StatusCode);
|
||||
|
||||
var getCall = await client.GetAsync(
|
||||
$"{VehicleApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getCall.StatusCode);
|
||||
|
||||
// Update
|
||||
var updateRequest = new UpdateVehicleEndpoint.Request("Test");
|
||||
var updateCall = await client.PutAsJsonAsync(
|
||||
$"{VehicleApi.Prefix}/{createResponse.Id}",
|
||||
updateRequest,
|
||||
cancellationToken: TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, updateCall.StatusCode);
|
||||
|
||||
// Delete
|
||||
var deleteCall = await client.DeleteAsync(
|
||||
$"{VehicleApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, deleteCall.StatusCode);
|
||||
|
||||
// Not found
|
||||
var deleteCallNotFound = await client.DeleteAsync(
|
||||
$"{VehicleApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.NotFound, deleteCallNotFound.StatusCode);
|
||||
|
||||
var getCallNotFound = await client.GetAsync(
|
||||
$"{VehicleApi.Prefix}/{createResponse.Id}",
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.NotFound, getCallNotFound.StatusCode);
|
||||
}
|
||||
}
|
||||
136
test-aspnetcore/src/Core/Vehicles/VehicleApi.cs
Executable file
136
test-aspnetcore/src/Core/Vehicles/VehicleApi.cs
Executable file
@@ -0,0 +1,136 @@
|
||||
using TestAspNetCore.Infra;
|
||||
using TestAspNetCore.Utils;
|
||||
|
||||
namespace TestAspNetCore.Core.Vehicles;
|
||||
|
||||
public static class VehicleApi
|
||||
{
|
||||
public const string Prefix = "/api/vehicles";
|
||||
|
||||
public static void MapEndpoints(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var group = endpoints.MapGroup(Prefix)
|
||||
.WithTags("Vehicles");
|
||||
group.MapPost("/", CreateVehicleEndpoint.Handle)
|
||||
.WithSummary("Create a vehicle")
|
||||
.WithRequestValidation<CreateVehicleEndpoint.Request>();
|
||||
group.MapGet("/", GetVehicleListEndpoint.Handle)
|
||||
.WithSummary("Get vehicle list");
|
||||
group.MapGet("/{id}", GetVehicleEndpoint.Handle)
|
||||
.WithSummary("Get vehicle by id");
|
||||
group.MapPut("/{id}", UpdateVehicleEndpoint.Handle)
|
||||
.WithSummary("Update vehicle by id")
|
||||
.WithRequestValidation<UpdateVehicleEndpoint.Request>();
|
||||
group.MapDelete("/{id}", DeleteVehicleEndpoint.Handle)
|
||||
.WithSummary("Delete vehicle by id");
|
||||
}
|
||||
}
|
||||
|
||||
public static class CreateVehicleEndpoint
|
||||
{
|
||||
public record Request(string Make);
|
||||
|
||||
public record Response(int Id);
|
||||
|
||||
public class RequestValidator : AbstractValidator<Request>
|
||||
{
|
||||
public RequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Make).NotEmpty().MaximumLength(250);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Ok<Response>> Handle(Request request, AppDbContext db, CancellationToken ct)
|
||||
{
|
||||
var row = new Vehicle
|
||||
{
|
||||
Make = request.Make,
|
||||
Model = "",
|
||||
Year = DateTime.Now.Year
|
||||
};
|
||||
|
||||
await db.Vehicles.AddAsync(row, ct);
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
var response = new Response(row.Id);
|
||||
return TypedResults.Ok(response);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetVehicleListEndpoint
|
||||
{
|
||||
public static async Task<Ok<Vehicle[]>> Handle(AppDbContext db, CancellationToken ct)
|
||||
{
|
||||
var results = await db.Vehicles.ToArrayAsync(ct);
|
||||
return TypedResults.Ok(results);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetVehicleEndpoint
|
||||
{
|
||||
public static async Task<Results<Ok<Vehicle>, NotFound>> Handle(
|
||||
int id,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var result = await db.Vehicles
|
||||
.Where(x => x.Id == id)
|
||||
.SingleOrDefaultAsync(ct);
|
||||
|
||||
return result is null
|
||||
? TypedResults.NotFound()
|
||||
: TypedResults.Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UpdateVehicleEndpoint
|
||||
{
|
||||
public record Request(string Make);
|
||||
|
||||
public class RequestValidator : AbstractValidator<Request>
|
||||
{
|
||||
public RequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Make).NotEmpty().MaximumLength(250);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Results<Ok, NotFound>> Handle(
|
||||
int id,
|
||||
Request request,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var result = await db.Vehicles
|
||||
.Where(x => x.Id == id)
|
||||
.SingleOrDefaultAsync(ct);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
result.Make = request.Make;
|
||||
result.LastUpdatedAtUtc = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DeleteVehicleEndpoint
|
||||
{
|
||||
public static async Task<Results<Ok, NotFound>> Handle(
|
||||
int id,
|
||||
AppDbContext db,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var rowsDeleted = await db.Vehicles
|
||||
.Where(x => x.Id == id)
|
||||
.ExecuteDeleteAsync(ct);
|
||||
|
||||
return rowsDeleted == 1
|
||||
? TypedResults.Ok()
|
||||
: TypedResults.NotFound();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using TestAspNetCore.Infra;
|
||||
|
||||
namespace TestAspNetCore.Core.WeatherForecasts;
|
||||
|
||||
public class WeatherForecastApiTests : IClassFixture<TestFixture>
|
||||
{
|
||||
private readonly HttpClient client;
|
||||
|
||||
public WeatherForecastApiTests(TestFixture fixture)
|
||||
{
|
||||
client = fixture.Client;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Base()
|
||||
{
|
||||
// Get
|
||||
var getCall = await client.GetAsync(
|
||||
WeatherForecastApi.Prefix,
|
||||
TestContext.Current.CancellationToken
|
||||
);
|
||||
Assert.Equal(HttpStatusCode.OK, getCall.StatusCode);
|
||||
}
|
||||
}
|
||||
39
test-aspnetcore/src/Core/WeatherForecasts/WeatherForecastApi.cs
Executable file
39
test-aspnetcore/src/Core/WeatherForecasts/WeatherForecastApi.cs
Executable file
@@ -0,0 +1,39 @@
|
||||
namespace TestAspNetCore.Core.WeatherForecasts;
|
||||
|
||||
public static class WeatherForecastApi
|
||||
{
|
||||
public const string Prefix = "/api/weatherforecasts";
|
||||
|
||||
public static void MapEndpoints(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var group = endpoints.MapGroup("/api/weatherforecasts")
|
||||
.WithTags("WeatherForecasts")
|
||||
.AllowAnonymous();
|
||||
group.MapGet("/", GetWeatherForecastListEndpoint.Handle)
|
||||
.WithSummary("Get weather forecast list");
|
||||
}
|
||||
}
|
||||
|
||||
public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
|
||||
{
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
|
||||
public static class GetWeatherForecastListEndpoint
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
public static WeatherForecast[] Handle()
|
||||
{
|
||||
var random = new Random();
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
(
|
||||
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
random.Next(-20, 55),
|
||||
Summaries[random.Next(Summaries.Length)]
|
||||
)).ToArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user