test: repair test suite broken by feature drift (red -> 81 passing)
CI/CD / CI · API (dotnet build + test) (pull_request) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (pull_request) Successful in 44s
CI/CD / CI · Dashboard (tsc) (pull_request) Successful in 1m7s
CI/CD / CI · Admin Web (tsc) (pull_request) Successful in 36s
CI/CD / CI · Website (tsc) (pull_request) Successful in 45s
CI/CD / CI · Koja (tsc) (pull_request) Successful in 51s
CI/CD / Deploy · all services (pull_request) Has been skipped
CI/CD / CI · API (dotnet build + test) (pull_request) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (pull_request) Successful in 44s
CI/CD / CI · Dashboard (tsc) (pull_request) Successful in 1m7s
CI/CD / CI · Admin Web (tsc) (pull_request) Successful in 36s
CI/CD / CI · Website (tsc) (pull_request) Successful in 45s
CI/CD / CI · Koja (tsc) (pull_request) Successful in 51s
CI/CD / Deploy · all services (pull_request) Has been skipped
The test project no longer compiled: recent feature commits changed interfaces and DTOs without updating the test doubles/call sites, so the whole suite (and therefore CI) was failing to build. - NoOpInventoryService: add IInventoryService.GetPurchasesSummaryAsync and the new string? userId param on AdjustAsync. - NoOpLoyaltyService: add ILoyaltyService.RedeemOnOrderAsync. - NoOpOrderNotificationService: add NotifyCallWaiterAsync. - New NoOpAbuseProtectionService and NoOpMediaStorageService test doubles. - QrMenuTests: ReviewService/PublicService gained IAbuseProtectionService + IHttpContextAccessor (and ReviewService an IMediaStorageService); wire the new no-op doubles + a real HttpContextAccessor. - PrintingTests: OrderDto gained a DisplayNumber int between CreatedAt and Items; pass it. - DiscoverFilterTests: add missing `using Xunit;` and the new openNow arg on DiscoverFilterParams.FromQuery. Result: dotnet test -> Passed: 81, Failed: 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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!);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Meezi.API.Security;
|
||||
|
||||
namespace Meezi.API.Tests;
|
||||
|
||||
/// <summary>Test double that allows every action and has no captcha configured.</summary>
|
||||
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));
|
||||
}
|
||||
@@ -16,9 +16,17 @@ internal sealed class NoOpInventoryService : IInventoryService
|
||||
public Task<IngredientDto?> UpdateAsync(string cafeId, string ingredientId, UpdateIngredientRequest request, CancellationToken ct = default) =>
|
||||
Task.FromResult<IngredientDto?>(null);
|
||||
|
||||
public Task<IngredientDto?> AdjustAsync(string cafeId, string ingredientId, AdjustStockRequest request, CancellationToken ct = default) =>
|
||||
public Task<IngredientDto?> AdjustAsync(string cafeId, string ingredientId, AdjustStockRequest request, string? userId, CancellationToken ct = default) =>
|
||||
Task.FromResult<IngredientDto?>(null);
|
||||
|
||||
public Task<InventoryPurchasesSummaryDto> GetPurchasesSummaryAsync(
|
||||
string cafeId,
|
||||
string branchId,
|
||||
DateOnly from,
|
||||
DateOnly to,
|
||||
CancellationToken ct = default) =>
|
||||
Task.FromResult(new InventoryPurchasesSummaryDto(0, 0, []));
|
||||
|
||||
public Task<MenuItemRecipeDto?> GetRecipeAsync(string cafeId, string menuItemId, CancellationToken ct = default) =>
|
||||
Task.FromResult<MenuItemRecipeDto?>(null);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Meezi.API.Services;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Meezi.API.Tests;
|
||||
|
||||
/// <summary>Test double that stores nothing and returns no URL.</summary>
|
||||
internal sealed class NoOpMediaStorageService : IMediaStorageService
|
||||
{
|
||||
public Task<string?> SaveMenuImageAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveMenuVideoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveTableImageAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveTableVideoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveCafeLogoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveCafeCoverAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveMenuModel3dAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveMenuModel3dFromBytesAsync(string cafeId, byte[] glbBytes, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveReviewPhotoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
public Task<string?> SaveCafeGalleryPhotoAsync(string cafeId, IFormFile file, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<string?>(null);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user