package de.otto.edison.jobs.controller; import de.otto.edison.jobs.definition.JobDefinition; import de.otto.edison.jobs.domain.JobMeta; import de.otto.edison.jobs.service.JobDefinitionService; import de.otto.edison.jobs.service.JobMetaService; import de.otto.edison.navigation.NavBar; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import java.time.Duration; import java.util.List; import java.util.Map; import java.util.Optional; import static de.otto.edison.jobs.definition.DefaultJobDefinition.fixedDelayJobDefinition; import static de.otto.edison.jobs.definition.DefaultJobDefinition.manuallyTriggerableJobDefinition; import static java.time.Duration.ofHours; import static java.time.Duration.ofSeconds; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.Optional.empty; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; public class JobDefinitionsControllerTest { private JobDefinitionsController controller; @Mock private JobDefinitionService jobDefinitionService; @Mock private JobMetaService jobMetaService; private MockMvc mockMvc; @Before public void setUp() throws Exception { initMocks(this); controller = new JobDefinitionsController(jobDefinitionService, jobMetaService, mock(NavBar.class)); mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } @Test public void shouldReturn404IfJobDefinitionIsUnknown() throws Exception { when(jobDefinitionService.getJobDefinition("FooJob")).thenReturn(Optional.empty()); mockMvc.perform(get("/internal/jobdefinitions/FooJob")) .andExpect(status().is(404)); } @Test public void shouldReturnJobDefinitionIfJobExists() throws Exception { // given final String jobType = "FooJob"; final JobDefinition expectedDef = jobDefinition(jobType, "Foo"); when(jobDefinitionService.getJobDefinition(jobType)).thenReturn(Optional.of(expectedDef)); // when mockMvc.perform( get("/internal/jobdefinitions/FooJob") .accept("application/json") ) .andExpect(status().is(200)) .andExpect(content().json("{\"type\":\"FooJob\"," + "\"name\":\"Foo\"," + "\"retries\":0," + "\"fixedDelay\":3600," + "\"links\":[" + "{\"href\":\"/internal/jobsdefinitions/FooJob\",\"rel\":\"self\"},{\"href\":\"/internal/jobdefinitions\",\"rel\":\"collection\"}," + "{\"href\":\"/internal/jobs/FooJob\",\"rel\":\"http://github.com/otto-de/edison/link-relations/job/trigger\"}" + "]" + "}")); } @Test public void shouldReturnAllJobDefinitions() throws Exception { // given final JobDefinition fooJobDef = jobDefinition("FooJob", "Foo"); final JobDefinition barJobDef = jobDefinition("BarJob", "Bar"); when(jobDefinitionService.getJobDefinitions()).thenReturn(asList(fooJobDef, barJobDef)); // when mockMvc.perform( get("/internal/jobdefinitions/") .accept("application/json") ) .andExpect(status().is(200)) .andExpect(content().json("{" + "\"links\":[" + "{\"href\":\"/internal/jobdefinitions/FooJob\",\"rel\":\"http://github.com/otto-de/edison/link-relations/job/definition\",\"title\":\"Foo\"}," + "{\"href\":\"/internal/jobdefinitions/BarJob\",\"rel\":\"http://github.com/otto-de/edison/link-relations/job/definition\",\"title\":\"Bar\"}," + "{\"href\":\"/internal/jobdefinitions\",\"rel\":\"self\",\"title\":\"Self\"}" + "]" + "}")); } @Test @SuppressWarnings("unchecked") public void shouldReturnAllJobDefinitionsAsHtml() throws Exception { // given final JobDefinition fooJobDef = jobDefinition("FooJob", "Foo"); final JobDefinition barJobDef = notTriggerableDefinition("BarJob", "Bar"); when(jobDefinitionService.getJobDefinitions()).thenReturn(asList(fooJobDef, barJobDef)); // when mockMvc.perform( get("/internal/jobdefinitions/") .accept("text/html") ) .andExpect(status().is(200)) .andDo(result -> { Map<String, Object> model = result.getModelAndView().getModel(); List<Map<String, Object>> jobDefinitions = (List<Map<String, Object>>) model.get("jobdefinitions"); assertThat(jobDefinitions.size(), is(2)); assertThat(jobDefinitions.get(0).get("frequency"), is("Every 60 Minutes")); assertThat(jobDefinitions.get(0).get("isDisabled"), is(false)); assertThat(jobDefinitions.get(0).get("comment"), is("")); assertThat(jobDefinitions.get(1).get("frequency"), is("Never")); assertThat(jobDefinitions.get(1).get("isDisabled"), is(false)); assertThat(jobDefinitions.get(1).get("comment"), is("")); }); } @Test @SuppressWarnings("unchecked") public void shouldConvertToSecondsIfSecondsIsLessThan60() throws Exception { // Given final JobDefinition jobDef = jobDefinition("TheJob", "Job", ofSeconds(59)); when(jobDefinitionService.getJobDefinitions()).thenReturn(singletonList(jobDef)); // when mockMvc.perform( get("/internal/jobdefinitions/") .accept("text/html") ) .andExpect(status().is(200)) .andDo(result -> { List<Map<String, Object>> jobDefinitions = (List<Map<String, Object>>) result.getModelAndView().getModel().get("jobdefinitions"); assertThat(jobDefinitions.size(), is(1)); assertThat(jobDefinitions.get(0).get("frequency"), is("Every 59 Seconds")); }); } @Test @SuppressWarnings("unchecked") public void shouldConvertToMinutesIfSecondsIsNotLessThan60() throws Exception { // Given final JobDefinition jobDef = jobDefinition("TheJob", "Job", ofSeconds(60)); when(jobDefinitionService.getJobDefinitions()).thenReturn(singletonList(jobDef)); // when mockMvc.perform( get("/internal/jobdefinitions/") .accept("text/html") ) .andExpect(status().is(200)) .andDo(result -> { List<Map<String, Object>> jobDefinitions = (List<Map<String, Object>>) result.getModelAndView().getModel().get("jobdefinitions"); assertThat(jobDefinitions.size(), is(1)); assertThat(jobDefinitions.get(0).get("frequency"), is("Every 1 Minutes")); }); } private JobDefinition jobDefinition(final String jobType, final String name) { return jobDefinition(jobType, name, ofHours(1)); } private JobDefinition jobDefinition(final String jobType, final String name, Duration fixedDelay) { return fixedDelayJobDefinition(jobType, name, name, fixedDelay, 0, empty()); } private JobDefinition notTriggerableDefinition(final String jobType, final String name) { return manuallyTriggerableJobDefinition(jobType, name, name, 0, empty()); } }