-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #61 from MrDave1999/feat/issue-59
feat: Add result operations to represent the file contents
- Loading branch information
Showing
24 changed files
with
613 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
samples/SimpleResults.Example.AspNetCore/Controllers/FileResultController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
namespace SimpleResults.Example.AspNetCore.Controllers; | ||
|
||
[Tags("FileResult WebApi")] | ||
[Route("FileResult-WebApi")] | ||
public class FileResultController | ||
{ | ||
private readonly FileResultService _fileResultService; | ||
|
||
public FileResultController(FileResultService fileResultService) | ||
{ | ||
_fileResultService = fileResultService; | ||
} | ||
|
||
[SwaggerResponse(type: typeof(byte[]), statusCode: StatusCodes.Status200OK, contentTypes: MediaTypeNames.Application.Pdf)] | ||
[SwaggerResponse(type: typeof(Result), statusCode: StatusCodes.Status400BadRequest, contentTypes: MediaTypeNames.Application.Json)] | ||
[HttpGet("byte-array")] | ||
public Result<ByteArrayFileContent> GetByteArray([FromQuery]FileResultRequest request) | ||
{ | ||
return _fileResultService.GetByteArray(request.FileName); | ||
} | ||
|
||
[SwaggerResponse(type: typeof(byte[]), statusCode: StatusCodes.Status200OK, contentTypes: MediaTypeNames.Application.Pdf)] | ||
[SwaggerResponse(type: typeof(Result), statusCode: StatusCodes.Status400BadRequest, contentTypes: MediaTypeNames.Application.Json)] | ||
[HttpGet("stream")] | ||
public Result<StreamFileContent> GetStream([FromQuery]FileResultRequest request) | ||
{ | ||
return _fileResultService.GetStream(request.FileName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
samples/SimpleResults.Example.AspNetCore/MinimalApi/FileResultEndpoint.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace SimpleResults.Example.AspNetCore.MinimalApi; | ||
|
||
public static class FileResultEndpoint | ||
{ | ||
public static void AddFileResultRoutes(this WebApplication app) | ||
{ | ||
var fileGroup = app | ||
.MapGroup("/FileResult-MinimalApi") | ||
.WithTags("FileResult MinimalApi") | ||
.AddEndpointFilter<TranslateResultToHttpResultFilter>(); | ||
|
||
fileGroup.MapGet("/byte-array", ([AsParameters]FileResultRequest request, FileResultService service) => | ||
{ | ||
return service.GetByteArray(request.FileName); | ||
}) | ||
.Produces<byte[]>(StatusCodes.Status200OK, MediaTypeNames.Application.Pdf) | ||
.Produces<Result>(StatusCodes.Status400BadRequest); | ||
|
||
fileGroup.MapGet("/stream", ([AsParameters]FileResultRequest request, FileResultService service) => | ||
{ | ||
return service.GetStream(request.FileName); | ||
}) | ||
.Produces<byte[]>(StatusCodes.Status200OK, MediaTypeNames.Application.Pdf) | ||
.Produces<Result>(StatusCodes.Status400BadRequest); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
samples/SimpleResults.Example.AspNetCore/Models/FileResultRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace SimpleResults.Example.AspNetCore.Models; | ||
|
||
public class FileResultRequest | ||
{ | ||
public string FileName { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
samples/SimpleResults.Example.Web.Tests/Features/GetFileResultTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
namespace SimpleResults.Example.Web.Tests.Features; | ||
|
||
public class GetFileResultTests | ||
{ | ||
[TestCase(Routes.File.ByteArrayController)] | ||
[TestCase(Routes.File.StreamController)] | ||
[TestCase(Routes.File.ByteArrayMinimalApi)] | ||
[TestCase(Routes.File.StreamMinimalApi)] | ||
public async Task Get_WhenBytesAreObtained_ShouldReturnsHttpStatusCodeOk(string route) | ||
{ | ||
// Arrange | ||
using var factory = new WebApplicationFactory<Program>(); | ||
var client = factory.CreateClient(); | ||
byte[] expected = [1, 1, 0, 0]; | ||
var fileName = "Report.pdf"; | ||
var requestUri = $"{route}?fileName={fileName}"; | ||
|
||
// Act | ||
var httpResponse = await client.GetAsync(requestUri); | ||
byte[] result = await httpResponse | ||
.Content | ||
.ReadAsByteArrayAsync(); | ||
|
||
// Asserts | ||
httpResponse.StatusCode.Should().Be(HttpStatusCode.OK); | ||
result.Should().BeEquivalentTo(expected); | ||
} | ||
|
||
[TestCase(Routes.File.ByteArrayController)] | ||
[TestCase(Routes.File.StreamController)] | ||
[TestCase(Routes.File.ByteArrayMinimalApi)] | ||
[TestCase(Routes.File.StreamMinimalApi)] | ||
public async Task Get_WhenFileNameIsEmpty_ShouldReturnsHttpStatusCodeBadRequest(string requestUri) | ||
{ | ||
// Arrange | ||
using var factory = new WebApplicationFactory<Program>(); | ||
var client = factory.CreateClient(); | ||
|
||
// Act | ||
var httpResponse = await client.GetAsync(requestUri); | ||
var result = await httpResponse | ||
.Content | ||
.ReadFromJsonAsync<Result>(); | ||
|
||
// Asserts | ||
httpResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest); | ||
result.IsSuccess.Should().BeFalse(); | ||
result.Message.Should().NotBeNullOrEmpty(); | ||
result.Errors.Should().BeEmpty(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
namespace SimpleResults.Example; | ||
|
||
public class FileResultService | ||
{ | ||
public Result<ByteArrayFileContent> GetByteArray(string fileName) | ||
{ | ||
if(string.IsNullOrWhiteSpace(fileName)) | ||
{ | ||
return Result.Invalid("FileName is required"); | ||
} | ||
|
||
byte[] content = [1, 1, 0, 0]; | ||
var byteArrayFileContent = new ByteArrayFileContent(content) | ||
{ | ||
ContentType = MediaTypeNames.Application.Pdf, | ||
FileName = fileName | ||
}; | ||
return Result.File(byteArrayFileContent); | ||
} | ||
|
||
public Result<StreamFileContent> GetStream(string fileName) | ||
{ | ||
if (string.IsNullOrWhiteSpace(fileName)) | ||
{ | ||
return Result.Invalid("FileName is required"); | ||
} | ||
|
||
byte[] buffer = [1, 1, 0, 0]; | ||
Stream content = new MemoryStream(buffer); | ||
var streamFileContent = new StreamFileContent(content) | ||
{ | ||
ContentType = MediaTypeNames.Application.Pdf, | ||
FileName = fileName | ||
}; | ||
return Result.File(streamFileContent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
global using FluentValidation; | ||
global using FluentValidation.Results; | ||
global using System.Text.Json.Serialization; | ||
global using System.Text.Json.Serialization; | ||
global using System.Net.Mime; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace SimpleResults; | ||
|
||
internal class FileResultConverter | ||
{ | ||
public static FileContentResult ConvertToFileContentResult(ResultBase resultBase) | ||
{ | ||
var result = resultBase as Result<ByteArrayFileContent>; | ||
if (result is null) | ||
{ | ||
var typeName = typeof(FileContentResult).FullName; | ||
throw new InvalidOperationException(new FailedConversionError(typeName).Message); | ||
} | ||
|
||
var byteArrayFile = result.Data; | ||
var fileContent = new FileContentResult(byteArrayFile.Content, byteArrayFile.ContentType) | ||
{ | ||
FileDownloadName = byteArrayFile.FileName | ||
}; | ||
return fileContent; | ||
} | ||
|
||
public static FileStreamResult ConvertToFileStreamResult(ResultBase resultBase) | ||
{ | ||
var result = resultBase as Result<StreamFileContent>; | ||
if (result is null) | ||
{ | ||
var typeName = typeof(FileStreamResult).FullName; | ||
throw new InvalidOperationException(new FailedConversionError(typeName).Message); | ||
} | ||
|
||
var streamFile = result.Data; | ||
var fileContent = new FileStreamResult(streamFile.Content, streamFile.ContentType) | ||
{ | ||
FileDownloadName = streamFile.FileName | ||
}; | ||
return fileContent; | ||
} | ||
|
||
public static IResult ConvertToFileContentHttpResult(ResultBase resultBase) | ||
{ | ||
var result = resultBase as Result<ByteArrayFileContent>; | ||
if (result is null) | ||
{ | ||
var typeName = typeof(IResult).FullName; | ||
throw new InvalidOperationException(new FailedConversionError(typeName).Message); | ||
} | ||
|
||
var byteArrayFile = result.Data; | ||
var fileContent = Results.File( | ||
byteArrayFile.Content, | ||
byteArrayFile.ContentType, | ||
byteArrayFile.FileName); | ||
|
||
return fileContent; | ||
} | ||
|
||
public static IResult ConvertToFileStreamHttpResult(ResultBase resultBase) | ||
{ | ||
var result = resultBase as Result<StreamFileContent>; | ||
if (result is null) | ||
{ | ||
var typeName = typeof(IResult).FullName; | ||
throw new InvalidOperationException(new FailedConversionError(typeName).Message); | ||
} | ||
|
||
var streamFile = result.Data; | ||
var fileContent = Results.File( | ||
streamFile.Content, | ||
streamFile.ContentType, | ||
streamFile.FileName); | ||
|
||
return fileContent; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using SimpleResults.Resources; | ||
|
||
namespace SimpleResults; | ||
|
||
internal readonly ref struct FailedConversionError | ||
{ | ||
public string Message { get; } | ||
public FailedConversionError(string typeName) | ||
=> Message = string.Format(ResponseMessages.FailedConversion, typeName ?? string.Empty); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.