33
44using System ;
55using System . Collections . Generic ;
6+ using System . Globalization ;
67using System . Text . Json ;
78using System . Threading . Tasks ;
89using Microsoft . VisualStudio . TestTools . UnitTesting ;
@@ -86,6 +87,115 @@ public async Task QueryTypeColumn(string type, int id)
8687 PerformTestEqualsForExtendedTypes ( type , expected , actual . ToString ( ) ) ;
8788 }
8889
90+ [ DataTestMethod ]
91+ [ DataRow ( BYTE_TYPE , "gt" , "0" , "0" , ">" ) ]
92+ [ DataRow ( BYTE_TYPE , "gte" , "0" , "0" , ">=" ) ]
93+ [ DataRow ( BYTE_TYPE , "lt" , "1" , "1" , "<" ) ]
94+ [ DataRow ( BYTE_TYPE , "lte" , "1" , "1" , "<=" ) ]
95+ [ DataRow ( BYTE_TYPE , "neq" , "0" , "0" , "!=" ) ]
96+ [ DataRow ( BYTE_TYPE , "eq" , "1" , "1" , "=" ) ]
97+ [ DataRow ( SHORT_TYPE , "gt" , "-1" , "-1" , ">" ) ]
98+ [ DataRow ( SHORT_TYPE , "gte" , "-1" , "-1" , ">=" ) ]
99+ [ DataRow ( SHORT_TYPE , "lt" , "1" , "1" , "<" ) ]
100+ [ DataRow ( SHORT_TYPE , "lte" , "1" , "1" , "<=" ) ]
101+ [ DataRow ( SHORT_TYPE , "neq" , "1" , "1" , "!=" ) ]
102+ [ DataRow ( SHORT_TYPE , "eq" , "-1" , "-1" , "=" ) ]
103+ [ DataRow ( INT_TYPE , "gt" , "-1" , "-1" , ">" ) ]
104+ [ DataRow ( INT_TYPE , "gte" , "2147483647" , "2147483647" , " >= " ) ]
105+ [ DataRow ( INT_TYPE , "lt" , "1" , "1" , "<" ) ]
106+ [ DataRow ( INT_TYPE , "lte" , "-2147483648" , "-2147483648" , " <= " ) ]
107+ [ DataRow ( INT_TYPE , "neq" , "1" , "1" , "!=" ) ]
108+ [ DataRow ( INT_TYPE , "eq" , "-1" , "-1" , "=" ) ]
109+ [ DataRow ( LONG_TYPE , "gt" , "-1" , "-1" , ">" ) ]
110+ [ DataRow ( LONG_TYPE , "gte" , "9223372036854775807" , "9223372036854775807" , " >= " ) ]
111+ [ DataRow ( LONG_TYPE , "lt" , "1" , "1" , "<" ) ]
112+ [ DataRow ( LONG_TYPE , "lte" , "-9223372036854775808" , "-9223372036854775808" , " <= " ) ]
113+ [ DataRow ( LONG_TYPE , "neq" , "1" , "1" , "!=" ) ]
114+ [ DataRow ( LONG_TYPE , "eq" , "-1" , "-1" , "=" ) ]
115+ [ DataRow ( STRING_TYPE , "neq" , "\' foo\' " , "\" foo\" " , "!=" ) ]
116+ [ DataRow ( STRING_TYPE , "eq" , "\' lksa;jdflasdf;alsdflksdfkldj\' " , "\" lksa;jdflasdf;alsdflksdfkldj\" " , "=" ) ]
117+ [ DataRow ( SINGLE_TYPE , "gt" , "-9.3" , "-9.3" , ">" ) ]
118+ [ DataRow ( SINGLE_TYPE , "gte" , "-9.2" , "-9.2" , ">=" ) ]
119+ [ DataRow ( SINGLE_TYPE , "lt" , ".33" , "0.33" , "<" ) ]
120+ [ DataRow ( SINGLE_TYPE , "lte" , ".33" , "0.33" , "<=" ) ]
121+ [ DataRow ( SINGLE_TYPE , "neq" , "9.2" , "9.2" , "!=" ) ]
122+ [ DataRow ( SINGLE_TYPE , "eq" , "\' 0.33\' " , "0.33" , "=" ) ]
123+ [ DataRow ( FLOAT_TYPE , "gt" , "-9.2" , "-9.2" , ">" ) ]
124+ [ DataRow ( FLOAT_TYPE , "gte" , "-9.2" , "-9.2" , ">=" ) ]
125+ [ DataRow ( FLOAT_TYPE , "lt" , ".33" , "0.33" , "<" ) ]
126+ [ DataRow ( FLOAT_TYPE , "lte" , ".33" , "0.33" , "<=" ) ]
127+ [ DataRow ( FLOAT_TYPE , "neq" , "-9.2" , "-9.2" , "!=" ) ]
128+ [ DataRow ( FLOAT_TYPE , "eq" , "-9.2" , "-9.2" , "=" ) ]
129+ [ DataRow ( DECIMAL_TYPE , "gt" , "-9.292929" , "-9.292929" , " > " ) ]
130+ [ DataRow ( DECIMAL_TYPE , "gte" , "-9.292929" , "-9.292929" , " >= " ) ]
131+ [ DataRow ( DECIMAL_TYPE , "lt" , "0.333333" , "0.333333" , "<" ) ]
132+ [ DataRow ( DECIMAL_TYPE , "lte" , "0.333333" , "0.333333" , " <= " ) ]
133+ [ DataRow ( DECIMAL_TYPE , "neq" , "0.0" , "0.0" , "!=" ) ]
134+ [ DataRow ( DECIMAL_TYPE , "eq" , "-9.292929" , "-9.292929" , "=" ) ]
135+ [ DataRow ( BOOLEAN_TYPE , "neq" , "\' false\' " , "false" , "!=" ) ]
136+ [ DataRow ( BOOLEAN_TYPE , "eq" , "\' false\' " , "false" , "=" ) ]
137+ public async Task QueryTypeColumnFilterAndOrderBy ( string type , string filterOperator , string sqlValue , string gqlValue , string queryOperator )
138+ {
139+ if ( ! IsSupportedType ( type ) )
140+ {
141+ Assert . Inconclusive ( "Type not supported" ) ;
142+ }
143+
144+ string field = $ "{ type . ToLowerInvariant ( ) } _types";
145+ string graphQLQueryName = "supportedTypes" ;
146+ string gqlQuery = @"{
147+ supportedTypes(first: 100 orderBy: { " + field + ": ASC } filter: { " + field + ": {" + filterOperator + ": " + gqlValue + @"} }) {
148+ items {
149+ " + field + @"
150+ }
151+ }
152+ }" ;
153+
154+ string dbQuery = MakeQueryOnTypeTable ( new List < string > { field } , filterValue : sqlValue , filterOperator : queryOperator , filterField : field , orderBy : field , limit : "100" ) ;
155+
156+ JsonElement actual = await ExecuteGraphQLRequestAsync ( gqlQuery , graphQLQueryName , isAuthenticated : false ) ;
157+ string expected = await GetDatabaseResultAsync ( dbQuery ) ;
158+
159+ PerformTestEqualsForExtendedTypes ( type , expected , actual . GetProperty ( "items" ) . ToString ( ) ) ;
160+ }
161+
162+ /// <summary>
163+ /// Separate test case for DateTime to allow overwrite for postgreSql.
164+ /// Year 9998 used in test and data within test tables to avoid out of
165+ /// date range error within GQL.
166+ /// </summary>
167+ [ DataTestMethod ]
168+ [ DataRow ( DATETIME_TYPE , "gt" , "\' 1999-01-08\' " , "\" 1999-01-08\" " , " > " ) ]
169+ [ DataRow ( DATETIME_TYPE , "gte" , "\' 1999-01-08\' " , "\" 1999-01-08\" " , " >= " ) ]
170+ [ DataRow ( DATETIME_TYPE , "lt" , "\' 0001-01-01\' " , "\" 0001-01-01\" " , " < " ) ]
171+ [ DataRow ( DATETIME_TYPE , "lte" , "\' 0001-01-01\' " , "\" 0001-01-01\" " , " <= " ) ]
172+ [ DataRow ( DATETIME_TYPE , "neq" , "\' 0001-01-01\' " , "\" 0001-01-01\" " , "!=" ) ]
173+ [ DataRow ( DATETIME_TYPE , "eq" , "\' 0001-01-01\' " , "\" 0001-01-01T01:01:01\" " , "=" ) ]
174+ [ DataRow ( DATETIME_TYPE , "gt" , "\' 1999-01-08 10:23:00\' " , "\" 1999-01-08 10:23:00\" " , " > " ) ]
175+ [ DataRow ( DATETIME_TYPE , "gte" , "\' 1999-01-08 10:23:00\' " , "\" 1999-01-08 10:23:00\" " , " >= " ) ]
176+ [ DataRow ( DATETIME_TYPE , "lt" , "\' 9998-12-31 23:59:59\' " , "\" 9998-12-31 23:59:59\" " , " < " ) ]
177+ [ DataRow ( DATETIME_TYPE , "lte" , "\' 9998-12-31 23:59:59\' " , "\" 9998-12-31 23:59:59\" " , " <= " ) ]
178+ [ DataRow ( DATETIME_TYPE , "neq" , "\' 1999-01-08 10:23:00\' " , "\" 1999-01-08 10:23:00\" " , "!=" ) ]
179+ [ DataRow ( DATETIME_TYPE , "eq" , "\' 1999-01-08 10:23:00\' " , "\" 1999-01-08 10:23:00\" " , "=" ) ]
180+ [ DataRow ( DATETIME_TYPE , "gt" , "\' 1999-01-08 10:23:00.9999999\' " , "\" 1999-01-08 10:23:00.9999999\" " , " > " ) ]
181+ [ DataRow ( DATETIME_TYPE , "gte" , "\' 1999-01-08 10:23:00.9999999\' " , "\" 1999-01-08 10:23:00.9999999\" " , " >= " ) ]
182+ [ DataRow ( DATETIME_TYPE , "lt" , "\' 9998-12-31 23:59:59.9999999\' " , "\" 9998-12-31 23:59:59.9999999\" " , " < " ) ]
183+ [ DataRow ( DATETIME_TYPE , "lte" , "\' 9998-12-31 23:59:59.9999999\' " , "\" 9998-12-31 23:59:59.9999999\" " , " <= " ) ]
184+ [ DataRow ( DATETIME_TYPE , "neq" , "\' 1999-01-08 10:23:00.9999999\' " , "\" 1999-01-08 10:23:00.9999999\" " , "!=" ) ]
185+ [ DataRow ( DATETIME_TYPE , "eq" , "\' 1999-01-08 10:23:00.9999999\' " , "\" 1999-01-08 10:23:00.9999999\" " , "=" ) ]
186+ [ DataRow ( DATETIME_TYPE , "neq" , "\' 1999-01-08 10:23:54.9999999-14:00\' " , "\" 1999-01-08 10:23:54.9999999-14:00\" " , "!=" ) ]
187+ [ DataRow ( DATETIME_TYPE , "eq" , "\' 1999-01-08 10:23:54.9999999-14:00\' " , "\" 1999-01-08 10:23:54.9999999-14:00\" " , "=" ) ]
188+ [ DataRow ( DATETIME_TYPE , "gt" , "\' 1999-01-08 10:22:00\' " , "\" 1999-01-08 10:22:00\" " , " > " ) ]
189+ [ DataRow ( DATETIME_TYPE , "gte" , "\' 1999-01-08 10:23:54\' " , "\" 1999-01-08 10:23:54\" " , " >= " ) ]
190+ [ DataRow ( DATETIME_TYPE , "lt" , "\' 2079-06-06\' " , "\" 2079-06-06\" " , " < " ) ]
191+ [ DataRow ( DATETIME_TYPE , "lte" , "\' 2079-06-06\' " , "\" 2079-06-06\" " , " <= " ) ]
192+ [ DataRow ( DATETIME_TYPE , "neq" , "\' 1999-01-08 10:23:54\' " , "\" 1999-01-08 10:23:54\" " , "!=" ) ]
193+ [ DataRow ( DATETIME_TYPE , "eq" , "\' 1999-01-08 10:23:54\' " , "\" 1999-01-08 10:23:54\" " , "=" ) ]
194+ public async Task QueryTypeColumnFilterAndOrderByDateTime ( string type , string filterOperator , string sqlValue , string gqlValue , string queryOperator )
195+ {
196+ await QueryTypeColumnFilterAndOrderBy ( type , filterOperator , sqlValue , gqlValue , queryOperator ) ;
197+ }
198+
89199 [ DataTestMethod ]
90200 [ DataRow ( BYTE_TYPE , "255" ) ]
91201 [ DataRow ( BYTE_TYPE , "0" ) ]
@@ -337,8 +447,16 @@ private static void CompareFloatResults(string floatType, string actual, string
337447 using JsonDocument actualJsonDoc = JsonDocument . Parse ( actual ) ;
338448 using JsonDocument expectedJsonDoc = JsonDocument . Parse ( expected ) ;
339449
340- string actualFloat = actualJsonDoc . RootElement . GetProperty ( fieldName ) . ToString ( ) ;
341- string expectedFloat = expectedJsonDoc . RootElement . GetProperty ( fieldName ) . ToString ( ) ;
450+ if ( actualJsonDoc . RootElement . ValueKind is JsonValueKind . Array )
451+ {
452+ ValidateArrayResults ( actualJsonDoc , expectedJsonDoc , fieldName ) ;
453+ return ;
454+ }
455+
456+ string actualFloat ;
457+ string expectedFloat ;
458+ actualFloat = actualJsonDoc . RootElement . GetProperty ( fieldName ) . ToString ( ) ;
459+ expectedFloat = expectedJsonDoc . RootElement . GetProperty ( fieldName ) . ToString ( ) ;
342460
343461 // handles cases when one of the values is null
344462 if ( string . IsNullOrEmpty ( actualFloat ) || string . IsNullOrEmpty ( expectedFloat ) )
@@ -375,6 +493,12 @@ private static void CompareDateTimeResults(string actual, string expected)
375493 using JsonDocument actualJsonDoc = JsonDocument . Parse ( actual ) ;
376494 using JsonDocument expectedJsonDoc = JsonDocument . Parse ( expected ) ;
377495
496+ if ( actualJsonDoc . RootElement . ValueKind is JsonValueKind . Array )
497+ {
498+ ValidateArrayResults ( actualJsonDoc , expectedJsonDoc , fieldName ) ;
499+ return ;
500+ }
501+
378502 string actualDateTime = actualJsonDoc . RootElement . GetProperty ( fieldName ) . ToString ( ) ;
379503 string expectedDateTime = expectedJsonDoc . RootElement . GetProperty ( fieldName ) . ToString ( ) ;
380504
@@ -389,6 +513,34 @@ private static void CompareDateTimeResults(string actual, string expected)
389513 }
390514 }
391515
516+ private static void ValidateArrayResults ( JsonDocument actualJsonDoc , JsonDocument expectedJsonDoc , string fieldName )
517+ {
518+ JsonElement . ArrayEnumerator actualEnumerater = actualJsonDoc . RootElement . EnumerateArray ( ) ;
519+ foreach ( JsonElement expectedElement in expectedJsonDoc . RootElement . EnumerateArray ( ) )
520+ {
521+ actualEnumerater . MoveNext ( ) ;
522+ JsonElement actualElement = actualEnumerater . Current ;
523+ actualElement . TryGetProperty ( fieldName , out JsonElement actualValue ) ;
524+ expectedElement . TryGetProperty ( fieldName , out JsonElement expectedValue ) ;
525+
526+ if ( fieldName . StartsWith ( DATETIME_TYPE . ToLower ( ) ) )
527+ {
528+ // MySql returns a format that will not directly parse into DateTime type so we use string here for parsing
529+ DateTime actualDateTime = DateTime . Parse ( actualValue . ToString ( ) , CultureInfo . InvariantCulture , DateTimeStyles . None ) ;
530+ DateTime expectedDateTime = DateTime . Parse ( expectedValue . ToString ( ) , CultureInfo . InvariantCulture , DateTimeStyles . None ) ;
531+ Assert . AreEqual ( expectedDateTime , actualDateTime ) ;
532+ }
533+ else if ( fieldName . StartsWith ( SINGLE_TYPE . ToLower ( ) ) )
534+ {
535+ Assert . AreEqual ( expectedValue . GetSingle ( ) , actualValue . GetSingle ( ) ) ;
536+ }
537+ else
538+ {
539+ Assert . AreEqual ( expectedValue . GetDouble ( ) , actualValue . GetDouble ( ) ) ;
540+ }
541+ }
542+ }
543+
392544 /// <summary>
393545 /// Needed to map the type name to a graphql type in argument tests
394546 /// where the argument type need to be specified.
@@ -403,6 +555,14 @@ private static string TypeNameToGraphQLType(string typeName)
403555 return typeName ;
404556 }
405557
558+ protected abstract string MakeQueryOnTypeTable (
559+ List < string > queriedColumns ,
560+ string filterValue = "1" ,
561+ string filterOperator = "=" ,
562+ string filterField = "1" ,
563+ string orderBy = "id" ,
564+ string limit = "1" ) ;
565+
406566 protected abstract string MakeQueryOnTypeTable ( List < string > columnsToQuery , int id ) ;
407567 protected virtual bool IsSupportedType ( string type )
408568 {
0 commit comments