Cenralized handling of USER_ID header
[sdc/sdc-workflow-designer.git] / workflow-designer-be / src / test / java / org / onap / sdc / workflow / api / WorkflowControllerTest.java
1 package org.onap.sdc.workflow.api;
2
3 import static org.hamcrest.Matchers.is;
4 import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
5 import static org.junit.Assert.assertEquals;
6 import static org.mockito.ArgumentMatchers.any;
7 import static org.mockito.Mockito.doReturn;
8 import static org.mockito.Mockito.verify;
9 import static org.onap.sdc.workflow.TestUtil.createWorkflow;
10 import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER;
11 import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT;
12 import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET;
13 import static org.onap.sdc.workflow.services.types.WorkflowValidationConstants.MAX_LENGTH;
14 import static org.onap.sdc.workflow.services.types.WorkflowValidationConstants.MIN_LENGTH;
15 import static org.springframework.http.MediaType.APPLICATION_JSON;
16 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
17 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
18 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
19 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
20 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
21
22 import com.amdocs.zusammen.datatypes.Id;
23 import com.amdocs.zusammen.datatypes.item.Item;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.mockito.ArgumentCaptor;
31 import org.mockito.Captor;
32 import org.mockito.InjectMocks;
33 import org.mockito.Mock;
34 import org.mockito.junit.MockitoJUnitRunner;
35 import org.onap.sdc.workflow.RestPath;
36 import org.onap.sdc.workflow.server.resolvers.UserIdResolver;
37 import org.onap.sdc.workflow.services.WorkflowManager;
38 import org.onap.sdc.workflow.services.types.Page;
39 import org.onap.sdc.workflow.services.types.PagingRequest;
40 import org.onap.sdc.workflow.services.types.RequestSpec;
41 import org.onap.sdc.workflow.services.types.Sort;
42 import org.onap.sdc.workflow.services.types.Workflow;
43 import org.onap.sdc.workflow.services.utilities.JsonUtil;
44 import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
45 import org.springframework.test.web.servlet.MockMvc;
46 import org.springframework.test.web.servlet.ResultActions;
47 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
48
49 @RunWith(MockitoJUnitRunner.class)
50 public class WorkflowControllerTest {
51
52     private static final String USER_ID = "userId";
53     private static final String MISSING_USER_HEADER_ERROR = "Missing mandatory request header 'USER_ID'";
54     private static final String DEFAULT_SORT_VALUE = "name:asc";
55
56     private MockMvc mockMvc;
57
58     @Mock
59     private WorkflowManager workflowManagerMock;
60     @Captor
61     private ArgumentCaptor<RequestSpec> requestSpecArg;
62     @InjectMocks
63     private WorkflowController workflowController;
64
65     @Before
66     public void setUp() {
67         mockMvc = MockMvcBuilders.standaloneSetup(workflowController)
68                                  .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
69                                  .setCustomArgumentResolvers(new UserIdResolver())
70                                  .setControllerAdvice(new ExceptionsHandler()).build();
71     }
72
73     @Test
74     public void shouldReturnErrorWhenMissingUserIdInGetReqHeader() throws Exception {
75         Workflow workflowMock = createWorkflow(1, true);
76         mockMvc.perform(get(RestPath.getWorkflowPath(workflowMock.getId())).contentType(APPLICATION_JSON))
77                .andDo(print()).andExpect(status().isBadRequest())
78                .andExpect(jsonPath("$.message", is(MISSING_USER_HEADER_ERROR)));
79     }
80
81     @Test
82     public void shouldReturnWorkflowDataWhenRequestPathIsOk() throws Exception {
83         Workflow workflowMock = createWorkflow(1, true);
84         doReturn(workflowMock).when(workflowManagerMock).get(any(Workflow.class));
85         mockMvc.perform(get(RestPath.getWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID)
86                                                                            .contentType(APPLICATION_JSON))
87                .andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.id", is(workflowMock.getId())))
88                .andExpect(jsonPath("$.name", is(workflowMock.getName())));
89     }
90
91     @Test
92     public void shouldReturnErrorWhenMissingUserIdInListReqHeader() throws Exception {
93         mockMvc.perform(get(RestPath.getWorkflowsPath()).contentType(APPLICATION_JSON)).andDo(print())
94                .andExpect(status().isBadRequest()).andExpect(jsonPath("$.message", is(MISSING_USER_HEADER_ERROR)));
95     }
96
97     @Test
98     public void listWhenExist() throws Exception {
99         mockManagerList3();
100         ResultActions result = mockMvc.perform(
101                 get(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON))
102                                       .andDo(print()).andExpect(status().isOk())
103                                       .andExpect(jsonPath("$.items", hasSize(3)));
104         for (int i = 0; i < 3; i++) {
105             result.andExpect(jsonPath(String.format("$.items[%s].id", i), is(String.valueOf(i + 1))));
106         }
107
108         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
109         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, DEFAULT_LIMIT, Collections.emptyList());
110     }
111
112     @Test
113     public void listWhenPagingAndSortingAreSet() throws Exception {
114         mockManagerList3();
115         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "1"))
116                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
117                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
118         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
119         assertRequestSpec(requestSpecArg.getValue(), 1, 2, Collections.singletonList(new Sort("name", true)));
120     }
121
122     @Test
123     public void shouldReturnResultsWithDefaultWhenLimitIsNegative() throws Exception {
124         mockManagerList3();
125         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "-2", "1"))
126                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
127                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
128         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
129         assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT,
130                 Collections.singletonList(new Sort("name", true)));
131     }
132
133     @Test
134     public void shouldFallbackOnDefaultOffsetWhenOffsetIsNegative() throws Exception {
135         mockManagerList3();
136         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "-1"))
137                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
138                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
139         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
140         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2,
141                 Collections.singletonList(new Sort("name", true)));
142     }
143
144     @Test
145     public void shouldFallbackOnDefaultLimitWhenLimitIsNotAnInteger() throws Exception {
146         mockManagerList3();
147         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "abc", "0"))
148                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
149                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
150         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
151         assertRequestSpec(requestSpecArg.getValue(), 0, DEFAULT_LIMIT,
152                 Collections.singletonList(new Sort("name", true)));
153     }
154
155     @Test
156     public void shouldFallbackOnDefaultOffsetWhenOffsetIsNotAnInteger() throws Exception {
157         mockManagerList3();
158         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "abc"))
159                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
160                .andExpect(jsonPath("$.items", hasSize(3)));
161         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
162         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2,
163                 Collections.singletonList(new Sort("name", true)));
164     }
165
166     @Test
167     public void shouldReturnDefaultLimitOffsetAppliedWorkflowsWhenLimitIsNotSpecified() throws Exception {
168         mockManagerList3();
169         mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndLimit("1")).header(USER_ID_HEADER, USER_ID)
170                                                                          .contentType(APPLICATION_JSON)).andDo(print())
171                .andExpect(jsonPath("$.items", hasSize(3)));
172         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
173         assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT, Collections.emptyList());
174     }
175
176     @Test
177     public void shouldReturnDefaultOffsetAppliedWorkflowsWhenOffsetIsNotSpecified() throws Exception {
178         mockManagerList3();
179         mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndOffset("1")).header(USER_ID_HEADER, USER_ID)
180                                                                           .contentType(APPLICATION_JSON)).andDo(print())
181                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
182         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
183         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 1, Collections.emptyList());
184     }
185
186     @Test
187     public void shouldCreateWorkflowWhenCallingPostRestRequest() throws Exception {
188         Item item = new Item();
189         item.setId(new Id("abc"));
190         Workflow reqWorkflow = createWorkflow(1, false);
191         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
192                                 .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
193                 .andExpect(status().isCreated());
194         verify(workflowManagerMock).create(reqWorkflow);
195     }
196
197     @Test
198     public void shouldThrowExceptionWhenWorkflowNameInvalid() throws Exception {
199         Workflow reqWorkflow = new Workflow();
200         reqWorkflow.setName("Invalid workflow name %");
201         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
202                                 .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
203                 .andExpect(status().isBadRequest()).andExpect(
204                 jsonPath("$.message", is("Workflow name must contain only letters, digits and underscores.")));
205     }
206
207     @Test
208     public void shouldThrowExceptionWhenWorkflowNameBlank() throws Exception {
209         Workflow reqWorkflow = new Workflow();
210         reqWorkflow.setName("  ");
211         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
212                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
213                .andExpect(status().isBadRequest());
214     }
215
216     @Test
217     public void shouldThrowExceptionWhenWorkflowNameNull() throws Exception {
218         Workflow reqWorkflow = new Workflow();
219         reqWorkflow.setName(null);
220         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
221                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
222                .andExpect(status().isBadRequest());
223     }
224
225     @Test
226     public void shouldThrowExceptionWhenWorkflowNameEmptyString() throws Exception {
227         Workflow reqWorkflow = new Workflow();
228         reqWorkflow.setName("");
229         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
230                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
231                .andExpect(status().isBadRequest());
232     }
233
234     @Test
235     public void shouldThrowExceptionWhenWorkflowNameMoreThanMax() throws Exception {
236         Workflow reqWorkflow = new Workflow();
237         reqWorkflow.setName("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
238         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
239                                 .content(JsonUtil.object2Json(reqWorkflow))).andDo(print()).andExpect(
240                                         status().isBadRequest()).andExpect(jsonPath("$.message", is(
241                                                 "Workflow name must be at least " + MIN_LENGTH
242                                                         + " characters, and no more than " + MAX_LENGTH
243                                                         + " characters.")));
244     }
245
246     @Test
247     public void shouldThrowExceptionWhenWorkflowNameLessThanMin() throws Exception {
248         Workflow reqWorkflow = new Workflow();
249         reqWorkflow.setName("AAA");
250         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
251                                 .content(JsonUtil.object2Json(reqWorkflow))).andDo(print()).andExpect(
252                                         status().isBadRequest()).andExpect(jsonPath("$.message",
253                 is("Workflow name must be at least " + MIN_LENGTH + " characters, and no more than "
254                            + MAX_LENGTH + " characters.")));
255     }
256
257     private void mockManagerList3() {
258         doReturn(new Page<>(Arrays.asList(createWorkflow(1, true),
259                 createWorkflow(2, true), createWorkflow(3, true)),
260                 new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), 3)).when(workflowManagerMock)
261                                                                      .list(any(), any(), any());
262     }
263
264     private static void assertRequestSpec(RequestSpec actual, int expectedOffset, int expectedLimit,
265             List<Sort> expectedSorts) {
266         assertEquals(Integer.valueOf(expectedOffset), actual.getPaging().getOffset());
267         assertEquals(Integer.valueOf(expectedLimit), actual.getPaging().getLimit());
268         if (expectedSorts.isEmpty()) {
269             assertEquals(expectedSorts, actual.getSorting().getSorts());
270         } else {
271             for (int i = 0; i < expectedSorts.size(); i++) {
272                 assertEquals(expectedSorts.get(i), actual.getSorting().getSorts().get(i));
273             }
274         }
275     }
276 }