Skip to content

Commit e11e026

Browse files
author
Mark Robinson
committed
Add full controller test coverage
1 parent b73616d commit e11e026

File tree

3 files changed

+146
-6
lines changed

3 files changed

+146
-6
lines changed

src/main/java/org/commonwl/view/workflow/WorkflowController.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ public ModelAndView getWorkflowByGithubDetails(@Value("${applicationURL}") Strin
156156
if (!errors.hasErrors()) {
157157
if (githubDetails.getPath().endsWith(".cwl")) {
158158
workflowModel = workflowService.createWorkflow(githubDetails);
159+
if (workflowModel == null) {
160+
errors.rejectValue("githubURL", "githubURL.parsingError", "The workflow could not be parsed from the given URL");
161+
}
159162
} else {
160163
// If this is a directory, get a list of workflows and return the view for it
161164
try {

src/test/java/org/commonwl/view/PageControllerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ public void homePage() throws Exception {
5656
*/
5757
@Test
5858
public void homePageWithURL() throws Exception {
59-
mockMvc.perform(get("/").param("url", "https://github.com/test/repo"))
59+
mockMvc.perform(get("/").param("url", "https://github.com/test/default/link"))
6060
.andExpect(status().isOk())
6161
.andExpect(view().name("index"))
6262
.andExpect(model().attributeExists("workflowForm"))
6363
.andExpect(model().attribute("workflowForm",
64-
hasProperty("githubURL", is("https://github.com/test/repo"))));
64+
hasProperty("githubURL", is("https://github.com/test/default/link"))));
6565
}
6666

6767
}

src/test/java/org/commonwl/view/workflow/WorkflowControllerTest.java

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,34 @@
2525
import org.junit.Rule;
2626
import org.junit.Test;
2727
import org.junit.rules.TemporaryFolder;
28+
import org.junit.runner.RunWith;
29+
import org.mockito.Matchers;
2830
import org.mockito.Mockito;
31+
import org.springframework.boot.test.context.SpringBootTest;
32+
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
33+
import org.springframework.test.context.junit4.SpringRunner;
2934
import org.springframework.test.web.servlet.MockMvc;
3035
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
36+
import org.springframework.web.servlet.view.InternalResourceViewResolver;
3137

38+
import java.io.IOException;
39+
import java.util.ArrayList;
40+
import java.util.Arrays;
41+
42+
import static org.hamcrest.Matchers.*;
43+
import static org.hamcrest.core.Is.is;
3244
import static org.mockito.Matchers.anyObject;
3345
import static org.mockito.Matchers.anyString;
3446
import static org.mockito.Mockito.when;
3547
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
3648
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
3749
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
3850

51+
/**
52+
* Tests the controller for workflow related functionality
53+
*/
54+
@RunWith(SpringRunner.class)
55+
@SpringBootTest
3956
public class WorkflowControllerTest {
4057

4158
/**
@@ -44,6 +61,38 @@ public class WorkflowControllerTest {
4461
@Rule
4562
public TemporaryFolder roBundleFolder = new TemporaryFolder();
4663

64+
/**
65+
* Get the full list of workflows
66+
* TODO: Mock the repository and test model attributes
67+
*/
68+
@Test
69+
public void getListOfWorkflows() throws Exception {
70+
71+
// Mock controller/MVC
72+
WorkflowController workflowController = new WorkflowController(
73+
Mockito.mock(WorkflowFormValidator.class),
74+
Mockito.mock(WorkflowService.class),
75+
Mockito.mock(GraphVizService.class));
76+
77+
// Lots of hassle to make Spring Data Pageable work
78+
PageableHandlerMethodArgumentResolver pageableArgumentResolver =
79+
new PageableHandlerMethodArgumentResolver();
80+
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
81+
viewResolver.setPrefix("/src/main/resources/templates");
82+
viewResolver.setSuffix(".html");
83+
MockMvc mockMvc = MockMvcBuilders
84+
.standaloneSetup(workflowController)
85+
.setCustomArgumentResolvers(pageableArgumentResolver)
86+
.setViewResolvers(viewResolver)
87+
.build();
88+
89+
// Simple test to check the view
90+
mockMvc.perform(get("/workflows"))
91+
.andExpect(status().isOk())
92+
.andExpect(view().name("workflows"));
93+
94+
}
95+
4796
/**
4897
* Endpoint for main form submission
4998
*/
@@ -104,14 +153,70 @@ public void newWorkflowFromGithubURL() throws Exception {
104153
}
105154

106155
/**
107-
* Endpoint for displaying workflows and directories of workflows
156+
* Displaying workflows
108157
*/
109158
@Test
110-
public void getWorkflowByGithubDetails() throws Exception {
159+
public void directWorkflowURL() throws Exception {
111160

112-
// Mock service to return a bundle file and then throw ROBundleNotFoundException
161+
Workflow mockWorkflow = Mockito.mock(Workflow.class);
162+
Workflow mockWorkflow2 = Mockito.mock(Workflow.class);
163+
164+
// Mock service
113165
WorkflowService mockWorkflowService = Mockito.mock(WorkflowService.class);
166+
when(mockWorkflowService.getWorkflow(Matchers.<GithubDetails>anyObject()))
167+
.thenReturn(mockWorkflow)
168+
.thenReturn(null);
169+
when(mockWorkflowService.createWorkflow(anyObject()))
170+
.thenReturn(mockWorkflow2)
171+
.thenReturn(null);
172+
173+
// Mock controller/MVC
174+
WorkflowController workflowController = new WorkflowController(
175+
Mockito.mock(WorkflowFormValidator.class),
176+
mockWorkflowService,
177+
Mockito.mock(GraphVizService.class));
178+
MockMvc mockMvc = MockMvcBuilders
179+
.standaloneSetup(workflowController)
180+
.build();
114181

182+
// Workflow already exists in the database
183+
mockMvc.perform(get("/workflows/github.com/owner/reponame/tree/branch/path/within/workflow.cwl"))
184+
.andExpect(status().isOk())
185+
.andExpect(view().name("workflow"))
186+
.andExpect(model().attribute("workflow", is(mockWorkflow)));
187+
188+
// Workflow needs to be created
189+
mockMvc.perform(get("/workflows/github.com/owner/reponame/tree/branch/path/within/workflow.cwl"))
190+
.andExpect(status().isOk())
191+
.andExpect(view().name("workflow"))
192+
.andExpect(model().attribute("workflow", is(mockWorkflow2)));
193+
194+
// Error creating workflow
195+
mockMvc.perform(get("/workflows/github.com/owner/reponame/tree/branch/path/within/badworkflow.cwl"))
196+
.andExpect(status().isFound())
197+
.andExpect(flash().attributeExists("errors"))
198+
.andExpect(redirectedUrl("/?url=https://github.com/owner/reponame/tree/branch/path/within/badworkflow.cwl"));
199+
200+
}
201+
202+
/**
203+
* Displaying directories of workflows
204+
*/
205+
@Test
206+
public void directDirectoryURL() throws Exception {
207+
208+
// Workflow overviews for testing
209+
WorkflowOverview overview1 = new WorkflowOverview("workflow1.cwl", "label1", "doc1");
210+
WorkflowOverview overview2 = new WorkflowOverview("workflow2.cwl", "label2", "doc2");
211+
212+
// Mock service to return these overviews
213+
WorkflowService mockWorkflowService = Mockito.mock(WorkflowService.class);
214+
when(mockWorkflowService.getWorkflowsFromDirectory(anyObject()))
215+
.thenReturn(new ArrayList<>())
216+
.thenReturn(new ArrayList<>(Arrays.asList(overview1)))
217+
.thenReturn(new ArrayList<>(Arrays.asList(overview1, overview2)))
218+
.thenReturn(new ArrayList<>(Arrays.asList(overview1, overview2)))
219+
.thenThrow(new IOException("Error getting contents"));
115220

116221
// Mock controller/MVC
117222
WorkflowController workflowController = new WorkflowController(
@@ -122,9 +227,41 @@ public void getWorkflowByGithubDetails() throws Exception {
122227
.standaloneSetup(workflowController)
123228
.build();
124229

125-
// Redirect with error
230+
// No workflows in directory, redirect with errors
231+
mockMvc.perform(get("/workflows/github.com/owner/reponame/tree/branch/path/within"))
232+
.andExpect(status().isFound())
233+
.andExpect(flash().attributeExists("errors"))
234+
.andExpect(redirectedUrl("/?url=https://github.com/owner/reponame/tree/branch/path/within"));
235+
236+
// 1 workflow in directory, redirect to it
237+
mockMvc.perform(get("/workflows/github.com/common-workflow-language/workflows/tree/master/workflows/lobSTR"))
238+
.andExpect(status().isFound())
239+
.andExpect(redirectedUrl("/workflows/github.com/common-workflow-language/workflows/tree/master/workflows/lobSTR/workflow1.cwl"));
240+
241+
// Multiple workflows in directory, show list
242+
mockMvc.perform(get("/workflows/github.com/common-workflow-language/workflows/tree/visu/workflows/scidap"))
243+
.andExpect(status().isOk())
244+
.andExpect(view().name("selectworkflow"))
245+
.andExpect(model().attribute("githubDetails", allOf(
246+
hasProperty("owner", is("common-workflow-language")),
247+
hasProperty("repoName", is("workflows")),
248+
hasProperty("branch", is("visu")),
249+
hasProperty("path", is("workflows/scidap"))
250+
)))
251+
.andExpect(model().attribute("workflowOverviews",
252+
containsInAnyOrder(overview1, overview2)));
253+
254+
// Workflows at the base of a repository
255+
mockMvc.perform(get("/workflows/github.com/genome/arvados_trial/tree/master"))
256+
.andExpect(status().isOk())
257+
.andExpect(view().name("selectworkflow"))
258+
.andExpect(model().attribute("githubDetails",
259+
hasProperty("path", is("/"))));
260+
261+
// Error getting contents of Github directory, redirect with errors
126262
mockMvc.perform(get("/workflows/github.com/owner/reponame/tree/branch/path/within"))
127263
.andExpect(status().isFound())
264+
.andExpect(flash().attributeExists("errors"))
128265
.andExpect(redirectedUrl("/?url=https://github.com/owner/reponame/tree/branch/path/within"));
129266

130267
}

0 commit comments

Comments
 (0)