1 // Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
2 
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Net.Http.Headers;
6 using System.Text;
7 using Microsoft.TestCommon;
8 using Xunit;
9 using Assert = Microsoft.TestCommon.AssertEx;
10 
11 namespace System.Net.Http
12 {
13     public class HttpContentCollectionExtensionsTests
14     {
15         private const string contentID = "content-id";
16         private const string matchContentID = "matchID";
17         private const string matchContentType = "text/plain";
18         private const string matchDispositionName = "N1";
19         private const string quotedMatchDispositionName = "\"" + matchDispositionName + "\"";
20         private const string matchDispositionType = "form-data";
21         private const string quotedMatchDispositionType = "\"" + matchDispositionType + "\"";
22 
23         private const string noMatchContentID = "nomatchID";
24         private const string noMatchContentType = "text/nomatch";
25         private const string noMatchDispositionName = "nomatchName";
26         private const string noMatchDispositionType = "nomatchType";
27 
28         [Fact]
29         [Trait("Description", "IEnumerableHttpContentExtensionMethods is a public static class.")]
TypeIsCorrect()30         public void TypeIsCorrect()
31         {
32             Assert.Type.HasProperties(
33                 typeof(HttpContentCollectionExtensions),
34                 TypeAssert.TypeProperties.IsPublicVisibleClass |
35                 TypeAssert.TypeProperties.IsStatic);
36         }
37 
38 
CreateContent()39         private static IEnumerable<HttpContent> CreateContent()
40         {
41             MultipartFormDataContent multipart = new MultipartFormDataContent();
42 
43             multipart.Add(new StringContent("A", UTF8Encoding.UTF8, matchContentType), matchDispositionName);
44             multipart.Add(new StringContent("B", UTF8Encoding.UTF8, matchContentType), "N2");
45             multipart.Add(new StringContent("C", UTF8Encoding.UTF8, matchContentType), "N3");
46 
47             multipart.Add(new ByteArrayContent(new byte[] { 0x65 }), "N4");
48             multipart.Add(new ByteArrayContent(new byte[] { 0x65 }), "N5");
49             multipart.Add(new ByteArrayContent(new byte[] { 0x65 }), "N6");
50 
51             HttpContent cidContent = new StringContent("<html>A</html>", UTF8Encoding.UTF8, "text/html");
52             cidContent.Headers.Add(contentID, matchContentID);
53             multipart.Add(cidContent);
54 
55             return multipart;
56         }
57 
ClearHeaders(IEnumerable<HttpContent> contents)58         private static void ClearHeaders(IEnumerable<HttpContent> contents)
59         {
60             foreach (var c in contents)
61             {
62                 c.Headers.Clear();
63             }
64         }
65 
66 
67 
68 
69         [Fact]
70         [Trait("Description", "FindAllContentType(IEnumerable<HttpContent>, string) throws on null.")]
FindAllContentTypeString()71         public void FindAllContentTypeString()
72         {
73             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FindAllContentType(null, "text/plain"); }, "contents");
74 
75             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
76             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FindAllContentType(content, (string)null); }, "contentType");
77             foreach (string empty in TestData.EmptyStrings)
78             {
79                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FindAllContentType(content, empty); }, "contentType");
80             }
81         }
82 
83         [Fact]
84         [Trait("Description", "FindAllContentType(IEnumerable<HttpContent>, string) no match.")]
FindAllContentTypeStringNoMatch()85         public void FindAllContentTypeStringNoMatch()
86         {
87             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
88             IEnumerable<HttpContent> result = null;
89             result = content.FindAllContentType(noMatchContentType);
90             Assert.Equal(0, result.Count());
91 
92             ClearHeaders(content);
93             result = content.FindAllContentType(noMatchContentType);
94             Assert.Equal(0, result.Count());
95         }
96 
97         [Fact]
98         [Trait("Description", "FindAllContentType(IEnumerable<HttpContent>, string) match.")]
FindAllContentTypeStringMatch()99         public void FindAllContentTypeStringMatch()
100         {
101             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
102             IEnumerable<HttpContent> result = content.FindAllContentType(matchContentType);
103             Assert.Equal(3, result.Count());
104         }
105 
106         [Fact]
107         [Trait("Description", "FindAllContentType(IEnumerable<HttpContent>, MediaTypeHeaderValue) throws on null.")]
FindAllContentTypeMediaTypeThrows()108         public void FindAllContentTypeMediaTypeThrows()
109         {
110             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FindAllContentType(null, new MediaTypeHeaderValue("text/plain")); }, "contents");
111 
112             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
113             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FindAllContentType(content, (MediaTypeHeaderValue)null); }, "contentType");
114         }
115 
116         [Fact]
117         [Trait("Description", "FindAllContentType(IEnumerable<HttpContent>, MediaTypeHeaderValue) no match.")]
FindAllContentTypeMediaTypeNoMatch()118         public void FindAllContentTypeMediaTypeNoMatch()
119         {
120             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
121             IEnumerable<HttpContent> result = null;
122 
123             result = content.FindAllContentType(new MediaTypeHeaderValue(noMatchContentType));
124             Assert.Equal(0, result.Count());
125 
126             ClearHeaders(content);
127             result = content.FindAllContentType(new MediaTypeHeaderValue(noMatchContentType));
128             Assert.Equal(0, result.Count());
129         }
130 
131         [Fact]
132         [Trait("Description", "FindAllContentType(IEnumerable<HttpContent>, string) match.")]
FindAllContentTypeMediaTypeMatch()133         public void FindAllContentTypeMediaTypeMatch()
134         {
135             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
136             IEnumerable<HttpContent> result = content.FindAllContentType(new MediaTypeHeaderValue(matchContentType));
137             Assert.Equal(3, result.Count());
138         }
139 
140         [Fact]
141         [Trait("Description", "FirstDispositionName(IEnumerable<HttpContent>, string) throws on null.")]
FirstDispositionNameThrows()142         public void FirstDispositionNameThrows()
143         {
144             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionName(null, "A"); }, "contents");
145 
146             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
147             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionName(content, null); }, "dispositionName");
148             foreach (string empty in TestData.EmptyStrings)
149             {
150                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionName(content, empty); }, "dispositionName");
151             }
152         }
153 
154         [Fact]
155         [Trait("Description", "FirstDispositionName(IEnumerable<HttpContent>, string) no match.")]
FirstDispositionNameNoMatch()156         public void FirstDispositionNameNoMatch()
157         {
158             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
159             Assert.Null(content.FirstDispositionNameOrDefault(noMatchDispositionName));
160 
161             ClearHeaders(content);
162             Assert.Throws<InvalidOperationException>(() => content.FirstDispositionName(noMatchDispositionName));
163         }
164 
165         [Fact]
166         [Trait("Description", "FirstDispositionName(IEnumerable<HttpContent>, string) match.")]
FirstDispositionNameMatch()167         public void FirstDispositionNameMatch()
168         {
169             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
170             Assert.NotNull(content.FirstDispositionName(matchDispositionName));
171             Assert.NotNull(content.FirstDispositionName(quotedMatchDispositionName));
172         }
173 
174         [Fact]
175         [Trait("Description", "FirstDispositionNameOrDefault(IEnumerable<HttpContent>, string) throws on null.")]
FirstDispositionNameOrDefaultThrows()176         public void FirstDispositionNameOrDefaultThrows()
177         {
178             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionNameOrDefault(null, "A"); }, "contents");
179 
180             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
181             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionNameOrDefault(content, null); }, "dispositionName");
182             foreach (string empty in TestData.EmptyStrings)
183             {
184                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionNameOrDefault(content, empty); }, "dispositionName");
185             }
186         }
187 
188         [Fact]
189         [Trait("Description", "FirstDispositionName(IEnumerable<HttpContent>, string) no match.")]
FirstDispositionNameOrDefaultNoMatch()190         public void FirstDispositionNameOrDefaultNoMatch()
191         {
192             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
193             Assert.Null(content.FirstDispositionNameOrDefault(noMatchDispositionName));
194 
195             ClearHeaders(content);
196             Assert.Null(content.FirstDispositionNameOrDefault(noMatchDispositionName));
197         }
198 
199         [Fact]
200         [Trait("Description", "FirstDispositionName(IEnumerable<HttpContent>, string) match.")]
FirstDispositionNameOrDefaultMatch()201         public void FirstDispositionNameOrDefaultMatch()
202         {
203             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
204             Assert.NotNull(content.FirstDispositionNameOrDefault(matchDispositionName));
205             Assert.NotNull(content.FirstDispositionNameOrDefault(quotedMatchDispositionName));
206         }
207 
208         [Fact]
209         [Trait("Description", "FirstDispositionType(IEnumerable<HttpContent>, string) throws on null.")]
FirstDispositionTypeThrows()210         public void FirstDispositionTypeThrows()
211         {
212             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionType(null, "A"); }, "contents");
213 
214             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
215             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionType(content, null); }, "dispositionType");
216             foreach (string empty in TestData.EmptyStrings)
217             {
218                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionType(content, empty); }, "dispositionType");
219             }
220         }
221 
222         [Fact]
223         [Trait("Description", "FirstDispositionType(IEnumerable<HttpContent>, string) no match.")]
FirstDispositionTypeNoMatch()224         public void FirstDispositionTypeNoMatch()
225         {
226             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
227             Assert.Throws<InvalidOperationException>(() => content.FirstDispositionType(noMatchDispositionType));
228 
229             Assert.Null(content.FirstDispositionTypeOrDefault(noMatchDispositionType));
230 
231             ClearHeaders(content);
232             Assert.Throws<InvalidOperationException>(() => content.FirstDispositionType(noMatchDispositionType));
233         }
234 
235         [Fact]
236         [Trait("Description", "FirstDispositionType(IEnumerable<HttpContent>, string) match.")]
FirstDispositionTypeMatch()237         public void FirstDispositionTypeMatch()
238         {
239             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
240             Assert.NotNull(content.FirstDispositionType(matchDispositionType));
241             Assert.NotNull(content.FirstDispositionType(quotedMatchDispositionType));
242         }
243 
244         [Fact]
245         [Trait("Description", "FirstDispositionTypeOrDefault(IEnumerable<HttpContent>, string) throws on null.")]
FirstDispositionTypeOrDefaultThrows()246         public void FirstDispositionTypeOrDefaultThrows()
247         {
248             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionTypeOrDefault(null, "A"); }, "contents");
249 
250             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
251             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionTypeOrDefault(content, null); }, "dispositionType");
252             foreach (string empty in TestData.EmptyStrings)
253             {
254                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstDispositionTypeOrDefault(content, empty); }, "dispositionType");
255             }
256         }
257 
258         [Fact]
259         [Trait("Description", "FirstDispositionTypeOrDefault(IEnumerable<HttpContent>, string) no match.")]
FirstDispositionTypeOrDefaultNoMatch()260         public void FirstDispositionTypeOrDefaultNoMatch()
261         {
262             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
263             Assert.Null(content.FirstDispositionTypeOrDefault(noMatchDispositionType));
264 
265             ClearHeaders(content);
266             Assert.Null(content.FirstDispositionTypeOrDefault(noMatchDispositionType));
267         }
268 
269         [Fact]
270         [Trait("Description", "FirstDispositionTypeOrDefault(IEnumerable<HttpContent>, string) match.")]
FirstDispositionTypeOrDefaultMatch()271         public void FirstDispositionTypeOrDefaultMatch()
272         {
273             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
274             Assert.NotNull(content.FirstDispositionTypeOrDefault(matchDispositionType));
275             Assert.NotNull(content.FirstDispositionTypeOrDefault(quotedMatchDispositionType));
276         }
277 
278         [Fact]
279         [Trait("Description", "FirstStart(IEnumerable<HttpContent>, string) throws on null.")]
FirstStartThrows()280         public void FirstStartThrows()
281         {
282             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstStart(null, "A"); }, "contents");
283 
284             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
285             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstStart(content, null); }, "start");
286             foreach (string empty in TestData.EmptyStrings)
287             {
288                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstStart(content, empty); }, "start");
289             }
290         }
291 
292         [Fact]
293         [Trait("Description", "FirstStart(IEnumerable<HttpContent>, string) no match.")]
FirstStartNoMatch()294         public void FirstStartNoMatch()
295         {
296             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
297             Assert.Throws<InvalidOperationException>(() => content.FirstStart(noMatchContentID));
298         }
299 
300         [Fact]
301         [Trait("Description", "FirstStart(IEnumerable<HttpContent>, string) match.")]
FirstStartMatch()302         public void FirstStartMatch()
303         {
304             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
305             Assert.NotNull(content.FirstStart(matchContentID));
306         }
307 
308         [Fact]
309         [Trait("Description", "FirstStartOrDefault(IEnumerable<HttpContent>, string) throws on null.")]
FirstStartOrDefaultThrows()310         public void FirstStartOrDefaultThrows()
311         {
312             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstStartOrDefault(null, "A"); }, "contents");
313 
314             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
315             Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstStartOrDefault(content, null); }, "start");
316             foreach (string empty in TestData.EmptyStrings)
317             {
318                 Assert.ThrowsArgumentNull(() => { HttpContentCollectionExtensions.FirstStartOrDefault(content, empty); }, "start");
319             }
320         }
321 
322         [Fact]
323         [Trait("Description", "FirstStartOrDefault(IEnumerable<HttpContent>, string) no match.")]
FirstStartOrDefaultNoMatch()324         public void FirstStartOrDefaultNoMatch()
325         {
326             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
327             Assert.Null(content.FirstStartOrDefault(noMatchContentID));
328         }
329 
330         [Fact]
331         [Trait("Description", "FirstStartOrDefault(IEnumerable<HttpContent>, string) match.")]
FirstStartOrDefaultMatch()332         public void FirstStartOrDefaultMatch()
333         {
334             IEnumerable<HttpContent> content = HttpContentCollectionExtensionsTests.CreateContent();
335             Assert.NotNull(content.FirstStartOrDefault(matchContentID));
336         }
337     }
338 }