Fix for substitution filter properties
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / servlets / ComponentSubstitutionFilterServletTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.openecomp.sdc.be.servlets;
21
22 import static org.assertj.core.api.Assertions.assertThat;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.ArgumentMatchers.anyString;
27 import static org.mockito.ArgumentMatchers.anyBoolean;
28 import static org.mockito.ArgumentMatchers.nullable;
29 import static org.mockito.ArgumentMatchers.anyList;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.reset;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 import static org.openecomp.sdc.common.api.Constants.USER_ID_HEADER;
36
37 import com.fasterxml.jackson.core.JsonProcessingException;
38 import com.fasterxml.jackson.databind.ObjectMapper;
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.LinkedList;
42 import java.util.Optional;
43 import javax.servlet.ServletContext;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpSession;
46 import javax.ws.rs.client.Entity;
47 import javax.ws.rs.core.MediaType;
48 import javax.ws.rs.core.Response;
49
50 import org.eclipse.jetty.http.HttpStatus;
51 import org.glassfish.hk2.utilities.binding.AbstractBinder;
52 import org.glassfish.jersey.server.ResourceConfig;
53 import org.glassfish.jersey.test.JerseyTest;
54 import org.glassfish.jersey.test.TestProperties;
55 import org.junit.jupiter.api.AfterEach;
56 import org.junit.jupiter.api.BeforeAll;
57 import org.junit.jupiter.api.BeforeEach;
58 import org.junit.jupiter.api.Test;
59 import org.mockito.ArgumentMatchers;
60 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
61 import org.openecomp.sdc.be.components.impl.ComponentSubstitutionFilterBusinessLogic;
62 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
63 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
64 import org.openecomp.sdc.be.components.validation.UserValidations;
65 import org.openecomp.sdc.be.config.SpringConfig;
66 import org.openecomp.sdc.be.dao.api.ActionStatus;
67 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
68 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
72 import org.openecomp.sdc.be.impl.ComponentsUtils;
73 import org.openecomp.sdc.be.impl.ServletUtils;
74 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
75 import org.openecomp.sdc.be.model.User;
76 import org.openecomp.sdc.be.ui.model.UIConstraint;
77 import org.openecomp.sdc.be.user.Role;
78 import org.openecomp.sdc.be.user.UserBusinessLogic;
79 import org.openecomp.sdc.common.api.Constants;
80 import org.openecomp.sdc.exception.ResponseFormat;
81 import org.springframework.context.ApplicationContext;
82 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
83 import org.springframework.web.context.WebApplicationContext;
84
85 public class ComponentSubstitutionFilterServletTest extends JerseyTest {
86
87     private static final String USER_ID = "jh0003";
88     private static final String servicePropertyName = "controller_actor";
89     private static final String constraintOperator = "equal";
90     private static final String sourceType = "static";
91     private static final String sourceName = sourceType;
92     private static final String propertyValue = "constraintValue";
93     private static final String componentId = "dac65869-dfb4-40d2-aa20-084324659ec1";
94     private static final String constraintType = "properties";
95     private static final String componentType = "services";
96
97     private static HttpServletRequest request;
98     private static HttpSession session;
99     private static ServletContext servletContext;
100     private static WebAppContextWrapper webAppContextWrapper;
101     private static WebApplicationContext webApplicationContext;
102     private static UserBusinessLogic userBusinessLogic;
103     private static ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
104     private static ComponentsUtils componentsUtils;
105     private static ServletUtils servletUtils;
106     private static ResourceImportManager resourceImportManager;
107     private static ComponentSubstitutionFilterBusinessLogic componentSubstitutionFilterBusinessLogic;
108     private static ResponseFormat responseFormat;
109     private static UserValidations userValidations;
110
111     private SubstitutionFilterDataDefinition substitutionFilterDataDefinition;
112     private RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition;
113     private UIConstraint uiConstraint;
114     private String constraint;
115     private String inputJson;
116     private User user;
117
118     @BeforeAll
119     public static void initClass() {
120         createMocks();
121         when(request.getSession()).thenReturn(session);
122         when(session.getServletContext()).thenReturn(servletContext);
123         when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
124             .thenReturn(webAppContextWrapper);
125         when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
126         when(webApplicationContext.getBean(ComponentSubstitutionFilterBusinessLogic.class))
127             .thenReturn(componentSubstitutionFilterBusinessLogic);
128         when(request.getHeader("USER_ID")).thenReturn(USER_ID);
129         when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
130         when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
131     }
132
133     @BeforeEach
134     public void resetMock() throws Exception {
135         super.setUp();
136         reset(componentSubstitutionFilterBusinessLogic);
137         initComponentData();
138     }
139
140     @AfterEach
141     void after() throws Exception {
142         super.tearDown();
143     }
144
145     @Test
146     public void addSubstitutionFilterTest() throws Exception {
147         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
148         final String path = String.format(pathFormat, componentType, componentId, constraintType);
149
150         when(userValidations.validateUserExists(user)).thenReturn(user);
151         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
152         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
153         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
154
155         assertNotNull(uiConstraint);
156         assertThat(servicePropertyName).isEqualToIgnoringCase(uiConstraint.getServicePropertyName());
157         assertThat(constraintOperator).isEqualToIgnoringCase(uiConstraint.getConstraintOperator());
158         assertThat(sourceType).isEqualToIgnoringCase(uiConstraint.getSourceType());
159         assertThat(sourceName).isEqualToIgnoringCase(uiConstraint.getSourceName());
160         assertThat(propertyValue).isEqualToIgnoringCase(uiConstraint.getValue().toString());
161
162         when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class)))
163             .thenReturn(Optional.of(uiConstraint));
164
165         assertNotNull(constraint);
166         assertNotNull(substitutionFilterDataDefinition);
167         assertThat(substitutionFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1);
168         assertThat("controller_actor: {equal: constraintValue}\n").isEqualToIgnoringCase(constraint);
169         when(componentSubstitutionFilterBusinessLogic.addSubstitutionFilter(componentId, uiConstraint.getServicePropertyName(), constraint,
170                 true, ComponentTypeEnum.SERVICE)).thenReturn(Optional.of(substitutionFilterDataDefinition));
171
172         final Response response = target()
173             .path(path)
174             .request(MediaType.APPLICATION_JSON)
175             .header(USER_ID_HEADER, USER_ID)
176             .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
177
178         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
179
180         verify(componentSubstitutionFilterBusinessLogic, times(1))
181                 .addSubstitutionFilter(componentId, uiConstraint.getServicePropertyName(), constraint,
182                         true, ComponentTypeEnum.SERVICE);
183     }
184
185     @Test
186     public void addSubstitutionFilterFailConstraintParseTest() {
187         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
188         final String path = String.format(pathFormat, componentType, componentId, constraintType);
189
190         when(userValidations.validateUserExists(user)).thenReturn(user);
191         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
192         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
193
194         when(componentsUtils.parseToConstraint(anyString(), any(User.class), nullable(ComponentTypeEnum.class)))
195             .thenReturn(Optional.empty());
196
197         final Response response = target()
198             .path(path)
199             .request(MediaType.APPLICATION_JSON)
200             .header(USER_ID_HEADER, USER_ID)
201             .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
202
203         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
204     }
205
206     @Test
207     public void addSubstitutionFilterFailTest() {
208         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
209         final String path = String.format(pathFormat, componentType, componentId, constraintType);
210
211         when(userValidations.validateUserExists(user)).thenReturn(user);
212         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
213         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
214
215         when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class)))
216             .thenReturn(Optional.of(uiConstraint));
217
218         final Response response = target()
219             .path(path)
220             .request(MediaType.APPLICATION_JSON)
221             .header(USER_ID_HEADER, USER_ID)
222             .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
223
224         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
225     }
226
227     @Test
228     public void updateSubstitutionFilterTest() throws BusinessLogicException {
229         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
230         final String path = String.format(pathFormat, componentType, componentId, constraintType);
231
232         when(userValidations.validateUserExists(user)).thenReturn(user);
233         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
234         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
235         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
236
237         when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(),
238             any(User.class))).thenReturn(Collections.singletonList(uiConstraint));
239
240         when(componentSubstitutionFilterBusinessLogic.updateSubstitutionFilter(componentId.toLowerCase(),
241             Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE))
242             .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition));
243
244         final Response response = target()
245             .path(path)
246             .request(MediaType.APPLICATION_JSON)
247             .header(USER_ID_HEADER, USER_ID)
248             .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
249
250         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
251
252         verify(componentSubstitutionFilterBusinessLogic, times(1))
253                 .updateSubstitutionFilter(anyString(), anyList(), anyBoolean(), any(ComponentTypeEnum.class));
254     }
255
256     @Test
257     public void updateSubstitutionFilterFailConstraintParseTest() {
258         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
259         final String path = String.format(pathFormat, componentType, componentId, constraintType);
260
261         when(userValidations.validateUserExists(user)).thenReturn(user);
262         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
263         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
264
265         when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(),
266             any(User.class))).thenReturn(Collections.emptyList());
267
268         final Response response = target()
269             .path(path)
270             .request(MediaType.APPLICATION_JSON)
271             .header(USER_ID_HEADER, USER_ID)
272             .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
273
274         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
275     }
276
277     @Test
278     public void updateSubstitutionFilterFailTest()  {
279         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
280         final String path = String.format(pathFormat, componentType, componentId, constraintType);
281
282         when(userValidations.validateUserExists(user)).thenReturn(user);
283         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
284         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
285
286         when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(),
287             any(User.class))).thenReturn(Collections.singletonList(uiConstraint));
288
289         final Response response = target()
290             .path(path)
291             .request(MediaType.APPLICATION_JSON)
292             .header(USER_ID_HEADER, USER_ID)
293             .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
294
295         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
296     }
297
298     @Test
299     public void deleteSubstitutionFilterConstraintTest() throws BusinessLogicException {
300         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0";
301         final String path = String.format(pathFormat, componentType, componentId, constraintType);
302
303         when(userValidations.validateUserExists(user)).thenReturn(user);
304         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
305         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
306         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
307
308         when(componentSubstitutionFilterBusinessLogic.deleteSubstitutionFilter(componentId, 0,
309                 true, ComponentTypeEnum.SERVICE))
310             .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition));
311
312         final Response response = target()
313             .path(path)
314             .request(MediaType.APPLICATION_JSON)
315             .header(USER_ID_HEADER, USER_ID)
316             .delete(Response.class);
317
318         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
319
320         verify(componentSubstitutionFilterBusinessLogic, times(1))
321                 .deleteSubstitutionFilter(anyString(), anyInt(), anyBoolean(), any(ComponentTypeEnum.class));
322     }
323
324     @Test
325     public void deleteSubstitutionFilterConstraintFailTest() {
326         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0";
327         final String path = String.format(pathFormat, componentType, componentId, constraintType);
328
329         when(userValidations.validateUserExists(user)).thenReturn(user);
330         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
331         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
332
333         final Response response = target()
334             .path(path)
335             .request(MediaType.APPLICATION_JSON)
336             .header(USER_ID_HEADER, USER_ID)
337             .delete(Response.class);
338
339         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
340     }
341
342     private static void createMocks() {
343         request = mock(HttpServletRequest.class);
344         userBusinessLogic = mock(UserBusinessLogic.class);
345         componentInstanceBusinessLogic = mock(ComponentInstanceBusinessLogic.class);
346         componentsUtils = mock(ComponentsUtils.class);
347         servletUtils = mock(ServletUtils.class);
348         resourceImportManager = mock(ResourceImportManager.class);
349         componentSubstitutionFilterBusinessLogic = mock(ComponentSubstitutionFilterBusinessLogic.class);
350
351         session = mock(HttpSession.class);
352         servletContext = mock(ServletContext.class);
353         webAppContextWrapper = mock(WebAppContextWrapper.class);
354         webApplicationContext = mock(WebApplicationContext.class);
355         responseFormat = mock(ResponseFormat.class);
356         userValidations = mock(UserValidations.class);
357     }
358
359     @Override
360     protected ResourceConfig configure() {
361         forceSet(TestProperties.CONTAINER_PORT, "0");
362         final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
363         return new ResourceConfig(ComponentSubstitutionFilterServlet.class)
364             .register(new AbstractBinder() {
365                 @Override
366                 protected void configure() {
367                     bind(request).to(HttpServletRequest.class);
368                     bind(userBusinessLogic).to(UserBusinessLogic.class);
369                     bind(componentInstanceBusinessLogic).to(ComponentInstanceBusinessLogic.class);
370                     bind(componentsUtils).to(ComponentsUtils.class);
371                     bind(servletUtils).to(ServletUtils.class);
372                     bind(resourceImportManager).to(ResourceImportManager.class);
373                     bind(componentSubstitutionFilterBusinessLogic).to(ComponentSubstitutionFilterBusinessLogic.class);
374                 }
375             })
376             .property("contextConfig", context);
377     }
378
379     private void initComponentData() throws JsonProcessingException {
380         uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue);
381         constraint = new ConstraintConvertor().convert(uiConstraint);
382         inputJson = buildConstraintDataJson(uiConstraint);
383
384         requirementSubstitutionFilterPropertyDataDefinition = new RequirementSubstitutionFilterPropertyDataDefinition();
385         requirementSubstitutionFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName());
386         requirementSubstitutionFilterPropertyDataDefinition.setConstraints(new LinkedList<>(Arrays.asList(constraint)));
387
388         final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> listDataDefinition =
389             new ListDataDefinition<>(
390                 new LinkedList<>(Arrays.asList(requirementSubstitutionFilterPropertyDataDefinition)));
391
392         substitutionFilterDataDefinition = new SubstitutionFilterDataDefinition();
393         substitutionFilterDataDefinition.setProperties(listDataDefinition);
394         substitutionFilterDataDefinition.setID("SUBSTITUTION_FILTER_UID");
395
396         user = new User();
397         user.setUserId(USER_ID);
398         user.setRole(Role.ADMIN.name());
399     }
400
401     private String buildConstraintDataJson(final UIConstraint uiConstraint) throws JsonProcessingException {
402         final ObjectMapper mapper = new ObjectMapper();
403         return mapper.writeValueAsString(uiConstraint);
404     }
405
406 }