/src/openrasta-core/src/OpenRasta.Tests.Unit/Codecs/CodecRepository_Specification.cs

https://github.com/PaulCampbell/openrasta-stable · C# · 324 lines · 236 code · 65 blank · 23 comment · 2 complexity · 82f2f714c6b6ff43f9534420a645bac6 MD5 · raw file

  1. #region License
  2. /* Authors:
  3. * Sebastien Lambla (seb@serialseb.com)
  4. * Copyright:
  5. * (C) 2007-2009 Caffeine IT & naughtyProd Ltd (http://www.caffeine-it.com)
  6. * License:
  7. * This file is distributed under the terms of the MIT License found at the end of this file.
  8. */
  9. #endregion
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using NUnit.Framework;
  15. using OpenRasta.Codecs;
  16. using OpenRasta.IO;
  17. using OpenRasta.Testing;
  18. using OpenRasta.Tests.Unit.Fakes;
  19. using OpenRasta.TypeSystem;
  20. using OpenRasta.Web;
  21. namespace CodecRepository_Specification
  22. {
  23. public class when_searching_for__media_type_reader : codec_repository_context
  24. {
  25. [Test]
  26. public void a_codec_for_a_parent_resource_type_is_found()
  27. {
  28. GivenACodec<CustomerCodec, object>("application/xml");
  29. WhenFindingCodec("application/xml", typeof(Customer));
  30. ThenTheResult.CodecType
  31. .ShouldBe<CustomerCodec>();
  32. }
  33. [Test]
  34. public void a_codec_for_a_parent_resource_type_with_strict_marker_is_not_found()
  35. {
  36. GivenACodec<CustomerCodec, Strictly<object>>("application/xml");
  37. WhenFindingCodec("application/xml", typeof(Customer));
  38. ThenTheResult.ShouldBeNull();
  39. }
  40. [Test]
  41. public void a_codec_for_the_exact_resource_type_is_found()
  42. {
  43. GivenACodec<CustomerCodec, Strictly<Customer>>("application/xml");
  44. WhenFindingCodec("application/xml", typeof(Customer));
  45. ThenTheResult.ShouldNotBeNull()
  46. .CodecType
  47. .ShouldBe<CustomerCodec>();
  48. }
  49. [Test]
  50. public void a_codec_that_is_not_registered_for_all_resource_types_is_not_selected()
  51. {
  52. GivenACodec<CustomerCodec, Customer>("application/xml");
  53. WhenFindingCodec("application/xml", typeof(Customer), typeof(Frodo));
  54. ThenTheResult.ShouldBeNull();
  55. }
  56. [Test]
  57. public void a_wildcard_codec_is_not_selected_wheN_another_codec_has_matching_media_type()
  58. {
  59. GivenACodec<ApplicationOctetStreamCodec, IFile>("*/*;q=0.5");
  60. GivenACodec<MultipartFormDataObjectCodec, IFile>("multipart/form-data;q=0.5");
  61. WhenFindingCodec("multipart/form-data", typeof(IFile));
  62. ThenTheResult.CodecType.ShouldBe<MultipartFormDataObjectCodec>();
  63. }
  64. [Test]
  65. public void a_wildcard_codec_is_selected_if_the_destination_type_is_closest_to_the_param_type()
  66. {
  67. GivenACodec<ApplicationOctetStreamCodec, IFile>("*/*;q=0.4");
  68. GivenACodec<TextPlainCodec, string>("text/plain;q=0.5");
  69. WhenFindingCodec("text/plain", typeof(IFile));
  70. ThenTheResult.CodecType.ShouldBe<ApplicationOctetStreamCodec>();
  71. }
  72. [Test]
  73. public void a_wildcard_selects_the_codec_with_the_highest_quality()
  74. {
  75. GivenACodec<CustomerCodec, object>("application/json;q=0.4");
  76. GivenACodec<AnotherCustomerCodec, object>("application/xml;q=0.3");
  77. WhenFindingCodec("*/*", typeof(Customer));
  78. ThenTheResult.CodecType.ShouldBe<CustomerCodec>();
  79. }
  80. [Test]
  81. public void the_codec_with_the_highest_quality_is_selected()
  82. {
  83. GivenACodec<CustomerCodec, object>("application/xml;q=0.9", "nonspecific");
  84. GivenACodec<AnotherCustomerCodec, object>("application/xml", "specific");
  85. WhenFindingCodec("application/xml", typeof(Customer));
  86. ThenTheResult.CodecType
  87. .ShouldBe<AnotherCustomerCodec>();
  88. ThenTheResult.Configuration
  89. .ShouldBe("specific");
  90. }
  91. [Test]
  92. public void the_most_specific_codec_for_a_resource_type_is_found()
  93. {
  94. GivenACodec<CustomerCodec, object>("application/xml", "nonspecific");
  95. GivenACodec<CustomerCodec, Customer>("application/xml", "specific");
  96. WhenFindingCodec("application/xml", typeof(Customer));
  97. ThenTheResult.CodecType
  98. .ShouldBe<CustomerCodec>();
  99. ThenTheResult.Configuration
  100. .ShouldBe("specific");
  101. }
  102. [Test, Ignore]
  103. public void the_most_specific_codec_is_found_when_matching_against_several_resource_types()
  104. {
  105. }
  106. }
  107. public class when_registering_a_codec : codec_repository_context
  108. {
  109. [Test]
  110. public void the_same_codec_can_be_registered_for_several_content_types()
  111. {
  112. }
  113. [Test]
  114. public void the_same_codec_can_be_registered_for_several_resource_types()
  115. {
  116. }
  117. }
  118. public class when_searching_for_content_type_writers_for_a_media_type : codec_repository_context
  119. {
  120. readonly ITypeSystem typeSystem = TypeSystems.Default;
  121. new IList<CodecRegistration> ThenTheResult;
  122. [Test]
  123. public void generic_types_are_found()
  124. {
  125. GivenACodec<CustomerCodec, IList<Customer>>("application/xml");
  126. WhenFindingCodecsFor<IList<Customer>>("application/xml");
  127. ThenTheResult.Count.ShouldBe(1);
  128. ThenTheResult[0].CodecType
  129. .ShouldBe<CustomerCodec>();
  130. }
  131. [Test]
  132. public void inherited_types_are_found()
  133. {
  134. GivenACodec<CustomerCodec, object>("application/xml");
  135. WhenFindingCodecsFor<IList<Customer>>("application/xml");
  136. ThenTheResult.Count.ShouldBe(1);
  137. ThenTheResult[0].CodecType
  138. .ShouldBe<CustomerCodec>();
  139. }
  140. [Test]
  141. public void interface_types_are_found()
  142. {
  143. GivenACodec<CustomerCodec, IList<Customer>>("application/xml");
  144. WhenFindingCodecsFor<List<Customer>>("application/xml");
  145. ThenTheResult.Count.ShouldBe(1);
  146. ThenTheResult[0].CodecType
  147. .ShouldBe<CustomerCodec>();
  148. }
  149. [Test]
  150. public void matching_is_done_against_parent_interfaces()
  151. {
  152. GivenACodec<AnotherCustomerCodec, IEnumerable>("text/plain");
  153. WhenFindingCodecsFor<IList<Customer>>("text/plain");
  154. ThenTheResult.Count.ShouldBe(1);
  155. ThenTheResult[0].CodecType
  156. .ShouldBe<AnotherCustomerCodec>();
  157. }
  158. [Test]
  159. public void object_registrations_are_found_for_interfaces()
  160. {
  161. GivenACodec<AnotherCustomerCodec, object>("text/plain");
  162. WhenFindingCodecsFor<IList<Customer>>("text/plain");
  163. ThenTheResult.Count.ShouldBe(1);
  164. ThenTheResult[0].CodecType
  165. .ShouldBe<AnotherCustomerCodec>();
  166. }
  167. [Test]
  168. public void only_codecs_for_a_compatible_mime_type_are_selected()
  169. {
  170. GivenACodec<CustomerCodec, IList<Customer>>("application/xml");
  171. GivenACodec<AnotherCustomerCodec, IList<Customer>>("text/plain");
  172. WhenFindingCodecsFor<IList<Customer>>("text/plain");
  173. ThenTheResult.Count.ShouldBe(1);
  174. ThenTheResult[0].CodecType
  175. .ShouldBe<AnotherCustomerCodec>();
  176. }
  177. [Test]
  178. public void the_closest_matching_type_is_selected()
  179. {
  180. GivenACodec<CustomerCodec, object>("application/xml;q=0.5");
  181. GivenACodec<AnotherCustomerCodec, string>("text/plain;q=0.4");
  182. WhenFindingCodecsFor<string>("*/*");
  183. ThenTheResult.Count.ShouldBe(2);
  184. ThenTheResult[0].CodecType.ShouldBe<AnotherCustomerCodec>();
  185. }
  186. [Test]
  187. public void the_server_quality_is_used_in_prioritizing_the_negotiated_media_type()
  188. {
  189. GivenACodec<CustomerCodec, object>(
  190. "application/xhtml+xml;q=0.9,text/html,application/vnd.openrasta.htmlfragment+xml;q=0.5");
  191. WhenFindingCodecsFor<object>("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
  192. ThenTheResult.Count.ShouldBeGreaterThan(0);
  193. ThenTheResult[0].MediaType.ToString().ShouldBe("text/html");
  194. }
  195. protected void WhenFindingCodecsFor<TResourceType>(params string[] contentTypes)
  196. {
  197. ThenTheResult =
  198. Codecs.FindMediaTypeWriter(typeSystem.FromClr(typeof(TResourceType)),
  199. MediaType.Parse(string.Join(",", contentTypes))).ToList();
  200. }
  201. }
  202. public class codec_repository_context : context
  203. {
  204. public ICodecRepository Codecs;
  205. public CodecRegistration ThenTheResult;
  206. public CodecMatch ThenTheResultScoring;
  207. public ITypeSystem TypeSystem = TypeSystems.Default;
  208. [SetUp]
  209. public void Setup()
  210. {
  211. Codecs = new CodecRepository();
  212. ThenTheResult = null;
  213. }
  214. protected void GivenACodec<TCodec, TResource>(string mediaTypes)
  215. {
  216. GivenACodec<TCodec, TResource>(mediaTypes, null);
  217. }
  218. protected void GivenACodec<TCodec, TResource>(string mediaTypes, string config)
  219. {
  220. foreach (var mediaType in MediaType.Parse(mediaTypes))
  221. {
  222. Type resourceType = typeof(TResource);
  223. Codecs.Add(CodecRegistration.FromResourceType(resourceType,
  224. typeof(TCodec),
  225. TypeSystems.Default,
  226. mediaType,
  227. null,
  228. config, false));
  229. }
  230. }
  231. protected void WhenFindingCodec(string contentType, params Type[] resourcetypes)
  232. {
  233. ThenTheResult = null;
  234. ThenTheResultScoring = null;
  235. ThenTheResultScoring = Codecs.FindMediaTypeReader(new MediaType(contentType), resourcetypes.Select(x => (IMember)TypeSystem.FromClr(x)), null);
  236. if (ThenTheResultScoring == null)
  237. return;
  238. ThenTheResult = ThenTheResultScoring.CodecRegistration;
  239. }
  240. }
  241. }
  242. #region Full license
  243. // Permission is hereby granted, free of charge, to any person obtaining
  244. // a copy of this software and associated documentation files (the
  245. // "Software"), to deal in the Software without restriction, including
  246. // without limitation the rights to use, copy, modify, merge, publish,
  247. // distribute, sublicense, and/or sell copies of the Software, and to
  248. // permit persons to whom the Software is furnished to do so, subject to
  249. // the following conditions:
  250. // The above copyright notice and this permission notice shall be
  251. // included in all copies or substantial portions of the Software.
  252. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  253. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  254. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  255. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  256. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  257. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  258. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  259. #endregion