package uk.ac.ox.zoo.seeg.abraid.mp.publicsite.web.admin; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.ui.Model; import uk.ac.ox.zoo.seeg.abraid.mp.common.config.ConfigurationService; import uk.ac.ox.zoo.seeg.abraid.mp.common.service.workflow.support.SourceCodeManager; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.*; import static uk.ac.ox.zoo.seeg.abraid.mp.testutils.GeneralTestUtils.captorForClass; /** * Tests for ModelRepositoryController. * Copyright (c) 2014 University of Oxford */ public class ModelRepositoryControllerTest { @Test public void showPageReturnsCorrectFreemarkerTemplateName() { // Arrange ModelRepositoryController target = new ModelRepositoryController(mock(ConfigurationService.class), mock(SourceCodeManager.class)); // Act String result = target.showPage(mock(Model.class)); // Assert assertThat(result).isEqualTo("admin/model"); } @Test public void showPageSetsCorrectModelData() throws Exception { // Arrange String expectedUrl = "foo1"; String expectedVersion = "foo2"; List<String> expectedVersions = Arrays.asList("1", "2", "3"); ConfigurationService configurationService = mock(ConfigurationService.class); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); when(configurationService.getModelRepositoryUrl()).thenReturn(expectedUrl); when(configurationService.getModelRepositoryVersion()).thenReturn(expectedVersion); when(sourceCodeManager.getAvailableVersions()).thenReturn(expectedVersions); Model model = mock(Model.class); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); // Act target.showPage(model); // Assert verify(model).addAttribute("repository_url", expectedUrl); verify(model).addAttribute("model_version", expectedVersion); verify(model).addAttribute("available_versions", expectedVersions); } @Test public void showPageSetsEmptyVersionListIfRepositoryCheckFails() throws Exception { // Arrange SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); when(sourceCodeManager.getAvailableVersions()).thenThrow(new IOException()); Model model = mock(Model.class); ModelRepositoryController target = new ModelRepositoryController(mock(ConfigurationService.class), sourceCodeManager); // Act target.showPage(model); // Assert ArgumentCaptor<List> captor = captorForClass(List.class); verify(model).addAttribute(eq("available_versions"), captor.capture()); assertThat(captor.getValue()).hasSize(0); } @Test public void setModelVersionRejectsInvalidVersion() throws Exception { // Arrange List<String> invalidUrls = Arrays.asList("", null); ModelRepositoryController target = new ModelRepositoryController(null, null); for (String invalidUrl : invalidUrls) { // Act ResponseEntity result = target.setModelVersion(invalidUrl); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); } } @Test public void setModelVersionFailsIfVersionsCanNotBeRetrieved() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doThrow(new IOException()).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); // Act ResponseEntity result = target.setModelVersion("version"); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); } @Test public void setModelVersionRejectsVersionsNotInRepository() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doReturn(Arrays.asList("1", "2", "3")).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); // Act ResponseEntity result = target.setModelVersion("4"); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); } @Test public void setModelVersionAcceptsValidVersion() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); String expectedVersion = "3"; doReturn(Arrays.asList("1", "2", expectedVersion)).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); // Act ResponseEntity result = target.setModelVersion(expectedVersion); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); verify(configurationService).setModelRepositoryVersion(expectedVersion); } @Test public void setModelVersionAcceptsCurrentVersionButSkipsLogic() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); String expectedVersion = "3"; when(configurationService.getModelRepositoryVersion()).thenReturn(expectedVersion); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); // Act ResponseEntity result = target.setModelVersion(expectedVersion); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); verify(configurationService, times(0)).setModelRepositoryVersion(expectedVersion); } @Test public void syncRepositoryRejectsInvalidRepositoryUrl() throws Exception { // Arrange List<String> invalidUrls = Arrays.asList("", null); ModelRepositoryController target = new ModelRepositoryController(null, null); for (String invalidUrl : invalidUrls) { // Act ResponseEntity result = target.syncRepository(invalidUrl); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); } } @Test public void syncRepositoryTriesURLButRejectsIfCloneFails() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); setupGetAndSetForRepositoryURL(configurationService, "initialValue"); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doThrow(new IOException()).when(sourceCodeManager).updateRepository(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); String url = "urlThatWontClone"; // Act ResponseEntity result = target.syncRepository(url); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); // should try the new url verify(configurationService).setModelRepositoryUrl(url); // which will fail verify(sourceCodeManager).updateRepository(); // so the url should be reset verify(configurationService).setModelRepositoryUrl("initialValue"); // leaving it at the initial value assertThat(configurationService.getModelRepositoryUrl()).isEqualTo("initialValue"); } @Test public void syncRepositoryTriesURLButRejectsIfTagRetrievalFails() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); setupGetAndSetForRepositoryURL(configurationService, "initialValue"); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doThrow(new IOException()).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); String url = "urlThatWontRetrieveTags"; // Act ResponseEntity result = target.syncRepository(url); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); // should try the new url verify(configurationService).setModelRepositoryUrl(url); // which will fail verify(sourceCodeManager).updateRepository(); // so the url should be reset verify(configurationService).setModelRepositoryUrl("initialValue"); // leaving it at the initial value assertThat(configurationService.getModelRepositoryUrl()).isEqualTo("initialValue"); } @Test public void syncRepositoryClearsVersionIfUrlChanges() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); setupGetAndSetForRepositoryURL(configurationService, "initialValue"); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doReturn(new ArrayList<String>()).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); String url = "urlThatWillWork"; // Act ResponseEntity result = target.syncRepository(url); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); verify(configurationService).setModelRepositoryVersion(""); } @Test public void syncRepositoryReturnsCorrectVersions() throws Exception { // Arrange List<String> expectedVersions = Arrays.asList("1", "2", "3"); ConfigurationService configurationService = mock(ConfigurationService.class); setupGetAndSetForRepositoryURL(configurationService, "initialValue"); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doReturn(expectedVersions).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); String url = "urlThatWillWork"; // Act ResponseEntity result = target.syncRepository(url); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(result.getBody()).isEqualTo(expectedVersions); } @Test public void syncRepositoryDoesNotClearVersionIfUrlHasNotChanged() throws Exception { // Arrange ConfigurationService configurationService = mock(ConfigurationService.class); setupGetAndSetForRepositoryURL(configurationService, "initialValue"); SourceCodeManager sourceCodeManager = mock(SourceCodeManager.class); doReturn(new ArrayList<String>()).when(sourceCodeManager).getAvailableVersions(); ModelRepositoryController target = new ModelRepositoryController(configurationService, sourceCodeManager); String url = "initialValue"; // Act ResponseEntity result = target.syncRepository(url); // Assert assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); verify(configurationService, never()).setModelRepositoryVersion(anyString()); } private String valueCache; private void setupGetAndSetForRepositoryURL(ConfigurationService configurationService, String initialValue) { doAnswer(new Answer<String>() { public String answer(InvocationOnMock invocation) { return valueCache; } }).when(configurationService).getModelRepositoryUrl(); doAnswer(new Answer<Void>() { public Void answer(InvocationOnMock invocation) { valueCache = (String) invocation.getArguments()[0]; return null; } }).when(configurationService).setModelRepositoryUrl(anyString()); valueCache = initialValue; } }