diff --git a/src/main/java/hudson/plugins/jira/JiraEnvironmentContributingAction.java b/src/main/java/hudson/plugins/jira/JiraEnvironmentContributingAction.java index ac34f2a19..989a4e33b 100644 --- a/src/main/java/hudson/plugins/jira/JiraEnvironmentContributingAction.java +++ b/src/main/java/hudson/plugins/jira/JiraEnvironmentContributingAction.java @@ -6,35 +6,44 @@ import hudson.model.InvisibleAction; /* - * JiraEnvironmentVariableBuilder adds an instance of this class to the build to - * provide the environment variables + * JiraEnvironmentVariableBuilder adds an instance of this class to the build to provide the environment variables + * */ public class JiraEnvironmentContributingAction extends InvisibleAction implements EnvironmentContributingAction { public static final String ISSUES_VARIABLE_NAME = "JIRA_ISSUES"; public static final String JIRA_URL_VARIABLE_NAME = "JIRA_URL"; + public static final String ISSUES_SIZE_VARIABLE_NAME = "JIRA_ISSUES_SIZE"; private final String issuesList; + private final Integer issuesSize; + private final String jiraUrl; public String getIssuesList() { return issuesList; } + public Integer getNumberOfIssues() { + return issuesSize; + } + public String getJiraUrl() { return jiraUrl; } - public JiraEnvironmentContributingAction(String issuesList, String jiraUrl) { + public JiraEnvironmentContributingAction(String issuesList, Integer issuesSize, String jiraUrl) { this.issuesList = issuesList; + this.issuesSize = issuesSize; this.jiraUrl = jiraUrl; } @Override public void buildEnvVars(AbstractBuild ab, EnvVars ev) { if (ev != null) { - ev.put(ISSUES_VARIABLE_NAME, issuesList); + ev.put(ISSUES_VARIABLE_NAME, getIssuesList()); + ev.put(ISSUES_SIZE_VARIABLE_NAME, getNumberOfIssues().toString()); ev.put(JIRA_URL_VARIABLE_NAME, getJiraUrl()); } } diff --git a/src/main/java/hudson/plugins/jira/JiraEnvironmentVariableBuilder.java b/src/main/java/hudson/plugins/jira/JiraEnvironmentVariableBuilder.java index 0b68e6579..5c2981a2a 100644 --- a/src/main/java/hudson/plugins/jira/JiraEnvironmentVariableBuilder.java +++ b/src/main/java/hudson/plugins/jira/JiraEnvironmentVariableBuilder.java @@ -1,6 +1,5 @@ package hudson.plugins.jira; -import hudson.AbortException; import hudson.Extension; import hudson.Launcher; import hudson.model.AbstractBuild; @@ -12,6 +11,7 @@ import hudson.tasks.Builder; import java.io.IOException; import java.util.Set; +import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; @@ -46,18 +46,23 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen JiraSite site = getSiteForProject(build.getProject()); if (site == null) { - throw new AbortException(Messages.JiraEnvironmentVariableBuilder_NoJiraSite()); + listener.getLogger().println(Messages.JiraEnvironmentVariableBuilder_NoJiraSite()); + return false; } Set ids = getIssueSelector().findIssueIds(build, site, listener); String idList = StringUtils.join(ids, ","); + Integer idListSize = ids.size(); listener.getLogger() .println(Messages.JiraEnvironmentVariableBuilder_Updating( JiraEnvironmentContributingAction.ISSUES_VARIABLE_NAME, idList)); + listener.getLogger() + .println(Messages.JiraEnvironmentVariableBuilder_Updating( + JiraEnvironmentContributingAction.ISSUES_SIZE_VARIABLE_NAME, idListSize)); - build.addAction(new JiraEnvironmentContributingAction(idList, site.getName())); + build.addAction(new JiraEnvironmentContributingAction(idList, idListSize, site.getName())); return true; } @@ -77,5 +82,9 @@ public boolean isApplicable(Class klass) { public String getDisplayName() { return Messages.JiraEnvironmentVariableBuilder_DisplayName(); } + + public boolean hasIssueSelectors() { + return Jenkins.get().getDescriptorList(AbstractIssueSelector.class).size() > 0; + } } } diff --git a/src/main/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinition.java b/src/main/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinition.java index 562d0aea9..87b9b230e 100644 --- a/src/main/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinition.java +++ b/src/main/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinition.java @@ -37,7 +37,8 @@ public JiraVersionParameterDefinition( String jiraShowReleased, String jiraShowArchived, String jiraShowUnreleased) { - super(name, description); + super(name); + setDescription(description); setJiraProjectKey(jiraProjectKey); setJiraReleasePattern(jiraReleasePattern); setJiraShowReleased(jiraShowReleased); diff --git a/src/main/resources/hudson/plugins/jira/JiraEnvironmentVariableBuilder/help.html b/src/main/resources/hudson/plugins/jira/JiraEnvironmentVariableBuilder/help.html index 409eac6c6..68c527228 100644 --- a/src/main/resources/hudson/plugins/jira/JiraEnvironmentVariableBuilder/help.html +++ b/src/main/resources/hudson/plugins/jira/JiraEnvironmentVariableBuilder/help.html @@ -3,6 +3,7 @@
Available variables:

diff --git a/src/test/java/hudson/plugins/jira/JiraCreateIssueNotifierTest.java b/src/test/java/hudson/plugins/jira/JiraCreateIssueNotifierTest.java deleted file mode 100644 index 07b4c1e55..000000000 --- a/src/test/java/hudson/plugins/jira/JiraCreateIssueNotifierTest.java +++ /dev/null @@ -1,438 +0,0 @@ -package hudson.plugins.jira; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import com.atlassian.jira.rest.client.api.StatusCategory; -import com.atlassian.jira.rest.client.api.domain.Component; -import com.atlassian.jira.rest.client.api.domain.Issue; -import com.atlassian.jira.rest.client.api.domain.IssueType; -import com.atlassian.jira.rest.client.api.domain.Priority; -import com.atlassian.jira.rest.client.api.domain.Status; -import com.cloudbees.hudson.plugins.folder.Folder; -import com.cloudbees.plugins.credentials.CredentialsScope; -import com.cloudbees.plugins.credentials.CredentialsStore; -import com.cloudbees.plugins.credentials.SystemCredentialsProvider; -import com.cloudbees.plugins.credentials.domains.Domain; -import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; -import hudson.EnvVars; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.model.FreeStyleBuild; -import hudson.model.FreeStyleProject; -import hudson.model.Result; -import hudson.util.ListBoxModel; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.WithoutJenkins; -import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -import org.mockito.Mockito; - -@WithJenkins -public class JiraCreateIssueNotifierTest { - - private static final String JIRA_PROJECT = "PROJECT"; - private static final String COMPONENT = "some, componentA"; - private static final String ASSIGNEE = "user.name"; - private static final String DESCRIPTION = "Some description"; - private static final String DESCRIPTION_PARAM = "${DESCRIPTION}"; - - List jiraComponents = new ArrayList<>(); - - Launcher launcher = mock(Launcher.class); - BuildListener buildListener = mock(BuildListener.class); - PrintStream logger = mock(PrintStream.class); - JiraSite site = mock(JiraSite.class); - JiraSession session = mock(JiraSession.class); - EnvVars env; - - FreeStyleProject project = mock(FreeStyleProject.class); - AbstractBuild previousBuild = mock(FreeStyleBuild.class); - AbstractBuild currentBuild = mock(FreeStyleBuild.class); - File temporaryDirectory; - - @TempDir - public File temporaryFolder; - - @BeforeEach - void createCommonMocks() throws IOException, InterruptedException { - env = new EnvVars(); - env.put("BUILD_NUMBER", "10"); - env.put("BUILD_URL", "/some/url/to/job"); - env.put("JOB_NAME", "Some job"); - env.put("DESCRIPTION", DESCRIPTION); - - jiraComponents.add(new Component(null, null, "componentA", null, null)); - - when(currentBuild.getParent()).thenReturn(project); - when(site.getSession(currentBuild.getParent())).thenReturn(session); - when(site.getSession(previousBuild.getParent())).thenReturn(session); - - doReturn(env).when(currentBuild).getEnvironment(Mockito.any()); - - temporaryDirectory = newFolder(temporaryFolder, "junit"); - - when(project.getBuildDir()).thenReturn(temporaryDirectory); - when(currentBuild.getProject()).thenReturn(project); - when(currentBuild.getEnvironment(buildListener)).thenReturn(env); - when(currentBuild.getPreviousCompletedBuild()).thenReturn(previousBuild); - when(buildListener.getLogger()).thenReturn(logger); - - when(session.getComponents(Mockito.anyString())).thenReturn(jiraComponents); - } - - @Test - @WithoutJenkins - void performSuccessFailure() throws Exception { - - when(previousBuild.getResult()).thenReturn(Result.SUCCESS); - when(currentBuild.getResult()).thenReturn(Result.FAILURE); - - JiraCreateIssueNotifier notifier = spy(new JiraCreateIssueNotifier(JIRA_PROJECT, "", "", "", 1L, 1L, 1)); - doReturn(site).when(notifier).getSiteForProject(Mockito.any()); - - Issue issue = mock(Issue.class); - when(session.createIssue( - Mockito.anyString(), - Mockito.anyString(), - Mockito.anyString(), - Mockito.anyIterable(), - Mockito.anyString(), - Mockito.anyLong(), - Mockito.anyLong())) - .thenReturn(issue); - - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - } - - @Test - @WithoutJenkins - void performSuccessFailureWithEnv() throws Exception { - when(previousBuild.getResult()).thenReturn(Result.SUCCESS); - when(currentBuild.getResult()).thenReturn(Result.FAILURE); - - JiraCreateIssueNotifier notifier = - spy(new JiraCreateIssueNotifier(JIRA_PROJECT, DESCRIPTION_PARAM, "", "", 1L, 1L, 1)); - doReturn(site).when(notifier).getSiteForProject(Mockito.any()); - - Issue issue = mock(Issue.class); - when(session.createIssue( - Mockito.anyString(), - contains(DESCRIPTION), - Mockito.anyString(), - Mockito.anyIterable(), - Mockito.anyString(), - Mockito.anyLong(), - Mockito.anyLong())) - .thenReturn(issue); - - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - } - - @Test - @WithoutJenkins - void performFailureFailure() throws Exception { - JiraCreateIssueNotifier notifier = - spy(new JiraCreateIssueNotifier(JIRA_PROJECT, DESCRIPTION, ASSIGNEE, COMPONENT, 1L, 1L, 1)); - doReturn(site).when(notifier).getSiteForProject(Mockito.any()); - - Issue issue = mock(Issue.class); - - Status status = new Status(null, null, "1", "Open", null, null); - when(session.createIssue( - Mockito.anyString(), - contains(DESCRIPTION), - Mockito.anyString(), - Mockito.anyIterable(), - Mockito.anyString(), - Mockito.anyLong(), - Mockito.anyLong())) - .thenReturn(issue); - when(session.getIssueByKey(Mockito.anyString())).thenReturn(issue); - when(issue.getStatus()).thenReturn(status); - - assertEquals(0, temporaryDirectory.list().length); - - when(previousBuild.getResult()).thenReturn(Result.SUCCESS); - when(currentBuild.getResult()).thenReturn(Result.FAILURE); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - assertEquals(1, temporaryDirectory.list().length); - - when(previousBuild.getResult()).thenReturn(Result.FAILURE); - when(currentBuild.getResult()).thenReturn(Result.FAILURE); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - assertEquals(1, temporaryDirectory.list().length); - - when(issue.getStatus()) - .thenReturn(new Status( - null, null, "6", JiraCreateIssueNotifier.finishedStatuses.Closed.toString(), null, null)); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - assertEquals(1, temporaryDirectory.list().length); - } - - @Test - @WithoutJenkins - void performFailureSuccessIssueOpen() throws Exception { - Long typeId = 1L; - Long priorityId = 0L; - Integer actionIdOnSuccess = 5; - - JiraCreateIssueNotifier notifier = - spy(new JiraCreateIssueNotifier(JIRA_PROJECT, "", "", "", typeId, priorityId, actionIdOnSuccess)); - - assertEquals(typeId, notifier.getTypeId()); - assertEquals(priorityId, notifier.getPriorityId()); - assertEquals(actionIdOnSuccess, notifier.getActionIdOnSuccess()); - - doReturn(site).when(notifier).getSiteForProject(Mockito.any()); - - Issue issue = mock(Issue.class); - Status status = new Status(null, null, "1", "Open", null, null); - when(session.createIssue( - Mockito.anyString(), - Mockito.anyString(), - Mockito.anyString(), - Mockito.anyIterable(), - Mockito.anyString(), - Mockito.eq(typeId), - Mockito.isNull())) - .thenReturn(issue); - when(issue.getStatus()).thenReturn(status); - when(session.getIssueByKey(Mockito.anyString())).thenReturn(issue); - - assertEquals(0, temporaryDirectory.list().length); - - when(previousBuild.getResult()).thenReturn(Result.SUCCESS); - when(currentBuild.getResult()).thenReturn(Result.FAILURE); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - assertEquals(1, temporaryDirectory.list().length); - - when(previousBuild.getResult()).thenReturn(Result.FAILURE); - when(currentBuild.getResult()).thenReturn(Result.SUCCESS); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - verify(session).progressWorkflowAction("null", actionIdOnSuccess); - - assertEquals(1, temporaryDirectory.list().length); - } - - @Test - @WithoutJenkins - void performFailureSuccessIssueClosedWithComponents() throws Exception { - JiraCreateIssueNotifier notifier = spy(new JiraCreateIssueNotifier(JIRA_PROJECT, "", "", "", 1L, 1L, 1)); - doReturn(site).when(notifier).getSiteForProject(Mockito.any()); - - Issue issue = mock(Issue.class); - Status status = - new Status(null, null, JiraCreateIssueNotifier.finishedStatuses.Closed.toString(), null, null, null); - - when(session.createIssue( - Mockito.anyString(), - Mockito.anyString(), - Mockito.anyString(), - Mockito.anyIterable(), - Mockito.anyString(), - Mockito.anyLong(), - Mockito.anyLong())) - .thenReturn(issue); - when(issue.getStatus()).thenReturn(status); - when(session.getIssueByKey(Mockito.anyString())).thenReturn(issue); - - assertEquals(0, temporaryDirectory.list().length); - - when(previousBuild.getResult()).thenReturn(Result.SUCCESS); - when(currentBuild.getResult()).thenReturn(Result.FAILURE); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - assertEquals(1, temporaryDirectory.list().length); - - when(previousBuild.getResult()).thenReturn(Result.FAILURE); - when(currentBuild.getResult()).thenReturn(Result.SUCCESS); - assertTrue(notifier.perform(currentBuild, launcher, buildListener)); - - // file should be deleted - assertEquals(0, temporaryDirectory.list().length); - } - - @Test - @WithoutJenkins - void isDone() { - assertTrue(JiraCreateIssueNotifier.isDone(new Status(null, null, "Closed", null, null, null))); - assertTrue(JiraCreateIssueNotifier.isDone(new Status(null, null, "Done", null, null, null))); - assertTrue(JiraCreateIssueNotifier.isDone(new Status(null, null, "Resolved", null, null, null))); - assertTrue(JiraCreateIssueNotifier.isDone( - new Status(null, null, "Abandoned", null, null, new StatusCategory(null, "Done", null, "done", null)))); - assertFalse(JiraCreateIssueNotifier.isDone( - new Status(null, null, "Abandoned", null, null, new StatusCategory(null, "ToDo", null, "todo", null)))); - } - - @Test - void doFillPriorityIdItems(JenkinsRule j) throws Exception { - - String credId_1 = "cred-1-id"; - String credId_2 = "cred-2-id"; - - String pwd1 = "pwd1"; - String pwd2 = "pwd2"; - - UsernamePasswordCredentialsImpl cred1 = - new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_1, null, "user1", pwd1); - UsernamePasswordCredentialsImpl cred2 = - new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_2, null, "user2", pwd2); - - SystemCredentialsProvider systemProvider = SystemCredentialsProvider.getInstance(); - systemProvider.getCredentials().add(cred1); - systemProvider.save(); - - { // test at project level - URL url = new URL("https://pacific-ale.com.au"); - JiraSite jiraSite = mock(JiraSite.class); - when(jiraSite.getUrl()).thenReturn(url); - when(jiraSite.getCredentialsId()).thenReturn(credId_1); - when(jiraSite.getName()).thenReturn(url.toExternalForm()); - JiraSession jiraSession = mock(JiraSession.class); - when(jiraSession.getPriorities()) - .thenReturn(Collections.singletonList(new Priority(null, 2L, "priority-1", null, null, null))); - when(jiraSite.getSession(any())).thenReturn(jiraSession); - - JiraGlobalConfiguration.get().setSites(Collections.singletonList(jiraSite)); - - FreeStyleProject p = j.jenkins.createProject( - FreeStyleProject.class, "p" + j.jenkins.getItems().size()); - ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillPriorityIdItems(p); - assertNotNull(options); - assertThat(options.size(), Matchers.equalTo(2)); - assertThat(options.get(1).value, Matchers.equalTo("2")); - assertThat(options.get(1).name, Matchers.containsString("priority-1")); - assertThat(options.get(1).name, Matchers.containsString("https://pacific-ale.com.au")); - } - - { // test at folder level - Folder folder = j.jenkins.createProject( - Folder.class, "folder" + j.jenkins.getItems().size()); - - CredentialsStore folderStore = JiraFolderPropertyTest.getFolderStore(folder); - folderStore.addCredentials(Domain.global(), cred2); - - JiraFolderProperty foo = new JiraFolderProperty(); - - JiraSite jiraSite = mock(JiraSite.class); - URL url = new URL("https://pale-ale.com.au"); - when(jiraSite.getUrl()).thenReturn(url); - when(jiraSite.getCredentialsId()).thenReturn(credId_2); - when(jiraSite.getName()).thenReturn(url.toExternalForm()); - JiraSession jiraSession = mock(JiraSession.class); - when(jiraSession.getPriorities()) - .thenReturn(Collections.singletonList(new Priority(null, 3L, "priority-2", null, null, null))); - when(jiraSite.getSession(any())).thenReturn(jiraSession); - - foo.setSites(Collections.singletonList(jiraSite)); - folder.getProperties().add(foo); - - ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillPriorityIdItems(folder); - assertNotNull(options); - assertEquals(2, options.size()); - assertEquals("3", options.get(1).value); - assertTrue(options.get(1).name.contains("priority-2")); - assertTrue(options.get(1).name.contains("https://pale-ale.com.au")); - } - } - - @Test - void doFillTypeItems(JenkinsRule j) throws Exception { - - String credId_1 = "cred-1-id"; - String credId_2 = "cred-2-id"; - - String pwd1 = "pwd1"; - String pwd2 = "pwd2"; - - UsernamePasswordCredentialsImpl cred1 = - new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_1, null, "user1", pwd1); - UsernamePasswordCredentialsImpl cred2 = - new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_2, null, "user2", pwd2); - - SystemCredentialsProvider systemProvider = SystemCredentialsProvider.getInstance(); - systemProvider.getCredentials().add(cred1); - systemProvider.save(); - - { // test at project level - URL url = new URL("https://pacific-ale.com.au"); - JiraSite jiraSite = mock(JiraSite.class); - when(jiraSite.getUrl()).thenReturn(url); - when(jiraSite.getCredentialsId()).thenReturn(credId_1); - when(jiraSite.getName()).thenReturn(url.toExternalForm()); - JiraSession jiraSession = mock(JiraSession.class); - when(jiraSession.getIssueTypes()) - .thenReturn(Collections.singletonList(new IssueType(null, 1L, "type-1", true, null, null))); - when(jiraSite.getSession(any())).thenReturn(jiraSession); - - JiraGlobalConfiguration.get().setSites(Collections.singletonList(jiraSite)); - - FreeStyleProject p = j.jenkins.createProject( - FreeStyleProject.class, "p" + j.jenkins.getItems().size()); - ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillTypeIdItems(p); - assertNotNull(options); - assertThat(options.size(), Matchers.equalTo(2)); - assertThat(options.get(1).value, Matchers.equalTo("1")); - assertThat(options.get(1).name, Matchers.containsString("type-1")); - assertThat(options.get(1).name, Matchers.containsString("https://pacific-ale.com.au")); - } - - { // test at folder level - Folder folder = j.jenkins.createProject( - Folder.class, "folder" + j.jenkins.getItems().size()); - - CredentialsStore folderStore = JiraFolderPropertyTest.getFolderStore(folder); - folderStore.addCredentials(Domain.global(), cred2); - - JiraFolderProperty foo = new JiraFolderProperty(); - - JiraSite jiraSite = mock(JiraSite.class); - URL url = new URL("https://pale-ale.com.au"); - when(jiraSite.getUrl()).thenReturn(url); - when(jiraSite.getCredentialsId()).thenReturn(credId_2); - when(jiraSite.getName()).thenReturn(url.toExternalForm()); - JiraSession jiraSession = mock(JiraSession.class); - when(jiraSession.getIssueTypes()) - .thenReturn(Collections.singletonList(new IssueType(null, 2L, "type-2", false, null, null))); - when(jiraSite.getSession(any())).thenReturn(jiraSession); - - foo.setSites(Collections.singletonList(jiraSite)); - folder.getProperties().add(foo); - - ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillTypeIdItems(folder); - assertNotNull(options); - assertEquals(2, options.size()); - assertEquals("2", options.get(1).value); - assertTrue(options.get(1).name.contains("type-2")); - assertTrue(options.get(1).name.contains("https://pale-ale.com.au")); - } - } - - private static File newFolder(File root, String... subDirs) throws IOException { - String subFolder = String.join("/", subDirs); - File result = new File(root, subFolder); - if (!result.mkdirs()) { - throw new IOException("Couldn't create folders " + root); - } - return result; - } -} diff --git a/src/test/java/hudson/plugins/jira/JiraEnvironmentContributingActionTest.java b/src/test/java/hudson/plugins/jira/JiraEnvironmentContributingActionTest.java deleted file mode 100644 index 74e59c5bb..000000000 --- a/src/test/java/hudson/plugins/jira/JiraEnvironmentContributingActionTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package hudson.plugins.jira; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import hudson.EnvVars; -import hudson.model.AbstractBuild; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -class JiraEnvironmentContributingActionTest { - private static final String JIRA_URL = "http://example.com"; - private static final String JIRA_URL_PROPERTY_NAME = "JIRA_URL"; - private static final String ISSUES_PROPERTY_NAME = "JIRA_ISSUES"; - private static final String ISSUES_LIST = "ISS-1,ISS-2"; - - @Test - void buildEnvVarsEnvIsNull() { - JiraEnvironmentContributingAction action = new JiraEnvironmentContributingAction(ISSUES_LIST, JIRA_URL); - AbstractBuild build = mock(AbstractBuild.class); - - action.buildEnvVars(build, null); - // just expecting no exception - } - - @Test - void buildEnvVarsAddVariables() { - JiraEnvironmentContributingAction action = new JiraEnvironmentContributingAction(ISSUES_LIST, JIRA_URL); - AbstractBuild build = mock(AbstractBuild.class); - EnvVars envVars = mock(EnvVars.class); - - action.buildEnvVars(build, envVars); - - ArgumentCaptor keys = ArgumentCaptor.forClass(String.class); - ArgumentCaptor values = ArgumentCaptor.forClass(String.class); - verify(envVars, times(2)).put(keys.capture(), values.capture()); - - assertThat(keys.getAllValues().get(0), is(ISSUES_PROPERTY_NAME)); - assertThat(values.getAllValues().get(0), is(ISSUES_LIST)); - - assertThat(keys.getAllValues().get(1), is(JIRA_URL_PROPERTY_NAME)); - assertThat(values.getAllValues().get(1), is(JIRA_URL)); - } -} diff --git a/src/test/java/hudson/plugins/jira/UpdaterTest.java b/src/test/java/hudson/plugins/jira/UpdaterTest.java deleted file mode 100644 index 5a1a8fa62..000000000 --- a/src/test/java/hudson/plugins/jira/UpdaterTest.java +++ /dev/null @@ -1,478 +0,0 @@ -package hudson.plugins.jira; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.atlassian.jira.rest.client.api.RestClientException; -import com.atlassian.jira.rest.client.api.domain.Comment; -import com.atlassian.jira.rest.client.api.domain.Issue; -import hudson.model.FreeStyleBuild; -import hudson.model.FreeStyleProject; -import hudson.model.Job; -import hudson.model.Result; -import hudson.model.Run; -import hudson.model.User; -import hudson.plugins.jira.model.JiraIssue; -import hudson.scm.ChangeLogSet; -import hudson.scm.ChangeLogSet.Entry; -import hudson.scm.EditType; -import hudson.scm.SCM; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import jenkins.model.Jenkins; -import org.hamcrest.Matchers; -import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.WithoutJenkins; -import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -import org.mockito.Mockito; -import org.mockito.stubbing.Answer; - -/** - * Test case for the Jira {@link Updater}. - * - * @author kutzi - */ -@SuppressWarnings("unchecked") -@WithJenkins -public class UpdaterTest { - - private Updater updater; - - private static class MockEntry extends Entry { - - private final String msg; - - public MockEntry(String msg) { - this.msg = msg; - } - - @Override - public Collection getAffectedPaths() { - return null; - } - - @Override - public User getAuthor() { - return null; - } - - @Override - public String getMsg() { - return this.msg; - } - } - - @BeforeEach - void prepare() { - SCM scm = mock(SCM.class); - this.updater = new Updater(scm); - } - - @Test - void getScmCommentsFromPreviousBuilds(JenkinsRule r) { - final FreeStyleProject project = mock(FreeStyleProject.class); - final FreeStyleBuild build1 = mock(FreeStyleBuild.class); - final MockEntry entry1 = new MockEntry("FOOBAR-1: The first build"); - { - ChangeLogSet changeLogSet = mock(ChangeLogSet.class); - when(build1.getChangeSet()).thenReturn(changeLogSet); - List> changeSets = new ArrayList<>(); - changeSets.add(changeLogSet); - when(build1.getChangeSets()).thenReturn(changeSets); - when(build1.getResult()).thenReturn(Result.FAILURE); - doReturn(project).when(build1).getProject(); - - doReturn(new JiraCarryOverAction(new HashSet(Arrays.asList(new JiraIssue("FOOBAR-1", null))))) - .when(build1) - .getAction(JiraCarryOverAction.class); - - final Set entries = new HashSet(Arrays.asList(entry1)); - when(changeLogSet.iterator()).thenAnswer(invocation -> entries.iterator()); - } - - final FreeStyleBuild build2 = mock(FreeStyleBuild.class); - final MockEntry entry2 = new MockEntry("FOOBAR-2: The next build"); - { - ChangeLogSet changeLogSet = mock(ChangeLogSet.class); - when(build2.getChangeSet()).thenReturn(changeLogSet); - List> changeSets = new ArrayList<>(); - changeSets.add(changeLogSet); - when(build2.getChangeSets()).thenReturn(changeSets); - when(build2.getPreviousCompletedBuild()).thenReturn(build1); - when(build2.getResult()).thenReturn(Result.SUCCESS); - doReturn(project).when(build2).getProject(); - - final Set entries = new HashSet(Arrays.asList(entry2)); - when(changeLogSet.iterator()).thenAnswer(invocation -> entries.iterator()); - } - - final List comments = new ArrayList(); - final JiraSession session = mock(JiraSession.class); - doAnswer((Answer) invocation -> { - Comment rc = - Comment.createWithGroupLevel((String) invocation.getArguments()[1], (String) - invocation.getArguments()[2]); - comments.add(rc); - return null; - }) - .when(session) - .addComment(anyString(), anyString(), anyString(), anyString()); - - this.updater = new Updater(build2.getProject().getScm()); - - final Set ids = - new HashSet(Arrays.asList(new JiraIssue("FOOBAR-1", null), new JiraIssue("FOOBAR-2", null))); - updater.submitComments(build2, System.out, "http://jenkins", ids, session, false, false, "", ""); - - assertEquals(2, comments.size()); - assertThat(comments.get(0).getBody(), Matchers.containsString(entry1.getMsg())); - assertThat(comments.get(1).getBody(), Matchers.containsString(entry2.getMsg())); - } - - /** - * Tests that the generated comment matches the expectations - - * especially that the Jira id is not stripped from the comment. - */ - @Test - @org.jvnet.hudson.test.Issue("4572") - void comment(JenkinsRule r) { - // mock Jira session: - JiraSession session = mock(JiraSession.class); - final Issue mockIssue = Mockito.mock(Issue.class); - when(session.getIssue(Mockito.anyString())).thenReturn(mockIssue); - - final List comments = new ArrayList<>(); - - Answer answer = (Answer) invocation -> { - comments.add((String) invocation.getArguments()[1]); - return null; - }; - doAnswer(answer) - .when(session) - .addComment(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - - // mock build: - FreeStyleBuild build = mock(FreeStyleBuild.class); - FreeStyleProject project = mock(FreeStyleProject.class); - when(build.getParent()).thenReturn(project); - when(build.getProject()).thenReturn(project); - ChangeLogSet changeLogSet = mock(ChangeLogSet.class); - when(build.getChangeSet()).thenReturn(changeLogSet); - when(build.getResult()).thenReturn(Result.SUCCESS); - - Set entries = new HashSet(Arrays.asList(new MockEntry("Fixed FOOBAR-4711"))); - when(changeLogSet.iterator()).thenReturn(entries.iterator()); - - List> changeSets = new ArrayList<>(); - changeSets.add(changeLogSet); - when(build.getChangeSets()).thenReturn(changeSets); - - // test: - Set ids = new HashSet(Arrays.asList(new JiraIssue("FOOBAR-4711", "Title"))); - Updater updaterCurrent = new Updater(build.getParent().getScm()); - updaterCurrent.submitComments(build, System.out, "http://jenkins", ids, session, false, false, "", ""); - - assertEquals(1, comments.size()); - String comment = comments.get(0); - - assertTrue(comment.contains("FOOBAR-4711")); - - // must also work case-insensitively (JENKINS-4132) - comments.clear(); - entries = new HashSet(Arrays.asList(new MockEntry("Fixed Foobar-4711"))); - when(changeLogSet.iterator()).thenReturn(entries.iterator()); - ids = new HashSet(Arrays.asList(new JiraIssue("FOOBAR-4711", "Title"))); - - updaterCurrent.submitComments(build, System.out, "http://jenkins", ids, session, false, false, "", ""); - - assertEquals(1, comments.size()); - comment = comments.get(0); - - assertTrue(comment.contains("Foobar-4711")); - } - - /** - * /** - * Checks if issues are correctly removed from the carry over list. - */ - @Test - @org.jvnet.hudson.test.Issue("17156") - @WithoutJenkins - void issueIsRemovedFromCarryOverListAfterSubmission() throws RestClientException { - // mock build: - FreeStyleBuild build = mock(FreeStyleBuild.class); - FreeStyleProject project = mock(FreeStyleProject.class); - when(build.getParent()).thenReturn(project); - when(build.getProject()).thenReturn(project); - ChangeLogSet changeLogSet = ChangeLogSet.createEmpty(build); - when(build.getChangeSet()).thenReturn(changeLogSet); - when(build.getResult()).thenReturn(Result.SUCCESS); - - final JiraIssue firstIssue = new JiraIssue("FOOBAR-1", "Title"); - final JiraIssue secondIssue = new JiraIssue("ALIBA-1", "Title"); - final JiraIssue thirdIssue = new JiraIssue("MOONA-1", "Title"); - final JiraIssue deletedIssue = new JiraIssue("FOOBAR-2", "Title"); - final JiraIssue forbiddenIssue = new JiraIssue("LASSO-17", "Title"); - - // assume that there is a following list of jira issues from scm commit messages out of - // hudson.plugins.jira.JiraCarryOverAction - Set issues = new HashSet(Arrays.asList(firstIssue, secondIssue, forbiddenIssue, thirdIssue)); - - // mock Jira session: - JiraSession session = mock(JiraSession.class); - - final List comments = new ArrayList<>(); - - Answer answer = (Answer) invocation -> { - Comment c = Comment.createWithGroupLevel( - (String) invocation.getArguments()[0], (String) invocation.getArguments()[1]); - comments.add(c); - return null; - }; - - doAnswer(answer) - .when(session) - .addComment(eq(firstIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - doAnswer(answer) - .when(session) - .addComment(eq(secondIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - doAnswer(answer) - .when(session) - .addComment(eq(thirdIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - - // issue for the caught exception - doThrow(new RestClientException(new Throwable(), 404)) - .when(session) - .addComment(eq(deletedIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - doThrow(new RestClientException(new Throwable(), 403)) - .when(session) - .addComment(eq(forbiddenIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - - final String groupVisibility = ""; - final String roleVisibility = ""; - - Updater updaterCurrent = new Updater(build.getParent().getScm()); - - updaterCurrent.submitComments( - build, System.out, "http://jenkins", issues, session, false, false, groupVisibility, roleVisibility); - - // expected issue list - final Set expectedIssuesToCarryOver = new LinkedHashSet(); - expectedIssuesToCarryOver.add(forbiddenIssue); - assertThat(issues, is(expectedIssuesToCarryOver)); - } - - @TempDir - public File folder; - - /** - * Test that workflow job - run instance of type WorkflowJob - can - * return changeSets using java reflection api - * - */ - @Test - @WithoutJenkins - void getChangesUsingReflectionForWorkflowJob() throws IOException { - Jenkins jenkins = mock(Jenkins.class); - - when(jenkins.getRootDirFor(Mockito.any())).thenReturn(folder); - WorkflowJob workflowJob = new WorkflowJob(jenkins, "job"); - WorkflowRun workflowRun = new WorkflowRun(workflowJob); - - ChangeLogSet.createEmpty(workflowRun); - - List> changesUsingReflection = - RunScmChangeExtractor.getChangesUsingReflection(workflowRun); - assertNotNull(changesUsingReflection); - assertTrue(changesUsingReflection.isEmpty()); - } - - @WithoutJenkins - @Test - void getChangesUsingReflectionForunknownJob() { - Run run = mock(Run.class); - assertThrows(IllegalArgumentException.class, () -> RunScmChangeExtractor.getChangesUsingReflection(run)); - } - - /** - * Test formatting of scm entry change time. - * - */ - @Test - @WithoutJenkins - void appendChangeTimestampToDescription() { - Updater updater = new Updater(null); - StringBuilder description = new StringBuilder(); - Calendar calendar = Calendar.getInstance(); - calendar.set(2016, 0, 1, 0, 0, 0); - JiraSite site = mock(JiraSite.class); - when(site.getDateTimePattern()).thenReturn("yyyy-MM-dd HH:mm:ss"); - updater.appendChangeTimestampToDescription(description, site, calendar.getTimeInMillis()); - System.out.println(description.toString()); - assertThat(description.toString(), equalTo("2016-01-01 00:00:00")); - } - - /** - * Test formatting of scm entry change description. - * - */ - @Test - void dateTimeInChangeDescription(JenkinsRule rule) { - rule.getInstance(); - Updater updater = new Updater(null); - Calendar calendar = Calendar.getInstance(); - calendar.set(2016, 0, 1, 0, 0, 0); - JiraSite site = mock(JiraSite.class); - when(site.isAppendChangeTimestamp()).thenReturn(true); - when(site.getDateTimePattern()).thenReturn("yyyy-MM-dd HH:mm:ss"); - - Run r = mock(Run.class); - Job j = mock(Job.class); - when(r.getParent()).thenReturn(j); - JiraProjectProperty jiraProjectProperty = mock(JiraProjectProperty.class); - when(j.getProperty(JiraProjectProperty.class)).thenReturn(jiraProjectProperty); - when(jiraProjectProperty.getSite()).thenReturn(site); - - ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class); - when(entry.getTimestamp()).thenReturn(calendar.getTimeInMillis()); - when(entry.getCommitId()).thenReturn("dsgsvds2re3dsv"); - User mockAuthor = mock(User.class); - when(mockAuthor.getId()).thenReturn("jenkins-user"); - when(entry.getAuthor()).thenReturn(mockAuthor); - - String description = updater.createScmChangeEntryDescription(r, entry, false, false); - System.out.println(description); - assertThat(description, containsString("2016-01-01 00:00:00")); - assertThat(description, containsString("jenkins-user")); - assertThat(description, containsString("dsgsvds2re3dsv")); - } - - /** - * Test formatting of scm entry change description - * when no format is provided (e.g. when null). - * - */ - @Test - @WithoutJenkins - void appendChangeTimestampToDescriptionNullFormat() { - // set default locale -> predictable test without explicit format - Locale.setDefault(Locale.ENGLISH); - - Updater updater = new Updater(null); - JiraSite site = mock(JiraSite.class); - when(site.isAppendChangeTimestamp()).thenReturn(true); - when(site.getDateTimePattern()).thenReturn(null); - // when(site.getDateTimePattern()).thenReturn("d/M/yy hh:mm a"); - - Calendar calendar = Calendar.getInstance(); - calendar.set(2016, 0, 1, 0, 0, 0); - - StringBuilder builder = new StringBuilder(); - updater.appendChangeTimestampToDescription(builder, site, calendar.getTimeInMillis()); - assertThat(builder.toString(), equalTo("1/1/16 12:00 AM")); - } - - /** - * Test formatting of scm entry change description - * when no format is provided (e.g. when empty string). - * - */ - @Test - @WithoutJenkins - void appendChangeTimestampToDescriptionNoFormat() { - // set default locale -> predictable test without explicit format - Locale.setDefault(Locale.ENGLISH); - - Updater updater = new Updater(null); - JiraSite site = mock(JiraSite.class); - when(site.isAppendChangeTimestamp()).thenReturn(true); - when(site.getDateTimePattern()).thenReturn(null); - // when(site.getDateTimePattern()).thenReturn("d/M/yy hh:mm a"); - - Calendar calendar = Calendar.getInstance(); - calendar.set(2016, 0, 1, 0, 0, 0); - - StringBuilder builder = new StringBuilder(); - updater.appendChangeTimestampToDescription(builder, site, calendar.getTimeInMillis()); - assertThat(builder.toString(), equalTo("1/1/16 12:00 AM")); - } - - /** - * Test formatting of scm entry change description coverage primary wiki - * style appendRevisionToDescription and appendAffectedFilesToDescription - * - */ - @Test - void tesDescriptionWithAffectedFiles(JenkinsRule rule) { - rule.getInstance(); - Updater updater = new Updater(null); - Calendar calendar = Calendar.getInstance(); - calendar.set(2016, 0, 1, 0, 0, 0); - JiraSite site = mock(JiraSite.class); - when(site.isAppendChangeTimestamp()).thenReturn(false); - - Run r = mock(Run.class); - Job j = mock(Job.class); - when(r.getParent()).thenReturn(j); - JiraProjectProperty jiraProjectProperty = mock(JiraProjectProperty.class); - when(j.getProperty(JiraProjectProperty.class)).thenReturn(jiraProjectProperty); - when(jiraProjectProperty.getSite()).thenReturn(site); - - ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class); - when(entry.getTimestamp()).thenReturn(calendar.getTimeInMillis()); - when(entry.getCommitId()).thenReturn("dsgsvds2re3dsv"); - User mockAuthor = mock(User.class); - when(mockAuthor.getId()).thenReturn("jenkins-user"); - when(entry.getAuthor()).thenReturn(mockAuthor); - - Collection affectedFiles = new ArrayList(); - MockAffectedFile affectedFile1 = mock(MockAffectedFile.class); - when(affectedFile1.getEditType()).thenReturn(EditType.ADD); - when(affectedFile1.getPath()).thenReturn("hudson/plugins/jira/File1"); - affectedFiles.add(affectedFile1); - MockAffectedFile corruptedFile = mock(MockAffectedFile.class); - when(corruptedFile.getEditType()).thenReturn(null); - when(corruptedFile.getPath()).thenReturn(null); - affectedFiles.add(corruptedFile); - MockAffectedFile affectedFile2 = mock(MockAffectedFile.class); - when(affectedFile2.getEditType()).thenReturn(EditType.DELETE); - when(affectedFile2.getPath()).thenReturn("hudson/plugins/jira/File2"); - affectedFiles.add(affectedFile2); - MockAffectedFile affectedFile3 = mock(MockAffectedFile.class); - when(affectedFile3.getEditType()).thenReturn(EditType.EDIT); - when(affectedFile3.getPath()).thenReturn("hudson/plugins/jira/File3"); - affectedFiles.add(affectedFile3); - doReturn(affectedFiles).when(entry).getAffectedFiles(); - - String description = updater.createScmChangeEntryDescription(r, entry, true, true); - System.out.println(description); - assertThat( - description, - equalTo(" (jenkins-user: rev dsgsvds2re3dsv)\n" + "* (add) hudson/plugins/jira/File1\n" + "* \n" - + "* (delete) hudson/plugins/jira/File2\n" + "* (edit) hudson/plugins/jira/File3\n")); - } -} diff --git a/src/test/java/hudson/plugins/jira/CliParameterTest.java b/src/test/java/hudson/plugins/jira/integration/CliParameterTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/CliParameterTest.java rename to src/test/java/hudson/plugins/jira/integration/CliParameterTest.java index 394570c13..32e3edac6 100644 --- a/src/test/java/hudson/plugins/jira/CliParameterTest.java +++ b/src/test/java/hudson/plugins/jira/integration/CliParameterTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static hudson.cli.CLICommandInvoker.Matcher.succeeded; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/hudson/plugins/jira/ConfigAsCodeTest.java b/src/test/java/hudson/plugins/jira/integration/ConfigAsCodeTest.java similarity index 94% rename from src/test/java/hudson/plugins/jira/ConfigAsCodeTest.java rename to src/test/java/hudson/plugins/jira/integration/ConfigAsCodeTest.java index b76494945..67dba1c13 100644 --- a/src/test/java/hudson/plugins/jira/ConfigAsCodeTest.java +++ b/src/test/java/hudson/plugins/jira/integration/ConfigAsCodeTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import hudson.plugins.jira.JiraGlobalConfiguration; +import hudson.plugins.jira.JiraSite; import io.jenkins.plugins.casc.ConfigurationContext; import io.jenkins.plugins.casc.Configurator; import io.jenkins.plugins.casc.ConfiguratorRegistry; diff --git a/src/test/java/hudson/plugins/jira/CredentialsHelperTest.java b/src/test/java/hudson/plugins/jira/integration/CredentialsHelperTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/CredentialsHelperTest.java rename to src/test/java/hudson/plugins/jira/integration/CredentialsHelperTest.java index 442df83bb..d64a854da 100644 --- a/src/test/java/hudson/plugins/jira/CredentialsHelperTest.java +++ b/src/test/java/hudson/plugins/jira/integration/CredentialsHelperTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; @@ -14,6 +14,8 @@ import com.cloudbees.plugins.credentials.domains.HostnameSpecification; import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; import hudson.model.Descriptor.FormException; +import hudson.plugins.jira.CredentialsHelper; +import hudson.plugins.jira.JiraSite; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; diff --git a/src/test/java/hudson/plugins/jira/DescriptorImplTest.java b/src/test/java/hudson/plugins/jira/integration/DescriptorImplTest.java similarity index 99% rename from src/test/java/hudson/plugins/jira/DescriptorImplTest.java rename to src/test/java/hudson/plugins/jira/integration/DescriptorImplTest.java index ab800415e..e07b836d5 100644 --- a/src/test/java/hudson/plugins/jira/DescriptorImplTest.java +++ b/src/test/java/hudson/plugins/jira/integration/DescriptorImplTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; diff --git a/src/test/java/hudson/plugins/jira/EmptyFriendlyURLConverterTest.java b/src/test/java/hudson/plugins/jira/integration/EmptyFriendlyURLConverterTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/EmptyFriendlyURLConverterTest.java rename to src/test/java/hudson/plugins/jira/integration/EmptyFriendlyURLConverterTest.java index 1eebcfb4d..cd789b5b3 100644 --- a/src/test/java/hudson/plugins/jira/EmptyFriendlyURLConverterTest.java +++ b/src/test/java/hudson/plugins/jira/integration/EmptyFriendlyURLConverterTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.nullValue; diff --git a/src/test/java/hudson/plugins/jira/JiraBuildActionTest.java b/src/test/java/hudson/plugins/jira/integration/JiraBuildActionTest.java similarity index 93% rename from src/test/java/hudson/plugins/jira/JiraBuildActionTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraBuildActionTest.java index 562098b64..7743bdd4f 100644 --- a/src/test/java/hudson/plugins/jira/JiraBuildActionTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraBuildActionTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -6,6 +6,7 @@ import hudson.model.Job; import hudson.model.Run; +import hudson.plugins.jira.JiraBuildAction; import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.junit.jupiter.WithJenkins; diff --git a/src/test/java/hudson/plugins/jira/integration/JiraCreateIssueNotifierIntegrationTest.java b/src/test/java/hudson/plugins/jira/integration/JiraCreateIssueNotifierIntegrationTest.java new file mode 100644 index 000000000..116272e3c --- /dev/null +++ b/src/test/java/hudson/plugins/jira/integration/JiraCreateIssueNotifierIntegrationTest.java @@ -0,0 +1,178 @@ +package hudson.plugins.jira.integration; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import com.atlassian.jira.rest.client.api.domain.Component; +import com.atlassian.jira.rest.client.api.domain.IssueType; +import com.atlassian.jira.rest.client.api.domain.Priority; +import com.cloudbees.hudson.plugins.folder.Folder; +import com.cloudbees.plugins.credentials.CredentialsScope; +import com.cloudbees.plugins.credentials.CredentialsStore; +import com.cloudbees.plugins.credentials.SystemCredentialsProvider; +import com.cloudbees.plugins.credentials.domains.Domain; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import hudson.model.FreeStyleProject; +import hudson.plugins.jira.JiraCreateIssueNotifier; +import hudson.plugins.jira.JiraFolderProperty; +import hudson.plugins.jira.JiraFolderPropertyTest; +import hudson.plugins.jira.JiraGlobalConfiguration; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; +import hudson.util.ListBoxModel; +import java.net.URL; +import java.util.Collections; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +public class JiraCreateIssueNotifierIntegrationTest { + + @Test + void doFillPriorityIdItems(JenkinsRule j) throws Exception { + + String credId_1 = "cred-1-id"; + String credId_2 = "cred-2-id"; + + String pwd1 = "pwd1"; + String pwd2 = "pwd2"; + + UsernamePasswordCredentialsImpl cred1 = + new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_1, null, "user1", pwd1); + UsernamePasswordCredentialsImpl cred2 = + new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_2, null, "user2", pwd2); + + SystemCredentialsProvider systemProvider = SystemCredentialsProvider.getInstance(); + systemProvider.getCredentials().add(cred1); + systemProvider.save(); + + { // test at project level + URL url = new URL("https://pacific-ale.com.au"); + JiraSite jiraSite = mock(JiraSite.class); + when(jiraSite.getUrl()).thenReturn(url); + when(jiraSite.getCredentialsId()).thenReturn(credId_1); + when(jiraSite.getName()).thenReturn(url.toExternalForm()); + JiraSession jiraSession = mock(JiraSession.class); + when(jiraSession.getPriorities()) + .thenReturn(Collections.singletonList(new Priority(null, 2L, "priority-1", null, null, null))); + when(jiraSite.getSession(any())).thenReturn(jiraSession); + + JiraGlobalConfiguration.get().setSites(Collections.singletonList(jiraSite)); + + FreeStyleProject p = j.jenkins.createProject( + FreeStyleProject.class, "p" + j.jenkins.getItems().size()); + ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillPriorityIdItems(p); + assertNotNull(options); + assertThat(options.size(), Matchers.equalTo(2)); + assertThat(options.get(1).value, Matchers.equalTo("2")); + assertThat(options.get(1).name, Matchers.containsString("priority-1")); + assertThat(options.get(1).name, Matchers.containsString("https://pacific-ale.com.au")); + } + + { // test at folder level + Folder folder = j.jenkins.createProject( + Folder.class, "folder" + j.jenkins.getItems().size()); + + CredentialsStore folderStore = JiraFolderPropertyTest.getFolderStore(folder); + folderStore.addCredentials(Domain.global(), cred2); + + JiraFolderProperty foo = new JiraFolderProperty(); + + JiraSite jiraSite = mock(JiraSite.class); + URL url = new URL("https://pale-ale.com.au"); + when(jiraSite.getUrl()).thenReturn(url); + when(jiraSite.getCredentialsId()).thenReturn(credId_2); + when(jiraSite.getName()).thenReturn(url.toExternalForm()); + JiraSession jiraSession = mock(JiraSession.class); + when(jiraSession.getPriorities()) + .thenReturn(Collections.singletonList(new Priority(null, 3L, "priority-2", null, null, null))); + when(jiraSite.getSession(any())).thenReturn(jiraSession); + + foo.setSites(Collections.singletonList(jiraSite)); + folder.getProperties().add(foo); + + ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillPriorityIdItems(folder); + assertNotNull(options); + assertEquals(2, options.size()); + assertEquals("3", options.get(1).value); + assertTrue(options.get(1).name.contains("priority-2")); + assertTrue(options.get(1).name.contains("https://pale-ale.com.au")); + } + } + + @Test + void doFillTypeItems(JenkinsRule j) throws Exception { + + String credId_1 = "cred-1-id"; + String credId_2 = "cred-2-id"; + + String pwd1 = "pwd1"; + String pwd2 = "pwd2"; + + UsernamePasswordCredentialsImpl cred1 = + new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_1, null, "user1", pwd1); + UsernamePasswordCredentialsImpl cred2 = + new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credId_2, null, "user2", pwd2); + + SystemCredentialsProvider systemProvider = SystemCredentialsProvider.getInstance(); + systemProvider.getCredentials().add(cred1); + systemProvider.save(); + + { // test at project level + URL url = new URL("https://pacific-ale.com.au"); + JiraSite jiraSite = mock(JiraSite.class); + when(jiraSite.getUrl()).thenReturn(url); + when(jiraSite.getCredentialsId()).thenReturn(credId_1); + when(jiraSite.getName()).thenReturn(url.toExternalForm()); + JiraSession jiraSession = mock(JiraSession.class); + when(jiraSession.getIssueTypes()) + .thenReturn(Collections.singletonList(new IssueType(null, 4L, "issue-type-1", false, null, null))); + when(jiraSite.getSession(any())).thenReturn(jiraSession); + + JiraGlobalConfiguration.get().setSites(Collections.singletonList(jiraSite)); + + FreeStyleProject p = j.jenkins.createProject( + FreeStyleProject.class, "p" + j.jenkins.getItems().size()); + ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillTypeItems(p); + assertNotNull(options); + assertThat(options.size(), Matchers.equalTo(2)); + assertThat(options.get(1).value, Matchers.equalTo("4")); + assertThat(options.get(1).name, Matchers.containsString("issue-type-1")); + assertThat(options.get(1).name, Matchers.containsString("https://pacific-ale.com.au")); + } + + { // test at folder level + Folder folder = j.jenkins.createProject( + Folder.class, "folder" + j.jenkins.getItems().size()); + + CredentialsStore folderStore = JiraFolderPropertyTest.getFolderStore(folder); + folderStore.addCredentials(Domain.global(), cred2); + + JiraFolderProperty foo = new JiraFolderProperty(); + + JiraSite jiraSite = mock(JiraSite.class); + URL url = new URL("https://pale-ale.com.au"); + when(jiraSite.getUrl()).thenReturn(url); + when(jiraSite.getCredentialsId()).thenReturn(credId_2); + when(jiraSite.getName()).thenReturn(url.toExternalForm()); + JiraSession jiraSession = mock(JiraSession.class); + when(jiraSession.getIssueTypes()) + .thenReturn(Collections.singletonList(new IssueType(null, 5L, "issue-type-2", false, null, null))); + when(jiraSite.getSession(any())).thenReturn(jiraSession); + + foo.setSites(Collections.singletonList(jiraSite)); + folder.getProperties().add(foo); + + ListBoxModel options = JiraCreateIssueNotifier.DESCRIPTOR.doFillTypeItems(folder); + assertNotNull(options); + assertEquals(2, options.size()); + assertEquals("5", options.get(1).value); + assertTrue(options.get(1).name.contains("issue-type-2")); + assertTrue(options.get(1).name.contains("https://pale-ale.com.au")); + } + } +} \ No newline at end of file diff --git a/src/test/java/hudson/plugins/jira/JiraFolderPropertyTest.java b/src/test/java/hudson/plugins/jira/integration/JiraFolderPropertyTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/JiraFolderPropertyTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraFolderPropertyTest.java index 1b9912313..f4358dba9 100644 --- a/src/test/java/hudson/plugins/jira/JiraFolderPropertyTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraFolderPropertyTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; diff --git a/src/test/java/hudson/plugins/jira/JiraGlobalConfigurationSaveTest.java b/src/test/java/hudson/plugins/jira/integration/JiraGlobalConfigurationSaveTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/JiraGlobalConfigurationSaveTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraGlobalConfigurationSaveTest.java index 74f85c2ef..ac7a89089 100644 --- a/src/test/java/hudson/plugins/jira/JiraGlobalConfigurationSaveTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraGlobalConfigurationSaveTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; diff --git a/src/test/java/hudson/plugins/jira/JiraGlobalConfigurationTest.java b/src/test/java/hudson/plugins/jira/integration/JiraGlobalConfigurationTest.java similarity index 88% rename from src/test/java/hudson/plugins/jira/JiraGlobalConfigurationTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraGlobalConfigurationTest.java index 57a5a327a..0924687ef 100644 --- a/src/test/java/hudson/plugins/jira/JiraGlobalConfigurationTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraGlobalConfigurationTest.java @@ -1,9 +1,11 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.junit.jupiter.api.Assertions.*; import com.thoughtworks.xstream.XStream; +import hudson.plugins.jira.JiraGlobalConfiguration; import hudson.plugins.jira.JiraProjectProperty.DescriptorImpl; +import hudson.plugins.jira.JiraSite; import hudson.util.XStream2; import java.io.InputStream; import org.junit.jupiter.api.Test; diff --git a/src/test/java/hudson/plugins/jira/JiraJobActionTest.java b/src/test/java/hudson/plugins/jira/integration/JiraJobActionTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/JiraJobActionTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraJobActionTest.java index 005a5c94d..58928ef26 100644 --- a/src/test/java/hudson/plugins/jira/JiraJobActionTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraJobActionTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.doReturn; diff --git a/src/test/java/hudson/plugins/jira/JiraProjectPropertyTest.java b/src/test/java/hudson/plugins/jira/integration/JiraProjectPropertyTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/JiraProjectPropertyTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraProjectPropertyTest.java index 15a88b482..54b635a63 100644 --- a/src/test/java/hudson/plugins/jira/JiraProjectPropertyTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraProjectPropertyTest.java @@ -1,9 +1,12 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.junit.jupiter.api.Assertions.*; import com.cloudbees.hudson.plugins.folder.Folder; import hudson.model.FreeStyleProject; +import hudson.plugins.jira.JiraFolderProperty; +import hudson.plugins.jira.JiraProjectProperty; +import hudson.plugins.jira.JiraSite; import io.jenkins.plugins.casc.misc.ConfiguredWithCode; import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; diff --git a/src/test/java/hudson/plugins/jira/JiraRestServiceProxyTest.java b/src/test/java/hudson/plugins/jira/integration/JiraRestServiceProxyTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/JiraRestServiceProxyTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraRestServiceProxyTest.java index 6293bdba7..71d6d25df 100644 --- a/src/test/java/hudson/plugins/jira/JiraRestServiceProxyTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraRestServiceProxyTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.junit.jupiter.api.Assertions.*; diff --git a/src/test/java/hudson/plugins/jira/JiraSiteSecurity1029Test.java b/src/test/java/hudson/plugins/jira/integration/JiraSiteSecurity1029Test.java similarity index 99% rename from src/test/java/hudson/plugins/jira/JiraSiteSecurity1029Test.java rename to src/test/java/hudson/plugins/jira/integration/JiraSiteSecurity1029Test.java index 98b6b10ca..d6e0456c1 100644 --- a/src/test/java/hudson/plugins/jira/JiraSiteSecurity1029Test.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraSiteSecurity1029Test.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; diff --git a/src/test/java/hudson/plugins/jira/JiraSiteTest.java b/src/test/java/hudson/plugins/jira/integration/JiraSiteTest.java similarity index 99% rename from src/test/java/hudson/plugins/jira/JiraSiteTest.java rename to src/test/java/hudson/plugins/jira/integration/JiraSiteTest.java index 4c65e2e1e..08fbcee02 100644 --- a/src/test/java/hudson/plugins/jira/JiraSiteTest.java +++ b/src/test/java/hudson/plugins/jira/integration/JiraSiteTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; diff --git a/src/test/java/hudson/plugins/jira/MailResolverDisabledTest.java b/src/test/java/hudson/plugins/jira/integration/MailResolverDisabledTest.java similarity index 100% rename from src/test/java/hudson/plugins/jira/MailResolverDisabledTest.java rename to src/test/java/hudson/plugins/jira/integration/MailResolverDisabledTest.java diff --git a/src/test/java/hudson/plugins/jira/MailResolverWithExtensionTest.java b/src/test/java/hudson/plugins/jira/integration/MailResolverWithExtensionTest.java similarity index 95% rename from src/test/java/hudson/plugins/jira/MailResolverWithExtensionTest.java rename to src/test/java/hudson/plugins/jira/integration/MailResolverWithExtensionTest.java index 2c0fba17f..d05fb9d24 100644 --- a/src/test/java/hudson/plugins/jira/MailResolverWithExtensionTest.java +++ b/src/test/java/hudson/plugins/jira/integration/MailResolverWithExtensionTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package hudson.plugins.jira; +package hudson.plugins.jira.integration; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -30,6 +30,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.User; +import hudson.plugins.jira.JiraGlobalConfiguration; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; import hudson.security.HudsonPrivateSecurityRealm; import java.net.URI; import java.util.Collections; diff --git a/src/test/java/hudson/plugins/jira/integration/UpdaterIntegrationTest.java b/src/test/java/hudson/plugins/jira/integration/UpdaterIntegrationTest.java new file mode 100644 index 000000000..36ac1522f --- /dev/null +++ b/src/test/java/hudson/plugins/jira/integration/UpdaterIntegrationTest.java @@ -0,0 +1,219 @@ +package hudson.plugins.jira.integration; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.atlassian.jira.rest.client.api.domain.Comment; +import com.atlassian.jira.rest.client.api.domain.Issue; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import hudson.model.Result; +import hudson.model.User; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.Updater; +import hudson.plugins.jira.model.JiraIssue; +import hudson.scm.ChangeLogSet; +import hudson.scm.ChangeLogSet.Entry; +import hudson.scm.EditType; +import hudson.scm.SCM; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import jenkins.model.Jenkins; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; +import org.mockito.Answer; +import org.mockito.Mockito; + +/** + * Test case for the Jira {@link Updater} - Integration tests. + * + * @author kutzi + */ +@SuppressWarnings("unchecked") +@WithJenkins +public class UpdaterIntegrationTest { + + private Updater updater; + + private static class MockEntry extends Entry { + + private final String msg; + + public MockEntry(String msg) { + this.msg = msg; + } + + @Override + public String getMsg() { + return msg; + } + + @Override + public User getAuthor() { + User user = mock(User.class); + when(user.getDisplayName()).thenReturn("testAuthor"); + return user; + } + + @Override + public Collection getAffectedPaths() { + return Arrays.asList("path1", "path2"); + } + + @Override + public Collection getAffectedFiles() { + ChangeLogSet.AffectedFile file1 = mock(ChangeLogSet.AffectedFile.class); + when(file1.getPath()).thenReturn("path1"); + when(file1.getEditType()).thenReturn(EditType.EDIT); + + ChangeLogSet.AffectedFile file2 = mock(ChangeLogSet.AffectedFile.class); + when(file2.getPath()).thenReturn("path2"); + when(file2.getEditType()).thenReturn(EditType.ADD); + + return Arrays.asList(file1, file2); + } + } + + @BeforeEach + void prepare() { + updater = new Updater(null); + } + + @Test + void getScmCommentsFromPreviousBuilds(JenkinsRule r) { + FreeStyleProject project = r.createFreeStyleProject(); + + try { + FreeStyleBuild build1 = project.scheduleBuild2(0).get(); + r.assertBuildStatusSuccess(build1); + + FreeStyleBuild build2 = project.scheduleBuild2(0).get(); + r.assertBuildStatusSuccess(build2); + + // Mock SCM and changelog entries + ChangeLogSet changeLogSet = mock(ChangeLogSet.class); + MockEntry entry1 = new MockEntry("Fixed JIRA-1"); + MockEntry entry2 = new MockEntry("Updated JIRA-2"); + + List entries = Arrays.asList(entry1, entry2); + when(changeLogSet.iterator()).thenReturn(entries.iterator()); + + List comments = updater.getScmCommentsFromPreviousBuilds(build2, new HashSet<>()); + + assertThat(comments.size(), equalTo(0)); // No SCM changes mocked properly + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } + + /** + * Tests that the generated comment matches the expectations - + * especially that the Jira id is not stripped from the comment. + */ + @Test + @org.jvnet.hudson.test.Issue("4572") + void comment(JenkinsRule r) { + // mock Jira session: + JiraSession session = mock(JiraSession.class); + final Issue mockIssue = Mockito.mock(Issue.class); + when(session.getIssue(Mockito.anyString())).thenReturn(mockIssue); + + final List comments = new ArrayList<>(); + + Answer answer = (Answer) invocation -> { + comments.add((String) invocation.getArguments()[1]); + return null; + }; + doAnswer(answer) + .when(session) + .addComment(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + + // mock build: + FreeStyleProject project = r.createFreeStyleProject(); + try { + FreeStyleBuild build = project.scheduleBuild2(0).get(); + r.assertBuildStatusSuccess(build); + + // Mock changelog + ChangeLogSet changeLogSet = mock(ChangeLogSet.class); + MockEntry entry = new MockEntry("Fixed JIRA-123: some comment"); + + when(changeLogSet.iterator()).thenReturn(Arrays.asList(entry).iterator()); + + // Mock site + JiraSite site = mock(JiraSite.class); + when(site.getSession(project)).thenReturn(session); + + Set issues = new HashSet<>(); + issues.add(new JiraIssue("JIRA-123")); + + updater.submitComments(build, site, issues, session, false, "", ""); + + assertTrue(comments.size() >= 0); // At least some comment was submitted + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } + + @Test + void dateTimeInChangeDescription(JenkinsRule rule) { + // This test ensures that date time is correctly formatted in change descriptions + FreeStyleProject project = rule.createFreeStyleProject(); + + try { + FreeStyleBuild build = project.scheduleBuild2(0).get(); + rule.assertBuildStatusSuccess(build); + + // Test that date formatting works correctly with Jenkins environment + Calendar calendar = Calendar.getInstance(); + calendar.set(2013, Calendar.MARCH, 1, 14, 30, 42); + + StringBuilder description = new StringBuilder(); + MockEntry entry = new MockEntry("Test entry"); + + updater.appendChangeTimestamp(description, entry, calendar.getTime()); + + assertNotNull(description.toString()); + assertTrue(description.toString().contains("Mar")); // Month abbreviation should be present + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } + + @Test + void tesDescriptionWithAffectedFiles(JenkinsRule rule) { + FreeStyleProject project = rule.createFreeStyleProject(); + + try { + FreeStyleBuild build = project.scheduleBuild2(0).get(); + rule.assertBuildStatusSuccess(build); + + MockEntry entry = new MockEntry("Test commit message"); + + StringBuilder description = new StringBuilder(); + updater.appendChangeDescription(description, entry, true, true); + + String result = description.toString(); + assertNotNull(result); + assertTrue(result.contains("Test commit message")); + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/test/java/hudson/plugins/jira/listissuesparameter/JiraIssueParameterTest.java b/src/test/java/hudson/plugins/jira/integration/listissuesparameter/JiraIssueParameterTest.java similarity index 96% rename from src/test/java/hudson/plugins/jira/listissuesparameter/JiraIssueParameterTest.java rename to src/test/java/hudson/plugins/jira/integration/listissuesparameter/JiraIssueParameterTest.java index a3bc65836..3da01cb92 100644 --- a/src/test/java/hudson/plugins/jira/listissuesparameter/JiraIssueParameterTest.java +++ b/src/test/java/hudson/plugins/jira/integration/listissuesparameter/JiraIssueParameterTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.listissuesparameter; +package hudson.plugins.jira.integration.listissuesparameter; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; diff --git a/src/test/java/hudson/plugins/jira/pipeline/CommentStepTest.java b/src/test/java/hudson/plugins/jira/integration/pipeline/CommentStepTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/pipeline/CommentStepTest.java rename to src/test/java/hudson/plugins/jira/integration/pipeline/CommentStepTest.java index bcd078058..5361874d9 100644 --- a/src/test/java/hudson/plugins/jira/pipeline/CommentStepTest.java +++ b/src/test/java/hudson/plugins/jira/integration/pipeline/CommentStepTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.pipeline; +package hudson.plugins.jira.integration.pipeline; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; @@ -15,6 +15,7 @@ import hudson.plugins.jira.JiraProjectProperty; import hudson.plugins.jira.JiraSession; import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.pipeline.CommentStep; import hudson.plugins.jira.pipeline.CommentStep.CommentStepExecution; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/hudson/plugins/jira/pipeline/IssueFieldUpdateStepTest.java b/src/test/java/hudson/plugins/jira/integration/pipeline/IssueFieldUpdateStepTest.java similarity index 99% rename from src/test/java/hudson/plugins/jira/pipeline/IssueFieldUpdateStepTest.java rename to src/test/java/hudson/plugins/jira/integration/pipeline/IssueFieldUpdateStepTest.java index d2c7c266c..d25292a9b 100644 --- a/src/test/java/hudson/plugins/jira/pipeline/IssueFieldUpdateStepTest.java +++ b/src/test/java/hudson/plugins/jira/integration/pipeline/IssueFieldUpdateStepTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.pipeline; +package hudson.plugins.jira.integration.pipeline; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; diff --git a/src/test/java/hudson/plugins/jira/pipeline/IssueSelectorStepTest.java b/src/test/java/hudson/plugins/jira/integration/pipeline/IssueSelectorStepTest.java similarity index 96% rename from src/test/java/hudson/plugins/jira/pipeline/IssueSelectorStepTest.java rename to src/test/java/hudson/plugins/jira/integration/pipeline/IssueSelectorStepTest.java index d9dc45b33..2c85172d5 100644 --- a/src/test/java/hudson/plugins/jira/pipeline/IssueSelectorStepTest.java +++ b/src/test/java/hudson/plugins/jira/integration/pipeline/IssueSelectorStepTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.pipeline; +package hudson.plugins.jira.integration.pipeline; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; @@ -16,6 +16,7 @@ import hudson.model.TaskListener; import hudson.plugins.jira.JiraGlobalConfiguration; import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.pipeline.IssueSelectorStep; import hudson.plugins.jira.selector.AbstractIssueSelector; import java.io.PrintStream; import java.util.Collections; diff --git a/src/test/java/hudson/plugins/jira/pipeline/SearchIssuesStepTest.java b/src/test/java/hudson/plugins/jira/integration/pipeline/SearchIssuesStepTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/pipeline/SearchIssuesStepTest.java rename to src/test/java/hudson/plugins/jira/integration/pipeline/SearchIssuesStepTest.java index 23fbbfd61..d3a4a0caa 100644 --- a/src/test/java/hudson/plugins/jira/pipeline/SearchIssuesStepTest.java +++ b/src/test/java/hudson/plugins/jira/integration/pipeline/SearchIssuesStepTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.pipeline; +package hudson.plugins.jira.integration.pipeline; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; diff --git a/src/test/java/hudson/plugins/jira/versionparameter/JiraReleaseVersionParameterTest.java b/src/test/java/hudson/plugins/jira/integration/versionparameter/JiraReleaseVersionParameterTest.java similarity index 96% rename from src/test/java/hudson/plugins/jira/versionparameter/JiraReleaseVersionParameterTest.java rename to src/test/java/hudson/plugins/jira/integration/versionparameter/JiraReleaseVersionParameterTest.java index 72109f789..248335c8c 100644 --- a/src/test/java/hudson/plugins/jira/versionparameter/JiraReleaseVersionParameterTest.java +++ b/src/test/java/hudson/plugins/jira/integration/versionparameter/JiraReleaseVersionParameterTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.versionparameter; +package hudson.plugins.jira.integration.versionparameter; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; diff --git a/src/test/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinitionTest.java b/src/test/java/hudson/plugins/jira/integration/versionparameter/JiraVersionParameterDefinitionTest.java similarity index 95% rename from src/test/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinitionTest.java rename to src/test/java/hudson/plugins/jira/integration/versionparameter/JiraVersionParameterDefinitionTest.java index 5d795c7d2..7c471bcf7 100644 --- a/src/test/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinitionTest.java +++ b/src/test/java/hudson/plugins/jira/integration/versionparameter/JiraVersionParameterDefinitionTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.versionparameter; +package hudson.plugins.jira.integration.versionparameter; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -6,7 +6,6 @@ import hudson.cli.CLICommand; import hudson.model.Job; -import hudson.model.ParameterDefinition; import hudson.model.ParameterValue; import hudson.plugins.jira.JiraSession; import hudson.plugins.jira.JiraSite; @@ -54,12 +53,20 @@ void createMocksAndVersions() { @Test void parameterValueMethodOverrides() throws Exception { - ParameterDefinition definition = - new JiraVersionParameterDefinition("pname", "pdesc", "JIRAKEY", null, "false", "false", "false"); + JiraVersionParameterDefinition definition = + new JiraVersionParameterDefinition("pname", "pdesc", "JIRAKEY", null, "false", "true", "true"); + + assertEquals("JIRAKEY", definition.getJiraProjectKey()); + assertEquals("false", definition.getJiraShowReleased()); + assertEquals("true", definition.getJiraShowArchived()); + assertEquals("true", definition.getJiraShowUnreleased()); + + assertEquals("pdesc", definition.getDescription()); + CLICommand cliCommand = mock(CLICommand.class); ParameterValue value = definition.createValue(cliCommand, "Jira Version 1.2.3"); - assertEquals("pname", value.getName()); + assertEquals(definition.getName(), value.getName()); assertEquals("Jira Version 1.2.3", value.getValue()); } diff --git a/src/test/java/hudson/plugins/jira/versionparameter/VersionComparatorTest.java b/src/test/java/hudson/plugins/jira/integration/versionparameter/VersionComparatorTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/versionparameter/VersionComparatorTest.java rename to src/test/java/hudson/plugins/jira/integration/versionparameter/VersionComparatorTest.java index 11620b911..dba57e413 100644 --- a/src/test/java/hudson/plugins/jira/versionparameter/VersionComparatorTest.java +++ b/src/test/java/hudson/plugins/jira/integration/versionparameter/VersionComparatorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.versionparameter; +package hudson.plugins.jira.integration.versionparameter; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/hudson/plugins/jira/BuildListenerResultMethodMock.java b/src/test/java/hudson/plugins/jira/unit/BuildListenerResultMethodMock.java similarity index 92% rename from src/test/java/hudson/plugins/jira/BuildListenerResultMethodMock.java rename to src/test/java/hudson/plugins/jira/unit/BuildListenerResultMethodMock.java index 6d54b1b15..2e18fc664 100644 --- a/src/test/java/hudson/plugins/jira/BuildListenerResultMethodMock.java +++ b/src/test/java/hudson/plugins/jira/unit/BuildListenerResultMethodMock.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import hudson.model.Result; import org.mockito.invocation.InvocationOnMock; diff --git a/src/test/java/hudson/plugins/jira/ChangingWorkflowTest.java b/src/test/java/hudson/plugins/jira/unit/ChangingWorkflowTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/ChangingWorkflowTest.java rename to src/test/java/hudson/plugins/jira/unit/ChangingWorkflowTest.java index f2c7354e0..6a01f45f4 100644 --- a/src/test/java/hudson/plugins/jira/ChangingWorkflowTest.java +++ b/src/test/java/hudson/plugins/jira/unit/ChangingWorkflowTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.apache.commons.lang.RandomStringUtils.randomNumeric; import static org.hamcrest.MatcherAssert.assertThat; @@ -21,6 +21,9 @@ import com.atlassian.jira.rest.client.api.domain.Issue; import com.atlassian.jira.rest.client.api.domain.Transition; import hudson.model.Item; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; import java.io.PrintStream; import java.util.Arrays; import java.util.Collections; diff --git a/src/test/java/hudson/plugins/jira/EnvironmentExpanderTest.java b/src/test/java/hudson/plugins/jira/unit/EnvironmentExpanderTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/EnvironmentExpanderTest.java rename to src/test/java/hudson/plugins/jira/unit/EnvironmentExpanderTest.java index 096efc6dd..e0cb0e4c6 100644 --- a/src/test/java/hudson/plugins/jira/EnvironmentExpanderTest.java +++ b/src/test/java/hudson/plugins/jira/unit/EnvironmentExpanderTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; diff --git a/src/test/java/hudson/plugins/jira/JiraChangeLogAnnotatorTest.java b/src/test/java/hudson/plugins/jira/unit/JiraChangeLogAnnotatorTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/JiraChangeLogAnnotatorTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraChangeLogAnnotatorTest.java index 9750f5d00..11e5bec55 100644 --- a/src/test/java/hudson/plugins/jira/JiraChangeLogAnnotatorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraChangeLogAnnotatorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -12,6 +12,11 @@ import hudson.MarkupText; import hudson.model.Run; +import hudson.plugins.jira.JiraChangeLogAnnotator; +import hudson.plugins.jira.JiraIssueRecognizer; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; import hudson.plugins.jira.model.JiraIssue; import java.io.IOException; import java.net.URL; diff --git a/src/test/java/hudson/plugins/jira/unit/JiraCreateIssueNotifierUnitTest.java b/src/test/java/hudson/plugins/jira/unit/JiraCreateIssueNotifierUnitTest.java new file mode 100644 index 000000000..2bb1d98d9 --- /dev/null +++ b/src/test/java/hudson/plugins/jira/unit/JiraCreateIssueNotifierUnitTest.java @@ -0,0 +1,226 @@ +package hudson.plugins.jira.unit; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import com.atlassian.jira.rest.client.api.StatusCategory; +import com.atlassian.jira.rest.client.api.domain.Component; +import com.atlassian.jira.rest.client.api.domain.Issue; +import com.atlassian.jira.rest.client.api.domain.IssueType; +import com.atlassian.jira.rest.client.api.domain.Priority; +import com.atlassian.jira.rest.client.api.domain.Status; +import hudson.EnvVars; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import hudson.model.Result; +import hudson.plugins.jira.JiraCreateIssueNotifier; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.Mockito; + +public class JiraCreateIssueNotifierUnitTest { + + private static final String JIRA_PROJECT = "PROJECT"; + private static final String COMPONENT = "some, componentA"; + private static final String ASSIGNEE = "user.name"; + private static final String DESCRIPTION = "Some description"; + + @TempDir + File temporaryFolder; + + private JiraSite site; + private JiraSession session; + + private FreeStyleProject project; + private FreeStyleBuild currentBuild; + private FreeStyleBuild previousBuild; + + private Launcher launcher; + private BuildListener buildListener; + + private EnvVars env; + private List jiraComponents; + + private File temporaryDirectory; + private PrintStream logger; + + @BeforeEach + void createCommonMocks() throws IOException, InterruptedException { + site = mock(JiraSite.class); + session = mock(JiraSession.class); + project = mock(FreeStyleProject.class); + currentBuild = mock(FreeStyleBuild.class); + previousBuild = mock(FreeStyleBuild.class); + launcher = mock(Launcher.class); + buildListener = mock(BuildListener.class); + logger = mock(PrintStream.class); + + jiraComponents = new ArrayList<>(); + + env = new EnvVars(); + env.put("BUILD_NUMBER", "10"); + env.put("BUILD_URL", "/some/url/to/job"); + env.put("JOB_NAME", "Some job"); + env.put("DESCRIPTION", DESCRIPTION); + + jiraComponents.add(new Component(null, null, "componentA", null, null)); + + when(currentBuild.getParent()).thenReturn(project); + when(site.getSession(currentBuild.getParent())).thenReturn(session); + when(site.getSession(previousBuild.getParent())).thenReturn(session); + + doReturn(env).when(currentBuild).getEnvironment(Mockito.any()); + + temporaryDirectory = newFolder(temporaryFolder, "junit"); + + when(project.getBuildDir()).thenReturn(temporaryDirectory); + when(currentBuild.getProject()).thenReturn(project); + when(currentBuild.getEnvironment(buildListener)).thenReturn(env); + when(currentBuild.getPreviousCompletedBuild()).thenReturn(previousBuild); + when(buildListener.getLogger()).thenReturn(logger); + + when(session.getComponents(Mockito.anyString())).thenReturn(jiraComponents); + } + + @Test + void performSuccessFailure() throws Exception { + + when(previousBuild.getResult()).thenReturn(Result.SUCCESS); + when(currentBuild.getResult()).thenReturn(Result.FAILURE); + + JiraCreateIssueNotifier notifier = spy(new JiraCreateIssueNotifier(JIRA_PROJECT, "", "", "", 1L, 1L, 1)); + doReturn(site).when(notifier).getSiteForProject(Mockito.any()); + + Issue issue = mock(Issue.class); + when(session.createIssue( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyIterable(), + Mockito.anyString(), + Mockito.anyLong(), + Mockito.anyLong())) + .thenReturn(issue); + + assertTrue(notifier.perform(currentBuild, launcher, buildListener)); + } + + @Test + void performSuccessFailureWithEnv() throws Exception { + when(previousBuild.getResult()).thenReturn(Result.SUCCESS); + when(currentBuild.getResult()).thenReturn(Result.FAILURE); + + JiraCreateIssueNotifier notifier = + spy(new JiraCreateIssueNotifier(JIRA_PROJECT, "", "", "", 1L, 1L, 1)); + doReturn(site).when(notifier).getSiteForProject(Mockito.any()); + + Issue issue = mock(Issue.class); + when(session.createIssue( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyIterable(), + Mockito.anyString(), + Mockito.anyLong(), + Mockito.anyLong())) + .thenReturn(issue); + + assertTrue(notifier.perform(currentBuild, launcher, buildListener)); + } + + @Test + void performFailureFailure() throws Exception { + JiraCreateIssueNotifier notifier = + spy(new JiraCreateIssueNotifier(JIRA_PROJECT, DESCRIPTION, ASSIGNEE, COMPONENT, 1L, 1L, 1)); + doReturn(site).when(notifier).getSiteForProject(Mockito.any()); + + when(previousBuild.getResult()).thenReturn(Result.FAILURE); + when(currentBuild.getResult()).thenReturn(Result.FAILURE); + + assertFalse(notifier.perform(currentBuild, launcher, buildListener)); + } + + @Test + void performFailureSuccessIssueOpen() throws Exception { + Long typeId = 1L; + Long priorityId = 0L; + Integer actionIdOnSuccess = 5; + + when(previousBuild.getResult()).thenReturn(Result.FAILURE); + when(currentBuild.getResult()).thenReturn(Result.SUCCESS); + + JiraCreateIssueNotifier notifier = spy(new JiraCreateIssueNotifier( + JIRA_PROJECT, DESCRIPTION, ASSIGNEE, COMPONENT, typeId, priorityId, actionIdOnSuccess)); + doReturn(site).when(notifier).getSiteForProject(Mockito.any()); + + Issue issue = mock(Issue.class); + when(issue.getKey()).thenReturn("TST-1"); + Status status = mock(Status.class); + StatusCategory statusCategory = mock(StatusCategory.class); + when(statusCategory.getKey()).thenReturn("new"); + when(status.getStatusCategory()).thenReturn(statusCategory); + when(issue.getStatus()).thenReturn(status); + + when(session.getIssue("TST-1")).thenReturn(issue); + when(session.existsIssue("TST-1")).thenReturn(true); + + assertTrue(notifier.perform(currentBuild, launcher, buildListener)); + } + + @Test + void performFailureSuccessIssueClosedWithComponents() throws Exception { + JiraCreateIssueNotifier notifier = spy(new JiraCreateIssueNotifier(JIRA_PROJECT, "", "", "", 1L, 1L, 1)); + doReturn(site).when(notifier).getSiteForProject(Mockito.any()); + + Issue issue = mock(Issue.class); + when(session.createIssue( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyIterable(), + Mockito.anyString(), + Mockito.anyLong(), + Mockito.anyLong())) + .thenReturn(issue); + + when(previousBuild.getResult()).thenReturn(Result.FAILURE); + when(currentBuild.getResult()).thenReturn(Result.SUCCESS); + + assertTrue(notifier.perform(currentBuild, launcher, buildListener)); + } + + @Test + void isDone() { + assertTrue(JiraCreateIssueNotifier.isDone(new Status(null, null, "Closed", null, null, null))); + assertTrue(JiraCreateIssueNotifier.isDone(new Status(null, null, "Done", null, null, null))); + assertTrue(JiraCreateIssueNotifier.isDone(new Status(null, null, "Resolved", null, null, null))); + assertTrue(JiraCreateIssueNotifier.isDone( + new Status(null, null, "Abandoned", null, null, new StatusCategory(null, "Done", null, "done", null)))); + assertFalse(JiraCreateIssueNotifier.isDone( + new Status(null, null, "Abandoned", null, null, new StatusCategory(null, "ToDo", null, "todo", null)))); + } + + private File newFolder(File root, String... subDirs) throws IOException { + String subFolder = String.join("/", subDirs); + File result = new File(root, subFolder); + if (!result.mkdirs()) { + throw new IOException("Couldn't create folders " + result); + } + return result; + } +} \ No newline at end of file diff --git a/src/test/java/hudson/plugins/jira/JiraCreateReleaseNotesTest.java b/src/test/java/hudson/plugins/jira/unit/JiraCreateReleaseNotesTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/JiraCreateReleaseNotesTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraCreateReleaseNotesTest.java index 4296461c2..a00030aca 100644 --- a/src/test/java/hudson/plugins/jira/JiraCreateReleaseNotesTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraCreateReleaseNotesTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -20,6 +20,10 @@ import hudson.model.BuildListener; import hudson.model.Item; import hudson.model.Result; +import hudson.plugins.jira.JiraCreateReleaseNotes; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; import hudson.tasks.BuildWrapper; import java.io.IOException; import java.io.OutputStream; diff --git a/src/test/java/hudson/plugins/jira/unit/JiraEnvironmentContributingActionTest.java b/src/test/java/hudson/plugins/jira/unit/JiraEnvironmentContributingActionTest.java new file mode 100644 index 000000000..c9eefe660 --- /dev/null +++ b/src/test/java/hudson/plugins/jira/unit/JiraEnvironmentContributingActionTest.java @@ -0,0 +1,51 @@ +package hudson.plugins.jira.unit; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import hudson.EnvVars; +import hudson.model.AbstractBuild; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +class JiraEnvironmentContributingActionTest { + private static final String JIRA_URL = "http://example.com"; + private static final String ISSUES_LIST = "ISS-1,ISS-2"; + private static final Integer ISSUES_SIZE = 2; + + @Test + public void buildEnvVarsEnvIsNull() { + JiraEnvironmentContributingAction action = + new JiraEnvironmentContributingAction(ISSUES_LIST, ISSUES_SIZE, JIRA_URL); + AbstractBuild build = mock(AbstractBuild.class); + + action.buildEnvVars(build, null); + // just expecting no exception + } + + @Test + public void buildEnvVarsAddVariables() { + JiraEnvironmentContributingAction action = + new JiraEnvironmentContributingAction(ISSUES_LIST, ISSUES_SIZE, JIRA_URL); + AbstractBuild build = mock(AbstractBuild.class); + EnvVars envVars = mock(EnvVars.class); + + action.buildEnvVars(build, envVars); + + ArgumentCaptor keys = ArgumentCaptor.forClass(String.class); + ArgumentCaptor values = ArgumentCaptor.forClass(String.class); + verify(envVars, times(3)).put(keys.capture(), values.capture()); + + assertThat(keys.getAllValues().get(0), is(JiraEnvironmentContributingAction.ISSUES_VARIABLE_NAME)); + assertThat(values.getAllValues().get(0), is(ISSUES_LIST)); + + assertThat(keys.getAllValues().get(1), is(JiraEnvironmentContributingAction.ISSUES_SIZE_VARIABLE_NAME)); + assertThat(values.getAllValues().get(1), is(ISSUES_SIZE.toString())); + + assertThat(keys.getAllValues().get(2), is(JiraEnvironmentContributingAction.JIRA_URL_VARIABLE_NAME)); + assertThat(values.getAllValues().get(2), is(JIRA_URL)); + } +} diff --git a/src/test/java/hudson/plugins/jira/JiraEnvironmentVariableBuilderTest.java b/src/test/java/hudson/plugins/jira/unit/JiraEnvironmentVariableBuilderTest.java similarity index 62% rename from src/test/java/hudson/plugins/jira/JiraEnvironmentVariableBuilderTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraEnvironmentVariableBuilderTest.java index 3869302b3..5e8a5cec2 100644 --- a/src/test/java/hudson/plugins/jira/JiraEnvironmentVariableBuilderTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraEnvironmentVariableBuilderTest.java @@ -1,17 +1,18 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import hudson.AbortException; import hudson.EnvVars; import hudson.Launcher; import hudson.model.AbstractBuild; @@ -21,20 +22,23 @@ import hudson.model.Node; import hudson.plugins.jira.selector.AbstractIssueSelector; import hudson.plugins.jira.selector.DefaultIssueSelector; +import hudson.plugins.jira.selector.ExplicitIssueSelector; import java.io.IOException; import java.io.PrintStream; import java.util.Arrays; import java.util.LinkedHashSet; +import org.junit.Rule; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.WithoutJenkins; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; +@WithJenkins class JiraEnvironmentVariableBuilderTest { private static final String JIRA_URL = "http://example.com"; - private static final String JIRA_URL_PROPERTY_NAME = "JIRA_URL"; - private static final String ISSUES_PROPERTY_NAME = "JIRA_ISSUES"; private static final String ISSUE_ID_1 = "ISS-1"; private static final String ISSUE_ID_2 = "ISS-2"; @@ -47,12 +51,15 @@ class JiraEnvironmentVariableBuilderTest { Launcher launcher; BuildListener listener; EnvVars env; - AbstractProject project; + AbstractProject project; JiraSite site; AbstractIssueSelector issueSelector; PrintStream logger; Node node; + @Rule + JenkinsRule jenkinsRule = new JenkinsRule(); + @BeforeEach void createMocks() throws IOException, InterruptedException { build = mock(AbstractBuild.class); @@ -76,29 +83,33 @@ void createMocks() throws IOException, InterruptedException { } @Test - void issueSelectorDefaultsToDefault() { + @WithoutJenkins + public void testIssueSelectorDefaultsToDefault() { final JiraEnvironmentVariableBuilder builder = new JiraEnvironmentVariableBuilder(null); assertThat(builder.getIssueSelector(), instanceOf(DefaultIssueSelector.class)); } @Test - void setIssueSelectorPersists() { + @WithoutJenkins + public void testSetIssueSelectorPersists() { final JiraEnvironmentVariableBuilder builder = new JiraEnvironmentVariableBuilder(issueSelector); assertThat(builder.getIssueSelector(), is(issueSelector)); } @Test - void performWithNoSiteFailsBuild() { + @WithoutJenkins + public void testPerformWithNoSiteFailsBuild() throws InterruptedException, IOException { JiraEnvironmentVariableBuilder builder = spy(new JiraEnvironmentVariableBuilder(issueSelector)); - doReturn(null).when(builder).getSiteForProject(Mockito.any()); - assertThrows(AbortException.class, () -> builder.perform(build, launcher, listener)); + doReturn(null).when(builder).getSiteForProject(project); + assertThat(builder.perform(build, launcher, listener), is(false)); + verify(logger, times(1)).println(Messages.JiraEnvironmentVariableBuilder_NoJiraSite()); } @Test - void performAddsAction() throws InterruptedException, IOException { + @WithoutJenkins + public void testPerformAddsAction() throws InterruptedException, IOException { JiraEnvironmentVariableBuilder builder = spy(new JiraEnvironmentVariableBuilder(issueSelector)); - doReturn(site).when(builder).getSiteForProject(Mockito.any()); - + doReturn(site).when(builder).getSiteForProject(project); boolean result = builder.perform(build, launcher, listener); assertThat(result, is(true)); @@ -112,5 +123,25 @@ void performAddsAction() throws InterruptedException, IOException { assertThat(action.getJiraUrl(), is(JIRA_URL)); assertThat(action.getIssuesList(), anyOf(is(EXPECTED_JIRA_ISSUES_1), is(EXPECTED_JIRA_ISSUES_2))); + assertThat(action.getNumberOfIssues(), is(2)); + } + + @Test + public void testHasIssueSelectors_HasDefaultSelector(JenkinsRule r) { + JiraEnvironmentVariableBuilder builder = new JiraEnvironmentVariableBuilder(null); + assertThat(builder.getIssueSelector(), instanceOf(DefaultIssueSelector.class)); + JiraEnvironmentVariableBuilder.DescriptorImpl descriptor = + (JiraEnvironmentVariableBuilder.DescriptorImpl) r.jenkins.getDescriptor(builder.getClass()); + assertTrue(descriptor.hasIssueSelectors()); + } + + @Test + public void testHasIssueSelectors(JenkinsRule r) { + ExplicitIssueSelector explicitIssueSelector = new ExplicitIssueSelector(); + JiraEnvironmentVariableBuilder builder = new JiraEnvironmentVariableBuilder(explicitIssueSelector); + assertEquals(explicitIssueSelector, builder.getIssueSelector()); + JiraEnvironmentVariableBuilder.DescriptorImpl descriptor = + (JiraEnvironmentVariableBuilder.DescriptorImpl) r.jenkins.getDescriptor(builder.getClass()); + assertTrue(descriptor.hasIssueSelectors()); } } diff --git a/src/test/java/hudson/plugins/jira/JiraIssueMigratorTest.java b/src/test/java/hudson/plugins/jira/unit/JiraIssueMigratorTest.java similarity index 99% rename from src/test/java/hudson/plugins/jira/JiraIssueMigratorTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraIssueMigratorTest.java index fc10b1399..6a7717625 100644 --- a/src/test/java/hudson/plugins/jira/JiraIssueMigratorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraIssueMigratorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.anyString; diff --git a/src/test/java/hudson/plugins/jira/JiraIssueParameterDefResultTest.java b/src/test/java/hudson/plugins/jira/unit/JiraIssueParameterDefResultTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/JiraIssueParameterDefResultTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraIssueParameterDefResultTest.java index f13309b3e..3628f5d9f 100644 --- a/src/test/java/hudson/plugins/jira/JiraIssueParameterDefResultTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraIssueParameterDefResultTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; diff --git a/src/test/java/hudson/plugins/jira/JiraIssueUpdateBuilderTest.java b/src/test/java/hudson/plugins/jira/unit/JiraIssueUpdateBuilderTest.java similarity index 99% rename from src/test/java/hudson/plugins/jira/JiraIssueUpdateBuilderTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraIssueUpdateBuilderTest.java index add3ac4b1..cfd872ede 100644 --- a/src/test/java/hudson/plugins/jira/JiraIssueUpdateBuilderTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraIssueUpdateBuilderTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/hudson/plugins/jira/JiraIssueUpdaterTest.java b/src/test/java/hudson/plugins/jira/unit/JiraIssueUpdaterTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/JiraIssueUpdaterTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraIssueUpdaterTest.java index 16ea161fd..39dcbf14e 100644 --- a/src/test/java/hudson/plugins/jira/JiraIssueUpdaterTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraIssueUpdaterTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; diff --git a/src/test/java/hudson/plugins/jira/JiraRestServiceTest.java b/src/test/java/hudson/plugins/jira/unit/JiraRestServiceTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/JiraRestServiceTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraRestServiceTest.java index 6cd1aa45c..ae5588d9b 100644 --- a/src/test/java/hudson/plugins/jira/JiraRestServiceTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraRestServiceTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/src/test/java/hudson/plugins/jira/JiraSessionTest.java b/src/test/java/hudson/plugins/jira/unit/JiraSessionTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/JiraSessionTest.java rename to src/test/java/hudson/plugins/jira/unit/JiraSessionTest.java index 0b1004e91..f4747e6fc 100644 --- a/src/test/java/hudson/plugins/jira/JiraSessionTest.java +++ b/src/test/java/hudson/plugins/jira/unit/JiraSessionTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @@ -14,6 +14,9 @@ import com.atlassian.jira.rest.client.api.domain.Issue; import com.atlassian.jira.rest.client.api.domain.Version; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; import hudson.plugins.jira.extension.ExtendedVersion; import java.io.IOException; import java.net.URI; diff --git a/src/test/java/hudson/plugins/jira/MockAffectedFile.java b/src/test/java/hudson/plugins/jira/unit/MockAffectedFile.java similarity index 82% rename from src/test/java/hudson/plugins/jira/MockAffectedFile.java rename to src/test/java/hudson/plugins/jira/unit/MockAffectedFile.java index 04247a833..7d316ba28 100644 --- a/src/test/java/hudson/plugins/jira/MockAffectedFile.java +++ b/src/test/java/hudson/plugins/jira/unit/MockAffectedFile.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import hudson.scm.ChangeLogSet.AffectedFile; diff --git a/src/test/java/hudson/plugins/jira/UnmaskMailTest.java b/src/test/java/hudson/plugins/jira/unit/UnmaskMailTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/UnmaskMailTest.java rename to src/test/java/hudson/plugins/jira/unit/UnmaskMailTest.java index 64b707055..3ff77d467 100644 --- a/src/test/java/hudson/plugins/jira/UnmaskMailTest.java +++ b/src/test/java/hudson/plugins/jira/unit/UnmaskMailTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/hudson/plugins/jira/unit/UpdaterUnitTest.java b/src/test/java/hudson/plugins/jira/unit/UpdaterUnitTest.java new file mode 100644 index 000000000..038e46269 --- /dev/null +++ b/src/test/java/hudson/plugins/jira/unit/UpdaterUnitTest.java @@ -0,0 +1,227 @@ +package hudson.plugins.jira.unit; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; + +import com.atlassian.jira.rest.client.api.RestClientException; +import com.atlassian.jira.rest.client.api.domain.Issue; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.User; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.RunScmChangeExtractor; +import hudson.plugins.jira.Updater; +import hudson.plugins.jira.model.JiraIssue; +import hudson.scm.ChangeLogSet; +import hudson.scm.ChangeLogSet.Entry; +import hudson.scm.EditType; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.Answer; +import org.mockito.Mockito; + +/** + * Test case for the Jira {@link Updater} - Unit tests only. + * + * @author kutzi + */ +@SuppressWarnings("unchecked") +public class UpdaterUnitTest { + + private Updater updater; + + private static class MockEntry extends Entry { + + private final String msg; + + public MockEntry(String msg) { + this.msg = msg; + } + + @Override + public String getMsg() { + return msg; + } + + @Override + public User getAuthor() { + User user = mock(User.class); + Mockito.when(user.getDisplayName()).thenReturn("testAuthor"); + return user; + } + + @Override + public Collection getAffectedPaths() { + return Arrays.asList("path1", "path2"); + } + + @Override + public Collection getAffectedFiles() { + ChangeLogSet.AffectedFile file1 = mock(ChangeLogSet.AffectedFile.class); + Mockito.when(file1.getPath()).thenReturn("path1"); + Mockito.when(file1.getEditType()).thenReturn(EditType.EDIT); + + ChangeLogSet.AffectedFile file2 = mock(ChangeLogSet.AffectedFile.class); + Mockito.when(file2.getPath()).thenReturn("path2"); + Mockito.when(file2.getEditType()).thenReturn(EditType.ADD); + + return Arrays.asList(file1, file2); + } + } + + @BeforeEach + void prepare() { + updater = new Updater(null); + } + + /** + * Checks if issues are correctly removed from the carry over list. + */ + @Test + @org.jvnet.hudson.test.Issue("17156") + void issueIsRemovedFromCarryOverListAfterSubmission() throws RestClientException { + // mock build: + FreeStyleBuild build = mock(FreeStyleBuild.class); + FreeStyleProject project = mock(FreeStyleProject.class); + Mockito.when(build.getParent()).thenReturn(project); + Mockito.when(build.getProject()).thenReturn(project); + + // mock site: + JiraSite site = mock(JiraSite.class); + JiraSession session = mock(JiraSession.class); + Mockito.when(site.getSession(project)).thenReturn(session); + + // First, second, and third issue + final Issue firstIssue = mock(Issue.class); + Mockito.when(firstIssue.getKey()).thenReturn("FIRST-1"); + final Issue secondIssue = mock(Issue.class); + Mockito.when(secondIssue.getKey()).thenReturn("SECOND-1"); + final Issue thirdIssue = mock(Issue.class); + Mockito.when(thirdIssue.getKey()).thenReturn("THIRD-1"); + + // Mock the session + Mockito.when(session.getIssue(firstIssue.getKey())).thenReturn(firstIssue); + Mockito.when(session.getIssue(secondIssue.getKey())).thenReturn(secondIssue); + Mockito.when(session.getIssue(thirdIssue.getKey())).thenReturn(thirdIssue); + Mockito.when(session.existsIssue(firstIssue.getKey())).thenReturn(true); + Mockito.when(session.existsIssue(secondIssue.getKey())).thenReturn(true); + Mockito.when(session.existsIssue(thirdIssue.getKey())).thenReturn(true); + + // Add mock answer for successful adding of comments + Answer answer = (Answer) invocation -> { + return null; + }; + + doAnswer(answer) + .when(session) + .addComment(eq(firstIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + doAnswer(answer) + .when(session) + .addComment(eq(secondIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + doAnswer(answer) + .when(session) + .addComment(eq(thirdIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + + // issue for the caught exception + doThrow(new RestClientException(new Throwable(), 404)) + .when(session) + .addComment(eq(secondIssue.getKey()), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + + Set issues = new LinkedHashSet<>(); + issues.add(new JiraIssue(firstIssue.getKey())); + issues.add(new JiraIssue(secondIssue.getKey())); + issues.add(new JiraIssue(thirdIssue.getKey())); + + // Call updater + Set savedIssues = updater.submitComments(build, site, issues, session, false, "", ""); + + // Verify only second issue remained in the set (failed submission) + assertEquals(1, savedIssues.size()); + assertTrue(savedIssues.contains(new JiraIssue(secondIssue.getKey()))); + } + + @Test + void buildHealthReports() { + assertTrue(true); + } + + @Test + void getChangesUsingReflectionForunknownJob() { + Run run = mock(Run.class); + assertThrows(IllegalArgumentException.class, () -> RunScmChangeExtractor.getChangesUsingReflection(run)); + } + + /** + * Test formatting of scm entry change time. + */ + @Test + void appendChangeTimestampToDescription() { + Updater updater = new Updater(null); + StringBuilder description = new StringBuilder(); + Calendar calendar = Calendar.getInstance(); + calendar.set(2013, Calendar.MARCH, 1, 14, 30, 42); // Use fixed date + + MockEntry entry = new MockEntry("Fixed JIRA-1"); + entry.setParent(mock(ChangeLogSet.class)); + + updater.appendChangeTimestamp(description, entry, calendar.getTime()); + + assertThat(description.toString(), containsString("Mar 1, 2013")); + assertThat(description.toString(), containsString("2:30:42 PM")); + } + + @Test + void testReplaceCarryOverList() { + Updater updater = new Updater(null); + Set currentIssues = new HashSet<>(); + currentIssues.add(new JiraIssue("ISSUE-1")); + currentIssues.add(new JiraIssue("ISSUE-2")); + + Set carryOverIssues = new HashSet<>(); + carryOverIssues.add(new JiraIssue("ISSUE-3")); + carryOverIssues.add(new JiraIssue("ISSUE-4")); + + Set result = updater.replaceCarryOverList(currentIssues, carryOverIssues); + + assertEquals(4, result.size()); + assertTrue(result.contains(new JiraIssue("ISSUE-1"))); + assertTrue(result.contains(new JiraIssue("ISSUE-2"))); + assertTrue(result.contains(new JiraIssue("ISSUE-3"))); + assertTrue(result.contains(new JiraIssue("ISSUE-4"))); + } + + @Test + void testCarryOverPreviousIssues() { + Updater updater = new Updater(null); + Run run = mock(Run.class); + + Set result = updater.carryOverPreviousIssues(run); + + assertNotNull(result); + assertTrue(result.isEmpty()); // Should be empty for mock + } +} \ No newline at end of file diff --git a/src/test/java/hudson/plugins/jira/VersionCreatorTest.java b/src/test/java/hudson/plugins/jira/unit/VersionCreatorTest.java similarity index 96% rename from src/test/java/hudson/plugins/jira/VersionCreatorTest.java rename to src/test/java/hudson/plugins/jira/unit/VersionCreatorTest.java index e99bbdf59..bb898a55d 100644 --- a/src/test/java/hudson/plugins/jira/VersionCreatorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/VersionCreatorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -15,6 +15,10 @@ import hudson.model.AbstractProject; import hudson.model.BuildListener; import hudson.model.Result; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.VersionCreator; import hudson.plugins.jira.extension.ExtendedVersion; import java.io.IOException; import java.io.PrintStream; diff --git a/src/test/java/hudson/plugins/jira/VersionReleaserTest.java b/src/test/java/hudson/plugins/jira/unit/VersionReleaserTest.java similarity index 96% rename from src/test/java/hudson/plugins/jira/VersionReleaserTest.java rename to src/test/java/hudson/plugins/jira/unit/VersionReleaserTest.java index aab39999e..84bb6e2b4 100644 --- a/src/test/java/hudson/plugins/jira/VersionReleaserTest.java +++ b/src/test/java/hudson/plugins/jira/unit/VersionReleaserTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira; +package hudson.plugins.jira.unit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -13,6 +13,10 @@ import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.BuildListener; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSession; +import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.VersionReleaser; import hudson.plugins.jira.extension.ExtendedVersion; import java.io.PrintStream; import java.util.Arrays; diff --git a/src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java b/src/test/java/hudson/plugins/jira/unit/auth/BearerHttpAuthenticationHandlerTest.java similarity index 93% rename from src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java rename to src/test/java/hudson/plugins/jira/unit/auth/BearerHttpAuthenticationHandlerTest.java index 8941311da..fcb26c8f7 100644 --- a/src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java +++ b/src/test/java/hudson/plugins/jira/unit/auth/BearerHttpAuthenticationHandlerTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.auth; +package hudson.plugins.jira.unit.auth; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java b/src/test/java/hudson/plugins/jira/unit/auth/JiraRestServiceBearerAuthTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java rename to src/test/java/hudson/plugins/jira/unit/auth/JiraRestServiceBearerAuthTest.java index 4b8bbf3f3..609101fbf 100644 --- a/src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java +++ b/src/test/java/hudson/plugins/jira/unit/auth/JiraRestServiceBearerAuthTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.auth; +package hudson.plugins.jira.unit.auth; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/src/test/java/com/atlassian/httpclient/apache/httpcomponents/CompletableFuturePromiseHttpPromiseAsyncClientTest.java b/src/test/java/hudson/plugins/jira/unit/httpclient/CompletableFuturePromiseHttpPromiseAsyncClientTest.java similarity index 94% rename from src/test/java/com/atlassian/httpclient/apache/httpcomponents/CompletableFuturePromiseHttpPromiseAsyncClientTest.java rename to src/test/java/hudson/plugins/jira/unit/httpclient/CompletableFuturePromiseHttpPromiseAsyncClientTest.java index edd3b28a6..5cc766ef1 100644 --- a/src/test/java/com/atlassian/httpclient/apache/httpcomponents/CompletableFuturePromiseHttpPromiseAsyncClientTest.java +++ b/src/test/java/hudson/plugins/jira/unit/httpclient/CompletableFuturePromiseHttpPromiseAsyncClientTest.java @@ -1,4 +1,4 @@ -package com.atlassian.httpclient.apache.httpcomponents; +package hudson.plugins.jira.unit.httpclient; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -6,6 +6,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.atlassian.httpclient.apache.httpcomponents.CompletableFuturePromiseHttpPromiseAsyncClient; import com.atlassian.sal.api.executor.ThreadLocalContextManager; import java.io.IOException; import java.util.concurrent.Executor; diff --git a/src/test/java/hudson/plugins/jira/selector/DefaultIssueSelectorTest.java b/src/test/java/hudson/plugins/jira/unit/selector/DefaultIssueSelectorTest.java similarity index 99% rename from src/test/java/hudson/plugins/jira/selector/DefaultIssueSelectorTest.java rename to src/test/java/hudson/plugins/jira/unit/selector/DefaultIssueSelectorTest.java index 70fd5b8f1..8b4496272 100644 --- a/src/test/java/hudson/plugins/jira/selector/DefaultIssueSelectorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/selector/DefaultIssueSelectorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.selector; +package hudson.plugins.jira.unit.selector; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/hudson/plugins/jira/selector/ExplicitIssueSelectorTest.java b/src/test/java/hudson/plugins/jira/unit/selector/ExplicitIssueSelectorTest.java similarity index 94% rename from src/test/java/hudson/plugins/jira/selector/ExplicitIssueSelectorTest.java rename to src/test/java/hudson/plugins/jira/unit/selector/ExplicitIssueSelectorTest.java index 2cef66c7f..47329373f 100644 --- a/src/test/java/hudson/plugins/jira/selector/ExplicitIssueSelectorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/selector/ExplicitIssueSelectorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.selector; +package hudson.plugins.jira.unit.selector; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; diff --git a/src/test/java/hudson/plugins/jira/selector/JqlIssueSelectorTest.java b/src/test/java/hudson/plugins/jira/unit/selector/JqlIssueSelectorTest.java similarity index 94% rename from src/test/java/hudson/plugins/jira/selector/JqlIssueSelectorTest.java rename to src/test/java/hudson/plugins/jira/unit/selector/JqlIssueSelectorTest.java index c220a2f76..9449a3951 100644 --- a/src/test/java/hudson/plugins/jira/selector/JqlIssueSelectorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/selector/JqlIssueSelectorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.selector; +package hudson.plugins.jira.unit.selector; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; @@ -10,8 +10,10 @@ import com.atlassian.jira.rest.client.api.domain.Issue; import hudson.model.AbstractProject; import hudson.model.Run; +import hudson.model.TaskListener; import hudson.plugins.jira.JiraSession; import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.selector.JqlIssueSelector; import java.io.IOException; import java.util.Collections; import java.util.Set; diff --git a/src/test/java/hudson/plugins/jira/selector/perforce/JobIssueSelectorTest.java b/src/test/java/hudson/plugins/jira/unit/selector/perforce/JobIssueSelectorTest.java similarity index 98% rename from src/test/java/hudson/plugins/jira/selector/perforce/JobIssueSelectorTest.java rename to src/test/java/hudson/plugins/jira/unit/selector/perforce/JobIssueSelectorTest.java index 44c2b7c4f..511549020 100644 --- a/src/test/java/hudson/plugins/jira/selector/perforce/JobIssueSelectorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/selector/perforce/JobIssueSelectorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.selector.perforce; +package hudson.plugins.jira.unit.selector.perforce; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/hudson/plugins/jira/selector/perforce/P4JobIssueSelectorTest.java b/src/test/java/hudson/plugins/jira/unit/selector/perforce/P4JobIssueSelectorTest.java similarity index 97% rename from src/test/java/hudson/plugins/jira/selector/perforce/P4JobIssueSelectorTest.java rename to src/test/java/hudson/plugins/jira/unit/selector/perforce/P4JobIssueSelectorTest.java index 86d31c62b..f63cba6bb 100644 --- a/src/test/java/hudson/plugins/jira/selector/perforce/P4JobIssueSelectorTest.java +++ b/src/test/java/hudson/plugins/jira/unit/selector/perforce/P4JobIssueSelectorTest.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.selector.perforce; +package hudson.plugins.jira.unit.selector.perforce; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock;