using Meezi.API.Models.Orders; using Meezi.API.Models.Tables; using Meezi.API.Services; using Meezi.Core.Entities; using Meezi.Core.Enums; using Meezi.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using Xunit; namespace Meezi.API.Tests; public class BranchTableTests { private sealed class NullKdsNotifier : IKdsNotifier { public Task NotifyOrderCreatedAsync(string cafeId, LiveOrderDto order, CancellationToken cancellationToken = default) => Task.CompletedTask; public Task NotifyOrderStatusChangedAsync(string cafeId, string orderId, OrderStatus status, CancellationToken cancellationToken = default) => Task.CompletedTask; public Task NotifyTableStatusChangedAsync(string cafeId, CancellationToken cancellationToken = default) => Task.CompletedTask; } private static (AppDbContext Db, TableService Tables, string CafeId, string BranchA, string BranchB, string ManagerId) CreateFixture() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; var db = new AppDbContext(options); var config = new Microsoft.Extensions.Configuration.ConfigurationBuilder().Build(); var tables = new TableService(db, config, new NullKdsNotifier(), new BranchIdentityService(db)); var cafeId = "cafe-1"; var branchA = "branch-a"; var branchB = "branch-b"; var managerId = "mgr-1"; db.Cafes.Add(new Cafe { Id = cafeId, Name = "Test", Slug = "test", PlanTier = PlanTier.Pro }); db.Branches.AddRange( new Branch { Id = branchA, CafeId = cafeId, Name = "A", IsActive = true, UpdatedAt = DateTime.UtcNow }, new Branch { Id = branchB, CafeId = cafeId, Name = "B", IsActive = true, UpdatedAt = DateTime.UtcNow }); db.Employees.Add(new Employee { Id = managerId, CafeId = cafeId, BranchId = branchA, Name = "Manager", Phone = "09121111111", Role = EmployeeRole.Manager }); db.Tables.AddRange( new Table { Id = "t-a", CafeId = cafeId, BranchId = branchA, Number = "1", QrCode = "qr-a" }, new Table { Id = "t-b", CafeId = cafeId, BranchId = branchB, Number = "2", QrCode = "qr-b" }); db.SaveChanges(); return (db, tables, cafeId, branchA, branchB, managerId); } [Fact] public async Task GetTables_ReturnsBranchTablesOnly() { var (_, tables, cafeId, branchA, _, _) = CreateFixture(); var result = await tables.GetBranchTablesAsync(cafeId, branchA); Assert.NotNull(result); Assert.Single(result); Assert.Equal("t-a", result[0].Id); } [Fact] public async Task GetTables_DoesNotReturnOtherBranchTables() { var (_, tables, cafeId, branchA, _, _) = CreateFixture(); var result = await tables.GetBranchTablesAsync(cafeId, branchA); Assert.NotNull(result); Assert.DoesNotContain(result, t => t.Id == "t-b"); } [Fact] public async Task CreateTable_AssignsToBranch() { var (db, tables, cafeId, branchA, _, _) = CreateFixture(); var created = await tables.CreateBranchTableAsync( cafeId, branchA, new CreateBranchTableRequest("9", 6)); Assert.True(created.Success); Assert.Equal(branchA, created.Data!.BranchId); Assert.Equal(1, await db.Tables.CountAsync(t => t.BranchId == branchA && t.Number == "9")); } [Fact] public async Task DeleteTable_WithOpenOrder_ReturnsTableHasOpenOrder() { var (db, tables, cafeId, branchA, _, _) = CreateFixture(); db.Orders.Add(new Order { Id = "ord-1", CafeId = cafeId, BranchId = branchA, TableId = "t-a", Status = OrderStatus.Preparing, OrderType = OrderType.DineIn, Subtotal = 100, Total = 100 }); await db.SaveChangesAsync(); var result = await tables.DeleteBranchTableAsync(cafeId, branchA, "t-a"); Assert.False(result.Success); Assert.Equal("TABLE_HAS_OPEN_ORDER", result.ErrorCode); } [Fact] public async Task DeleteSection_WithTables_ReturnsTableSectionHasTables() { var (db, tables, cafeId, branchA, _, _) = CreateFixture(); var section = new TableSection { Id = "sec-1", CafeId = cafeId, BranchId = branchA, Name = "Hall" }; db.TableSections.Add(section); var table = await db.Tables.FirstAsync(t => t.Id == "t-a"); table.SectionId = section.Id; await db.SaveChangesAsync(); var result = await tables.DeleteBranchSectionAsync(cafeId, branchA, section.Id); Assert.False(result.Success); Assert.Equal("TABLE_SECTION_HAS_TABLES", result.ErrorCode); } [Fact] public async Task ManagerCannotAccessOtherBranchTables() { var (_, tables, cafeId, _, branchB, managerId) = CreateFixture(); var allowed = await tables.CanAccessBranchAsync( cafeId, branchB, managerId, EmployeeRole.Manager); Assert.False(allowed); } }