summaryrefslogtreecommitdiff
path: root/external/aspnetwebstack/test/System.Net.Http.Formatting.Test.Unit/UriQueryUtilityTests.cs
blob: 8f47e1598112860ef1151e1a3d074056c4b4fd9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net.Http.Formatting;
using System.Net.Http.Internal;
using System.Text;
using Microsoft.TestCommon;
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;

namespace System.Net.Http
{
    public class UriQueryUtilityTests
    {
        [Fact]
        public void TypeIsCorrect()
        {
            Assert.Type.HasProperties(typeof(UriQueryUtility), TypeAssert.TypeProperties.IsClass | TypeAssert.TypeProperties.IsStatic);
        }

        #region UrlEncode

        [Fact]
        public void UrlEncodeReturnsNull()
        {
            Assert.Null(UriQueryUtility.UrlEncode(null));
        }

        public void UrlEncodeToBytesThrowsOnInvalidArgs()
        {
            Assert.Null(UriQueryUtility.UrlEncodeToBytes(null, 0, 0));
            Assert.ThrowsArgumentNull(() => UriQueryUtility.UrlEncodeToBytes(null, 0, 2), "bytes");

            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlEncodeToBytes(new byte[0], -1, 0), "offset", null);
            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlEncodeToBytes(new byte[0], 2, 0), "offset", null);

            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlEncodeToBytes(new byte[0], 0, -1), "count", null);
            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlEncodeToBytes(new byte[0], 0, 2), "count", null);
        }

        #endregion

        #region UrlDecode

        [Fact]
        public void UrlDecodeReturnsNull()
        {
            Assert.Null(UriQueryUtility.UrlDecode(null));
        }

        [Fact]
        public void UrlDecodeParsesEmptySegmentsCorrectly()
        {
            int iterations = 16;
            List<string> segments = new List<string>();

            for (int index = 1; index < iterations; index++)
            {
                segments.Add("&");
                string query = string.Join("", segments);
                NameValueCollection result = ParseQueryString(query);
                Assert.NotNull(result);

                // Because this is a NameValueCollection, the same name appears only once
                Assert.Equal(1, result.Count);

                // Values should be a comma separated list of empty strings
                string[] values = result[""].Split(new char[] { ',' });

                // We expect length+1 segment as the final '&' counts as a segment 
                Assert.Equal(index + 1, values.Length);
                foreach (var value in values)
                {
                    Assert.Equal("", value);
                }
            }
        }

        public static TheoryDataSet<string, string, string> UriQueryData
        {
            get
            {
                return UriQueryTestData.UriQueryData;
            }
        }

        private static string CreateQuery(params string[] segments)
        {
            StringBuilder buffer = new StringBuilder();
            bool first = true;
            foreach (string segment in segments)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    buffer.Append('&');
                }

                buffer.Append(segment);
            }

            return buffer.ToString();
        }

        [Theory]
        [InlineData("N", "N", "")]
        [InlineData("%26", "&", "")]
        [PropertyData("UriQueryData")]
        public void UrlDecodeParsesCorrectly(string segment, string resultName, string resultValue)
        {
            int iterations = 16;
            List<string> segments = new List<string>();

            for (int index = 1; index < iterations; index++)
            {
                segments.Add(segment);
                string query = CreateQuery(segments.ToArray());
                NameValueCollection result = ParseQueryString(query);
                Assert.NotNull(result);

                // Because this is a NameValueCollection, the same name appears only once
                Assert.Equal(1, result.Count);

                // Values should be a comma separated list of resultValue
                string[] values = result[resultName].Split(new char[] { ',' });
                Assert.Equal(index, values.Length);
                foreach (var value in values)
                {
                    Assert.Equal(resultValue, value);
                }
            }
        }

        public void UrlDecodeToBytesThrowsOnInvalidArgs()
        {
            Assert.Null(UriQueryUtility.UrlDecodeToBytes(null, 0, 0));
            Assert.ThrowsArgumentNull(() => UriQueryUtility.UrlDecodeToBytes(null, 0, 2), "bytes");

            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlDecodeToBytes(new byte[0], -1, 0), "offset", null);
            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlDecodeToBytes(new byte[0], 2, 0), "offset", null);

            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlDecodeToBytes(new byte[0], 0, -1), "count", null);
            Assert.ThrowsArgumentOutOfRange(() => UriQueryUtility.UrlDecodeToBytes(new byte[0], 0, 2), "count", null);
        }

        #endregion


        private static NameValueCollection ParseQueryString(string query)
        {
            return new FormDataCollection(query).ReadAsNameValueCollection();
        }
    }
}