using Domain.Entities.Members;
using Domain.Entities.Payments;
using Domain.Entities.Payments.ValueObject;
using Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
namespace Application.Tests;
///
/// LocalDB 기반 테스트 DB. 운영과 동일한 SQL Server 프로바이더를 사용해
/// rowversion 동시성·유니크 인덱스 등 관계형 동작을 그대로 검증한다.
///
[TestClass]
public sealed class TestDb
{
private const string ConnectionString = @"Server=(localdb)\MSSQLLocalDB;Database=antooza_test;Integrated Security=True;TrustServerCertificate=True;";
public static DbContextOptions Options { get; } = new DbContextOptionsBuilder().UseSqlServer(ConnectionString).Options;
public static AppDbContext Create() => new(Options);
[AssemblyInitialize]
public static void AssemblyInit(TestContext _)
{
using var db = Create();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
}
public static async Task CreateMemberAsync(AppDbContext db)
{
var member = Member.Create($"test-{Guid.NewGuid():N}@antooza.test");
await db.Member.AddAsync(member);
await db.SaveChangesAsync(default);
return member.ID;
}
public static async Task CreateOrderAsync(AppDbContext db, int memberID, int pointAmount = 10000, bool paid = false)
{
var order = PaymentOrder.Create(memberID, $"ORD-{Guid.NewGuid():N}", "TOSS", pointAmount, PaymentMethod.Integrated);
if (paid)
{
// TossConfirm.PaymentKey 에 unique 인덱스가 있고 테스트 DB 는 어셈블리 단위로 공유되므로
// 주문별 고유 paymentKey(TransactionID)를 부여해 테스트 간 시드 충돌을 방지한다.
order.MarkPaid($"TX-{Guid.NewGuid():N}");
}
await db.PaymentOrder.AddAsync(order);
await db.SaveChangesAsync(default);
return order;
}
}