using Meezi.API.Configuration; using Meezi.API.Models.Snappfood; using Meezi.API.Models.Tap30; using Meezi.API.Services.Delivery; using Meezi.Core.Delivery; using Meezi.Core.Enums; using Meezi.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Xunit; namespace Meezi.API.Tests; public class DeliveryIntegrationTests { private static DeliveryPlatformsOptions TestOptions() => new() { DefaultSnappfoodCommissionPercent = 18, DefaultTap30CommissionPercent = 15 }; [Fact] public void OrderNormalizer_Snappfood_MapsToUnifiedOrder() { var normalizer = new OrderNormalizer(); var unified = normalizer.FromSnappfood(new SnappfoodWebhookOrder( "sf-100", "vendor-1", "Ali", "09121234567", 250_000m, [new SnappfoodWebhookItem("Espresso", 2, 100_000m)])); Assert.NotNull(unified); Assert.Equal("sf-100", unified!.ExternalId); Assert.Equal(DeliveryPlatform.Snappfood, unified.Platform); Assert.Equal(2, unified.Items[0].Quantity); Assert.Equal(UnifiedDeliveryStatus.Confirmed, unified.Status); } [Fact] public void OrderNormalizer_Tap30_MapsToUnifiedOrder() { var normalizer = new OrderNormalizer(); var unified = normalizer.FromTap30(new Tap30WebhookOrder( "t30-55", "tap-vendor", new Tap30Customer("Sara", "09129876543", "Tehran", null, null), 180_000m, "online", true, null, "delivery", 35, null, null, "confirmed", [new Tap30WebhookItem("latte-1", "Latte", 1, 180_000m, null)])); Assert.NotNull(unified); Assert.Equal(DeliveryPlatform.Tap30, unified!.Platform); Assert.Equal("Sara", unified.Customer.Name); Assert.Equal(35, unified.Delivery.EstimatedMinutes); } [Fact] public async Task CommissionCalculator_SnappfoodDefault_Is18Percent() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; await using var db = new AppDbContext(options); var calc = new CommissionCalculator(db, Options.Create(TestOptions())); var commission = await calc.CalculateForOrderAsync( "cafe-1", new UnifiedDeliveryOrder( "x1", DeliveryPlatform.Snappfood, "v1", DateTime.UtcNow, new UnifiedDeliveryCustomer("A", "09"), [new UnifiedDeliveryItem("1", "Coffee", 1, 100_000m)], new UnifiedDeliveryPayment(100_000m, "online", true), new UnifiedDeliveryInfo("delivery"), UnifiedDeliveryStatus.Confirmed)); Assert.Equal(18_000m, commission); } [Fact] public async Task CommissionCalculator_Tap30Default_Is15Percent() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; await using var db = new AppDbContext(options); var calc = new CommissionCalculator(db, Options.Create(TestOptions())); var rate = await calc.ResolveRatePercentAsync("cafe-1", DeliveryPlatform.Tap30); Assert.Equal(15m, rate); Assert.Equal(15_000m, calc.CalculateCommission(100_000m, rate)); } [Fact] public void WebhookSignature_ValidHmac_Accepts() { const string secret = "test-secret"; const string body = """{"orderId":"1"}"""; var expected = WebhookSignatureService.ComputeHmacSha256Hex(body, secret); var svc = new WebhookSignatureService(Options.Create(new DeliveryPlatformsOptions { Snappfood = new SnappfoodPlatformOptions { WebhookSecret = secret } })); Assert.True(svc.Verify(DeliveryPlatform.Snappfood, body, expected)); Assert.True(svc.Verify(DeliveryPlatform.Snappfood, body, $"sha256={expected}")); } }