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