/src/Typesafe.Mailgun.Tests/FormPartsBuilderTests.cs

https://github.com/typesafe/mnailgun · C# · 252 lines · 217 code · 32 blank · 3 comment · 21 complexity · d33873b3539ddcfce617fe9c6cc3fe5a MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net.Mail;
  6. using System.Net.Mime;
  7. using FluentAssertions;
  8. using Typesafe.Mailgun.Extensions;
  9. using Typesafe.Mailgun.Http;
  10. using Xunit;
  11. namespace Typesafe.Mailgun.Tests
  12. {
  13. [Trait("Category", TestCategory.Unit)]
  14. public class FormPartsBuilderTests
  15. {
  16. /// <summary>
  17. /// Factory method for spinning up a MailMessage to play with.
  18. /// </summary>
  19. private MailMessage BuildMessage(Action<MailMessage> mutator = null)
  20. {
  21. var sender = new MailAddress("somesender@mailinator.com", "Sender");
  22. var recipient = new MailAddress("somerecipient@mailinator.com", "Recipient");
  23. var message = new MailMessage(sender, recipient);
  24. if (mutator != null)
  25. {
  26. mutator(message);
  27. }
  28. return message;
  29. }
  30. [Fact]
  31. public void Build_BCCSpecified_AddsCCPart()
  32. {
  33. var bcc = new MailAddress("test@success.com", "Test Passed");
  34. var message = BuildMessage(x =>
  35. {
  36. x.Bcc.Clear();
  37. x.Bcc.Add(bcc);
  38. });
  39. var result = FormPartsBuilder.Build(message);
  40. result.AssertContains("bcc", bcc.ToString());
  41. }
  42. [Fact]
  43. public void Build_BodyIsHtml_AddsHtmlPart_NoTextPart()
  44. {
  45. var message = BuildMessage(x =>
  46. {
  47. x.IsBodyHtml = true;
  48. x.Body = "<h1>Test Passed</h1>";
  49. });
  50. var result = FormPartsBuilder.Build(message);
  51. result.AssertContains("html", "<h1>Test Passed</h1>");
  52. result.AssertDoesntContain("text");
  53. }
  54. [Fact]
  55. public void Build_BodyIsText_AddsTextPart_NoHtmlPart()
  56. {
  57. var message = BuildMessage(x =>
  58. {
  59. x.IsBodyHtml = false;
  60. x.Body = "Test Passed";
  61. });
  62. var result = FormPartsBuilder.Build(message);
  63. result.AssertContains("text", "Test Passed");
  64. result.AssertDoesntContain("html");
  65. }
  66. [Fact]
  67. public void Build_CCSpecified_AddsCCPart()
  68. {
  69. var cc = new MailAddress("test@success.com", "Test Passed");
  70. var message = BuildMessage(x =>
  71. {
  72. x.CC.Clear();
  73. x.CC.Add(cc);
  74. });
  75. var result = FormPartsBuilder.Build(message);
  76. result.AssertContains("cc", cc.ToString());
  77. }
  78. [Fact]
  79. public void Build_FromSpecified_AddsFromPart()
  80. {
  81. var from = new MailAddress("test@success.com", "Test Passed");
  82. var message = BuildMessage(x => x.From = from);
  83. var result = FormPartsBuilder.Build(message);
  84. result.AssertContains("from", from.ToString());
  85. }
  86. [Fact]
  87. public void Build_MessageHasAttachments_AddsAttachmentParts()
  88. {
  89. var attachment = new Attachment(new MemoryStream(), "Test Attachment");
  90. var message = BuildMessage(x => x.Attachments.Add(attachment));
  91. var result = FormPartsBuilder.Build(message);
  92. result.AssertContains(attachment);
  93. }
  94. [Fact]
  95. public void Build_MessageHasHtmlTextAlternateView_AddsHtmlPart()
  96. {
  97. var view = AlternateView.CreateAlternateViewFromString("<h1>html</h1>", new ContentType("text/html"));
  98. var message = BuildMessage(x => x.AlternateViews.Add(view));
  99. var result = FormPartsBuilder.Build(message);
  100. result.AssertContains("html", "<h1>html</h1>");
  101. }
  102. [Fact]
  103. public void Build_MessageHasPlainTextAlternateView_AddsTextPart_NotHtmlPart()
  104. {
  105. var view = AlternateView.CreateAlternateViewFromString("plaintext", new ContentType("text/plain"));
  106. var message = BuildMessage(x => x.AlternateViews.Add(view));
  107. var result = FormPartsBuilder.Build(message);
  108. result.AssertContains("text", "plaintext");
  109. result.AssertDoesntContain("html");
  110. }
  111. [Fact]
  112. public void Build_MessageHasPlainTextAlternateViewAndBodyIsText_BodyWins()
  113. {
  114. var view = AlternateView.CreateAlternateViewFromString("plaintext", new ContentType("text/plain"));
  115. var message = BuildMessage(x =>
  116. {
  117. x.AlternateViews.Add(view);
  118. x.Body = "success";
  119. x.IsBodyHtml = false;
  120. });
  121. var result = FormPartsBuilder.Build(message);
  122. result.AssertContains("text", "success");
  123. result.AssertDoesntContain("text", "plaintext");
  124. }
  125. [Fact]
  126. public void Build_NullMessage_ReturnsEmptyList()
  127. {
  128. var result = FormPartsBuilder.Build(null);
  129. result.Should().BeEmpty();
  130. }
  131. [Fact]
  132. public void Build_ReplyToSpecified_AddsReplyToPart()
  133. {
  134. var replyTo = new MailAddress("test@success.com", "Test Passed");
  135. var message = BuildMessage(x =>
  136. {
  137. x.ReplyToList.Clear();
  138. x.ReplyToList.Add(replyTo);
  139. });
  140. var result = FormPartsBuilder.Build(message);
  141. result.AssertContains("h:Reply-To", replyTo.ToString());
  142. }
  143. [Fact]
  144. public void Build_SubjectSpecified_AddsSubjectPart()
  145. {
  146. var message = BuildMessage(x => x.Subject = "Test Passed");
  147. var result = FormPartsBuilder.Build(message);
  148. result.AssertContains("subject", "Test Passed");
  149. }
  150. [Fact]
  151. public void Build_TagsSpecified_AddsTagPart()
  152. {
  153. var message = BuildMessage(x => { x.AddTag("TagExample"); });
  154. var result = FormPartsBuilder.Build(message);
  155. result.AssertContains("o:tag", "TagExample");
  156. }
  157. [Fact]
  158. public void Build_ToSpecified_AddsToPart()
  159. {
  160. var to = new MailAddress("test@success.com", "Test Passed");
  161. var message = BuildMessage(x =>
  162. {
  163. x.To.Clear();
  164. x.To.Add(to);
  165. });
  166. var result = FormPartsBuilder.Build(message);
  167. result.AssertContains("to", to.ToString());
  168. }
  169. [Fact]
  170. public void Build_VariablesSpecified_AddsVariablesPart()
  171. {
  172. var message = BuildMessage(x => x.AddVariable("my_message_id", "123"));
  173. var result = FormPartsBuilder.Build(message);
  174. result.AssertContains("v:my_message_id", "123");
  175. }
  176. }
  177. internal static class FormPartsBuilderTestsExtensions
  178. {
  179. internal static void AssertContains(this List<FormPart> parts, string name, string value)
  180. {
  181. parts.Should()
  182. .NotBeNullOrEmpty(
  183. $"Expected FormParts list to contain '{name}' with value '{value}', but the list is null / empty.");
  184. var match = parts.OfType<SimpleFormPart>().Where(x => x.Name == name && x.Value == value);
  185. match.Should()
  186. .NotBeNullOrEmpty(
  187. "Expected FormParts list to contain '{0}' with value '{1}', but no matching name/value pair was found.",
  188. name, value);
  189. }
  190. internal static void AssertDoesntContain(this List<FormPart> parts, string name)
  191. {
  192. if (parts == null || !parts.Any()) return;
  193. parts.OfType<SimpleFormPart>()
  194. .Should()
  195. .NotContain(x => x.Name == name, "Found FormPart item in list named '{0}'.", name);
  196. }
  197. internal static void AssertDoesntContain(this List<FormPart> parts, string name, string value)
  198. {
  199. if (parts == null || !parts.Any())
  200. return;
  201. var match = parts.OfType<SimpleFormPart>().Where(x => x.Name == name && x.Value == value);
  202. if (!match.Any())
  203. return;
  204. match.Should().BeEmpty("Found FormPart item in list named '{0}' with value '{1}'.", name, value);
  205. }
  206. internal static void AssertContains(this List<FormPart> parts, Attachment attachment)
  207. {
  208. if (parts == null || !parts.Any())
  209. parts.Should()
  210. .BeNullOrEmpty("Expected FormParts list to contain attachment '{0}', but the list is null/empty.",
  211. attachment.Name);
  212. var match = parts.OfType<AttachmentFormPart>().Where(x => x.Attachment == attachment);
  213. if (!match.Any())
  214. match.Should()
  215. .BeNullOrEmpty(
  216. "Expected FormParts list to contain attachment '{0}', but no matching item was found.",
  217. attachment.Name);
  218. }
  219. }
  220. }