Skip to content

Commit 2efe857

Browse files
committed
Fix styling of select boxes for issue and version parameter
1 parent 984160c commit 2efe857

File tree

8 files changed

+180
-52
lines changed

8 files changed

+180
-52
lines changed

src/main/java/hudson/plugins/jira/listissuesparameter/JiraIssueParameterDefinition.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,28 @@
2222
import com.atlassian.jira.rest.client.api.domain.IssueField;
2323
import hudson.Extension;
2424
import hudson.cli.CLICommand;
25+
import hudson.model.Item;
2526
import hudson.model.Job;
2627
import hudson.model.ParameterDefinition;
2728
import hudson.model.ParameterValue;
29+
import hudson.model.ParametersDefinitionProperty;
2830
import hudson.plugins.jira.JiraSession;
2931
import hudson.plugins.jira.JiraSite;
32+
import hudson.util.ListBoxModel;
3033
import java.io.IOException;
3134
import java.util.ArrayList;
3235
import java.util.List;
3336
import java.util.concurrent.TimeoutException;
3437
import net.sf.json.JSONObject;
3538
import org.apache.commons.lang.StringUtils;
3639
import org.jenkinsci.Symbol;
40+
import org.kohsuke.stapler.AncestorInPath;
3741
import org.kohsuke.stapler.DataBoundConstructor;
3842
import org.kohsuke.stapler.DataBoundSetter;
43+
import org.kohsuke.stapler.QueryParameter;
3944
import org.kohsuke.stapler.Stapler;
4045
import org.kohsuke.stapler.StaplerRequest2;
46+
import org.kohsuke.stapler.interceptor.RequirePOST;
4147

4248
public class JiraIssueParameterDefinition extends ParameterDefinition {
4349
private static final long serialVersionUID = 3927562542249244416L;
@@ -75,7 +81,10 @@ public ParameterValue createValue(CLICommand command, String value) throws IOExc
7581
public List<JiraIssueParameterDefinition.Result> getIssues()
7682
throws IOException, TimeoutException, RestClientException {
7783
Job<?, ?> job = Stapler.getCurrentRequest2().findAncestorObject(Job.class);
84+
return getIssues(job);
85+
}
7886

87+
public List<JiraIssueParameterDefinition.Result> getIssues(Job<?, ?> job) {
7988
JiraSite site = JiraSite.get(job);
8089
if (site == null) {
8190
throw new IllegalStateException(
@@ -122,6 +131,22 @@ public static class DescriptorImpl extends ParameterDescriptor {
122131
public String getDisplayName() {
123132
return "Jira Issue Parameter";
124133
}
134+
135+
@RequirePOST
136+
public ListBoxModel doFillValueItems(@AncestorInPath Job<?, ?> job, @QueryParameter String name) {
137+
ListBoxModel items = new ListBoxModel();
138+
if (job.hasPermission(Item.BUILD)) {
139+
ParametersDefinitionProperty prop = job.getProperty(ParametersDefinitionProperty.class);
140+
if (prop != null) {
141+
ParameterDefinition def = prop.getParameterDefinition(name);
142+
if (def instanceof JiraIssueParameterDefinition jiraIssueDef) {
143+
List<Result> issueValues = jiraIssueDef.getIssues(job);
144+
issueValues.forEach(it -> items.add(it.summary, it.key));
145+
}
146+
}
147+
}
148+
return items;
149+
}
125150
}
126151

127152
public static class Result {

src/main/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinition.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,19 @@
44
import com.atlassian.jira.rest.client.api.domain.Version;
55
import hudson.Extension;
66
import hudson.cli.CLICommand;
7-
import hudson.model.Job;
8-
import hudson.model.ParameterDefinition;
9-
import hudson.model.ParameterValue;
7+
import hudson.model.*;
108
import hudson.plugins.jira.JiraSession;
119
import hudson.plugins.jira.JiraSite;
10+
import hudson.util.ListBoxModel;
1211
import java.io.IOException;
1312
import java.util.List;
1413
import java.util.Objects;
1514
import java.util.regex.Pattern;
1615
import java.util.stream.Collectors;
1716
import net.sf.json.JSONObject;
1817
import org.jenkinsci.Symbol;
19-
import org.kohsuke.stapler.DataBoundConstructor;
20-
import org.kohsuke.stapler.Stapler;
21-
import org.kohsuke.stapler.StaplerRequest2;
18+
import org.kohsuke.stapler.*;
19+
import org.kohsuke.stapler.interceptor.RequirePOST;
2220

2321
public class JiraVersionParameterDefinition extends ParameterDefinition {
2422
private static final long serialVersionUID = 4232979892748310160L;
@@ -69,7 +67,10 @@ public ParameterValue createValue(CLICommand command, String value) throws IOExc
6967

7068
public List<JiraVersionParameterDefinition.Result> getVersions() throws IOException, RestClientException {
7169
Job<?, ?> contextJob = Stapler.getCurrentRequest2().findAncestorObject(Job.class);
70+
return getVersions(contextJob);
71+
}
7272

73+
public List<JiraVersionParameterDefinition.Result> getVersions(Job<?, ?> contextJob) {
7374
JiraSite site = JiraSite.get(contextJob);
7475
if (site == null) {
7576
throw new IllegalStateException(
@@ -173,6 +174,22 @@ public static class DescriptorImpl extends ParameterDescriptor {
173174
public String getDisplayName() {
174175
return "Jira Release Version Parameter";
175176
}
177+
178+
@RequirePOST
179+
public ListBoxModel doFillVersionItems(@AncestorInPath Job<?, ?> job, @QueryParameter String name) {
180+
ListBoxModel items = new ListBoxModel();
181+
if (job.hasPermission(Item.BUILD)) {
182+
ParametersDefinitionProperty prop = job.getProperty(ParametersDefinitionProperty.class);
183+
if (prop != null) {
184+
ParameterDefinition def = prop.getParameterDefinition(name);
185+
if (def instanceof JiraVersionParameterDefinition jiraVersionDef) {
186+
List<JiraVersionParameterDefinition.Result> issueValues = jiraVersionDef.getVersions(job);
187+
issueValues.forEach(it -> items.add(it.name));
188+
}
189+
}
190+
}
191+
return items;
192+
}
176193
}
177194

178195
public static class Result {

src/main/resources/hudson/plugins/jira/listissuesparameter/JiraIssueParameterDefinition/index.jelly

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,13 @@ limitations under the License.
1616
<!-- this is the page fragment displayed when triggering a new build -->
1717
<?jelly escape-by-default='true'?>
1818
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
19-
<j:set var="escapeEntryTitleAndDescription" value="false"/>
20-
<f:entry title="${h.escape(it.name)}" description="${it.formattedDescription}">
21-
<!-- this div is required because of ParametersDefinitionProperty.java#117 -->
22-
<div name="parameter">
23-
<input type="hidden" name="name" value="${it.name}"/>
24-
<j:choose>
25-
<j:when test="${it.issues == null or it.issues.size() == 0}">
26-
<!-- no tags at all -->
27-
${%No issues matched the search.}<br/>
28-
${%If you trigger the build, it will likely fail.}
29-
</j:when>
30-
<j:otherwise>
31-
<!-- everything is fine, we can display the drop-down list to the user -->
32-
<select name="value">
33-
<j:forEach var="issue" items="${it.issues}">
34-
<option value="${issue.key}">${issue.key}: ${issue.summary}</option>
35-
</j:forEach>
36-
</select>
37-
</j:otherwise>
38-
</j:choose>
39-
</div>
40-
</f:entry>
19+
<j:set var="escapeEntryTitleAndDescription" value="false"/>
20+
<j:set var="instance" value="${it}"/>
21+
<j:set var="descriptor" value="${it.descriptor}"/>
22+
<f:entry field="value" title="${h.escape(it.name)}" description="${it.formattedDescription}">
23+
<div name="parameter">
24+
<input type="hidden" name="name" value="${it.name}"/>
25+
<f:select/>
26+
</div>
27+
</f:entry>
4128
</j:jelly>

src/main/resources/hudson/plugins/jira/listissuesparameter/JiraIssueParameterValue/value.jelly

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
1818
<j:set var="escapeEntryTitleAndDescription" value="false"/>
1919
<f:entry title="${h.escape(it.name)}">
20-
<f:textbox name="${it.name}" value="${it.issue}" />
20+
<j:set var="readOnlyMode" value="true"/>
21+
<f:textbox name="${it.name}" value="${it.value}"/>
2122
</f:entry>
2223
</j:jelly>
Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,13 @@
11
<!-- this is the page fragment displayed when triggering a new build -->
22
<?jelly escape-by-default='true'?>
33
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
4-
<j:set var="escapeEntryTitleAndDescription" value="false"/>
5-
<f:entry title="${h.escape(it.name)}" description="${it.formattedDescription}">
6-
<!-- this div is required because of ParametersDefinitionProperty.java#117 -->
7-
<div name="parameter">
8-
<input type="hidden" name="name" value="${it.name}"/>
9-
<j:choose>
10-
<j:when test="${it.versions == null or it.versions.size() == 0}">
11-
<!-- no tags at all -->
12-
${%No versions found meeting your filter criteria.}<br/>
13-
${%If you trigger the build, it will likely fail.}
14-
</j:when>
15-
<j:otherwise>
16-
<!-- everything is fine, we can display the drop-down list to the user -->
17-
<select name="version">
18-
<j:forEach var="version" items="${it.versions}">
19-
<option value="${version.name}">${version.name}</option>
20-
</j:forEach>
21-
</select>
22-
</j:otherwise>
23-
</j:choose>
24-
</div>
25-
</f:entry>
4+
<j:set var="escapeEntryTitleAndDescription" value="false"/>
5+
<j:set var="instance" value="${it}"/>
6+
<j:set var="descriptor" value="${it.descriptor}"/>
7+
<f:entry field="version" title="${h.escape(it.name)}" description="${it.formattedDescription}">
8+
<div name="parameter">
9+
<input type="hidden" name="name" value="${it.name}"/>
10+
<f:select/>
11+
</div>
12+
</f:entry>
2613
</j:jelly>

src/main/resources/hudson/plugins/jira/versionparameter/JiraVersionParameterValue/value.jelly

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
33
<j:set var="escapeEntryTitleAndDescription" value="false"/>
44
<f:entry title="${h.escape(it.name)}">
5-
<f:textbox name="${it.name}" value="${it.version}" />
5+
<j:set var="readOnlyMode" value="true"/>
6+
<f:textbox name="${it.name}" value="${it.version}"/>
67
</f:entry>
78
</j:jelly>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package hudson.plugins.jira.listissuesparameter;
2+
3+
import static org.hamcrest.MatcherAssert.assertThat;
4+
import static org.hamcrest.Matchers.hasSize;
5+
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
import static org.mockito.ArgumentMatchers.any;
7+
import static org.mockito.Mockito.verify;
8+
import static org.mockito.Mockito.verifyNoMoreInteractions;
9+
import static org.mockito.Mockito.when;
10+
11+
import com.atlassian.jira.rest.client.api.domain.Issue;
12+
import hudson.model.Item;
13+
import hudson.model.Job;
14+
import hudson.model.ParametersDefinitionProperty;
15+
import hudson.util.ListBoxModel;
16+
import java.util.List;
17+
import org.junit.jupiter.api.Nested;
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.extension.ExtendWith;
20+
import org.mockito.Mock;
21+
import org.mockito.junit.jupiter.MockitoExtension;
22+
23+
class JiraIssueParameterDefinitionTest {
24+
25+
@Nested
26+
@ExtendWith(MockitoExtension.class)
27+
class DescriptorImplTest {
28+
29+
private JiraIssueParameterDefinition.DescriptorImpl uut = new JiraIssueParameterDefinition.DescriptorImpl();
30+
31+
@Test
32+
void shouldFillValueItems(
33+
@Mock Job<?, ?> job,
34+
@Mock ParametersDefinitionProperty propertyDef,
35+
@Mock JiraIssueParameterDefinition paramDef,
36+
@Mock Issue issue) {
37+
when(job.hasPermission(Item.BUILD)).thenReturn(true);
38+
when(job.getProperty(ParametersDefinitionProperty.class)).thenReturn(propertyDef);
39+
when(propertyDef.getParameterDefinition("PARAM_NAME")).thenReturn(paramDef);
40+
when(issue.getKey()).thenReturn("JIRA-1234");
41+
when(issue.getSummary()).thenReturn("Summary");
42+
JiraIssueParameterDefinition.Result item = new JiraIssueParameterDefinition.Result(issue, null);
43+
when(paramDef.getIssues(any())).thenReturn(List.of(item));
44+
45+
ListBoxModel result = uut.doFillValueItems(job, "PARAM_NAME");
46+
47+
assertThat(result, hasSize(1));
48+
ListBoxModel.Option option = result.get(0);
49+
assertEquals("JIRA-1234", option.value);
50+
assertEquals("Summary", option.name);
51+
verify(job).hasPermission(Item.BUILD);
52+
}
53+
54+
@Test
55+
void shouldNotFillValueItemsIfPermissionMissing(@Mock Job<?, ?> job) {
56+
ListBoxModel result = uut.doFillValueItems(job, "PARAM_NAME");
57+
58+
assertThat(result, hasSize(0));
59+
verify(job).hasPermission(Item.BUILD);
60+
verifyNoMoreInteractions(job);
61+
}
62+
}
63+
}

src/test/java/hudson/plugins/jira/versionparameter/JiraVersionParameterDefinitionTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
11
package hudson.plugins.jira.versionparameter;
22

3+
import static org.hamcrest.MatcherAssert.assertThat;
4+
import static org.hamcrest.Matchers.hasSize;
35
import static org.junit.jupiter.api.Assertions.*;
46
import static org.mockito.Mockito.*;
57
import static org.mockito.Mockito.mockStatic;
68

9+
import com.atlassian.jira.rest.client.api.domain.Version;
710
import hudson.cli.CLICommand;
11+
import hudson.model.Item;
812
import hudson.model.Job;
913
import hudson.model.ParameterValue;
14+
import hudson.model.ParametersDefinitionProperty;
1015
import hudson.plugins.jira.JiraSession;
1116
import hudson.plugins.jira.JiraSite;
1217
import hudson.plugins.jira.extension.ExtendedVersion;
18+
import hudson.util.ListBoxModel;
1319
import java.io.IOException;
1420
import java.util.ArrayList;
1521
import java.util.List;
1622
import org.junit.jupiter.api.BeforeEach;
23+
import org.junit.jupiter.api.Nested;
1724
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.extension.ExtendWith;
1826
import org.kohsuke.stapler.Stapler;
1927
import org.kohsuke.stapler.StaplerRequest2;
28+
import org.mockito.Mock;
2029
import org.mockito.MockedStatic;
30+
import org.mockito.junit.jupiter.MockitoExtension;
2131

2232
class JiraVersionParameterDefinitionTest {
2333

@@ -258,4 +268,41 @@ private void withJiraStaticMocks(Runnable testLogic) {
258268
throw new RuntimeException(e);
259269
}
260270
}
271+
272+
@Nested
273+
@ExtendWith(MockitoExtension.class)
274+
class DescriptorImplTest {
275+
276+
private JiraVersionParameterDefinition.DescriptorImpl uut = new JiraVersionParameterDefinition.DescriptorImpl();
277+
278+
@Test
279+
void shouldFillVersionItems(
280+
@Mock Job<?, ?> job,
281+
@Mock ParametersDefinitionProperty propertyDef,
282+
@Mock JiraVersionParameterDefinition paramDef) {
283+
when(job.hasPermission(Item.BUILD)).thenReturn(true);
284+
when(job.getProperty(ParametersDefinitionProperty.class)).thenReturn(propertyDef);
285+
when(propertyDef.getParameterDefinition("PARAM_NAME")).thenReturn(paramDef);
286+
Version version = new Version(null, 1L, "1.0.0", "", false, false, null);
287+
JiraVersionParameterDefinition.Result item = new JiraVersionParameterDefinition.Result(version);
288+
when(paramDef.getVersions(any())).thenReturn(List.of(item));
289+
290+
ListBoxModel result = uut.doFillVersionItems(job, "PARAM_NAME");
291+
292+
assertThat(result, hasSize(1));
293+
ListBoxModel.Option option = result.get(0);
294+
assertEquals("1.0.0", option.value);
295+
assertEquals("1.0.0", option.name);
296+
verify(job).hasPermission(Item.BUILD);
297+
}
298+
299+
@Test
300+
void shouldNotFillVersionsItemsIfPermissionMissing(@Mock Job<?, ?> job) {
301+
ListBoxModel result = uut.doFillVersionItems(job, "PARAM_NAME");
302+
303+
assertThat(result, hasSize(0));
304+
verify(job).hasPermission(Item.BUILD);
305+
verifyNoMoreInteractions(job);
306+
}
307+
}
261308
}

0 commit comments

Comments
 (0)