Fix locally failing TCs in catalog-be
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / servlets / GroupEndpointTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. 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
21 package org.openecomp.sdc.be.servlets;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyString;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.ArgumentMatchers.isA;
28 import static org.mockito.Mockito.anyList;
29 import static org.mockito.Mockito.doNothing;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.when;
32 import static org.openecomp.sdc.be.model.operations.api.StorageOperationStatus.NOT_FOUND;
33
34 import com.fasterxml.jackson.databind.DeserializationFeature;
35 import fj.data.Either;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.List;
39 import java.util.Optional;
40 import javax.ws.rs.client.Entity;
41 import javax.ws.rs.client.Invocation;
42 import javax.ws.rs.core.GenericType;
43 import javax.ws.rs.core.MediaType;
44 import javax.ws.rs.core.Response;
45 import org.assertj.core.api.AssertionsForClassTypes;
46 import org.glassfish.jersey.client.ClientConfig;
47 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
48 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;
49 import org.glassfish.jersey.logging.LoggingFeature;
50 import org.glassfish.jersey.server.ResourceConfig;
51 import org.glassfish.jersey.test.TestProperties;
52 import org.junit.jupiter.api.AfterEach;
53 import org.junit.jupiter.api.BeforeAll;
54 import org.junit.jupiter.api.BeforeEach;
55 import org.junit.jupiter.api.Test;
56 import org.mockito.invocation.InvocationOnMock;
57 import org.mockito.stubbing.Answer;
58 import org.openecomp.sdc.be.components.impl.GroupBusinessLogicNew;
59 import org.openecomp.sdc.be.components.validation.AccessValidations;
60 import org.openecomp.sdc.be.components.validation.ComponentValidations;
61 import org.openecomp.sdc.be.config.ConfigurationManager;
62 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
63 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
64 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
65 import org.openecomp.sdc.be.impl.ComponentsUtils;
66 import org.openecomp.sdc.be.model.ComponentInstance;
67 import org.openecomp.sdc.be.model.GroupDefinition;
68 import org.openecomp.sdc.be.model.GroupProperty;
69 import org.openecomp.sdc.be.model.Resource;
70 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.GroupsOperation;
71 import org.openecomp.sdc.be.model.operations.StorageException;
72 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
73 import org.openecomp.sdc.be.model.operations.impl.GroupOperation;
74 import org.openecomp.sdc.be.user.UserBusinessLogic;
75 import org.openecomp.sdc.common.api.ConfigurationSource;
76 import org.openecomp.sdc.common.api.Constants;
77 import org.openecomp.sdc.common.impl.ExternalConfiguration;
78 import org.openecomp.sdc.common.impl.FSConfigurationSource;
79 import org.springframework.context.annotation.Bean;
80 import org.springframework.context.annotation.Configuration;
81 import org.springframework.context.annotation.Import;
82 import org.springframework.http.HttpStatus;
83
84 class GroupEndpointTest extends JerseySpringBaseTest {
85
86     private static final String VALID_USER = "ab001";
87     private static final String INVALID_USER = "ab002";
88     private static final String VALID_COMPONENT_ID = "12345";
89     private static final String INVALID_COMPONENT_ID = "9999";
90     private static final String VALID_GROUP_ID = "1";
91     private static final String INVALID_GROUP_ID = "2";
92     public static final String A = "a";
93     private static final String VL1 = "VL1";
94     private static final String OLD_VALUE = "old value";
95     private static AccessValidations accessValidations;
96     private static ComponentValidations componentValidations;
97     private static GroupsOperation groupsOperation;
98     private static GroupOperation groupOperation;
99     private Resource cr;
100     private GroupDefinition g1;
101     private ComponentInstance ci;
102     private GroupProperty gp1;
103
104     @Configuration
105     @Import(BaseTestConfig.class)
106     static class GroupEndpointTestConfig {
107
108         @Bean
109         GroupEndpoint groupEndpoint() {
110             UserBusinessLogic userBusinessLogic = mock(UserBusinessLogic.class);
111             ComponentsUtils componentsUtils = mock(ComponentsUtils.class);
112
113             return new GroupEndpoint(userBusinessLogic, componentsUtils, groupBusinessLogic());
114         }
115
116         @Bean
117         GroupBusinessLogicNew groupBusinessLogic() {
118             return new GroupBusinessLogicNew(accessValidations, componentValidations, groupsOperation, groupOperation);
119         }
120     }
121
122     @BeforeAll
123     public static void initClass() {
124         ExternalConfiguration.setAppName("catalog-be");
125         String appConfigDir = "src/test/resources/config/catalog-be";
126         ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(),
127             appConfigDir);
128         ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
129         //ComponentsUtils needs configuration singleton to be set
130         componentValidations = mock(ComponentValidations.class);
131         accessValidations = mock(AccessValidations.class);
132         groupsOperation = mock(GroupsOperation.class);
133         groupOperation = mock(GroupOperation.class);
134
135     }
136
137     @Override
138     protected void configureClient(ClientConfig config) {
139         final JacksonJsonProvider jacksonJsonProvider = new JacksonJaxbJsonProvider()
140             .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
141         config.register(jacksonJsonProvider);
142     }
143
144     @Override
145     protected ResourceConfig configure() {
146         forceSet(TestProperties.CONTAINER_PORT, "0");
147         return super.configure(GroupEndpointTestConfig.class)
148             .register(GroupEndpoint.class)
149             .property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, "WARNING");
150     }
151
152     @BeforeEach
153     public void before() throws Exception {
154         super.setUp();
155         cr = new Resource();
156         cr.setSystemName("CR1");
157         g1 = new GroupDefinition();
158         g1.setUniqueId(VALID_GROUP_ID);
159         gp1 = new GroupProperty();
160         gp1.setUniqueId("1");
161         gp1.setName("p1");
162         gp1.setValue(OLD_VALUE);
163         g1.setProperties(Arrays.asList(gp1));
164         cr.setGroups(Arrays.asList(g1));
165         ci = new ComponentInstance();
166         ci.setUniqueId(A);
167         ci.setName(VL1);
168         happyScenarioSetup();
169         unhappyScenarioSetup();
170     }
171
172     @AfterEach
173     void after() throws Exception {
174         super.tearDown();
175     }
176
177     private void unhappyScenarioSetup() {
178         when(accessValidations
179             .validateUserCanWorkOnComponent(eq(INVALID_COMPONENT_ID), eq(ComponentTypeEnum.RESOURCE), eq(VALID_USER),
180                 anyString())).thenThrow(new StorageException(NOT_FOUND, INVALID_COMPONENT_ID));
181         when(componentValidations.getComponentInstance(cr, A)).thenReturn(Optional.of(ci));
182     }
183
184     private void happyScenarioSetup() {
185         when(accessValidations
186             .validateUserCanWorkOnComponent(eq(VALID_COMPONENT_ID), any(ComponentTypeEnum.class), eq(VALID_USER),
187                 anyString())).thenReturn(cr);
188         when(accessValidations
189             .validateUserCanRetrieveComponentData(eq(VALID_COMPONENT_ID), eq("resources"), eq(VALID_USER), anyString()))
190             .thenReturn(cr);
191         when(componentValidations.getComponentInstance(cr, A)).thenReturn(Optional.of(ci));
192         doNothing().when(groupsOperation)
193             .updateGroupOnComponent(eq(VALID_COMPONENT_ID), isA(GroupDefinition.class), any(PromoteVersionEnum.class));
194         when(groupOperation.validateAndUpdatePropertyValue(isA(GroupProperty.class)))
195             .thenReturn(StorageOperationStatus.OK);
196         when(groupsOperation
197             .updateGroupPropertiesOnComponent(eq(VALID_COMPONENT_ID), isA(GroupDefinition.class), anyList(),
198                 any(PromoteVersionEnum.class))).thenAnswer(new Answer<Either>() {
199             @Override
200             public Either answer(InvocationOnMock invocationOnMock) throws Throwable {
201                 Object[] args = invocationOnMock.getArguments();
202                 return Either.left(Arrays.asList(args[2]));
203             }
204         });
205     }
206
207     @Test
208     void updateGroupMembers_success() {
209         List<String> ids = Arrays.asList(A);
210         List<String> updatedIds = buildUpdateGroupMembersCall(VALID_COMPONENT_ID, VALID_GROUP_ID, VALID_USER)
211             .post(Entity.entity(ids, MediaType.APPLICATION_JSON), new GenericType<List<String>>() {
212             });
213         assertThat(updatedIds.size()).isEqualTo(ids.size());
214         assertThat(updatedIds).containsExactlyInAnyOrder(ids.toArray(new String[ids.size()]));
215     }
216
217     @Test
218     void updateGroupMembersWith2IdenticalMembers_success() {
219         List<String> ids = Arrays.asList(A, A);
220         List<String> updatedIds = buildUpdateGroupMembersCall(VALID_COMPONENT_ID, VALID_GROUP_ID, VALID_USER)
221             .post(Entity.entity(ids, MediaType.APPLICATION_JSON), new GenericType<List<String>>() {
222             });
223         assertThat(updatedIds.size()).isEqualTo(1);
224         assertThat(updatedIds).containsExactlyInAnyOrder(String.valueOf(A));
225     }
226
227     @Test
228     void updateGroupMembersWithEmptyList_success() {
229         List<String> ids = new ArrayList<>();
230         List<String> updatedIds = buildUpdateGroupMembersCall(VALID_COMPONENT_ID, VALID_GROUP_ID, VALID_USER)
231             .post(Entity.entity(ids, MediaType.APPLICATION_JSON), new GenericType<List<String>>() {
232             });
233         assertThat(updatedIds.size()).isZero();
234     }
235
236     @Test
237     void updateGroupMember_InvalidComponentId_failure() {
238         List<String> ids = new ArrayList<>();
239         Response response = buildUpdateGroupMembersCall(INVALID_COMPONENT_ID, VALID_GROUP_ID, VALID_USER)
240             .post(Entity.entity(ids, MediaType.APPLICATION_JSON), Response.class);
241         AssertionsForClassTypes.assertThat(response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND.value());
242     }
243
244     @Test
245     void updateGroupProperty_success() {
246         GroupProperty property = new GroupProperty();
247         property.setValue("value1");
248         property.setName("prop");
249         String propertyStr = "[{\"uniqueId\":\"1\",\"type\":null,\"required\":false,\"definition\":false,\"defaultValue\":null,\"description\":null,\"schema\":null,\"password\":false,\"name\":\"p1\",\"value\":\"new value\",\"label\":null,\"hidden\":false,\"immutable\":false,\"inputPath\":null,\"status\":null,\"inputId\":null,\"instanceUniqueId\":null,\"propertyId\":null,\"parentUniqueId\":null,\"getInputValues\":null,\"constraints\":null,\"valueUniqueUid\":null,\"ownerId\":null}]";
250         List<GroupProperty> properties = Arrays.asList(property);
251         //TODO define GroupPropertyDTO (after finding other usage in UI code) and improve test coverage
252 //        List<GroupProperty> updatedProperties = buildUpdateGroupPropertiesCall(VALID_COMPONENT_ID, VALID_GROUP_ID, VALID_USER)
253 //                .put(Entity.entity(propertyStr, MediaType.APPLICATION_JSON), new GenericType<List<GroupProperty>>() {
254 //                });
255 //        assertThat(updatedProperties.size()).isEqualTo(1);
256         Response response = buildUpdateGroupPropertiesCall(VALID_COMPONENT_ID, VALID_GROUP_ID, VALID_USER)
257             .put(Entity.entity(propertyStr, MediaType.APPLICATION_JSON));
258         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
259     }
260
261     @Test
262     void getGroupProperties_success() {
263         List<PropertyDataDefinition> properties = buildUpdateGroupPropertiesCall(VALID_COMPONENT_ID, VALID_GROUP_ID,
264             VALID_USER)
265             .get(new GenericType<List<PropertyDataDefinition>>() {
266             });
267         assertThat(properties.size()).isEqualTo(1);
268         assertThat(properties.get(0).getValue()).isEqualTo(OLD_VALUE);
269     }
270
271     private Invocation.Builder buildUpdateGroupMembersCall(String componentId, String groupId, String userId) {
272         return target("/v1/catalog/resources/" + componentId + "/groups/" + groupId + "/members")
273             .request(MediaType.APPLICATION_JSON)
274             .accept(MediaType.APPLICATION_JSON)
275             .header(Constants.USER_ID_HEADER, userId);
276     }
277
278     private Invocation.Builder buildUpdateGroupPropertiesCall(String componentId, String groupId, String userId) {
279         return target("/v1/catalog/resources/" + componentId + "/groups/" + groupId + "/properties")
280             .request(MediaType.APPLICATION_JSON)
281             .accept(MediaType.APPLICATION_JSON)
282             .header(Constants.USER_ID_HEADER, userId);
283     }
284
285
286 }