using System.Text; using ApiOPE.Configuration; using ApiOPE.Contracts; using ApiOPE.Security; using ApiOPE.Services; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; namespace ApiOPE.Tests; public sealed class OpeProtocolTests { [Fact] public void ResponseSigner_MatchesGestionaHexThenBase64Algorithm() { var signer = new OpeResponseSigner(Options.Create(new OpeOptions { SecretKey = "test-secret-key-with-more-than-32-characters" })); var signature = signer.Sign("26cd0da5-c45f-497d-b380-820c03cf3237"); Assert.Equal( "MmE0MjEwM2Y1NTM2NjRkM2FmMzRhNDZlNmQxNjE0NzVmNmE0OTQxNDUxN2NlYmU2ODZjOTZiYzg5YmFjY2FmYw==", signature); } [Fact] public void ResponseSigner_PreservesUuidTextCasing() { var signer = new OpeResponseSigner(Options.Create(new OpeOptions { SecretKey = "test-secret-key-with-more-than-32-characters" })); Assert.NotEqual( signer.Sign("26cd0da5-c45f-497d-b380-820c03cf3237"), signer.Sign("26CD0DA5-C45F-497D-B380-820C03CF3237")); } [Fact] public async Task RequestReader_AcceptsVendorJsonMediaType() { var context = CreateHttpContext( "application/vnd.generic-operation-request+json; charset=utf-8", """ {"data":{"FIELD_0":{"type":"STRING","value":"53/2026"}}} """); var result = await GenericOperationRequestReader.ReadAsync( context.Request, CancellationToken.None); Assert.True(result.IsValid); Assert.Equal("53/2026", result.Request!.Data["FIELD_0"].Value); } [Fact] public async Task RequestReader_ReturnsFieldErrorsForUnexpectedInput() { var context = CreateHttpContext( OpeMediaTypes.GenericOperationRequest, """ {"data":{"FIELD_1":{"type":"STRING","value":"unexpected"}}} """); var result = await GenericOperationRequestReader.ReadAsync( context.Request, CancellationToken.None); Assert.False(result.IsValid); Assert.Equal(OpeFieldErrors.NotExpected, result.Errors["FIELD_1"]); Assert.Equal(OpeFieldErrors.Expected, result.Errors["FIELD_0"]); } private static DefaultHttpContext CreateHttpContext(string contentType, string body) { var context = new DefaultHttpContext(); context.Request.ContentType = contentType; context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body)); return context; } }