2424import java .io .IOException ;
2525import java .io .PrintWriter ;
2626import java .io .StringWriter ;
27+ import java .io .UnsupportedEncodingException ;
2728import java .lang .annotation .Annotation ;
2829import java .lang .reflect .Method ;
2930import java .lang .reflect .Parameter ;
@@ -81,83 +82,7 @@ static void deleteChampionGGAPI() throws IOException {
8182 args .stream ().map (arg -> DynamicTest .dynamicTest (getMethodName (method , arg ), () -> {
8283 APIResponse <?> actualResponse = (APIResponse ) method .invoke (API , arg );
8384 actualResponse .waitForResponse ();
84- MockResponse response = dispatcher .getLastResponse ();
85- Assert .assertNotNull ("mock response is null" , response );
86-
87- Assert .assertTrue ("is complete returned false after waitForResponse" , actualResponse .isComplete ());
88- Assert .assertNotEquals ("state is still IN_PROGRESS after waitForResponse" ,
89- APIResponse .State .IN_PROGRESS , actualResponse .getState ());
90-
91- Assert .assertFalse ("got invalid api key, error stacktrace: "
92- + getStackTrace (actualResponse .getError ()), actualResponse .isInvalidAPIKey ());
93-
94- if (actualResponse .isFailure ()) {
95- Object actualContent = actualResponse .getContent ();
96- ErrorResponse actualErrorResponse = actualResponse .getErrorResponse ();
97- Throwable actualError = actualResponse .getError ();
98-
99- Assert .assertTrue ("isFailure returns true but state is not FAILURE" ,
100- actualResponse .getState () == APIResponse .State .FAILURE );
101-
102- Assert .assertNull ("failure response has content" , actualContent );
103- Assert .assertNull ("failure response has an error response" , actualErrorResponse );
104- Assert .assertNotNull ("failure response does not have an error exception" , actualError );
105-
106- Assert .fail ("an error occurred while executing an api request, stacktrace: "
107- + getStackTrace (actualError ));
108- }
109-
110- String expectedResponseCode = response .getStatus ().split (" " )[1 ];
111- int actualResponseCode = actualResponse .getResponseCode ();
112- Assert .assertEquals ("response codes does not match" ,
113- expectedResponseCode , String .valueOf (actualResponseCode ));
114-
115- if (actualResponse .isSuccess ()) {
116- Object actualContent = actualResponse .getContent ();
117- ErrorResponse actualErrorResponse = actualResponse .getErrorResponse ();
118- Throwable actualError = actualResponse .getError ();
119-
120- Assert .assertTrue ("isSuccess returns true but state is not SUCCESS" ,
121- actualResponse .getState () == APIResponse .State .SUCCESS );
122- Assert .assertNotNull ("success response does not have content" , actualContent );
123- Assert .assertNull ("success response has an error response" , actualErrorResponse );
124- Assert .assertNull ("success response has an error exception" , actualError );
125-
126- String expectedResponseJson = new String (response .getBody ().clone ().readByteArray (), "UTF-8" );
127- Object expectedContent = Constants .GSON .fromJson (expectedResponseJson ,
128- ((ParameterizedType ) method .getGenericReturnType ()).getActualTypeArguments ()[0 ]);
129- Assert .assertEquals ("response content does not match" , expectedContent , actualContent );
130-
131- JsonElement expectedJsonElement = Constants .GSON .fromJson (expectedResponseJson , JsonElement .class );
132- JsonElement actualJsonElement = Constants .GSON .fromJson (Constants .GSON .toJson (actualContent ), JsonElement .class );
133- assertEqualJsonElements (expectedJsonElement , actualJsonElement );
134- // TODO: find fields that may be null; assertNoNullFields(actualContent);
135- }
136-
137- if (actualResponse .isAPIError ()) {
138- Object actualContent = actualResponse .getContent ();
139- ErrorResponse actualErrorResponse = actualResponse .getErrorResponse ();
140- Throwable actualError = actualResponse .getError ();
141-
142- Assert .assertTrue ("isAPIError returns true but state is not API_ERROR" ,
143- actualResponse .getState () == APIResponse .State .API_ERROR );
144-
145- Assert .assertFalse ("response code is 2xx but api error is set" ,
146- 200 <= actualResponse .getResponseCode ()
147- && actualResponse .getResponseCode () < 300 );
148-
149- Assert .assertNull ("api error response has content" , actualContent );
150- Assert .assertNotNull ("api error response does not have an error response" , actualErrorResponse );
151- Assert .assertNull ("api error response has an error exception" , actualError );
152-
153- ErrorResponse expectedErrorResponse = Constants .GSON .fromJson (new String (response .getBody ().clone ().readByteArray (), "UTF-8" ),
154- ErrorResponse .class );
155- Assert .assertEquals ("error response content does not match" , expectedErrorResponse , actualErrorResponse );
156- }
157-
158- if (actualResponse .isInvalidAPIKey ()) {
159- Assert .fail ("invalid api key triggered with valid api key: " + actualResponse );
160- }
85+ validateResponse (dispatcher .getLastResponse (), actualResponse , method );
16186 })
16287 ).forEach (tests ::add );
16388 }
@@ -231,10 +156,95 @@ void testSlowResponse() {
231156
232157 }
233158
159+ private void validateResponse (MockResponse response , APIResponse <?> actualResponse , Method method ) throws Throwable {
160+ Assert .assertNotNull ("mock response is null" , response );
161+
162+ Assert .assertTrue ("is complete returned false after waitForResponse" , actualResponse .isComplete ());
163+ Assert .assertNotEquals ("state is still IN_PROGRESS after waitForResponse" ,
164+ APIResponse .State .IN_PROGRESS , actualResponse .getState ());
165+
166+ Assert .assertFalse ("got invalid api key, error stacktrace: "
167+ + getStackTrace (actualResponse .getError ()), actualResponse .isInvalidAPIKey ());
168+
169+ if (actualResponse .isFailure ()) validateFailedRequest (actualResponse );
170+
171+ String expectedResponseCode = response .getStatus ().split (" " )[1 ];
172+ int actualResponseCode = actualResponse .getResponseCode ();
173+ Assert .assertEquals ("response codes does not match" ,
174+ expectedResponseCode , String .valueOf (actualResponseCode ));
175+
176+ if (actualResponse .isSuccess ()) validateSuccessfulRequest (response , actualResponse , method );
177+
178+ if (actualResponse .isAPIError ()) validateAPIErrorResponse (response , actualResponse );
179+
180+ if (actualResponse .isInvalidAPIKey ()) {
181+ Assert .fail ("invalid api key triggered with valid api key: " + actualResponse );
182+ }
183+ }
184+
185+ private void validateFailedRequest (APIResponse <?> actualResponse ) {
186+ Object actualContent = actualResponse .getContent ();
187+ ErrorResponse actualErrorResponse = actualResponse .getErrorResponse ();
188+ Throwable actualError = actualResponse .getError ();
189+
190+ Assert .assertTrue ("isFailure returns true but state is not FAILURE" ,
191+ actualResponse .getState () == APIResponse .State .FAILURE );
192+
193+ Assert .assertNull ("failure response has content" , actualContent );
194+ Assert .assertNull ("failure response has an error response" , actualErrorResponse );
195+ Assert .assertNotNull ("failure response does not have an error exception" , actualError );
196+
197+ Assert .fail ("an error occurred while executing an api request, stacktrace: "
198+ + getStackTrace (actualError ));
199+ }
200+
201+ private void validateSuccessfulRequest (MockResponse response , APIResponse <?> actualResponse , Method method ) throws UnsupportedEncodingException {
202+ Object actualContent = actualResponse .getContent ();
203+ ErrorResponse actualErrorResponse = actualResponse .getErrorResponse ();
204+ Throwable actualError = actualResponse .getError ();
205+
206+ Assert .assertTrue ("isSuccess returns true but state is not SUCCESS" ,
207+ actualResponse .getState () == APIResponse .State .SUCCESS );
208+ Assert .assertNotNull ("success response does not have content" , actualContent );
209+ Assert .assertNull ("success response has an error response" , actualErrorResponse );
210+ Assert .assertNull ("success response has an error exception" , actualError );
211+
212+ String expectedResponseJson = new String (response .getBody ().clone ().readByteArray (), "UTF-8" );
213+ Object expectedContent = Constants .GSON .fromJson (expectedResponseJson ,
214+ ((ParameterizedType ) method .getGenericReturnType ()).getActualTypeArguments ()[0 ]);
215+ Assert .assertEquals ("response content does not match" , expectedContent , actualContent );
216+
217+ JsonElement expectedJsonElement = Constants .GSON .fromJson (expectedResponseJson , JsonElement .class );
218+ JsonElement actualJsonElement = Constants .GSON .fromJson (Constants .GSON .toJson (actualContent ), JsonElement .class );
219+ assertEqualJsonElements (expectedJsonElement , actualJsonElement );
220+ // TODO: find fields that may be null; assertNoNullFields(actualContent);
221+ }
222+
223+ private void validateAPIErrorResponse (MockResponse response , APIResponse <?> actualResponse ) throws UnsupportedEncodingException {
224+ Object actualContent = actualResponse .getContent ();
225+ ErrorResponse actualErrorResponse = actualResponse .getErrorResponse ();
226+ Throwable actualError = actualResponse .getError ();
227+
228+ Assert .assertTrue ("isAPIError returns true but state is not API_ERROR" ,
229+ actualResponse .getState () == APIResponse .State .API_ERROR );
230+
231+ Assert .assertFalse ("response code is 2xx but api error is set" ,
232+ 200 <= actualResponse .getResponseCode ()
233+ && actualResponse .getResponseCode () < 300 );
234+
235+ Assert .assertNull ("api error response has content" , actualContent );
236+ Assert .assertNotNull ("api error response does not have an error response" , actualErrorResponse );
237+ Assert .assertNull ("api error response has an error exception" , actualError );
238+
239+ ErrorResponse expectedErrorResponse = Constants .GSON .fromJson (new String (response .getBody ().clone ().readByteArray (), "UTF-8" ),
240+ ErrorResponse .class );
241+ Assert .assertEquals ("error response content does not match" , expectedErrorResponse , actualErrorResponse );
242+ }
243+
234244 private int getIndex (Parameter [] parameters , Class <? extends Annotation > targetAnnotation , Class <?> targetType ) {
235- targetType = ClassUtils .primitiveToWrapper (targetType );
245+ Class <?> wrappedType = ClassUtils .primitiveToWrapper (targetType );
236246 for (int i = 0 ; i < parameters .length ; i ++) {
237- if (targetType .isAssignableFrom (ClassUtils .primitiveToWrapper (parameters [i ].getType ()))
247+ if (wrappedType .isAssignableFrom (ClassUtils .primitiveToWrapper (parameters [i ].getType ()))
238248 && parameters [i ].isAnnotationPresent (targetAnnotation )) return i ;
239249
240250 }
@@ -260,7 +270,7 @@ private <T> List<Object[]> extendWithValues(List<Object[]> args, List<T> values,
260270 }
261271
262272 private String getStackTrace (Throwable t ) {
263- if (t == null ) return "throwable is null" ;
273+ if (t == null ) return "throwable is null" ;
264274 StringWriter stringWriter = new StringWriter ();
265275 t .printStackTrace (new PrintWriter (stringWriter ));
266276 return stringWriter .toString ();
@@ -273,80 +283,82 @@ private void assertEqualJsonElements(JsonElement expected, JsonElement actual) {
273283 private void assertEqualJsonElements (JsonElement expected , JsonElement actual , String path ) {
274284 if (expected == null ) {
275285 Assert .assertNull ("expected is null actual not" , actual );
286+ return ;
276287 }
277288
278289 Assert .assertEquals ("wrong element type at " + path , getJsonType (expected ), getJsonType (actual ));
279290 if (expected .isJsonNull ()) return ;
280- if (expected .isJsonArray ()) {
281- JsonArray expectedArray = expected .getAsJsonArray ();
282- JsonArray actualArray = actual .getAsJsonArray ();
283291
284- Assert .assertEquals ("json array at " + path + " has wrong length" ,
285- expectedArray .size (), actualArray .size ());
292+ if (expected .isJsonArray ()) assertEqualsJsonArray (expected .getAsJsonArray (), actual .getAsJsonArray (), path );
286293
287- for (int i = 0 ; i < expectedArray .size (); i ++)
288- assertEqualJsonElements (expectedArray .get (i ), actualArray .get (i ), path + "[" + i + "]" );
289- }
294+ if (expected .isJsonObject ()) assertEqualsJsonObject (expected .getAsJsonObject (), actual .getAsJsonObject (), path );
290295
291- if (expected .isJsonObject ()) {
292- JsonObject expectedObject = expected .getAsJsonObject ( );
293- JsonObject actualObject = actual . getAsJsonObject ();
296+ if (expected .isJsonPrimitive ())
297+ assertEqualsJsonPrimitive ( expected .getAsJsonPrimitive (), actual . getAsJsonPrimitive (), path );
298+ }
294299
295- for ( Map . Entry < String , JsonElement > expectedEntry : expectedObject . entrySet () ) {
296- String expectedKey = expectedEntry . getKey ();
297- JsonElement expectedValue = expectedEntry . getValue ( );
300+ private void assertEqualsJsonArray ( JsonArray expectedArray , JsonArray actualArray , String path ) {
301+ Assert . assertEquals ( "json array at " + path + " has wrong length" ,
302+ expectedArray . size (), actualArray . size () );
298303
299- String entryPath = path + "[" + expectedKey + "]" ;
304+ for (int i = 0 ; i < expectedArray .size (); i ++)
305+ assertEqualJsonElements (expectedArray .get (i ), actualArray .get (i ), path + "[" + i + "]" );
306+ }
300307
308+ private void assertEqualsJsonObject (JsonObject expectedObject , JsonObject actualObject , String path ) {
309+ for (Map .Entry <String , JsonElement > expectedEntry : expectedObject .entrySet ()) {
310+ String expectedKey = expectedEntry .getKey ();
311+ JsonElement expectedValue = expectedEntry .getValue ();
301312
302- JsonElement actualValue = actualObject .get (expectedKey );
303- if (expectedValue == null ) continue ;
304- Assert .assertNotNull ("missing key at path " + entryPath +
305- " of type " + getJsonType (expectedValue ) + ", expected value " +
306- expectedValue + ", enclosing object: " + expectedObject , actualValue );
313+ String entryPath = path + "[" + expectedKey + "]" ;
307314
308- assertEqualJsonElements (expectedValue , actualValue , entryPath );
309- }
310315
311- for ( Map . Entry < String , JsonElement > actualEntry : actualObject .entrySet ()) {
312- JsonElement actualValue = actualEntry . getValue () ;
313- if ( actualValue == null ) continue ;
314- String actualKey = actualEntry . getKey ();
315- JsonElement expectedValue = expectedObject . get ( actualKey );
316+ JsonElement actualValue = actualObject .get ( expectedKey );
317+ if ( expectedValue == null ) continue ;
318+ Assert . assertNotNull ( "missing key at path " + entryPath +
319+ " of type " + getJsonType ( expectedValue ) + ", expected value " +
320+ expectedValue + ", enclosing object: " + expectedObject , actualValue );
316321
317- Assert .assertNotNull ("unknown key " + path + "[" + actualKey + "] of type " +
318- getJsonType (actualValue ) + " with value " +
319- actualValue + " present, enclosing object: " + actualObject , expectedValue );
320- }
322+ assertEqualJsonElements (expectedValue , actualValue , entryPath );
321323 }
322324
323- if (expected .isJsonPrimitive ()) {
324- JsonPrimitive expectedPrimitive = expected .getAsJsonPrimitive ();
325- JsonPrimitive actualPrimitive = actual .getAsJsonPrimitive ();
325+ for (Map .Entry <String , JsonElement > actualEntry : actualObject .entrySet ()) {
326+ JsonElement actualValue = actualEntry .getValue ();
327+ if (actualValue == null ) continue ;
328+ String actualKey = actualEntry .getKey ();
329+ JsonElement expectedValue = expectedObject .get (actualKey );
326330
327- if (expectedPrimitive .isString ()) {
328- Assert .assertEquals ("strings at " + path + " do not match" ,
329- expectedPrimitive .getAsString (), actualPrimitive .getAsString ());
330- }
331- if (expectedPrimitive .isBoolean ()) {
332- Assert .assertEquals ("booleans at " + path + " do not match" ,
333- expectedPrimitive .getAsBoolean (), actualPrimitive .getAsBoolean ());
334- }
335- if (expectedPrimitive .isNumber ()) {
336- boolean equal = expectedPrimitive .getAsBigDecimal ().compareTo (actualPrimitive .getAsBigDecimal ()) == 0 ;
337- Assert .assertTrue ("numbers at " + path + " do not match expected <" +
338- expectedPrimitive .getAsBigDecimal () + "> but was:<" +
339- actualPrimitive .getAsBigDecimal () + ">" ,
340- equal );
341- }
331+ Assert .assertNotNull ("unknown key " + path + "[" + actualKey + "] of type " +
332+ getJsonType (actualValue ) + " with value " +
333+ actualValue + " present, enclosing object: " + actualObject , expectedValue );
334+ }
335+ }
336+
337+ private void assertEqualsJsonPrimitive (JsonPrimitive expectedPrimitive , JsonPrimitive actualPrimitive , String path ) {
338+ if (expectedPrimitive .isString ()) {
339+ Assert .assertEquals ("strings at " + path + " do not match" ,
340+ expectedPrimitive .getAsString (), actualPrimitive .getAsString ());
341+ }
342+ if (expectedPrimitive .isBoolean ()) {
343+ Assert .assertEquals ("booleans at " + path + " do not match" ,
344+ expectedPrimitive .getAsBoolean (), actualPrimitive .getAsBoolean ());
345+ }
346+ if (expectedPrimitive .isNumber ()) {
347+ boolean equal = expectedPrimitive .getAsBigDecimal ().compareTo (actualPrimitive .getAsBigDecimal ()) == 0 ;
348+ Assert .assertTrue ("numbers at " + path + " do not match expected <" +
349+ expectedPrimitive .getAsBigDecimal () + "> but was:<" +
350+ actualPrimitive .getAsBigDecimal () + ">" ,
351+ equal );
342352 }
353+ Assert .assertEquals ("expected primitive (" + expectedPrimitive + ") and actual primitive (" +
354+ actualPrimitive + ") at " + path + " are not equal; " , expectedPrimitive , actualPrimitive );
343355 }
344356
345357 @ Test
346358 void testObjectMethodOnApi () {
347359 //noinspection ResultOfMethodCallIgnored
348360 new ChampionGGAPIFactory (Constants .API_KEY , 10 )
349- .buildChampionGGAPI ().getClass ();
361+ .buildChampionGGAPI ().getClass ();
350362 }
351363
352364 private String getJsonType (JsonElement element ) {
0 commit comments