modify listeners to only start when props present
[appc.git] / appc-adapters / appc-chef-adapter / appc-chef-adapter-bundle / src / test / java / org / onap / appc / adapter / chef / chefclient / ChefApiClientTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2018 Nokia. All rights reserved.
6  * =============================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.appc.adapter.chef.chefclient;
21
22 import static junit.framework.TestCase.assertEquals;
23 import static org.mockito.BDDMockito.given;
24 import static org.mockito.Matchers.argThat;
25 import static org.mockito.Mockito.mock;
26
27 import com.google.common.collect.ImmutableMap;
28 import java.io.IOException;
29 import java.net.URI;
30 import java.net.URISyntaxException;
31 import java.util.function.Supplier;
32 import org.apache.http.Header;
33 import org.apache.http.HttpResponse;
34 import org.apache.http.HttpStatus;
35 import org.apache.http.StatusLine;
36 import org.apache.http.client.HttpClient;
37 import org.apache.http.client.methods.HttpRequestBase;
38 import org.apache.http.entity.StringEntity;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.mockito.ArgumentMatcher;
43 import org.mockito.InjectMocks;
44 import org.mockito.Mock;
45 import org.mockito.runners.MockitoJUnitRunner;
46
47 @RunWith(MockitoJUnitRunner.class)
48 public class ChefApiClientTest {
49
50     private static final String END_POINT = "https://chefServer";
51     private static final String ORGANIZATIONS_PATH = "onap";
52     private static final String USER_ID = "testUser";
53     private static final String REQUEST_PATH = "/test/path";
54     private static final String BODY = "SOME BODY STRING";
55     private static final ImmutableMap<String, String> HEADERS = ImmutableMap.<String, String>builder()
56         .put("Content-type", "application/json")
57         .put("Accept", "application/json")
58         .put("X-Ops-Timestamp", "1970-01-15T06:56:07Z")
59         .put("X-Ops-UserId", USER_ID)
60         .put("X-Chef-Version", "12.4.1")
61         .put("X-Ops-Content-Hash", BODY)
62         .put("X-Ops-Sign", "version=1.0").build();
63
64     @Mock
65     private HttpClient httpClient;
66     @Mock
67     private ChefApiHeaderFactory chefHttpHeaderFactory;
68
69     @InjectMocks
70     private ChefApiClientFactory chefApiClientFactory;
71     private static final String PEM_FILEPATH = "path/to/pemFile";
72     private ChefApiClient chefApiClient;
73
74     @Before
75     public void setUp() {
76         chefApiClient = chefApiClientFactory.create(
77             END_POINT,
78             ORGANIZATIONS_PATH,
79             USER_ID,
80             PEM_FILEPATH);
81     }
82
83     @Test
84     public void execute_HttpGet_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException {
85         // GIVEN
86         String methodName = "GET";
87         String body = "";
88         Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.get(REQUEST_PATH);
89
90         // WHEN //THEN
91         assertChefApiClientCall(methodName, body, chefClientApiCall);
92     }
93
94     @Test
95     public void execute_HttpDelete_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException {
96         // GIVEN
97         String methodName = "DELETE";
98         String body = "";
99         Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.delete(REQUEST_PATH);
100
101         // WHEN //THEN
102         assertChefApiClientCall(methodName, body, chefClientApiCall);
103     }
104
105     @Test
106     public void execute_HttpPost_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException {
107         // GIVEN
108         String methodName = "POST";
109         Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.post(REQUEST_PATH, BODY);
110
111         // WHEN //THEN
112         assertChefApiClientCall(methodName, BODY, chefClientApiCall);
113     }
114
115     @Test
116     public void execute_HttpPut_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException {
117         // GIVEN
118         String methodName = "PUT";
119         Supplier<ChefResponse> chefClientApiCall = () -> chefApiClient.put(REQUEST_PATH, BODY);
120
121         // WHEN //THEN
122         assertChefApiClientCall(methodName, BODY, chefClientApiCall);
123     }
124
125     private void assertChefApiClientCall(String methodName, String body, Supplier<ChefResponse> httpMethod)
126         throws IOException {
127         // GIVEN
128         given(chefHttpHeaderFactory.create(methodName, REQUEST_PATH, body, USER_ID, ORGANIZATIONS_PATH, PEM_FILEPATH))
129             .willReturn(HEADERS);
130
131         StatusLine statusLine = mock(StatusLine.class);
132         given(statusLine.getStatusCode()).willReturn(HttpStatus.SC_OK);
133         HttpResponse httpResponse = mock(HttpResponse.class);
134         given(httpResponse.getStatusLine()).willReturn(statusLine);
135         given(httpResponse.getEntity()).willReturn(new StringEntity("Successful Response String"));
136         given(httpClient.execute(argThat(new HttpRequestBaseMatcher(methodName))))
137             .willReturn(httpResponse);
138
139         // WHEN
140         ChefResponse chefResponse = httpMethod.get();
141
142         // THEN
143         assertEquals("Successful Response String", chefResponse.getBody());
144         assertEquals(HttpStatus.SC_OK, chefResponse.getStatusCode());
145     }
146
147     @Test
148     public void execute_shouldHandleException_whenHttpClientExecutionFails() throws IOException {
149
150         // GIVEN
151         given(chefHttpHeaderFactory.create("GET", REQUEST_PATH, "", USER_ID, ORGANIZATIONS_PATH, PEM_FILEPATH))
152             .willReturn(HEADERS);
153
154         String expectedErrorMsg = "HttpClient call failed";
155         given(httpClient.execute(argThat(new HttpRequestBaseMatcher("GET"))))
156             .willThrow(new IOException(expectedErrorMsg));
157
158         // WHEN
159         ChefResponse chefResponse = chefApiClient.get(REQUEST_PATH);
160
161         // THEN
162         assertEquals(expectedErrorMsg, chefResponse.getBody());
163         assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, chefResponse.getStatusCode());
164     }
165
166     @Test
167     public void execute_shouldHandleException_whenEndpointURIisMalformed() {
168         // GIVEN
169         String expectedErrorMsg = "Malformed escape pair at index 1: /%#@/";
170
171         // WHEN
172         ChefApiClient chefApiClient = chefApiClientFactory.create(
173             "/%#@/",
174             ORGANIZATIONS_PATH,
175             USER_ID,
176             PEM_FILEPATH);
177         ChefResponse chefResponse = chefApiClient.get(REQUEST_PATH);
178
179         // THEN
180         assertEquals(expectedErrorMsg, chefResponse.getBody());
181         assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, chefResponse.getStatusCode());
182     }
183
184     private class HttpRequestBaseMatcher extends ArgumentMatcher<HttpRequestBase> {
185
186         private final String methodName;
187
188         public HttpRequestBaseMatcher(String methodName) {
189             this.methodName = methodName;
190         }
191
192         @Override
193         public boolean matches(Object argument) {
194             HttpRequestBase httpRequestBase = (HttpRequestBase) argument;
195
196             boolean headersMatch = checkIfHeadersMatch(httpRequestBase);
197             try {
198                 return methodName.equals(httpRequestBase.getMethod())
199                     && new URI(END_POINT + REQUEST_PATH).equals(httpRequestBase.getURI())
200                     && headersMatch;
201             } catch (URISyntaxException e) {
202                 e.printStackTrace();
203                 return false;
204             }
205         }
206
207         private boolean checkIfHeadersMatch(HttpRequestBase httpRequestBase) {
208             Header[] generatedHeaders = httpRequestBase.getAllHeaders();
209             return generatedHeaders.length > 0
210                 && generatedHeaders.length == HEADERS.size()
211                 && HEADERS.entrySet().stream()
212                 .allMatch(p -> httpRequestBase.getFirstHeader(p.getKey()).getValue().equals(p.getValue()));
213         }
214     }
215 }