feat(api): add validation for connect account request
This commit is contained in:
@@ -9,7 +9,9 @@ internal static class Endpoint
|
|||||||
return groupBuilder.MapPost(Route, HandleAsync);
|
return groupBuilder.MapPost(Route, HandleAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IResult> HandleAsync()
|
private static async Task<IResult> HandleAsync(
|
||||||
|
[FromBody] Request request
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return Results.Ok();
|
return Results.Ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
namespace FiscalOS.API.Accounts.Connect;
|
||||||
|
|
||||||
|
public record Request : IValidatableObject
|
||||||
|
{
|
||||||
|
public string PublicToken { get; init; } = string.Empty;
|
||||||
|
public string PlaidInstitutionId { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(PublicToken))
|
||||||
|
{
|
||||||
|
var fieldName = nameof(PublicToken);
|
||||||
|
yield return new($"The {fieldName} field is required.", [fieldName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PlaidInstitutionId))
|
||||||
|
{
|
||||||
|
var fieldName = nameof(PlaidInstitutionId);
|
||||||
|
yield return new($"The {fieldName} field is required.", [fieldName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,4 +11,73 @@ public class ConnectTests(TestApi testApi) : IntegrationTest(testApi)
|
|||||||
|
|
||||||
await res.Should().BeProblemDetails(HttpStatusCode.Unauthorized);
|
await res.Should().BeProblemDetails(HttpStatusCode.Unauthorized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Connect_WhenCalledWithoutPublicTokenOrPlaidInstitutionId_ItShouldReturn400WithProblemDetails()
|
||||||
|
{
|
||||||
|
var jwt = JwtTokenBuilder.New()
|
||||||
|
.WithClaim(JwtRegisteredClaimNames.Sub, Guid.NewGuid().ToString())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
using var content = new StringContent(JsonSerializer.Serialize(new { }), Encoding.UTF8, "application/json");
|
||||||
|
using var request = new HttpRequestMessage(HttpMethod.Post, ConnectUri)
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
};
|
||||||
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt);
|
||||||
|
|
||||||
|
var response = await Client.SendAsync(request, TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
|
await response.Should().BeValidationProblemDetails(new Dictionary<string, string[]>()
|
||||||
|
{
|
||||||
|
["PublicToken"] = ["The PublicToken field is required."],
|
||||||
|
["PlaidInstitutionId"] = ["The PlaidInstitutionId field is required."],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Connect_WhenCalledWithoutPublicToken_ItShouldReturn400WithProblemDetails()
|
||||||
|
{
|
||||||
|
var jwt = JwtTokenBuilder.New()
|
||||||
|
.WithClaim(JwtRegisteredClaimNames.Sub, Guid.NewGuid().ToString())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(new { plaidInstitutionId = "id" });
|
||||||
|
using var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||||
|
using var request = new HttpRequestMessage(HttpMethod.Post, ConnectUri)
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
};
|
||||||
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt);
|
||||||
|
|
||||||
|
var response = await Client.SendAsync(request, TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
|
await response.Should().BeValidationProblemDetails(new Dictionary<string, string[]>()
|
||||||
|
{
|
||||||
|
["PublicToken"] = ["The PublicToken field is required."],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Connect_WhenCalledWithoutPlaidInstitutionId_ItShouldReturn400WithProblemDetails()
|
||||||
|
{
|
||||||
|
var jwt = JwtTokenBuilder.New()
|
||||||
|
.WithClaim(JwtRegisteredClaimNames.Sub, Guid.NewGuid().ToString())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(new { publicToken = "token" });
|
||||||
|
using var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||||
|
using var request = new HttpRequestMessage(HttpMethod.Post, ConnectUri)
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
};
|
||||||
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt);
|
||||||
|
|
||||||
|
var response = await Client.SendAsync(request, TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
|
await response.Should().BeValidationProblemDetails(new Dictionary<string, string[]>()
|
||||||
|
{
|
||||||
|
["PlaidInstitutionId"] = ["The PlaidInstitutionId field is required."],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,8 @@ global using System.Net.Http.Headers;
|
|||||||
global using System.Net.Http.Json;
|
global using System.Net.Http.Json;
|
||||||
global using System.Security.Claims;
|
global using System.Security.Claims;
|
||||||
global using System.Security.Cryptography;
|
global using System.Security.Cryptography;
|
||||||
|
global using System.Text;
|
||||||
|
global using System.Text.Json;
|
||||||
|
|
||||||
global using AwesomeAssertions.Execution;
|
global using AwesomeAssertions.Execution;
|
||||||
global using AwesomeAssertions.Primitives;
|
global using AwesomeAssertions.Primitives;
|
||||||
|
|||||||
Reference in New Issue
Block a user