Skip to content

Commit 88218f7

Browse files
committed
chore: Real life scenario tests
1 parent f80ad9a commit 88218f7

2 files changed

Lines changed: 195 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace ObjectSemantics.NET.Tests.MoqModels
5+
{
6+
public class OrderEmailModel
7+
{
8+
public string OrderNo { get; set; }
9+
public DateTime OrderDate { get; set; }
10+
public decimal Subtotal { get; set; }
11+
public decimal Tax { get; set; }
12+
public decimal Total { get; set; }
13+
public bool IsPaid { get; set; }
14+
public OrderCustomer Customer { get; set; }
15+
public List<OrderLineItem> Items { get; set; } = new List<OrderLineItem>();
16+
}
17+
18+
public class OrderCustomer
19+
{
20+
public string FullName { get; set; }
21+
public string Email { get; set; }
22+
public OrderAddress BillingAddress { get; set; }
23+
}
24+
25+
public class OrderAddress
26+
{
27+
public string Line1 { get; set; }
28+
public string City { get; set; }
29+
public string Country { get; set; }
30+
}
31+
32+
public class OrderLineItem
33+
{
34+
public string Name { get; set; }
35+
public int Quantity { get; set; }
36+
public decimal UnitPrice { get; set; }
37+
public decimal LineTotal { get; set; }
38+
}
39+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using ObjectSemantics.NET.Tests.MoqModels;
2+
using System;
3+
using System.Collections.Generic;
4+
using Xunit;
5+
6+
namespace ObjectSemantics.NET.Tests
7+
{
8+
public class RealLifeTemplateScenarioTests
9+
{
10+
[Fact]
11+
public void Should_Render_Order_Confirmation_Email_With_Mixed_Features()
12+
{
13+
OrderEmailModel order = new OrderEmailModel
14+
{
15+
OrderNo = "ORD-1001",
16+
OrderDate = new DateTime(2026, 03, 06, 9, 30, 0),
17+
Subtotal = 2500,
18+
Tax = 400,
19+
Total = 2900,
20+
IsPaid = true,
21+
Customer = new OrderCustomer
22+
{
23+
FullName = "jane doe",
24+
BillingAddress = new OrderAddress
25+
{
26+
Line1 = "12 River Road",
27+
City = "Nairobi",
28+
Country = "Kenya"
29+
}
30+
},
31+
Items = new List<OrderLineItem>
32+
{
33+
new OrderLineItem { Name = "Keyboard", Quantity = 1, UnitPrice = 1200, LineTotal = 1200 },
34+
new OrderLineItem { Name = "Mouse", Quantity = 2, UnitPrice = 650, LineTotal = 1300 }
35+
}
36+
};
37+
38+
var extra = new Dictionary<string, object>
39+
{
40+
["SupportEmail"] = "support@crudsoft.com"
41+
};
42+
43+
string template = "Order {{ OrderNo }}|Date {{ OrderDate:yyyy-MM-dd }}|Customer {{ Customer.FullName:titlecase }}|{{ #if(IsPaid == true) }}PAID{{ #else }}UNPAID{{ #endif }}|Items {{ #foreach(Items) }}[{{ Quantity }}x{{ Name }}={{ LineTotal:N2 }}]{{ #endforeach }}|Ship {{ Customer.BillingAddress.City }},{{ Customer.BillingAddress.Country }}|Total {{ Total:N2 }}|Support {{ SupportEmail }}";
44+
45+
string result = order.Map(template, extra);
46+
string expected = "Order ORD-1001|Date 2026-03-06|Customer Jane Doe|PAID|Items [1xKeyboard=1,200.00][2xMouse=1,300.00]|Ship Nairobi,Kenya|Total 2,900.00|Support support@crudsoft.com";
47+
48+
Assert.Equal(expected, result);
49+
}
50+
51+
[Fact]
52+
public void Should_Evaluate_Nested_If_Condition_For_Message_Routing()
53+
{
54+
OrderEmailModel order = new OrderEmailModel
55+
{
56+
Customer = new OrderCustomer
57+
{
58+
BillingAddress = new OrderAddress
59+
{
60+
Country = "Kenya"
61+
}
62+
}
63+
};
64+
65+
string template = "{{ #if(Customer.BillingAddress.Country == Kenya) }}LOCAL{{ #else }}INTERNATIONAL{{ #endif }}";
66+
string result = order.Map(template);
67+
68+
Assert.Equal("LOCAL", result);
69+
}
70+
71+
[Fact]
72+
public void Should_Fallback_To_Else_When_Intermediate_Nested_Object_Is_Null()
73+
{
74+
OrderEmailModel order = new OrderEmailModel
75+
{
76+
Customer = new OrderCustomer
77+
{
78+
BillingAddress = null
79+
}
80+
};
81+
82+
string template = "{{ #if(Customer.BillingAddress.Country == Kenya) }}LOCAL{{ #else }}INTERNATIONAL{{ #endif }}";
83+
string result = order.Map(template);
84+
85+
Assert.Equal("INTERNATIONAL", result);
86+
}
87+
88+
[Fact]
89+
public void Should_Map_Additional_Parameters_With_Dot_Notation()
90+
{
91+
OrderEmailModel order = new OrderEmailModel
92+
{
93+
OrderNo = "ORD-9999"
94+
};
95+
96+
var extra = new Dictionary<string, object>
97+
{
98+
["Meta.UnsubscribeUrl"] = "https://example.com/unsub/abc123",
99+
["Meta.Channel"] = "EMAIL"
100+
};
101+
102+
string template = "Order {{ OrderNo }} via {{ Meta.Channel }}; Unsubscribe: {{ Meta.UnsubscribeUrl }}";
103+
string result = order.Map(template, extra);
104+
105+
Assert.Equal("Order ORD-9999 via EMAIL; Unsubscribe: https://example.com/unsub/abc123", result);
106+
}
107+
108+
[Fact]
109+
public void Should_Escape_Xml_In_Nested_And_Additional_Values_For_Email()
110+
{
111+
OrderEmailModel order = new OrderEmailModel
112+
{
113+
Customer = new OrderCustomer
114+
{
115+
FullName = "Tom & Jerry <Ltd>"
116+
}
117+
};
118+
119+
var extra = new Dictionary<string, object>
120+
{
121+
["SupportLink"] = "<a href='https://example.com/help'>Help</a>"
122+
};
123+
124+
string template = "{{ Customer.FullName }}|{{ SupportLink }}";
125+
string result = order.Map(template, extra, new TemplateMapperOptions
126+
{
127+
XmlCharEscaping = true
128+
});
129+
130+
Assert.Equal("Tom &amp; Jerry &lt;Ltd&gt;|&lt;a href=&apos;https://example.com/help&apos;&gt;Help&lt;/a&gt;", result);
131+
}
132+
133+
[Fact]
134+
public void Should_Remain_Deterministic_Across_Repeated_Message_Mapping()
135+
{
136+
string template = "Hello {{ Customer.FullName }} - {{ OrderNo }}";
137+
138+
for (int i = 1; i <= 200; i++)
139+
{
140+
OrderEmailModel order = new OrderEmailModel
141+
{
142+
OrderNo = "ORD-" + i.ToString("000", System.Globalization.CultureInfo.InvariantCulture),
143+
Customer = new OrderCustomer
144+
{
145+
FullName = "Customer " + i.ToString(System.Globalization.CultureInfo.InvariantCulture)
146+
}
147+
};
148+
149+
string result = order.Map(template);
150+
string expected = "Hello Customer " + i.ToString(System.Globalization.CultureInfo.InvariantCulture) + " - ORD-" + i.ToString("000", System.Globalization.CultureInfo.InvariantCulture);
151+
152+
Assert.Equal(expected, result);
153+
}
154+
}
155+
}
156+
}

0 commit comments

Comments
 (0)