diff --git a/tests/Meezi.API.Tests/DiscoverFilterTests.cs b/tests/Meezi.API.Tests/DiscoverFilterTests.cs
index ae0dc54..01a52df 100644
--- a/tests/Meezi.API.Tests/DiscoverFilterTests.cs
+++ b/tests/Meezi.API.Tests/DiscoverFilterTests.cs
@@ -1,5 +1,6 @@
using Meezi.API.Services;
using Meezi.Core.Discover;
+using Xunit;
namespace Meezi.API.Tests;
@@ -44,7 +45,8 @@ public class DiscoverFilterTests
noise: "quiet",
priceTier: "mid",
size: null,
- requireProfile: true);
+ requireProfile: true,
+ openNow: false);
Assert.Equal("تهران", f.City);
Assert.Equal(4, f.MinRating);
Assert.Contains("modern", f.Themes!);
diff --git a/tests/Meezi.API.Tests/NoOpAbuseProtectionService.cs b/tests/Meezi.API.Tests/NoOpAbuseProtectionService.cs
new file mode 100644
index 0000000..7a668fb
--- /dev/null
+++ b/tests/Meezi.API.Tests/NoOpAbuseProtectionService.cs
@@ -0,0 +1,26 @@
+using Meezi.API.Security;
+
+namespace Meezi.API.Tests;
+
+/// Test double that allows every action and has no captcha configured.
+internal sealed class NoOpAbuseProtectionService : IAbuseProtectionService
+{
+ public bool IsCaptchaConfigured => false;
+ public string? CaptchaSiteKey => null;
+
+ public Task<(bool Allowed, string? ErrorCode, string? Message)> CheckAuthOtpByIpAsync(
+ string clientIp, CancellationToken cancellationToken = default) =>
+ Task.FromResult<(bool, string?, string?)>((true, null, null));
+
+ public Task<(bool Allowed, string? ErrorCode, string? Message)> CheckGuestOrderAsync(
+ string cafeId, string clientIp, CancellationToken cancellationToken = default) =>
+ Task.FromResult<(bool, string?, string?)>((true, null, null));
+
+ public Task<(bool Allowed, string? ErrorCode, string? Message)> CheckPublicWriteByIpAsync(
+ string clientIp, CancellationToken cancellationToken = default) =>
+ Task.FromResult<(bool, string?, string?)>((true, null, null));
+
+ public Task<(bool Ok, string? ErrorCode, string? Message)> VerifyCaptchaAsync(
+ string? captchaToken, CancellationToken cancellationToken = default) =>
+ Task.FromResult<(bool, string?, string?)>((true, null, null));
+}
diff --git a/tests/Meezi.API.Tests/NoOpInventoryService.cs b/tests/Meezi.API.Tests/NoOpInventoryService.cs
index d894f66..3794e5a 100644
--- a/tests/Meezi.API.Tests/NoOpInventoryService.cs
+++ b/tests/Meezi.API.Tests/NoOpInventoryService.cs
@@ -16,9 +16,17 @@ internal sealed class NoOpInventoryService : IInventoryService
public Task UpdateAsync(string cafeId, string ingredientId, UpdateIngredientRequest request, CancellationToken ct = default) =>
Task.FromResult(null);
- public Task AdjustAsync(string cafeId, string ingredientId, AdjustStockRequest request, CancellationToken ct = default) =>
+ public Task AdjustAsync(string cafeId, string ingredientId, AdjustStockRequest request, string? userId, CancellationToken ct = default) =>
Task.FromResult(null);
+ public Task GetPurchasesSummaryAsync(
+ string cafeId,
+ string branchId,
+ DateOnly from,
+ DateOnly to,
+ CancellationToken ct = default) =>
+ Task.FromResult(new InventoryPurchasesSummaryDto(0, 0, []));
+
public Task GetRecipeAsync(string cafeId, string menuItemId, CancellationToken ct = default) =>
Task.FromResult(null);
diff --git a/tests/Meezi.API.Tests/NoOpLoyaltyService.cs b/tests/Meezi.API.Tests/NoOpLoyaltyService.cs
index cfc2f35..292d874 100644
--- a/tests/Meezi.API.Tests/NoOpLoyaltyService.cs
+++ b/tests/Meezi.API.Tests/NoOpLoyaltyService.cs
@@ -1,4 +1,5 @@
using Meezi.API.Services;
+using Meezi.Core.Entities;
namespace Meezi.API.Tests;
@@ -10,4 +11,11 @@ internal sealed class NoOpLoyaltyService : ILoyaltyService
decimal paidAmount,
CancellationToken ct = default) =>
Task.CompletedTask;
+
+ public Task<(bool Success, LoyaltyRedeemResult? Data, string? ErrorCode)> RedeemOnOrderAsync(
+ string cafeId,
+ Order order,
+ int pointsRequested,
+ CancellationToken ct = default) =>
+ Task.FromResult<(bool, LoyaltyRedeemResult?, string?)>((false, null, null));
}
diff --git a/tests/Meezi.API.Tests/NoOpMediaStorageService.cs b/tests/Meezi.API.Tests/NoOpMediaStorageService.cs
new file mode 100644
index 0000000..50ca2be
--- /dev/null
+++ b/tests/Meezi.API.Tests/NoOpMediaStorageService.cs
@@ -0,0 +1,29 @@
+using Meezi.API.Services;
+using Microsoft.AspNetCore.Http;
+
+namespace Meezi.API.Tests;
+
+/// Test double that stores nothing and returns no URL.
+internal sealed class NoOpMediaStorageService : IMediaStorageService
+{
+ public Task SaveMenuImageAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveMenuVideoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveTableImageAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveTableVideoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveCafeLogoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveCafeCoverAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveMenuModel3dAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveMenuModel3dFromBytesAsync(string cafeId, byte[] glbBytes, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveReviewPhotoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+ public Task SaveCafeGalleryPhotoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
+ Task.FromResult(null);
+}
diff --git a/tests/Meezi.API.Tests/NoOpOrderNotificationService.cs b/tests/Meezi.API.Tests/NoOpOrderNotificationService.cs
index b2deae8..9d688ca 100644
--- a/tests/Meezi.API.Tests/NoOpOrderNotificationService.cs
+++ b/tests/Meezi.API.Tests/NoOpOrderNotificationService.cs
@@ -11,4 +11,7 @@ internal sealed class NoOpOrderNotificationService : IOrderNotificationService
public Task NotifyOrderStatusChangedAsync(Order order, CancellationToken ct = default) =>
Task.CompletedTask;
+
+ public Task NotifyCallWaiterAsync(string cafeId, string tableId, string tableNumber, CancellationToken ct = default) =>
+ Task.CompletedTask;
}
diff --git a/tests/Meezi.API.Tests/PrintingTests.cs b/tests/Meezi.API.Tests/PrintingTests.cs
index fe60152..0334aa4 100644
--- a/tests/Meezi.API.Tests/PrintingTests.cs
+++ b/tests/Meezi.API.Tests/PrintingTests.cs
@@ -28,6 +28,7 @@ public class PrintingTests
218_000m,
0m,
DateTime.UtcNow,
+ 1,
[
new OrderItemDto("i1", "m1", "Espresso", 2, 100_000m, null),
new OrderItemDto("i2", "m2", "Void Latte", 1, 50_000m, null, true)
diff --git a/tests/Meezi.API.Tests/QrMenuTests.cs b/tests/Meezi.API.Tests/QrMenuTests.cs
index da91e40..40ab6a6 100644
--- a/tests/Meezi.API.Tests/QrMenuTests.cs
+++ b/tests/Meezi.API.Tests/QrMenuTests.cs
@@ -1,11 +1,13 @@
using Meezi.API.Models.Menu;
using Meezi.API.Models.Orders;
using Meezi.API.Models.Public;
+using Meezi.API.Security;
using Meezi.API.Services;
using Meezi.Core.Entities;
using Meezi.Core.Enums;
using Meezi.Core.Interfaces;
using Meezi.Infrastructure.Data;
+using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Xunit;
@@ -114,7 +116,11 @@ public class QrMenuTests
var tables = new TableService(db, config, kds, identity);
var shifts = new ShiftService(db);
var orders = new OrderService(db, kds, new NoOpSnappfood(), new NoOpDeliverySync(), shifts, TestServiceScopeFactory.Create(), new NoOpOrderNotificationService(), new NoOpInventoryService(), new NoOpLoyaltyService());
- var publicSvc = new PublicService(db, orders, new ReviewService(db), kds, branchMenu, identity);
+ var abuse = new NoOpAbuseProtectionService();
+ var http = new HttpContextAccessor();
+ var media = new NoOpMediaStorageService();
+ var reviews = new ReviewService(db, abuse, http, media);
+ var publicSvc = new PublicService(db, orders, reviews, kds, branchMenu, identity, abuse, http);
return (db, tables, publicSvc, cafeId, branchId, tableId, itemA, itemB, qrCode);
}