feat: add receipt upload API and target net10
Build MoneyMap image / build-and-push (push) Failing after 10s
Build MoneyMap image / build-and-push (push) Failing after 10s
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moq;
|
||||
using MoneyMap.Controllers;
|
||||
using MoneyMap.Models;
|
||||
using MoneyMap.Services;
|
||||
using MoneyMap.Tests.TestHelpers;
|
||||
|
||||
namespace MoneyMap.Tests.Controllers;
|
||||
|
||||
public class ReceiptsControllerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Upload_NoFile_ReturnsBadRequest()
|
||||
{
|
||||
using var context = DbContextHelper.CreateInMemoryContext();
|
||||
var manager = new Mock<IReceiptManager>();
|
||||
var controller = CreateController(context, manager.Object);
|
||||
|
||||
var result = await controller.Upload(null);
|
||||
|
||||
Assert.IsType<BadRequestObjectResult>(result);
|
||||
manager.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upload_UnmappedFile_QueuesReceiptAndReturnsMetadata()
|
||||
{
|
||||
using var context = DbContextHelper.CreateInMemoryContext();
|
||||
var manager = new Mock<IReceiptManager>();
|
||||
var receipt = new Receipt
|
||||
{
|
||||
Id = 42,
|
||||
FileName = "receipt.png",
|
||||
ContentType = "image/png",
|
||||
FileSizeBytes = 3,
|
||||
UploadedAtUtc = new DateTime(2026, 9, 11, 12, 0, 0, DateTimeKind.Utc),
|
||||
ParseStatus = ReceiptParseStatus.Queued
|
||||
};
|
||||
manager.Setup(m => m.UploadUnmappedReceiptAsync(It.IsAny<IFormFile>()))
|
||||
.ReturnsAsync(ReceiptUploadResult.Success(receipt));
|
||||
var controller = CreateController(context, manager.Object);
|
||||
|
||||
var result = await controller.Upload(CreateFormFile("receipt.png"));
|
||||
|
||||
var ok = Assert.IsType<OkObjectResult>(result);
|
||||
using var json = JsonDocument.Parse(JsonSerializer.Serialize(ok.Value));
|
||||
Assert.Equal(42, json.RootElement.GetProperty("Id").GetInt64());
|
||||
Assert.Equal("Queued", json.RootElement.GetProperty("ParseStatus").GetString());
|
||||
Assert.Equal(JsonValueKind.Null, json.RootElement.GetProperty("TransactionId").ValueKind);
|
||||
manager.Verify(m => m.UploadUnmappedReceiptAsync(It.IsAny<IFormFile>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upload_WithTransactionId_DelegatesToMappedUpload()
|
||||
{
|
||||
using var context = DbContextHelper.CreateInMemoryContext();
|
||||
var manager = new Mock<IReceiptManager>();
|
||||
manager.Setup(m => m.UploadReceiptAsync(99, It.IsAny<IFormFile>()))
|
||||
.ReturnsAsync(ReceiptUploadResult.Failure("Transaction not found."));
|
||||
var controller = CreateController(context, manager.Object);
|
||||
|
||||
var result = await controller.Upload(CreateFormFile("receipt.png"), 99);
|
||||
|
||||
var badRequest = Assert.IsType<BadRequestObjectResult>(result);
|
||||
using var json = JsonDocument.Parse(JsonSerializer.Serialize(badRequest.Value));
|
||||
Assert.Equal("Transaction not found.", json.RootElement.GetProperty("message").GetString());
|
||||
manager.Verify(m => m.UploadReceiptAsync(99, It.IsAny<IFormFile>()), Times.Once);
|
||||
}
|
||||
|
||||
private static ReceiptsController CreateController(
|
||||
MoneyMap.Data.MoneyMapContext context,
|
||||
IReceiptManager receiptManager) =>
|
||||
new(context, new TestReceiptStorageOptions(), receiptManager);
|
||||
|
||||
private static IFormFile CreateFormFile(string fileName)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes("png");
|
||||
return new FormFile(new MemoryStream(bytes), 0, bytes.Length, "file", fileName)
|
||||
{
|
||||
Headers = new HeaderDictionary(),
|
||||
ContentType = "image/png"
|
||||
};
|
||||
}
|
||||
|
||||
private sealed class TestReceiptStorageOptions : IReceiptStorageOptions
|
||||
{
|
||||
public string ReceiptsBasePath => Path.GetTempPath();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user