258e9c5173f77a5fb6462028e54cc49db780c711
[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.services.WorkflowManager;
37 import org.onap.sdc.workflow.services.types.Page;
38 import org.onap.sdc.workflow.services.types.PagingRequest;
39 import org.onap.sdc.workflow.services.types.RequestSpec;
40 import org.onap.sdc.workflow.services.types.Sort;
41 import org.onap.sdc.workflow.services.types.Workflow;
42 import org.onap.sdc.workflow.services.utilities.JsonUtil;
43 import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
44 import org.springframework.test.web.servlet.MockMvc;
45 import org.springframework.test.web.servlet.ResultActions;
46 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
47
48 @RunWith(MockitoJUnitRunner.class)
49 public class WorkflowControllerTest {
50
51     private static final String USER_ID = "userId";
52     private static final String MISSING_USER_HEADER_ERROR =
53             "Missing request header 'USER_ID' for method parameter of type String";
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                                  .setControllerAdvice(new ExceptionsHandler()).build();
70     }
71
72     @Test
73     public void shouldReturnErrorWhenMissingUserIdInGetReqHeader() throws Exception {
74         Workflow workflowMock = createWorkflow(1, true);
75         mockMvc.perform(get(RestPath.getWorkflowPath(workflowMock.getId())).contentType(APPLICATION_JSON))
76                .andDo(print()).andExpect(status().isBadRequest())
77                .andExpect(jsonPath("$.message", is(MISSING_USER_HEADER_ERROR)));
78     }
79
80     @Test
81     public void shouldReturnWorkflowDataWhenRequestPathIsOk() throws Exception {
82         Workflow workflowMock = createWorkflow(1, true);
83         doReturn(workflowMock).when(workflowManagerMock).get(any(Workflow.class));
84         mockMvc.perform(get(RestPath.getWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID)
85                                                                            .contentType(APPLICATION_JSON))
86                .andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.id", is(workflowMock.getId())))
87                .andExpect(jsonPath("$.name", is(workflowMock.getName())));
88     }
89
90     @Test
91     public void shouldReturnErrorWhenMissingUserIdInListReqHeader() throws Exception {
92         mockMvc.perform(get(RestPath.getWorkflowsPath()).contentType(APPLICATION_JSON)).andDo(print())
93                .andExpect(status().isBadRequest()).andExpect(jsonPath("$.message", is(MISSING_USER_HEADER_ERROR)));
94     }
95
96     @Test
97     public void listWhenExist() throws Exception {
98         mockManagerList3();
99         ResultActions result = mockMvc.perform(
100                 get(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON))
101                                       .andDo(print()).andExpect(status().isOk())
102                                       .andExpect(jsonPath("$.items", hasSize(3)));
103         for (int i = 0; i < 3; i++) {
104             result.andExpect(jsonPath(String.format("$.items[%s].id", i), is(String.valueOf(i + 1))));
105         }
106
107         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
108         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, DEFAULT_LIMIT, Collections.emptyList());
109     }
110
111     @Test
112     public void listWhenPagingAndSortingAreSet() throws Exception {
113         mockManagerList3();
114         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "1"))
115                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
116                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
117         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
118         assertRequestSpec(requestSpecArg.getValue(), 1, 2, Collections.singletonList(new Sort("name", true)));
119     }
120
121     @Test
122     public void shouldReturnResultsWithDefaultWhenLimitIsNegative() throws Exception {
123         mockManagerList3();
124         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "-2", "1"))
125                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
126                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
127         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
128         assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT,
129                 Collections.singletonList(new Sort("name", true)));
130     }
131
132     @Test
133     public void shouldFallbackOnDefaultOffsetWhenOffsetIsNegative() throws Exception {
134         mockManagerList3();
135         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "-1"))
136                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
137                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
138         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
139         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2,
140                 Collections.singletonList(new Sort("name", true)));
141     }
142
143     @Test
144     public void shouldFallbackOnDefaultLimitWhenLimitIsNotAnInteger() throws Exception {
145         mockManagerList3();
146         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "abc", "0"))
147                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
148                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
149         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
150         assertRequestSpec(requestSpecArg.getValue(), 0, DEFAULT_LIMIT,
151                 Collections.singletonList(new Sort("name", true)));
152     }
153
154     @Test
155     public void shouldFallbackOnDefaultOffsetWhenOffsetIsNotAnInteger() throws Exception {
156         mockManagerList3();
157         mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "abc"))
158                                 .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)).andDo(print())
159                .andExpect(jsonPath("$.items", hasSize(3)));
160         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
161         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2,
162                 Collections.singletonList(new Sort("name", true)));
163     }
164
165     @Test
166     public void shouldReturnDefaultLimitOffsetAppliedWorkflowsWhenLimitIsNotSpecified() throws Exception {
167         mockManagerList3();
168         mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndLimit("1")).header(USER_ID_HEADER, USER_ID)
169                                                                          .contentType(APPLICATION_JSON)).andDo(print())
170                .andExpect(jsonPath("$.items", hasSize(3)));
171         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
172         assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT, Collections.emptyList());
173     }
174
175     @Test
176     public void shouldReturnDefaultOffsetAppliedWorkflowsWhenOffsetIsNotSpecified() throws Exception {
177         mockManagerList3();
178         mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndOffset("1")).header(USER_ID_HEADER, USER_ID)
179                                                                           .contentType(APPLICATION_JSON)).andDo(print())
180                .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3)));
181         verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
182         assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 1, Collections.emptyList());
183     }
184
185     @Test
186     public void shouldCreateWorkflowWhenCallingPostRESTRequest() throws Exception {
187         Item item = new Item();
188         item.setId(new Id("abc"));
189         Workflow reqWorkflow = createWorkflow(1, false);
190         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
191                                 .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
192                 .andExpect(status().isCreated());
193         verify(workflowManagerMock).create(reqWorkflow);
194     }
195
196     @Test
197     public void shouldThrowExceptionWhenWorkflowNameInvalid() throws Exception {
198         Workflow reqWorkflow = new Workflow();
199         reqWorkflow.setName("Invalid workflow name %");
200         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
201                                 .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
202                 .andExpect(status().isBadRequest()).andExpect(
203                 jsonPath("$.message", is("Workflow name must contain only letters, digits and underscores.")));
204     }
205
206     @Test
207     public void shouldThrowExceptionWhenWorkflowNameBlank() throws Exception {
208         Workflow reqWorkflow = new Workflow();
209         reqWorkflow.setName("  ");
210         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
211                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
212                .andExpect(status().isBadRequest());
213     }
214
215     @Test
216     public void shouldThrowExceptionWhenWorkflowNameNull() throws Exception {
217         Workflow reqWorkflow = new Workflow();
218         reqWorkflow.setName(null);
219         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
220                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
221                .andExpect(status().isBadRequest());
222     }
223
224     @Test
225     public void shouldThrowExceptionWhenWorkflowNameEmptyString() throws Exception {
226         Workflow reqWorkflow = new Workflow();
227         reqWorkflow.setName("");
228         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
229                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
230                .andExpect(status().isBadRequest());
231     }
232
233     @Test
234     public void shouldThrowExceptionWhenWorkflowNameMoreThanMax() throws Exception {
235         Workflow reqWorkflow = new Workflow();
236         reqWorkflow.setName("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
237         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
238                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
239                .andExpect(status().isBadRequest()).andExpect(
240                 jsonPath("$.message", is("Workflow name must be at least " + MIN_LENGTH + " characters, and no more than " + MAX_LENGTH + " characters.")));
241     }
242
243     @Test
244     public void shouldThrowExceptionWhenWorkflowNameLessThanMin() throws Exception {
245         Workflow reqWorkflow = new Workflow();
246         reqWorkflow.setName("AAA");
247         mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)
248                                                          .content(JsonUtil.object2Json(reqWorkflow))).andDo(print())
249                .andExpect(status().isBadRequest()).andExpect(
250                 jsonPath("$.message", is("Workflow name must be at least " + MIN_LENGTH + " characters, and no more than " + MAX_LENGTH + " characters.")));
251     }
252
253     private void mockManagerList3() {
254         doReturn(new Page<>(Arrays.asList(createWorkflow(1, true),
255                 createWorkflow(2, true), createWorkflow(3, true)),
256                 new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), 3)).when(workflowManagerMock)
257                                                                      .list(any(), any(), any());
258     }
259
260     private static void assertRequestSpec(RequestSpec actual, int expectedOffset, int expectedLimit,
261             List<Sort> expectedSorts) {
262         assertEquals(Integer.valueOf(expectedOffset), actual.getPaging().getOffset());
263         assertEquals(Integer.valueOf(expectedLimit), actual.getPaging().getLimit());
264         if (expectedSorts.isEmpty()) {
265             assertEquals(expectedSorts, actual.getSorting().getSorts());
266         } else {
267             for (int i = 0; i < expectedSorts.size(); i++) {
268                 assertEquals(expectedSorts.get(i), actual.getSorting().getSorts().get(i));
269             }
270         }
271     }
272 }