using System.ComponentModel.DataAnnotations; using System.Net; using System.Text; using AyCode.Services.Nav; using AyCode.Services.Nav.Ekaer; using AyCode.Services.Nav.Ekaer.Models; using TradeType = AyCode.Services.Nav.Ekaer.Models.Common.TradeType; namespace AyCode.Services.Tests.Nav; /// /// Az tesztjei: a validate → send sorrend a valódi /// fölött, fake -rel (nincs valódi hálózat) és stub validátorral. /// [TestClass] public sealed class EkaerSubmitServiceTests { // ---- Test doubles ------------------------------------------------------- private sealed class FakeHttpMessageHandler(HttpStatusCode status, string body) : HttpMessageHandler { public int CallCount { get; private set; } public string? LastRequestBody { get; private set; } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { CallCount++; if (request.Content is not null) LastRequestBody = await request.Content.ReadAsStringAsync(cancellationToken); return new HttpResponseMessage(status) { Content = new StringContent(body, Encoding.UTF8, "text/xml") }; } } private sealed class StubValidator(IReadOnlyList errors) : IEkaerTradeCardValidator { public IReadOnlyList Validate(TradeCardOperationType operation) => errors; public IReadOnlyList Validate(IEnumerable operations) => errors; } private sealed class FakeCredentials : INavCredentials { public string User => "u"; public string Password => "p"; public string SigningKey => "k"; public string TaxNumber => "12345678"; public string BaseUrl => "https://test.example"; } // ---- Helpers ------------------------------------------------------------ private static EkaerSubmitService CreateSut(IReadOnlyList validationErrors, FakeHttpMessageHandler handler) { var manageService = new EkaerManageService(new HttpClient(handler), new FakeCredentials()); return new EkaerSubmitService(manageService, new StubValidator(validationErrors)); } private static string OkResponseXml() => NavXmlHelper.Serialize(new ManageTradeCardsResponse { Result = new BaseResultType { FuncCode = FunctionCodeType.Ok } }); private static TradeCardOperationType SomeOperation() => new() { Index = 1, Operation = OperationType.Create, TradeCard = new TradeCardType { TradeType = TradeType.I } }; // ---- Tesztek ------------------------------------------------------------ [TestMethod] public async Task SubmitAsync_ValidationFails_DoesNotSend() { var handler = new FakeHttpMessageHandler(HttpStatusCode.OK, OkResponseXml()); var sut = CreateSut([new ValidationResult("teszthiba")], handler); var result = await sut.SubmitAsync([SomeOperation()]); Assert.IsFalse(result.IsValid); Assert.AreEqual(1, result.ValidationErrors.Count); Assert.IsNull(result.Response); Assert.AreEqual(0, handler.CallCount, "validációs hiba esetén NEM mehet ki kérés a NAV-nak"); } [TestMethod] public async Task SubmitAsync_Valid_SendsAndReturnsResponse() { var handler = new FakeHttpMessageHandler(HttpStatusCode.OK, OkResponseXml()); var sut = CreateSut([], handler); var result = await sut.SubmitAsync([SomeOperation()]); Assert.IsTrue(result.IsValid); Assert.AreEqual(1, handler.CallCount, "érvényes esetben egy kérés megy ki"); Assert.IsNotNull(result.Response); Assert.AreEqual(0, result.ValidationErrors.Count); } [TestMethod] public async Task SubmitAsync_Valid_RequestContainsOperations() { var handler = new FakeHttpMessageHandler(HttpStatusCode.OK, OkResponseXml()); var sut = CreateSut([], handler); await sut.SubmitAsync([SomeOperation()]); Assert.IsNotNull(handler.LastRequestBody); StringAssert.Contains(handler.LastRequestBody, "tradeCardOperation", "a beküldött XML tartalmazza a műveleteket"); } [TestMethod] public async Task SubmitAsync_NavHttpError_PropagatesNavReportException() { var handler = new FakeHttpMessageHandler(HttpStatusCode.InternalServerError, "boom"); var sut = CreateSut([], handler); await Assert.ThrowsExactlyAsync(() => sut.SubmitAsync([SomeOperation()])); } [TestMethod] public async Task SubmitAsync_NullOperations_Throws() { var handler = new FakeHttpMessageHandler(HttpStatusCode.OK, OkResponseXml()); var sut = CreateSut([], handler); await Assert.ThrowsExactlyAsync(() => sut.SubmitAsync(null!)); } }