/* * Copyright 2016 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.thoughtworks.go.tfssdk10; import com.microsoft.tfs.core.TFSTeamProjectCollection; import com.microsoft.tfs.core.clients.versioncontrol.GetOptions; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Changeset; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.GetRequest; import com.microsoft.tfs.core.clients.versioncontrol.specs.version.ChangesetVersionSpec; import com.thoughtworks.go.domain.materials.Modification; import com.thoughtworks.go.domain.materials.mercurial.StringRevision; import com.thoughtworks.go.tfssdk10.wrapper.GoTfsVersionControlClient; import com.thoughtworks.go.tfssdk10.wrapper.GoTfsWorkspace; import com.thoughtworks.go.util.command.StringArgument; import org.junit.Before; import org.junit.Test; import java.io.File; import java.util.List; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.*; public class TfsSDKCommandTest { private TfsSDKCommand tfsCommand; private final String DOMAIN = "domain"; private final String USERNAME = "username"; private final String PASSWORD = "password"; private final String TFS_COLLECTION = "http://some.repo.local:8000/"; private final String TFS_PROJECT = "$/project_path"; private final String TFS_WORKSPACE = "workspace"; private GoTfsVersionControlClient client; private TFSTeamProjectCollection collection; @Before public void setUp() { client = mock(GoTfsVersionControlClient.class); collection = mock(TFSTeamProjectCollection.class); tfsCommand = new TfsSDKCommand(client, collection, null, new StringArgument(TFS_COLLECTION), DOMAIN, USERNAME, PASSWORD, TFS_WORKSPACE, TFS_PROJECT); } @Test public void shouldGetLatestModifications() throws Exception { Changeset[] changeSets = getChangeSets(42); when(client.queryHistory(TFS_PROJECT, null, 1)).thenReturn(changeSets); TfsSDKCommand spy = spy(tfsCommand); doReturn(null).when(spy).getModifiedFiles(changeSets[0]); assertThat(spy.latestModification(null).isEmpty(), is(false)); verify(client).queryHistory(TFS_PROJECT, null, 1); verify(spy).getModifiedFiles(changeSets[0]); } @Test public void shouldCheckConnectionSuccessfullyIfAllCredentialsAreValid() throws Exception { Changeset[] changeSets = getChangeSets(42); when(client.queryHistory(TFS_PROJECT, null, 1)).thenReturn(changeSets); TfsSDKCommand spy = spy(tfsCommand); doReturn(null).when(spy).getModifiedFiles(changeSets[0]); try{ spy.checkConnection(); } catch (Exception e){ fail("Should not have thrown exception"); } verify(client).queryHistory(TFS_PROJECT, null, 1); verify(spy).getModifiedFiles(changeSets[0]); } @Test public void shouldThrowExceptionDuringCheckConnectionIfInvalid() throws Exception { when(client.queryHistory(TFS_PROJECT, null, 1)).thenThrow(new RuntimeException("could not connect")); try{ tfsCommand.checkConnection(); fail("should have thrown an exception"); } catch (RuntimeException e) { assertThat(e.getMessage(), is("Failed while checking connection using Url: http://some.repo.local:8000/, Project Path: $/project_path, Username: username, Domain: domain, Root Cause: could not connect")); } verify(client).queryHistory(TFS_PROJECT, null, 1); } @Test public void shouldReturnChangeSetsFromAPreviouslyKnownRevisionUptilTheLatest() throws Exception { Changeset[] changeSets = getChangeSets(42); when(client.queryHistory(eq(TFS_PROJECT), any(ChangesetVersionSpec.class), anyInt())).thenReturn(changeSets); TfsSDKCommand spy = spy(tfsCommand); doReturn(null).when(spy).getModifiedFiles(changeSets[0]); List<Modification> modifications = spy.modificationsSince(null, new StringRevision("2")); assertThat(modifications.isEmpty(), is(false)); verify(client, times(2)).queryHistory(eq(TFS_PROJECT), any(ChangesetVersionSpec.class), anyInt()); } @Test public void shouldCreateWorkspaceAndMapDirectory() throws Exception { File workingDirectory = mock(File.class); when(workingDirectory.exists()).thenReturn(false); GoTfsWorkspace[] workspaces = {}; when(client.queryWorkspaces(TFS_WORKSPACE, USERNAME)).thenReturn(workspaces); GoTfsWorkspace workspace = mock(GoTfsWorkspace.class); when(client.createWorkspace(TFS_WORKSPACE)).thenReturn(workspace); when(workspace.isLocalPathMapped(anyString())).thenReturn(false); doNothing().when(workspace).createWorkingFolder(any(com.microsoft.tfs.core.clients.versioncontrol.soapextensions.WorkingFolder.class)); TfsSDKCommand spy = spy(tfsCommand); doNothing().when(spy).retrieveFiles(workingDirectory, null); spy.checkout(workingDirectory, null); verify(client, times(1)).queryWorkspaces(TFS_WORKSPACE, USERNAME); verify(client, times(1)).createWorkspace(TFS_WORKSPACE); verify(workspace, times(1)).isLocalPathMapped(anyString()); verify(workspace, times(1)).createWorkingFolder(any(com.microsoft.tfs.core.clients.versioncontrol.soapextensions.WorkingFolder.class)); verify(spy).retrieveFiles(workingDirectory, null); } @Test public void shouldOnlyMapDirectoryAndNotCreateAWorkspaceIfWorkspaceIsAlreadyCreated() throws Exception { File workingDirectory = mock(File.class); when(workingDirectory.exists()).thenReturn(false); GoTfsWorkspace workspace = mock(GoTfsWorkspace.class); GoTfsWorkspace[] workspaces = {workspace}; when(client.queryWorkspaces(TFS_WORKSPACE, USERNAME)).thenReturn(workspaces); when(workspace.isLocalPathMapped(anyString())).thenReturn(false); doNothing().when(workspace).createWorkingFolder(any(com.microsoft.tfs.core.clients.versioncontrol.soapextensions.WorkingFolder.class)); TfsSDKCommand spy = spy(tfsCommand); doNothing().when(spy).retrieveFiles(workingDirectory, null); spy.checkout(workingDirectory, null); verify(client, times(1)).queryWorkspaces(TFS_WORKSPACE, USERNAME); verify(client, never()).createWorkspace(TFS_WORKSPACE); verify(workspace, times(1)).isLocalPathMapped(anyString()); verify(workspace, times(1)).createWorkingFolder(any(com.microsoft.tfs.core.clients.versioncontrol.soapextensions.WorkingFolder.class)); verify(spy).retrieveFiles(workingDirectory, null); } @Test public void shouldThrowUpWhenUrlIsInvalid() throws Exception { TfsSDKCommand tfsCommandForInvalidCollection = new TfsSDKCommand(null, new StringArgument("invalid_url"), DOMAIN, USERNAME, PASSWORD, TFS_WORKSPACE, TFS_PROJECT); try { tfsCommandForInvalidCollection.init(); } catch (RuntimeException e) { assertThat(e.getMessage(), is("Unable to connect to TFS Collection invalid_url com.microsoft.tfs.core.config.IllegalConfigurationException: Unable to produce a server URI")); } } @Test public void shouldCheckoutAllFilesWhenWorkingDirectoryIsDeleted() throws Exception { File workingDirectory = mock(File.class); when(workingDirectory.exists()).thenReturn(false); when(workingDirectory.getCanonicalPath()).thenReturn("canonical_path"); when(workingDirectory.listFiles()).thenReturn(null); TfsSDKCommand spy = spy(tfsCommand); doNothing().when(spy).initializeWorkspace(workingDirectory); GoTfsWorkspace workspace = mock(GoTfsWorkspace.class); when(client.queryWorkspace(TFS_WORKSPACE, USERNAME)).thenReturn(workspace); doNothing().when(workspace).get(any(GetRequest.class), eq(GetOptions.FORCE_GET_ALL)); spy.checkout(workingDirectory, null); verify(workingDirectory).getCanonicalPath(); verify(workingDirectory).listFiles(); verify(workspace).get(any(GetRequest.class), eq(GetOptions.FORCE_GET_ALL)); } @Test public void should_GetLatestRevisions_WhenCheckingOutToLaterRevision() throws Exception { File workingDirectory = mock(File.class); when(workingDirectory.exists()).thenReturn(false); when(workingDirectory.getCanonicalPath()).thenReturn("canonical_path"); File[] checkedOutFiles = {mock(File.class)}; when(workingDirectory.listFiles()).thenReturn(checkedOutFiles); TfsSDKCommand spy = spy(tfsCommand); doNothing().when(spy).initializeWorkspace(workingDirectory); GoTfsWorkspace workspace = mock(GoTfsWorkspace.class); when(client.queryWorkspace(TFS_WORKSPACE, USERNAME)).thenReturn(workspace); doNothing().when(workspace).get(any(GetRequest.class), eq(GetOptions.NONE)); spy.checkout(workingDirectory, null); verify(workingDirectory).getCanonicalPath(); verify(workingDirectory).listFiles(); verify(workspace).get(any(GetRequest.class), eq(GetOptions.NONE)); } @Test public void shouldClearWorkingDirectoryBeforeCheckingOut() throws Exception { File workingDirectory = mock(File.class); when(workingDirectory.exists()).thenReturn(true); TfsSDKCommand spy = spy(tfsCommand); doNothing().when(spy).initializeWorkspace(workingDirectory); doNothing().when(spy).retrieveFiles(workingDirectory, null); spy.checkout(workingDirectory, null); verify(workingDirectory).exists(); } @Test public void shouldDeleteWorkspace() throws Exception { GoTfsWorkspace workspace = mock(GoTfsWorkspace.class); when(client.queryWorkspace(TFS_WORKSPACE, USERNAME)).thenReturn(workspace); doNothing().when(client).deleteWorkspace(workspace); tfsCommand.deleteWorkspace(); verify(client).queryWorkspace(TFS_WORKSPACE, USERNAME); verify(client).deleteWorkspace(workspace); } @Test public void destroyShouldCloseClientAndCollection() throws Exception { doNothing().when(client).close(); doNothing().when(collection).close(); tfsCommand.destroy(); verify(client).close(); verify(collection).close(); } private Changeset[] getChangeSets(int changeSetID) { Changeset oneChangeSet = new Changeset("owner", "comment", null, null); oneChangeSet.setChangesetID(changeSetID); return new Changeset[]{oneChangeSet}; } }