Files
MoneyMap/MoneyMap.Tests/Controllers/ReceiptsControllerTests.cs
T
aj 08e54a4d31
Build MoneyMap image / build-and-push (push) Failing after 10s
feat: add receipt upload API and target net10
2026-09-11 20:31:51 -04:00

93 lines
3.5 KiB
C#

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();
}
}