Skip to content

Commit

Permalink
Merge pull request #61 from AmielCyber/dev
Browse files Browse the repository at this point in the history
Update to .NET 8
  • Loading branch information
AmielCyber authored Jun 9, 2024
2 parents 37338cf + 8a95366 commit c52ad72
Show file tree
Hide file tree
Showing 49 changed files with 292 additions and 217 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using PetSearch.API.Clients;
using PetSearch.API.Common.Errors;
using PetSearch.API.Common.Exceptions;
using PetSearch.API.Models.MabBoxResponse;
using PetSearch.API.Models.MapBoxResponse;
using PetSearch.API.StronglyTypedConfigurations;
using RichardSzalay.MockHttp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using PetSearch.API.Clients;
using PetSearch.API.Common.Errors;
using PetSearch.API.Common.Exceptions;
using PetSearch.API.Models.MabBoxResponse;
using PetSearch.API.Models.MapBoxResponse;
using PetSearch.API.StronglyTypedConfigurations;
using RichardSzalay.MockHttp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static Error GetExpectedErrorType(HttpStatusCode responseStatusCode)
return responseStatusCode switch
{
HttpStatusCode.BadRequest => Errors.Location.BadRequest,
HttpStatusCode.Unauthorized => Errors.Token.NotAuthorized,
HttpStatusCode.Unauthorized => Errors.Token.Unauthorized,
HttpStatusCode.NotFound => Errors.Location.NotFound,
_ => Errors.Location.ServerError,
};
Expand Down
2 changes: 1 addition & 1 deletion PetSearch.API.Tests/PetFinderClientTests/GetPetsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using PetSearch.API.Common.Exceptions;
using PetSearch.API.Models.PetFinderResponse;
using PetSearch.API.RequestHelpers;
using PetSearch.Data.Entity;
using PetSearch.Data.Entities;
using PetSearch.Data.Services;
using RichardSzalay.MockHttp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using PetSearch.API.Clients;
using PetSearch.API.Common.Exceptions;
using PetSearch.API.Models.PetFinderResponse;
using PetSearch.Data.Entity;
using PetSearch.Data.Entities;
using PetSearch.Data.Services;
using RichardSzalay.MockHttp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static Error GetExpectedErrorType(HttpStatusCode responseStatusCode)
return responseStatusCode switch
{
HttpStatusCode.BadRequest => Errors.Pets.BadRequest,
HttpStatusCode.Unauthorized => Errors.Token.NotAuthorized,
HttpStatusCode.Unauthorized => Errors.Token.Unauthorized,
HttpStatusCode.NotFound => Errors.Pets.NotFound,
_ => Errors.Pets.ServerError,
};
Expand Down
22 changes: 10 additions & 12 deletions PetSearch.API.Tests/PetSearch.API.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -10,18 +10,16 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="RichardSzalay.MockHttp" Version="6.0.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
</ItemGroup>

<ItemGroup>
<Using Include="Xunit"/>
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion PetSearch.API.Tests/Usings.cs

This file was deleted.

6 changes: 3 additions & 3 deletions PetSearch.API/Clients/IMapBoxClient.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using ErrorOr;
using PetSearch.API.Models.MabBoxResponse;
using PetSearch.API.Models.MapBoxResponse;

namespace PetSearch.API.Clients;

/// <summary>
/// MapBox Client interface to handle MapBox API requests.
/// Such as getting the location information from a zipcode or coordinates.
/// MapBox Client interface to handle MapBox API requests,
/// such as getting the location information from a zipcode or coordinates.
/// </summary>
public interface IMapBoxClient
{
Expand Down
4 changes: 2 additions & 2 deletions PetSearch.API/Clients/IPetFinderClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
namespace PetSearch.API.Clients;

/// <summary>
/// Pet Finder Client interface to handle PetFinder API requests.
/// Such as getting a list of pets and a single pet object from the PetFinder API.
/// Pet Finder Client interface to handle PetFinder API requests,
/// such as getting a list of pets and a single pet object from the PetFinder API.
/// </summary>
public interface IPetFinderClient
{
Expand Down
26 changes: 6 additions & 20 deletions PetSearch.API/Clients/MapBoxClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
using Microsoft.Extensions.Options;
using PetSearch.API.Common.Errors;
using PetSearch.API.Common.Exceptions;
using PetSearch.API.Models.MabBoxResponse;
using PetSearch.API.Models.MapBoxResponse;
using PetSearch.API.StronglyTypedConfigurations;

namespace PetSearch.API.Clients;

/// <summary>
/// MapBoxClient implementation to handle requests from the MapBox API.
/// Returns Location object to our client app.
/// Returns Location object to our client application.
/// </summary>
public class MapBoxClient : IMapBoxClient
{
Expand All @@ -21,26 +21,12 @@ public class MapBoxClient : IMapBoxClient
/// </summary>
/// <param name="httpClient">Have access to the global HttpClient object to make external API requests.</param>
/// <param name="options">The configuration options for using the MapBox API.</param>
/// <exception cref="MissingMapBoxToken">If configuration options was not set up.</exception>
public MapBoxClient(HttpClient httpClient, IOptions<MapBoxConfiguration> options)
{
_httpClient = httpClient;
MapBoxConfiguration keys = options.Value;
string? accessToken = keys.AccessToken;
Dictionary<string, string> queryParameters = keys.QueryParameters;

if (string.IsNullOrEmpty(accessToken))
{
throw new MissingMapBoxToken();
}

var queryParameters = new Dictionary<string, string>
{
{ "country", "us" },
{ "limit", "1" },
{ "types", "postcode" },
{ "language", "en" },
{ "access_token", accessToken }
};
_queryFormUrlEncoded = new FormUrlEncodedContent(queryParameters);
}

Expand All @@ -49,7 +35,8 @@ public MapBoxClient(HttpClient httpClient, IOptions<MapBoxConfiguration> options
/// </summary>
/// <param name="zipcode">Five digit zipcode to get location information.</param>
/// <returns>Location object if successful or an Error type if response was not successful.</returns>
/// <exception cref="MapBoxForbidden">If we are denied from using MapBox then we should log it with our exception middleware.</exception>
/// <exception cref="MapBoxForbidden">If we are denied from using MapBox then we should log it with our
/// exception middleware.</exception>
public async Task<ErrorOr<LocationDto>> GetLocationFromZipCode(string zipcode)
{
string queryString = await _queryFormUrlEncoded.ReadAsStringAsync();
Expand Down Expand Up @@ -120,14 +107,13 @@ private static Error GetLocationError(int statusCode)
{
// Throw exception since its unexpected and something we have to handle on our end, since our
// client app handles auto refresh token.
// Is catch by our global error handler and will log exception.
throw new MapBoxForbidden();
}

return statusCode switch
{
400 => Errors.Location.BadRequest,
401 => Errors.Token.NotAuthorized,
401 => Errors.Token.Unauthorized,
404 => Errors.Location.NotFound,
_ => Errors.Location.ServerError,
};
Expand Down
4 changes: 2 additions & 2 deletions PetSearch.API/Clients/PetFinderClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using PetSearch.API.Common.Exceptions;
using PetSearch.API.Models.PetFinderResponse;
using PetSearch.API.RequestHelpers;
using PetSearch.Data.Entity;
using PetSearch.Data.Entities;
using PetSearch.Data.Services;

namespace PetSearch.API.Clients;
Expand Down Expand Up @@ -148,7 +148,7 @@ private static Error GetPetsError(int statusCode)
return statusCode switch
{
400 => Errors.Pets.BadRequest,
401 => Errors.Token.NotAuthorized,
401 => Errors.Token.Unauthorized,
404 => Errors.Pets.NotFound,
_ => Errors.Pets.ServerError,
};
Expand Down
16 changes: 11 additions & 5 deletions PetSearch.API/Common/Errors/Errors.Location.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,32 @@ namespace PetSearch.API.Common.Errors;
public static partial class Errors
{
/// <summary>
/// Error types after or before sending a request to the PetFinder API.
/// Error types after or before sending a request to the MapBox API.
/// </summary>
public static class Location
{
// 400
/// <summary>
/// Bad Request due to validation error.
/// </summary>
public static Error BadRequest => Error.Validation(
code: "Location.BadRequest",
description: "Invalid parameters entered."
);

// 404
/// <summary>
/// Not Found Error.
/// </summary>
public static Error NotFound => Error.NotFound(
code: "Location.NotFound",
description: "Location was not found. Please enter a valid zip code or coordinates"
);

// 500
/// <summary>
/// Server Error.
/// </summary>
public static Error ServerError => Error.Failure(
code: "Location.ServerError",
description: "Something went wrong with your request."
);
}
}
}
12 changes: 9 additions & 3 deletions PetSearch.API/Common/Errors/Errors.Pets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@ public static partial class Errors
/// </summary>
public static class Pets
{
// 400
/// <summary>
/// Bad Request due to validation error.
/// </summary>
public static Error BadRequest => Error.Validation(
code: "Pets.BadRequest",
description: "Invalid parameters entered."
);

// 404
/// <summary>
/// Not Found Error.
/// </summary>
public static Error NotFound => Error.NotFound(
code: "Pets.NotFound",
description: "Pet with the passed id was not found."
);

// 500
/// <summary>
/// Server Error.
/// </summary>
public static Error ServerError => Error.Failure(
code: "Pets.ServerError",
description: "Something went wrong with your request."
Expand Down
3 changes: 1 addition & 2 deletions PetSearch.API/Common/Errors/Errors.Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ public static partial class Errors
/// </summary>
public static class Token
{
public static Error NotAuthorized => Error.Custom(
type: MyErrorTypes.Unauthorized,
public static Error Unauthorized => Error.Unauthorized(
code: "Token.NotAuthorized",
description: "Access token is invalid or expired."
);
Expand Down
9 changes: 0 additions & 9 deletions PetSearch.API/Common/Errors/MyErrorTypes.cs

This file was deleted.

5 changes: 4 additions & 1 deletion PetSearch.API/Common/Exceptions/MapBoxForbidden.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace PetSearch.API.Common.Exceptions;

public class MapBoxForbidden: Exception
/// <summary>
/// Exception object when we obtain a forbidden response from MapBox API.
/// </summary>
public class MapBoxForbidden : Exception
{
public MapBoxForbidden() : base("Forbidden response from MapBox API")
{
Expand Down
10 changes: 0 additions & 10 deletions PetSearch.API/Common/Exceptions/MissingMapBoxToken.cs

This file was deleted.

9 changes: 4 additions & 5 deletions PetSearch.API/Handlers/BaseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,19 @@ namespace PetSearch.API.Handlers;
public class BaseHandler
{
/// <summary>
/// Returns a problem detail that is rfc7807 compliant based on the list of custom Errors
/// that occurred while using the PetFinder API (https://tools.ietf.org/html/rfc7807).
/// Maps a list Error type to a problem details object.
/// </summary>
/// <param name="errors">List of custom ErrorOr Errors</param>
/// <returns>A problem details object</returns>
/// <returns>A problem details object(rfc7807 compliant).</returns>
protected static IResult GetProblems(List<Error> errors)
{
var firstError = errors[0];
var firstError = errors.First();

var statusCode = firstError.NumericType switch
{
(int)ErrorType.Validation => StatusCodes.Status400BadRequest,
(int)ErrorType.NotFound => StatusCodes.Status404NotFound,
MyErrorTypes.Unauthorized => StatusCodes.Status401Unauthorized,
(int)ErrorType.Unauthorized => StatusCodes.Status401Unauthorized,
_ => StatusCodes.Status500InternalServerError,
};

Expand Down
2 changes: 1 addition & 1 deletion PetSearch.API/Handlers/LocationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using ErrorOr;
using Microsoft.AspNetCore.Mvc;
using PetSearch.API.Clients;
using PetSearch.API.Models.MabBoxResponse;
using PetSearch.API.Models.MapBoxResponse;

namespace PetSearch.API.Handlers;

Expand Down
19 changes: 15 additions & 4 deletions PetSearch.API/Middleware/ExceptionMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
namespace PetSearch.API.Middleware;

/// <summary>
/// Our global middleware that will catch errors and logged them.
/// Our global middleware that will catch errors and log them.
/// </summary>
public class ExceptionMiddleware
{
private const string DefaultErrorDetail = "An error occurred while processing your request.";
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;
private readonly IHostEnvironment _env;
Expand Down Expand Up @@ -37,15 +38,25 @@ public async Task InvokeAsync(HttpContext context)
{
Title = e.Message,
// Only show stack trace in development.
Detail = _env.IsDevelopment() ? e.StackTrace : "An error occurred while processing your request.",
Detail = GetErrorDetail(e),
Status = (int)HttpStatusCode.InternalServerError,
};


// We are outside of our api controller so we need to specify JsonNamingPolicy
// We are outside our api controller, so we need to specify JsonNamingPolicy
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var json = JsonSerializer.Serialize(response, options);
string json = JsonSerializer.Serialize(response, options);
await context.Response.WriteAsync(json);
}
}

/// <summary>
/// Gets the error detail from an exception.
/// </summary>
/// <param name="exception">Exception object</param>
/// <returns>Stacktrace string if in development, else the default error message.</returns>
private string? GetErrorDetail(Exception exception)
{
return _env.IsDevelopment() ? exception.StackTrace : DefaultErrorDetail;
}
}
Loading

0 comments on commit c52ad72

Please sign in to comment.