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