@@ -9,39 +9,106 @@ namespace Tests
99{
1010 public static class UriExtensions
1111 {
12- public static void PathEquals ( this Uri u , string pathAndQueryString , string because )
12+ public static void PathEquals ( this Uri actualUri , string pathAndQueryString , string origin )
1313 {
14- var paths = ( pathAndQueryString ?? "" ) . Split ( new [ ] { '?' } , 2 ) ;
14+ var expectedUri = CreateExpectedUri ( actualUri , pathAndQueryString ) ;
1515
16- string path = paths . First ( ) , query = string . Empty ;
17- if ( paths . Length > 1 )
18- query = paths . Last ( ) ;
16+ var actualParameters = ExplodeQueryString ( actualUri ) ;
17+ var expectedParameters = ExplodeQueryString ( expectedUri ) ;
1918
20- var expectedUri = new UriBuilder ( "http" , "localhost" , u . Port , path , "?" + query ) . Uri ;
19+ AssertSpecialQueryStringValues ( expectedUri , expectedParameters , actualUri , actualParameters , origin ) ;
20+
21+ actualUri = CreateUri ( actualUri , actualParameters ) ;
22+ expectedUri = CreateUri ( expectedUri , expectedParameters ) ;
23+
24+ AssertQueryString ( actualUri , expectedUri , origin ) ;
25+
26+ ComparePaths ( actualUri , expectedUri , origin ) ;
27+ }
2128
22- u . AbsolutePath . Should ( ) . Be ( expectedUri . AbsolutePath , because ) ;
23- u = new UriBuilder ( u . Scheme , u . Host , u . Port , u . AbsolutePath , u . Query . Replace ( "pretty=true&" , "" ) . Replace ( "pretty=true" , "" ) ) . Uri ;
29+ private static Uri CreateUri ( Uri baseUri , Dictionary < string , string > newQueryString )
30+ {
31+ var query = FlattenQueryString ( newQueryString ) ;
32+ var uriBuilder = new UriBuilder ( baseUri ) { Query = query } ;
33+ return uriBuilder . Uri ;
34+ }
35+
36+ private static void AssertQueryString ( Uri actualUri , Uri expectedUri , string origin )
37+ {
38+ var because = $ "\r \n Expected query string from { origin } : { expectedUri . Query } on { expectedUri . PathAndQuery } ";
39+ because += $ "\r \n Actual querystring from { origin } : { actualUri . Query } on { actualUri . PathAndQuery } \r \n ";
2440
25- var queries = new [ ] { u . Query , expectedUri . Query } ;
26- if ( queries . All ( string . IsNullOrWhiteSpace ) ) return ;
27- if ( queries . Any ( string . IsNullOrWhiteSpace ) )
41+ var actualParameters = ExplodeQueryString ( actualUri ) ;
42+ var expectedParameters = ExplodeQueryString ( expectedUri ) ;
43+
44+ actualParameters . Keys . Should ( )
45+ . BeEquivalentTo ( expectedParameters . Keys , "All query string parameters need to be asserted.\r \n {0}" , because ) ;
46+
47+ //actualParameters.Count.Should().Be(expectedParameters.Count, "All query string parameters need to be asserted.\r\n{0}", because);
48+ if ( actualParameters . Count == 0 ) return ;
49+ actualParameters . Should ( ) . ContainKeys ( expectedParameters . Keys . ToArray ( ) , because ) ;
50+ actualParameters . Should ( ) . Equal ( expectedParameters , because ) ;
51+ }
52+
53+ private static void AssertSpecialQueryStringValues (
54+ Uri expectedUri ,
55+ Dictionary < string , string > expectedParameters ,
56+ Uri actualUri ,
57+ Dictionary < string , string > actualParameters ,
58+ string origin )
59+ {
60+ var because = $ "\r \n Expected query string from { origin } : { expectedUri . Query } on { expectedUri . PathAndQuery } ";
61+ because += $ "\r \n Actual query string from { origin } : { actualUri . Query } on { actualUri . PathAndQuery } \r \n ";
62+
63+ //only assert these if they appear in expectedUri
64+ var specialQueryStringParameters = new [ ] { "pretty" , "typed_keys" , "error_trace" } ;
65+ foreach ( var key in specialQueryStringParameters )
2866 {
29- queries . Last ( ) . Should ( ) . Be ( queries . First ( ) , because ) ;
30- return ;
67+ if ( ! expectedParameters . ContainsKey ( key ) ) continue ;
68+ var expected = expectedParameters [ key ] ;
69+ actualParameters . Should ( ) . ContainKey ( key , "query value for '{0}' expected to exist\r \n {1}" , key , because ) ;
70+ var actual = actualParameters [ key ] ;
71+ new [ ] { key , actual } . Should ( ) . BeEquivalentTo ( new [ ] { key , expected } , "query value for '{0}' should be equal\r \n {1}" , key , because ) ;
3172 }
3273
33- var clientKeyValues = u . Query . Substring ( 1 ) . Split ( '&' )
34- . Select ( v => v . Split ( '=' ) )
35- . Where ( k => ! string . IsNullOrWhiteSpace ( k [ 0 ] ) )
36- . ToDictionary ( k => k [ 0 ] , v => v . Last ( ) ) ;
37- var expectedKeyValues = expectedUri . Query . Substring ( 1 ) . Split ( '&' )
74+ foreach ( var key in specialQueryStringParameters )
75+ {
76+ if ( actualParameters . ContainsKey ( key ) ) actualParameters . Remove ( key ) ;
77+ if ( expectedParameters . ContainsKey ( key ) ) expectedParameters . Remove ( key ) ;
78+ }
79+ }
80+
81+ private static void ComparePaths ( Uri actualUri , Uri expectedUri , string origin )
82+ {
83+ var because = $ "\r \n Expected from { origin } : { expectedUri . PathAndQuery } ";
84+ because += $ "\r \n Actual from { origin } : { actualUri . PathAndQuery } \r \n ";
85+ actualUri . AbsolutePath . Should ( ) . Be ( expectedUri . AbsolutePath , because ) ;
86+ }
87+
88+ private static Uri CreateExpectedUri ( Uri u , string pathAndQueryString )
89+ {
90+ var paths = ( pathAndQueryString ?? "" ) . Split ( new [ ] { '?' } , 2 ) ;
91+
92+ string path = paths . First ( ) , query = string . Empty ;
93+ if ( paths . Length > 1 ) query = paths . Last ( ) ;
94+
95+ var expectedUri = new UriBuilder ( "http" , "localhost" , u . Port , path , "?" + query ) . Uri ;
96+ return expectedUri ;
97+ }
98+ private static string FlattenQueryString ( Dictionary < string , string > queryString )
99+ {
100+ if ( queryString == null || queryString . Count == 0 ) return string . Empty ;
101+ return string . Join ( "&" , queryString . Select ( kv => $ "{ kv . Key } ={ kv . Value } ") ) ;
102+ }
103+
104+ private static Dictionary < string , string > ExplodeQueryString ( Uri u )
105+ {
106+ var query = u . Query ;
107+ if ( string . IsNullOrEmpty ( query ) || query . Length <= 1 ) return new Dictionary < string , string > ( ) ;
108+ return query . Substring ( 1 ) . Split ( '&' )
38109 . Select ( v => v . Split ( '=' ) )
39110 . Where ( k => ! string . IsNullOrWhiteSpace ( k [ 0 ] ) )
40111 . ToDictionary ( k => k [ 0 ] , v => v . Last ( ) ) ;
41-
42- clientKeyValues . Count . Should ( ) . Be ( expectedKeyValues . Count , because ) ;
43- clientKeyValues . Should ( ) . ContainKeys ( expectedKeyValues . Keys . ToArray ( ) , because ) ;
44- clientKeyValues . Should ( ) . Equal ( expectedKeyValues , because ) ;
45112 }
46113 }
47114}
0 commit comments