com.thoughtworks.go.config.materials.tfs.TfsMaterialConfigUpdateTest.java Source code

Java tutorial

Introduction

Here is the source code for com.thoughtworks.go.config.materials.tfs.TfsMaterialConfigUpdateTest.java

Source

/*************************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."));
        }
    }
}