Merge from ECOMP's repository
[vid.git] / vid-app-common / src / test / java / org / onap / vid / testUtils / TestUtils.java
1 package org.onap.vid.testUtils;
2
3 import com.fasterxml.jackson.databind.DeserializationFeature;
4 import com.fasterxml.jackson.databind.ObjectMapper;
5 import com.google.common.collect.ImmutableList;
6 import org.apache.log4j.LogManager;
7 import org.apache.log4j.Logger;
8 import org.json.JSONArray;
9 import org.json.JSONObject;
10 import org.junit.Assert;
11 import org.mockito.MockSettings;
12 import org.mockito.Mockito;
13 import org.mockito.invocation.InvocationOnMock;
14 import org.mockito.stubbing.Answer;
15 import org.onap.portalsdk.core.util.SystemProperties;
16 import org.onap.vid.asdc.beans.Service;
17 import org.springframework.mock.env.MockEnvironment;
18
19 import javax.ws.rs.client.Client;
20 import javax.ws.rs.client.Invocation;
21 import javax.ws.rs.client.WebTarget;
22 import javax.ws.rs.core.GenericType;
23 import javax.ws.rs.core.MediaType;
24 import javax.ws.rs.core.Response;
25 import java.io.ByteArrayInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.Serializable;
29 import java.net.URI;
30 import java.util.Iterator;
31 import java.util.List;
32
33 import static fj.parser.Parser.fail;
34 import static org.mockito.Matchers.any;
35 import static org.mockito.Mockito.*;
36
37 /**
38  * Created by Oren on 6/7/17.
39  */
40 public class TestUtils {
41
42     private static final Logger logger = LogManager.getLogger(TestUtils.class);
43
44     /**
45      * The method compares between two jsons. the function assert that the actual object does not reduce or change the functionallity/parsing of the expected json.
46      * This means that if the expected JSON has a key which is null or the JSON doesn't have a key which contained in the expected JSON the assert will succeed and the will pass.
47      * For example : For JSON expected = {a:null} and actual {a:3} the test will pass
48      * Other example : For JSON expected = {a:3} and actual {a:null} the test will fail
49      *
50      * @param expected JSON
51      * @param actual JSON
52      */
53     public static void assertJsonStringEqualsIgnoreNulls(String expected, String actual) {
54         if (expected == null || expected == JSONObject.NULL) {return;}
55
56         JSONObject expectedJSON = new JSONObject(expected);
57         JSONObject actualJSON = new JSONObject(actual);
58         Iterator<?> keys = expectedJSON.keys();
59
60         while( keys.hasNext() ) {
61             String key = (String)keys.next();
62             Object expectedValue = expectedJSON.get(key);
63             if (expectedValue == JSONObject.NULL){
64                 continue;
65             }
66
67             Object actualValue = actualJSON.get(key);
68
69             if (expectedValue instanceof JSONObject) {
70                 String expectedVal = expectedValue.toString();
71                 String actualVal = actualValue.toString();
72                 assertJsonStringEqualsIgnoreNulls(expectedVal, actualVal);
73             }
74             else if (expectedValue instanceof JSONArray) {
75                 if (actualValue instanceof JSONArray) {
76                     JSONArray expectedJSONArray = (JSONArray)expectedValue;
77                     JSONArray actualJSONArray = (JSONArray)actualValue;
78                     for (int i = 0; i < expectedJSONArray.length(); i++) {
79                         String expectedItem = expectedJSONArray.get(i).toString();
80                         String actualItem = actualJSONArray.get(i).toString();
81                         if (expectedValue instanceof JSONObject)
82                             assertJsonStringEqualsIgnoreNulls(expectedItem, actualItem);
83                     }
84                 }
85                 else {
86                     fail("expected: " + expectedValue + " got:" + actualValue);
87                 }
88             }
89             else {
90                 Assert.assertEquals("assertion fail for key:"+key, expectedValue, actualValue);
91             }
92         }
93     }
94
95     public static <T> T readJsonResourceFileAsObject(String pathInResource, Class<T> valueType) throws IOException {
96         return readJsonResourceFileAsObject(pathInResource, valueType, false);
97     }
98
99     public static <T> T readJsonResourceFileAsObject(String pathInResource, Class<T> valueType, boolean ignoreUnknownProperties)
100             throws IOException {
101         ObjectMapper objectMapper = new ObjectMapper();
102         objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, ignoreUnknownProperties);
103         return objectMapper.readValue(
104                 TestUtils.class.getResource(pathInResource),
105                 valueType);
106     }
107
108
109     public static class JavaxRsClientMocks {
110         private final javax.ws.rs.client.Client fakeClient;
111         private final javax.ws.rs.client.Invocation.Builder fakeBuilder;
112         private final javax.ws.rs.client.Invocation fakeInvocation;
113         private final Response fakeResponse;
114
115         public javax.ws.rs.client.Client getFakeClient() {
116             return fakeClient;
117         }
118
119         public javax.ws.rs.client.Invocation.Builder getFakeBuilder() {
120             return fakeBuilder;
121         }
122
123         public Response getFakeResponse() {
124             return fakeResponse;
125         }
126
127         public JavaxRsClientMocks() {
128             final MockSettings mockSettings = withSettings().defaultAnswer(new TriesToReturnMockByType());
129
130             fakeClient = mock(javax.ws.rs.client.Client.class, mockSettings);
131             fakeBuilder = mock(javax.ws.rs.client.Invocation.Builder.class, mockSettings);
132             fakeInvocation = mock(javax.ws.rs.client.Invocation.class, mockSettings);
133             fakeResponse = mock(Response.class, mockSettings);
134             final javax.ws.rs.client.WebTarget fakeWebTarget = mock(javax.ws.rs.client.WebTarget.class, mockSettings);
135
136             TriesToReturnMockByType.setAvailableMocks(
137                     fakeClient,
138                     fakeWebTarget,
139                     fakeBuilder,
140                     fakeInvocation,
141                     fakeResponse
142             );
143             Mockito.when(fakeBuilder.get(any(Class.class))).thenReturn(null);
144             Mockito.when(fakeBuilder.get(any(GenericType.class))).thenReturn(null);
145             Mockito.when(fakeResponse.getStatus()).thenReturn(200);
146             Mockito.when(fakeResponse.getStatusInfo()).thenReturn(Response.Status.OK);
147             Mockito.when(fakeResponse.readEntity(Service.class)).thenReturn(null);
148             Mockito.when(fakeResponse.readEntity(InputStream.class)).thenReturn(new ByteArrayInputStream(new byte[]{}));
149             Mockito.when(fakeResponse.readEntity(String.class)).thenReturn(null);
150         }
151     }
152
153     /*
154        inspired out from newer Mockito version
155         returns a mock from given list if it's a matching return-type
156     */
157     private static class TriesToReturnMockByType implements Answer<Object>, Serializable {
158         private final Answer<Object> defaultReturn = RETURNS_DEFAULTS;
159         private static List<Object> availableMocks = ImmutableList.of();
160
161         static void setAvailableMocks(Object... mocks) {
162             availableMocks = ImmutableList.copyOf(mocks);
163         }
164
165         public Object answer(InvocationOnMock invocation) throws Throwable {
166             Class<?> methodReturnType = invocation.getMethod().getReturnType();
167
168             return availableMocks.stream()
169                     .filter(mock -> methodReturnType.isAssignableFrom(mock.getClass()))
170                     //.peek(m -> logger.info("found a mock: " + m.getClass().getName()))
171                     .findFirst()
172                     .orElse(defaultReturn.answer(invocation));
173         }
174     }
175
176
177     //The method mocks only some methods used in my case
178     //You may add some other when for your test here
179     public static Response mockResponseForJavaxClient(Client javaxClientMock) {
180         Response  mockResponse = mock(Response.class);
181         WebTarget webTarget = mock(WebTarget.class);
182         Invocation.Builder builder = mock(Invocation.Builder.class);
183         when(javaxClientMock.target(any(URI.class))).thenReturn(webTarget);
184         when(webTarget.path(any())).thenReturn(webTarget);
185         when(webTarget.request(any(MediaType.class))).thenReturn(builder);
186         when(builder.headers(any())).thenReturn(builder);
187         when(builder.header(any(), any())).thenReturn(builder);
188         when(builder.get()).thenReturn(mockResponse);
189         return mockResponse;
190     }
191
192
193     //Please use resetSystemProperties after using this method, so other test won't be affected
194     public static void mockSystemPropertyWithKeyValue(String key, String value) {
195         MockEnvironment mockEnvironment = new MockEnvironment();
196         mockEnvironment.setProperty(key, value);
197
198         SystemProperties systemProperties = new SystemProperties();
199         systemProperties.setEnvironment(mockEnvironment);
200     }
201
202     public static void resetSystemProperties() {
203         SystemProperties systemProperties = new SystemProperties();
204         systemProperties.setEnvironment(null);
205     }
206
207 }