Java tutorial
/*************************GO-LICENSE-START********************************* * Copyright 2014 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. *************************GO-LICENSE-END***********************************/ package com.thoughtworks.go.config.materials.tfs; import java.util.Collections; import java.util.HashMap; import java.util.Map; import com.thoughtworks.go.config.CaseInsensitiveString; import com.thoughtworks.go.config.ValidationContext; import com.thoughtworks.go.config.materials.AbstractMaterialConfig; import com.thoughtworks.go.config.materials.Filter; import com.thoughtworks.go.config.materials.IgnoredFiles; import com.thoughtworks.go.config.materials.ScmMaterialConfig; import com.thoughtworks.go.security.GoCipher; import com.thoughtworks.go.util.ReflectionUtil; import com.thoughtworks.go.util.command.UrlArgument; import org.bouncycastle.crypto.InvalidCipherTextException; import org.junit.Before; import org.junit.Test; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.nullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class TfsMaterialConfigUpdateTest { @Before public void setUp() throws Exception { } @Test public void shouldSetConfigAttributes() { TfsMaterialConfig tfsMaterialConfig = new TfsMaterialConfig(new GoCipher(), new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "some_domain", "passwd", "walk_this_path"); Map<String, String> map = new HashMap<String, String>(); map.put(ScmMaterialConfig.URL, "http://foo:8080/tfs/HelloWorld"); map.put(ScmMaterialConfig.USERNAME, "boozer"); map.put(ScmMaterialConfig.PASSWORD, "secret"); map.put(ScmMaterialConfig.FOLDER, "folder"); map.put(ScmMaterialConfig.AUTO_UPDATE, "0"); map.put(ScmMaterialConfig.FILTER, "/root,/**/*.help"); map.put(AbstractMaterialConfig.MATERIAL_NAME, "my-tfs-material-name"); map.put(TfsMaterialConfig.PROJECT_PATH, "/useless/project"); map.put(TfsMaterialConfig.DOMAIN, "CORPORATE"); tfsMaterialConfig.setConfigAttributes(map); TfsMaterialConfig newTfsMaterialConfig = new TfsMaterialConfig(new GoCipher(), new UrlArgument("http://foo:8080/tfs/HelloWorld"), "boozer", "CORPORATE", "secret", "/useless/project"); newTfsMaterialConfig.setName(new CaseInsensitiveString("my-tfs-material-name")); newTfsMaterialConfig.setFolder("folder"); assertThat(tfsMaterialConfig, is(newTfsMaterialConfig)); assertThat(tfsMaterialConfig.getPassword(), is("passwd")); assertThat(tfsMaterialConfig.isAutoUpdate(), is(false)); assertThat(tfsMaterialConfig.getDomain(), is("CORPORATE")); assertThat(tfsMaterialConfig.getName(), is(new CaseInsensitiveString("my-tfs-material-name"))); assertThat(tfsMaterialConfig.filter(), is(new Filter(new IgnoredFiles("/root"), new IgnoredFiles("/**/*.help")))); } @Test public void shouldDefaultDomainToEmptyStringWhenNothingIsSet() throws Exception { TfsMaterialConfig tfsMaterialConfig = new TfsMaterialConfig(mock(GoCipher.class)); assertThat(tfsMaterialConfig.getDomain(), is("")); } @Test public void setConfigAttributes_shouldUpdatePasswordWhenPasswordChangedBooleanChanged() throws Exception { TfsMaterialConfig tfsMaterialConfig = new TfsMaterialConfig(new GoCipher(), new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "passwd", "walk_this_path"); Map<String, String> map = new HashMap<String, String>(); map.put(TfsMaterialConfig.PASSWORD, "secret"); map.put(TfsMaterialConfig.PASSWORD_CHANGED, "1"); tfsMaterialConfig.setConfigAttributes(map); tfsMaterialConfig.setConfigAttributes(map); assertThat(ReflectionUtil.getField(tfsMaterialConfig, "password"), is(nullValue())); assertThat(tfsMaterialConfig.getPassword(), is("secret")); assertThat(tfsMaterialConfig.getEncryptedPassword(), is(new GoCipher().encrypt("secret"))); //Dont change map.put(TfsMaterialConfig.PASSWORD, "Hehehe"); map.put(TfsMaterialConfig.PASSWORD_CHANGED, "0"); tfsMaterialConfig.setConfigAttributes(map); assertThat(ReflectionUtil.getField(tfsMaterialConfig, "password"), is(nullValue())); assertThat(tfsMaterialConfig.getPassword(), is("secret")); assertThat(tfsMaterialConfig.getEncryptedPassword(), is(new GoCipher().encrypt("secret"))); map.put(TfsMaterialConfig.PASSWORD, ""); map.put(TfsMaterialConfig.PASSWORD_CHANGED, "1"); tfsMaterialConfig.setConfigAttributes(map); assertThat(tfsMaterialConfig.getPassword(), is(nullValue())); assertThat(tfsMaterialConfig.getEncryptedPassword(), is(nullValue())); } @Test public void validate_shouldEnsureMandatoryFieldsAreNotBlank() { TfsMaterialConfig tfsMaterialConfig = new TfsMaterialConfig(new GoCipher(), new UrlArgument(""), "", "CORPORATE", "", ""); tfsMaterialConfig.validate(new ValidationContext(null)); assertThat(tfsMaterialConfig.errors().on(TfsMaterialConfig.URL), is("URL cannot be blank")); assertThat(tfsMaterialConfig.errors().on(TfsMaterialConfig.USERNAME), is("Username cannot be blank")); assertThat(tfsMaterialConfig.errors().on(TfsMaterialConfig.PROJECT_PATH), is("Project Path cannot be blank")); } @Test public void validate_shouldEnsureMaterialNameIsValid() { TfsMaterialConfig tfsMaterialConfig = new TfsMaterialConfig(new GoCipher(), new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "passwd", "walk_this_path"); tfsMaterialConfig.validate(new ValidationContext(null)); assertThat(tfsMaterialConfig.errors().on(TfsMaterialConfig.MATERIAL_NAME), is(nullValue())); tfsMaterialConfig.setName(new CaseInsensitiveString(".bad-name-with-dot")); tfsMaterialConfig.validate(new ValidationContext(null)); assertThat(tfsMaterialConfig.errors().on(TfsMaterialConfig.MATERIAL_NAME), is( "Invalid material name '.bad-name-with-dot'. This must be alphanumeric and can contain underscores and periods (however, it cannot start with a period). The maximum allowed length is 255 characters.")); } @Test public void validate_shouldEnsureDestFilePathIsValid() { TfsMaterialConfig tfsMaterialConfig = new TfsMaterialConfig(new GoCipher(), new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "passwd", "walk_this_path"); tfsMaterialConfig.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "../a")); tfsMaterialConfig.validate(new ValidationContext(null)); assertThat(tfsMaterialConfig.errors().on(TfsMaterialConfig.FOLDER), is("Dest folder '../a' is not valid. It must be a sub-directory of the working folder.")); } @Test public void shouldEncryptTfsPasswordAndMarkPasswordAsNull() throws Exception { GoCipher mockGoCipher = mock(GoCipher.class); when(mockGoCipher.encrypt("password")).thenReturn("encrypted"); TfsMaterialConfig materialConfig = new TfsMaterialConfig(mockGoCipher, new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "password", "walk_this_path"); materialConfig.ensureEncrypted(); assertThat(materialConfig.getPassword(), is(nullValue())); assertThat(materialConfig.getEncryptedPassword(), is("encrypted")); } @Test public void shouldDecryptTfsPassword() throws Exception { GoCipher mockGoCipher = mock(GoCipher.class); when(mockGoCipher.decrypt("encrypted")).thenReturn("password"); TfsMaterialConfig materialConfig = new TfsMaterialConfig(mockGoCipher, new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "secret", "walk_this_path"); ReflectionUtil.setField(materialConfig, "encryptedPassword", "encrypted"); materialConfig.ensureEncrypted(); assertThat(materialConfig.getPassword(), is("password")); } @Test public void shouldNotDecryptTfsPasswordIfPasswordIsNotNull() throws Exception { GoCipher mockGoCipher = mock(GoCipher.class); when(mockGoCipher.encrypt("password")).thenReturn("encrypted"); when(mockGoCipher.decrypt("encrypted")).thenReturn("password"); TfsMaterialConfig materialConfig = new TfsMaterialConfig(mockGoCipher, new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "password", "walk_this_path"); materialConfig.ensureEncrypted(); when(mockGoCipher.encrypt("new_password")).thenReturn("new_encrypted"); materialConfig.setPassword("new_password"); when(mockGoCipher.decrypt("new_encrypted")).thenReturn("new_password"); assertThat(materialConfig.getPassword(), is("new_password")); } @Test public void shouldErrorOutIfDecryptionFails() throws InvalidCipherTextException { GoCipher mockGoCipher = mock(GoCipher.class); String fakeCipherText = "fake cipher text"; when(mockGoCipher.decrypt(fakeCipherText)).thenThrow(new InvalidCipherTextException("exception")); TfsMaterialConfig materialConfig = new TfsMaterialConfig(mockGoCipher, new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "passwd", "walk_this_path"); ReflectionUtil.setField(materialConfig, "encryptedPassword", fakeCipherText); try { materialConfig.getPassword(); fail("Should have thrown up"); } catch (Exception e) { assertThat(e.getMessage(), is("Could not decrypt the password to get the real password")); } } @Test public void shouldErrorOutIfEncryptionFails() throws Exception { GoCipher mockGoCipher = mock(GoCipher.class); when(mockGoCipher.encrypt("password")).thenThrow(new InvalidCipherTextException("exception")); try { new TfsMaterialConfig(mockGoCipher, new UrlArgument("http://10.4.4.101:8080/tfs/Sample"), "loser", "CORPORATE", "password", "walk_this_path"); fail("Should have thrown up"); } catch (Exception e) { assertThat(e.getMessage(), is("Password encryption failed. Please verify your cipher key.")); } } }