/* * Copyright 2017 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.server.service.tasks; import com.thoughtworks.go.config.pluggabletask.PluggableTask; import com.thoughtworks.go.domain.config.Configuration; import com.thoughtworks.go.domain.config.ConfigurationValue; import com.thoughtworks.go.domain.config.PluginConfiguration; import com.thoughtworks.go.domain.packagerepository.ConfigurationPropertyMother; import com.thoughtworks.go.i18n.Localizer; import com.thoughtworks.go.plugin.access.pluggabletask.PluggableTaskConfigStore; import com.thoughtworks.go.plugin.access.pluggabletask.TaskExtension; import com.thoughtworks.go.plugin.access.pluggabletask.TaskPreference; import com.thoughtworks.go.plugin.api.config.Property; import com.thoughtworks.go.plugin.api.response.validation.ValidationError; import com.thoughtworks.go.plugin.api.response.validation.ValidationResult; import com.thoughtworks.go.plugin.api.task.TaskConfig; import com.thoughtworks.go.plugin.api.task.TaskConfigProperty; import com.thoughtworks.go.util.ListUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.List; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; public class PluggableTaskServiceTest { private PluggableTaskService pluggableTaskService; private TaskExtension taskExtension; private String pluginId = "abc.def"; private Localizer localizer; @Before public void setUp() throws Exception { taskExtension = mock(TaskExtension.class); localizer = mock(Localizer.class); pluggableTaskService = new PluggableTaskService(taskExtension, localizer); final TaskPreference preference = mock(TaskPreference.class); final TaskConfig taskConfig = new TaskConfig(); final TaskConfigProperty key1 = taskConfig.addProperty("KEY1"); key1.with(Property.REQUIRED, true); taskConfig.addProperty("KEY2"); when(preference.getConfig()).thenReturn(taskConfig); PluggableTaskConfigStore.store().setPreferenceFor(pluginId, preference); } @After public void teardown() { PluggableTaskConfigStore.store().removePreferenceFor(pluginId); } @Test public void shouldValidateTask() { Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1")); PluggableTask modifiedTask = new PluggableTask(new PluginConfiguration(pluginId, "1"), configuration); ValidationResult validationResult = new ValidationResult(); validationResult.addError(new ValidationError("KEY1", "error message")); when(taskExtension.validate(eq(modifiedTask.getPluginConfiguration().getId()), any(TaskConfig.class))).thenReturn(validationResult); pluggableTaskService.validate(modifiedTask); assertThat(modifiedTask.getConfiguration().getProperty("KEY1").errors().isEmpty(), is(false)); assertThat(modifiedTask.getConfiguration().getProperty("KEY1").errors().firstError(), is("error message")); verify(taskExtension).validate(eq(modifiedTask.getPluginConfiguration().getId()), any(TaskConfig.class)); } @Test public void shouldValidateMandatoryFields() { Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1")); PluggableTask modifiedTask = new PluggableTask(new PluginConfiguration(pluginId, "1"), configuration); ValidationResult validationResult = new ValidationResult(); when(taskExtension.validate(eq(modifiedTask.getPluginConfiguration().getId()), any(TaskConfig.class))).thenReturn(validationResult); when(localizer.localize("MANDATORY_CONFIGURATION_FIELD")).thenReturn("MANDATORY_CONFIGURATION_FIELD"); pluggableTaskService.validate(modifiedTask); final List<ValidationError> validationErrors = validationResult.getErrors(); assertFalse(validationErrors.isEmpty()); final ValidationError validationError = ListUtil.find(validationErrors, new ListUtil.Condition() { @Override public <T> boolean isMet(T item) { return ((ValidationError) item).getKey().equals("KEY1"); } }); assertNotNull(validationError); assertThat(validationError.getMessage(), is("MANDATORY_CONFIGURATION_FIELD")); } @Test public void shouldPassValidationIfAllRequiredFieldsHaveValues() { Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1")); configuration.getProperty("KEY1").setConfigurationValue(new ConfigurationValue("junk")); PluggableTask modifiedTask = new PluggableTask(new PluginConfiguration(pluginId, "1"), configuration); ValidationResult validationResult = new ValidationResult(); when(taskExtension.validate(eq(modifiedTask.getPluginConfiguration().getId()), any(TaskConfig.class))).thenReturn(validationResult); pluggableTaskService.validate(modifiedTask); final List<ValidationError> validationErrors = validationResult.getErrors(); assertTrue(validationErrors.isEmpty()); } @Test public void isValidShouldValidateThePluggableTask() { PluggableTask pluggableTask = mock(PluggableTask.class); PluginConfiguration pluginConfiguration = new PluginConfiguration("plugin_id", "version"); when(pluggableTask.isValid()).thenReturn(true); when(pluggableTask.getPluginConfiguration()).thenReturn(pluginConfiguration); when(taskExtension.validate(any(String.class), any(TaskConfig.class))).thenReturn(new ValidationResult()); assertTrue(pluggableTaskService.isValid(pluggableTask)); } @Test public void isValidShouldValidateTaskAgainstPlugin() { TaskConfig taskConfig = mock(TaskConfig.class); ValidationResult validationResult = mock(ValidationResult.class); PluggableTask pluggableTask = mock(PluggableTask.class); PluginConfiguration pluginConfiguration = new PluginConfiguration("plugin_id", "version"); when(pluggableTask.isValid()).thenReturn(true); when(pluggableTask.getPluginConfiguration()).thenReturn(pluginConfiguration); when(pluggableTask.toTaskConfig()).thenReturn(taskConfig); when(taskExtension.validate(pluginConfiguration.getId(), taskConfig)).thenReturn(validationResult); when(validationResult.isSuccessful()).thenReturn(true); assertTrue(pluggableTaskService.isValid(pluggableTask)); } @Test public void isValidShouldSkipValidationAgainstPluginIfPluggableTaskIsInvalid() { PluggableTask pluggableTask = mock(PluggableTask.class); when(pluggableTask.isValid()).thenReturn(false); assertFalse(pluggableTaskService.isValid(pluggableTask)); verifyZeroInteractions(taskExtension); } @Test public void isValidShouldMapPluginValidationErrorsToPluggableTaskConfigrations() { PluginConfiguration pluginConfiguration = new PluginConfiguration("plugin_id", "version"); Configuration configuration = new Configuration(); configuration.add(ConfigurationPropertyMother.create("source", false, "src_dir")); configuration.add(ConfigurationPropertyMother.create("destination", false, "dest_dir")); ValidationResult validationResult = new ValidationResult(); validationResult.addError(new ValidationError("source", "source directory format is invalid")); validationResult.addError(new ValidationError("destination", "destination directory format is invalid")); PluggableTask pluggableTask = mock(PluggableTask.class); when(pluggableTask.isValid()).thenReturn(true); when(pluggableTask.getPluginConfiguration()).thenReturn(pluginConfiguration); when(pluggableTask.getConfiguration()).thenReturn(configuration); when(taskExtension.validate(any(String.class), any(TaskConfig.class))).thenReturn(validationResult); assertFalse(pluggableTaskService.isValid(pluggableTask)); assertThat(configuration.getProperty("source").errors().get("source").get(0), is("source directory format is invalid")); assertThat(configuration.getProperty("destination").errors().get("destination").get(0), is("destination directory format is invalid")); } @Test public void isValidShouldMapPluginValidationErrorsToPluggableTaskForMissingConfigurations() { PluginConfiguration pluginConfiguration = new PluginConfiguration("plugin_id", "version"); ValidationResult validationResult = new ValidationResult(); validationResult.addError(new ValidationError("source", "source is mandatory")); PluggableTask pluggableTask = mock(PluggableTask.class); when(pluggableTask.isValid()).thenReturn(true); when(pluggableTask.getPluginConfiguration()).thenReturn(pluginConfiguration); when(pluggableTask.getConfiguration()).thenReturn(new Configuration()); when(taskExtension.validate(any(String.class), any(TaskConfig.class))).thenReturn(validationResult); assertFalse(pluggableTaskService.isValid(pluggableTask)); verify(pluggableTask).addError("source", "source is mandatory"); } }