using Domain; using System.Reflection; using static TestData.ClientBuilder; using static TestData.OrderBuilder; namespace Web.Tests; /// The WebApp consumes only DTOs; persistence types are excluded at compile time (no Web → Db project reference). public class WebAppTests { // The WebApp's public API references no domain type (reflection). private static readonly Type[] BannedTypes = [typeof(Client), typeof(Order)]; private static IEnumerable TypeAndArguments(Type t) { yield return t; if (t.IsGenericType) foreach (var arg in t.GetGenericArguments()) foreach (var nested in TypeAndArguments(arg)) yield return nested; if (t.IsArray && t.GetElementType() is { } elem) foreach (var nested in TypeAndArguments(elem)) yield return nested; } [Fact] public void WebApp_public_api_references_no_domain_types() { var app = typeof(WebApp); var banned = BannedTypes.ToList(); foreach (var m in app.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { var signature = m.GetParameters() .Select(p => p.ParameterType) .Append(m.ReturnType) .ToList(); foreach (var t in signature.SelectMany(TypeAndArguments)) Assert.False(banned.Contains(t), $"WebApp.{m.Name}({string.Join(", ", signature)}) references banned type {t}"); } foreach (var p in app.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) foreach (var t in TypeAndArguments(p.PropertyType)) Assert.False(banned.Contains(t), $"WebApp.{p.Name} references banned type {t}"); } [Fact] public void WebApp_consumes_dtos() { var app = new WebApp(); var order = ValidOrder().WithId(Guid.NewGuid()).WithDescription("order one").WithTotal(150_00).Build(); var client = ValidClient().WithId(Guid.NewGuid()).WithName("Acme").WithOrder(order).Build(); var view = app.ShowClient(DtoMappers.ToClientDto(client)); Assert.Contains("Acme", view); Assert.Contains("order one", view); } }