PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/test/System.Net.Http.Formatting.Test.Unit/Formatting/MediaTypeFormatterTestBase.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 379 lines | 286 code | 52 blank | 41 comment | 4 complexity | 3703e6896df4967efbda9aca3b42304c MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Net.Http.Headers;
  5. using System.Runtime.Serialization;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using Microsoft.TestCommon;
  9. using Moq;
  10. using Xunit;
  11. using Xunit.Extensions;
  12. using Assert = Microsoft.TestCommon.AssertEx;
  13. namespace System.Net.Http.Formatting
  14. {
  15. /// <summary>
  16. /// A test class for common <see cref="MediaTypeFormatter"/> functionality across multiple implementations.
  17. /// </summary>
  18. /// <typeparam name="TFormatter">The type of formatter under test.</typeparam>
  19. public abstract class MediaTypeFormatterTestBase<TFormatter> where TFormatter : MediaTypeFormatter, new()
  20. {
  21. protected MediaTypeFormatterTestBase()
  22. {
  23. }
  24. public abstract IEnumerable<MediaTypeHeaderValue> ExpectedSupportedMediaTypes { get; }
  25. public abstract IEnumerable<Encoding> ExpectedSupportedEncodings { get; }
  26. /// <summary>
  27. /// Byte representation of an <see cref="SampleType"/> with value 42 using the default encoding
  28. /// for this media type formatter.
  29. /// </summary>
  30. public abstract byte[] ExpectedSampleTypeByteRepresentation { get; }
  31. [Fact]
  32. public void TypeIsCorrect()
  33. {
  34. Assert.Type.HasProperties<TFormatter, MediaTypeFormatter>(TypeAssert.TypeProperties.IsPublicVisibleClass);
  35. }
  36. [Fact]
  37. public void SupportEncoding_DefaultSupportedMediaTypes()
  38. {
  39. TFormatter formatter = new TFormatter();
  40. Assert.True(ExpectedSupportedMediaTypes.SequenceEqual(formatter.SupportedMediaTypes));
  41. }
  42. [Fact]
  43. public void SupportEncoding_DefaultSupportedEncodings()
  44. {
  45. TFormatter formatter = new TFormatter();
  46. Assert.True(ExpectedSupportedEncodings.SequenceEqual(formatter.SupportedEncodings));
  47. }
  48. [Fact]
  49. public void ReadFromStreamAsync_ThrowsOnNull()
  50. {
  51. TFormatter formatter = new TFormatter();
  52. Assert.ThrowsArgumentNull(() => { formatter.ReadFromStreamAsync(null, Stream.Null, null, null); }, "type");
  53. Assert.ThrowsArgumentNull(() => { formatter.WriteToStreamAsync(typeof(object), null, null, null, null); }, "stream");
  54. }
  55. [Fact]
  56. public Task ReadFromStreamAsync_WhenContentLengthIsZero_DoesNotReadStream()
  57. {
  58. // Arrange
  59. TFormatter formatter = new TFormatter();
  60. Mock<Stream> mockStream = new Mock<Stream>();
  61. IFormatterLogger mockFormatterLogger = new Mock<IFormatterLogger>().Object;
  62. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  63. contentHeaders.ContentLength = 0;
  64. // Act
  65. return formatter.ReadFromStreamAsync(typeof(object), mockStream.Object, contentHeaders, mockFormatterLogger).
  66. ContinueWith(
  67. readTask =>
  68. {
  69. // Assert
  70. mockStream.Verify(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()), Times.Never());
  71. mockStream.Verify(s => s.ReadByte(), Times.Never());
  72. mockStream.Verify(s => s.BeginRead(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()), Times.Never());
  73. });
  74. }
  75. [Fact]
  76. public Task ReadFromStreamAsync_WhenContentLengthIsZero_DoesNotCloseStream()
  77. {
  78. // Arrange
  79. TFormatter formatter = new TFormatter();
  80. Mock<Stream> mockStream = new Mock<Stream>();
  81. IFormatterLogger mockFormatterLogger = new Mock<IFormatterLogger>().Object;
  82. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  83. contentHeaders.ContentLength = 0;
  84. // Act
  85. return formatter.ReadFromStreamAsync(typeof(object), mockStream.Object, contentHeaders, mockFormatterLogger).
  86. ContinueWith(
  87. readTask =>
  88. {
  89. // Assert
  90. mockStream.Verify(s => s.Close(), Times.Never());
  91. });
  92. }
  93. [Theory]
  94. [InlineData(false)]
  95. [InlineData(0)]
  96. [InlineData("")]
  97. public void ReadFromStreamAsync_WhenContentLengthIsZero_ReturnsDefaultTypeValue<T>(T value)
  98. {
  99. // Arrange
  100. TFormatter formatter = new TFormatter();
  101. HttpContent content = new StringContent("");
  102. // Act
  103. var result = formatter.ReadFromStreamAsync(typeof(T), content.ReadAsStreamAsync().Result,
  104. content.Headers, null);
  105. result.WaitUntilCompleted();
  106. // Assert
  107. Assert.Equal(default(T), (T)result.Result);
  108. }
  109. [Fact]
  110. public Task ReadFromStreamAsync_ReadsDataButDoesNotCloseStream()
  111. {
  112. // Arrange
  113. TFormatter formatter = new TFormatter();
  114. MemoryStream memStream = new MemoryStream(ExpectedSampleTypeByteRepresentation);
  115. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  116. contentHeaders.ContentLength = memStream.Length;
  117. // Act
  118. return formatter.ReadFromStreamAsync(typeof(SampleType), memStream, contentHeaders, null).ContinueWith(
  119. readTask =>
  120. {
  121. // Assert
  122. var value = Assert.IsType<SampleType>(readTask.Result);
  123. Assert.Equal(42, value.Number);
  124. Assert.True(memStream.CanRead);
  125. });
  126. }
  127. [Fact]
  128. public Task ReadFromStreamAsync_WhenContentLengthIsNull_ReadsDataButDoesNotCloseStream()
  129. {
  130. // Arrange
  131. TFormatter formatter = new TFormatter();
  132. MemoryStream memStream = new MemoryStream(ExpectedSampleTypeByteRepresentation);
  133. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  134. contentHeaders.ContentLength = null;
  135. // Act
  136. return formatter.ReadFromStreamAsync(typeof(SampleType), memStream, contentHeaders, null).ContinueWith(
  137. readTask =>
  138. {
  139. // Assert
  140. var value = Assert.IsType<SampleType>(readTask.Result);
  141. Assert.Equal(42, value.Number);
  142. Assert.True(memStream.CanRead);
  143. });
  144. }
  145. [Fact]
  146. public void WriteToStreamAsync_ThrowsOnNull()
  147. {
  148. TFormatter formatter = new TFormatter();
  149. Assert.ThrowsArgumentNull(() => { formatter.WriteToStreamAsync(null, new object(), Stream.Null, null, null); }, "type");
  150. Assert.ThrowsArgumentNull(() => { formatter.WriteToStreamAsync(typeof(object), new object(), null, null, null); }, "stream");
  151. }
  152. [Fact]
  153. public Task WriteToStreamAsync_WhenObjectIsNull_WritesDataButDoesNotCloseStream()
  154. {
  155. // Arrange
  156. TFormatter formatter = new TFormatter();
  157. Mock<Stream> mockStream = new Mock<Stream>();
  158. mockStream.Setup(s => s.CanWrite).Returns(true);
  159. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  160. // Act
  161. return formatter.WriteToStreamAsync(typeof(object), null, mockStream.Object, contentHeaders, null).ContinueWith(
  162. writeTask =>
  163. {
  164. // Assert
  165. mockStream.Verify(s => s.Close(), Times.Never());
  166. mockStream.Verify(s => s.BeginWrite(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()), Times.Never());
  167. });
  168. }
  169. [Fact]
  170. public Task WriteToStreamAsync_WritesDataButDoesNotCloseStream()
  171. {
  172. // Arrange
  173. TFormatter formatter = new TFormatter();
  174. SampleType sampleType = new SampleType { Number = 42 };
  175. MemoryStream memStream = new MemoryStream();
  176. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  177. // Act
  178. return formatter.WriteToStreamAsync(typeof(SampleType), sampleType, memStream, contentHeaders, null).ContinueWith(
  179. writeTask =>
  180. {
  181. // Assert
  182. byte[] actualSampleTypeByteRepresentation = memStream.ToArray();
  183. Assert.Equal(ExpectedSampleTypeByteRepresentation, actualSampleTypeByteRepresentation);
  184. Assert.True(memStream.CanRead);
  185. });
  186. }
  187. public abstract Task ReadFromStreamAsync_UsesCorrectCharacterEncoding(string content, string encoding, bool isDefaultEncoding);
  188. public abstract Task WriteToStreamAsync_UsesCorrectCharacterEncoding(string content, string encoding, bool isDefaultEncoding);
  189. public Task ReadFromStreamAsync_UsesCorrectCharacterEncodingHelper(MediaTypeFormatter formatter, string content, string formattedContent, string mediaType, string encoding, bool isDefaultEncoding)
  190. {
  191. // Arrange
  192. Encoding enc = null;
  193. if (isDefaultEncoding)
  194. {
  195. enc = formatter.SupportedEncodings.First((e) => e.WebName.Equals(encoding, StringComparison.OrdinalIgnoreCase));
  196. }
  197. else
  198. {
  199. enc = Encoding.GetEncoding(encoding);
  200. formatter.SupportedEncodings.Add(enc);
  201. }
  202. byte[] data = enc.GetBytes(formattedContent);
  203. MemoryStream memStream = new MemoryStream(data);
  204. StringContent dummyContent = new StringContent(string.Empty);
  205. HttpContentHeaders headers = dummyContent.Headers;
  206. headers.Clear();
  207. headers.ContentType = MediaTypeHeaderValue.Parse(mediaType);
  208. headers.ContentLength = data.Length;
  209. IFormatterLogger mockFormatterLogger = new Mock<IFormatterLogger>().Object;
  210. // Act
  211. return formatter.ReadFromStreamAsync(typeof(string), memStream, headers, mockFormatterLogger).ContinueWith(
  212. (readTask) =>
  213. {
  214. string result = readTask.Result as string;
  215. // Assert
  216. Assert.True(readTask.IsCompleted);
  217. Assert.Equal(content, result);
  218. });
  219. }
  220. public Task WriteToStreamAsync_UsesCorrectCharacterEncodingHelper(MediaTypeFormatter formatter, string content, string formattedContent, string mediaType, string encoding, bool isDefaultEncoding)
  221. {
  222. // Arrange
  223. Encoding enc = null;
  224. if (isDefaultEncoding)
  225. {
  226. enc = formatter.SupportedEncodings.First((e) => e.WebName.Equals(encoding, StringComparison.OrdinalIgnoreCase));
  227. }
  228. else
  229. {
  230. enc = Encoding.GetEncoding(encoding);
  231. formatter.SupportedEncodings.Add(enc);
  232. }
  233. byte[] preamble = enc.GetPreamble();
  234. byte[] data = enc.GetBytes(formattedContent);
  235. byte[] expectedData = new byte[preamble.Length + data.Length];
  236. Buffer.BlockCopy(preamble, 0, expectedData, 0, preamble.Length);
  237. Buffer.BlockCopy(data, 0, expectedData, preamble.Length, data.Length);
  238. MemoryStream memStream = new MemoryStream();
  239. HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders();
  240. contentHeaders.Clear();
  241. contentHeaders.ContentType = MediaTypeHeaderValue.Parse(mediaType);
  242. contentHeaders.ContentLength = expectedData.Length;
  243. IFormatterLogger mockFormatterLogger = new Mock<IFormatterLogger>().Object;
  244. // Act
  245. return formatter.WriteToStreamAsync(typeof(string), content, memStream, contentHeaders, null).ContinueWith(
  246. (writeTask) =>
  247. {
  248. // Assert
  249. Assert.True(writeTask.IsCompleted);
  250. byte[] actualData = memStream.ToArray();
  251. Assert.Equal(expectedData, actualData);
  252. });
  253. }
  254. public static Task ReadContentUsingCorrectCharacterEncodingHelper(MediaTypeFormatter formatter, string content, string formattedContent, string mediaType, string encoding, bool isDefaultEncoding)
  255. {
  256. // Arrange
  257. Encoding enc = null;
  258. if (isDefaultEncoding)
  259. {
  260. enc = formatter.SupportedEncodings.First((e) => e.WebName.Equals(encoding, StringComparison.OrdinalIgnoreCase));
  261. }
  262. else
  263. {
  264. enc = Encoding.GetEncoding(encoding);
  265. formatter.SupportedEncodings.Add(enc);
  266. }
  267. byte[] data = enc.GetBytes(formattedContent);
  268. MemoryStream memStream = new MemoryStream(data);
  269. StringContent dummyContent = new StringContent(string.Empty);
  270. HttpContentHeaders headers = dummyContent.Headers;
  271. headers.Clear();
  272. headers.ContentType = MediaTypeHeaderValue.Parse(mediaType);
  273. headers.ContentLength = data.Length;
  274. IFormatterLogger mockFormatterLogger = new Mock<IFormatterLogger>().Object;
  275. // Act
  276. return formatter.ReadFromStreamAsync(typeof(string), memStream, headers, mockFormatterLogger).ContinueWith(
  277. (readTask) =>
  278. {
  279. string result = readTask.Result as string;
  280. // Assert
  281. Assert.True(readTask.IsCompleted);
  282. Assert.Equal(content, result);
  283. });
  284. }
  285. public static Task WriteContentUsingCorrectCharacterEncodingHelper(MediaTypeFormatter formatter, string content, string formattedContent, string mediaType, string encoding, bool isDefaultEncoding)
  286. {
  287. // Arrange
  288. Encoding enc = null;
  289. if (isDefaultEncoding)
  290. {
  291. enc = formatter.SupportedEncodings.First((e) => e.WebName.Equals(encoding, StringComparison.OrdinalIgnoreCase));
  292. }
  293. else
  294. {
  295. enc = Encoding.GetEncoding(encoding);
  296. formatter.SupportedEncodings.Add(enc);
  297. }
  298. byte[] preamble = enc.GetPreamble();
  299. byte[] data = enc.GetBytes(formattedContent);
  300. byte[] expectedData = new byte[preamble.Length + data.Length];
  301. Buffer.BlockCopy(preamble, 0, expectedData, 0, preamble.Length);
  302. Buffer.BlockCopy(data, 0, expectedData, preamble.Length, data.Length);
  303. MemoryStream memStream = new MemoryStream();
  304. StringContent dummyContent = new StringContent(string.Empty);
  305. HttpContentHeaders headers = dummyContent.Headers;
  306. headers.Clear();
  307. headers.ContentType = MediaTypeHeaderValue.Parse(mediaType);
  308. headers.ContentLength = expectedData.Length;
  309. IFormatterLogger mockFormatterLogger = new Mock<IFormatterLogger>().Object;
  310. // Act
  311. return formatter.WriteToStreamAsync(typeof(string), content, memStream, headers, null).ContinueWith(
  312. (writeTask) =>
  313. {
  314. // Assert
  315. Assert.True(writeTask.IsCompleted);
  316. byte[] actualData = memStream.ToArray();
  317. Assert.Equal(expectedData, actualData);
  318. });
  319. }
  320. [DataContract(Name = "DataContractSampleType")]
  321. public class SampleType
  322. {
  323. [DataMember]
  324. public int Number { get; set; }
  325. }
  326. }
  327. }