using System.Net;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using FluentAssertions;
using foodmarket.IntegrationTests.Support;
using Xunit;
namespace foodmarket.IntegrationTests;
/// Регресс по hotfix-invoice500: до фикса
/// POST /api/purchases/invoices/upload ложился в 500 из-за
/// NOT NULL constraint на UpdatedAt. Тест ХОДИТ ЧЕРЕЗ HTTP на реальной
/// Postgres (Testcontainers), с мульти-файловой multipart-формой, чтобы впредь
/// заметить, если кто-то снова сделает UpdatedAt NOT NULL.
[Collection(ApiCollection.Name)]
public class InvoiceUploadHttpTests
{
private readonly ApiFactory _factory;
public InvoiceUploadHttpTests(ApiFactory factory) => _factory = factory;
[Fact]
public async Task Upload_single_file_returns_200_and_persists_row()
{
var http = _factory.CreateClient();
var actor = new ApiActor(http);
await actor.SignupAndLoginAsync($"invup-{Guid.NewGuid():N}".Substring(0, 20));
using var form = new MultipartFormDataContent();
var bytes = Encoding.UTF8.GetBytes("not a real jpeg — байты всё равно сохранятся как файл");
var filePart = new ByteArrayContent(bytes);
filePart.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
form.Add(filePart, "files", "invoice-test.jpg");
var resp = await http.PostAsync("/api/purchases/invoices/upload", form);
var body = await resp.Content.ReadAsStringAsync();
resp.StatusCode.Should().Be(HttpStatusCode.OK, $"body: {body}");
var json = JsonDocument.Parse(body).RootElement;
var ids = json.GetProperty("ids").EnumerateArray().Select(e => e.GetGuid()).ToList();
ids.Should().HaveCount(1);
// detail endpoint тоже должен корректно отвечать 200 (UpdatedAt null в select'е ок)
var detail = await http.GetFromJsonAsync($"/api/purchases/invoices/{ids[0]}");
detail.GetProperty("fileName").GetString().Should().Be("invoice-test.jpg");
detail.GetProperty("status").GetString().Should().Be("pending");
}
[Fact]
public async Task Upload_multiple_files_in_one_request_all_persist()
{
var http = _factory.CreateClient();
var actor = new ApiActor(http);
await actor.SignupAndLoginAsync($"invup2-{Guid.NewGuid():N}".Substring(0, 20));
using var form = new MultipartFormDataContent();
for (var i = 0; i < 3; i++)
{
var fp = new ByteArrayContent(Encoding.UTF8.GetBytes($"file-{i}"));
fp.Headers.ContentType = new MediaTypeHeaderValue("image/png");
form.Add(fp, "files", $"inv-{i}.png");
}
var resp = await http.PostAsync("/api/purchases/invoices/upload", form);
resp.StatusCode.Should().Be(HttpStatusCode.OK);
var ids = (await resp.Content.ReadFromJsonAsync())
.GetProperty("ids").EnumerateArray().Select(e => e.GetGuid()).ToList();
ids.Should().HaveCount(3);
}
}