1 package org.onap.sdc.workflow.api;
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;
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;
49 @RunWith(MockitoJUnitRunner.class)
50 public class WorkflowControllerTest {
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";
56 private MockMvc mockMvc;
59 private WorkflowManager workflowManagerMock;
61 private ArgumentCaptor<RequestSpec> requestSpecArg;
63 private WorkflowController workflowController;
67 mockMvc = MockMvcBuilders.standaloneSetup(workflowController)
68 .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
69 .setCustomArgumentResolvers(new UserIdResolver())
70 .setControllerAdvice(new ExceptionsHandler()).build();
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)));
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())));
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)));
98 public void listWhenExist() throws Exception {
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))));
108 verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture());
109 assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, DEFAULT_LIMIT, Collections.emptyList());
113 public void listWhenPagingAndSortingAreSet() throws Exception {
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)));
123 public void shouldReturnResultsWithDefaultWhenLimitIsNegative() throws Exception {
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)));
134 public void shouldFallbackOnDefaultOffsetWhenOffsetIsNegative() throws Exception {
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)));
145 public void shouldFallbackOnDefaultLimitWhenLimitIsNotAnInteger() throws Exception {
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)));
156 public void shouldFallbackOnDefaultOffsetWhenOffsetIsNotAnInteger() throws Exception {
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)));
167 public void shouldReturnDefaultLimitOffsetAppliedWorkflowsWhenLimitIsNotSpecified() throws Exception {
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());
177 public void shouldReturnDefaultOffsetAppliedWorkflowsWhenOffsetIsNotSpecified() throws Exception {
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());
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);
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.")));
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());
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());
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());
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
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.")));
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());
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());
271 for (int i = 0; i < expectedSorts.size(); i++) {
272 assertEquals(expectedSorts.get(i), actual.getSorting().getSorts().get(i));