Skip to content

Commit 6708376

Browse files
authored
Merge pull request #1971 from jenkinsci/JENKINS-75394-project-action-url
[JENKINS-75394] Use custom ID and icon in project action
2 parents c8706d1 + 620a67b commit 6708376

File tree

7 files changed

+159
-48
lines changed

7 files changed

+159
-48
lines changed

plugin/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<groupId>io.jenkins.plugins</groupId>
1313
<artifactId>warnings-ng</artifactId>
14-
<version>12.5.0-SNAPSHOT</version>
14+
<version>12.4.1-SNAPSHOT</version>
1515
<packaging>hpi</packaging>
1616
<name>Warnings Plugin</name>
1717

plugin/src/main/java/io/jenkins/plugins/analysis/core/model/JobAction.java

+36-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package io.jenkins.plugins.analysis.core.model;
22

3-
import java.io.IOException;
4-
import java.util.Optional;
5-
63
import edu.hm.hafner.echarts.BuildResult;
74
import edu.hm.hafner.echarts.ChartModelConfiguration;
85
import edu.hm.hafner.echarts.JacksonFacade;
96
import edu.umd.cs.findbugs.annotations.CheckForNull;
107

8+
import java.io.IOException;
9+
import java.util.Optional;
10+
1111
import org.kohsuke.stapler.StaplerRequest2;
1212
import org.kohsuke.stapler.StaplerResponse2;
1313
import org.kohsuke.stapler.bind.JavaScriptMethod;
@@ -38,6 +38,7 @@ public class JobAction implements Action, AsyncConfigurableTrendChart {
3838
private final StaticAnalysisLabelProvider labelProvider;
3939
private final int numberOfTools;
4040
private final TrendChartType trendChartType;
41+
private final String urlName;
4142

4243
/**
4344
* Creates a new instance of {@link JobAction}.
@@ -48,9 +49,12 @@ public class JobAction implements Action, AsyncConfigurableTrendChart {
4849
* the label provider
4950
* @param numberOfTools
5051
* the number of tools that have results to show
52+
* @deprecated
53+
* Use {@link #JobAction(Job, StaticAnalysisLabelProvider, int, TrendChartType, String)} instead.
5154
*/
55+
@Deprecated
5256
public JobAction(final Job<?, ?> owner, final StaticAnalysisLabelProvider labelProvider, final int numberOfTools) {
53-
this(owner, labelProvider, numberOfTools, TrendChartType.TOOLS_ONLY);
57+
this(owner, labelProvider, numberOfTools, TrendChartType.TOOLS_ONLY, labelProvider.getId());
5458
}
5559

5660
/**
@@ -64,9 +68,32 @@ public JobAction(final Job<?, ?> owner, final StaticAnalysisLabelProvider labelP
6468
* the number of tools that have results to show
6569
* @param trendChartType
6670
* determines if the trend chart will be shown
71+
* @deprecated
72+
* Use {@link #JobAction(Job, StaticAnalysisLabelProvider, int, TrendChartType, String)} instead.
6773
*/
74+
@Deprecated
6875
public JobAction(final Job<?, ?> owner, final StaticAnalysisLabelProvider labelProvider, final int numberOfTools,
6976
final TrendChartType trendChartType) {
77+
this(owner, labelProvider, numberOfTools, trendChartType, labelProvider.getId());
78+
}
79+
80+
/**
81+
* Creates a new instance of {@link JobAction}.
82+
*
83+
* @param owner
84+
* the job that owns this action
85+
* @param labelProvider
86+
* the label provider
87+
* @param numberOfTools
88+
* the number of tools that have results to show
89+
* @param trendChartType
90+
* determines if the trend chart will be shown
91+
* @param urlName
92+
* the custom URL name of this action
93+
*/
94+
public JobAction(final Job<?, ?> owner, final StaticAnalysisLabelProvider labelProvider, final int numberOfTools,
95+
final TrendChartType trendChartType, final String urlName) {
96+
this.urlName = urlName;
7097
this.owner = owner;
7198
this.labelProvider = labelProvider;
7299
this.numberOfTools = numberOfTools;
@@ -79,7 +106,7 @@ public JobAction(final Job<?, ?> owner, final StaticAnalysisLabelProvider labelP
79106
* @return the ID
80107
*/
81108
public String getId() {
82-
return labelProvider.getId();
109+
return urlName;
83110
}
84111

85112
@Override
@@ -116,7 +143,7 @@ public History createBuildHistory() {
116143
return new NullAnalysisHistory();
117144
}
118145
else {
119-
return new AnalysisHistory(lastCompletedBuild, new ByIdResultSelector(labelProvider.getId()));
146+
return new AnalysisHistory(lastCompletedBuild, new ByIdResultSelector(getId()));
120147
}
121148
}
122149

@@ -129,14 +156,12 @@ public History createBuildHistory() {
129156
@Override
130157
@CheckForNull
131158
public String getIconFileName() {
132-
return createBuildHistory().getBaselineResult()
133-
.map(result -> labelProvider.getSmallIconUrl())
134-
.orElse(null);
159+
return labelProvider.getSmallIconUrl();
135160
}
136161

137162
@Override
138163
public String getUrlName() {
139-
return labelProvider.getId();
164+
return urlName;
140165
}
141166

142167
/**
@@ -155,7 +180,7 @@ public void doIndex(final StaplerRequest2 request, final StaplerResponse2 respon
155180
Optional<ResultAction> action = getLatestAction();
156181
if (action.isPresent()) {
157182
response.sendRedirect2(String.format("../%d/%s", action.get().getOwner().getNumber(),
158-
labelProvider.getId()));
183+
getId()));
159184
}
160185
}
161186

plugin/src/main/java/io/jenkins/plugins/analysis/core/model/ResultAction.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import edu.umd.cs.findbugs.annotations.CheckForNull;
1010
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
1111

12+
import java.io.Serial;
1213
import java.io.Serializable;
1314
import java.nio.charset.Charset;
1415
import java.util.Collection;
@@ -93,6 +94,7 @@ public ResultAction(final Run<?, ?> owner, final AnalysisResult result, final He
9394
*
9495
* @return this
9596
*/
97+
@Serial
9698
protected Object readResolve() {
9799
if (trendChartType == null) {
98100
trendChartType = TrendChartType.TOOLS_ONLY;
@@ -202,7 +204,7 @@ HealthDescriptor getHealthDescriptor() {
202204
public Collection<? extends Action> getProjectActions() {
203205
return Collections.singleton(
204206
new JobAction(owner.getParent(), getLabelProvider(), result.getSizePerOrigin().size(),
205-
trendChartType));
207+
trendChartType, getUrlName()));
206208
}
207209

208210
@Whitelisted

plugin/src/test/java/io/jenkins/plugins/analysis/core/model/JobActionTest.java

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package io.jenkins.plugins.analysis.core.model;
22

3+
import org.junit.jupiter.api.Test;
4+
35
import java.io.IOException;
46
import java.util.Collections;
57

6-
import org.junit.jupiter.api.Test;
7-
88
import org.kohsuke.stapler.StaplerRequest2;
99
import org.kohsuke.stapler.StaplerResponse2;
1010
import hudson.model.Job;
@@ -38,23 +38,27 @@ void shouldUseLabelProvider() {
3838

3939
Job<?, ?> job = mock(Job.class);
4040

41-
JobAction action = new JobAction(job, labelProvider, 1);
41+
JobAction action = createJobAction(job, labelProvider);
4242
assertThat(action.getDisplayName()).isEqualTo(LINK_NAME);
4343
assertThat(action.getTrendName()).isEqualTo(TREND_NAME);
4444
assertThat(action.getId()).isEqualTo(ID);
4545
assertThat(action.getUrlName()).isEqualTo(ID);
4646
assertThat(action.getOwner()).isEqualTo(job);
4747
}
4848

49+
private JobAction createJobAction(final Job<?, ?> job, final StaticAnalysisLabelProvider labelProvider) {
50+
return new JobAction(job, labelProvider, 1, TrendChartType.TOOLS_ONLY, labelProvider.getId());
51+
}
52+
4953
@Test
5054
void shouldShowIconIfThereIsABuildResultAvailable() throws IOException {
5155
StaticAnalysisLabelProvider labelProvider = mock(StaticAnalysisLabelProvider.class);
5256
when(labelProvider.getId()).thenReturn(ANALYSIS_ID);
5357
when(labelProvider.getSmallIconUrl()).thenReturn(ICON);
5458

5559
Job<?, ?> job = mock(Job.class);
56-
JobAction action = new JobAction(job, labelProvider, 1);
57-
assertThat(action.getIconFileName()).isNull();
60+
JobAction action = createJobAction(job, labelProvider);
61+
assertThat(action.getIconFileName()).isEqualTo(ICON); // a JobAction should always show an icon
5862

5963
Run<?, ?> reference = createValidReferenceBuild(0);
6064
when(job.getLastCompletedBuild()).thenAnswer(i -> reference);
@@ -74,15 +78,17 @@ void shouldShowIconIfThereIsABuildResultAvailable() throws IOException {
7478

7579
verify(response).sendRedirect2("../0/" + ANALYSIS_ID);
7680

77-
JobAction hiddenAction = new JobAction(job, labelProvider, 1, TrendChartType.NONE);
81+
var url = "something";
82+
JobAction hiddenAction = new JobAction(job, labelProvider, 1, TrendChartType.NONE, url);
7883
assertThat(hiddenAction.isTrendVisible()).isFalse();
84+
assertThat(hiddenAction.getUrlName()).isEqualTo(url);
7985
}
8086

8187
@Test
8288
void shouldRedirect() throws IOException {
8389
StaticAnalysisLabelProvider labelProvider = mock(StaticAnalysisLabelProvider.class);
8490
Job<?, ?> job = mock(Job.class);
85-
JobAction action = new JobAction(job, labelProvider, 1);
91+
JobAction action = createJobAction(job, labelProvider);
8692

8793
StaplerRequest2 request = mock(StaplerRequest2.class);
8894
action.doIndex(request, mock(StaplerResponse2.class));

plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/JobActionITest.java

+42-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package io.jenkins.plugins.analysis.warnings.steps;
22

3-
import java.util.List;
4-
53
import org.junit.jupiter.api.Test;
4+
import org.junitpioneer.jupiter.Issue;
5+
6+
import java.util.List;
67

78
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
89
import hudson.model.Actionable;
@@ -69,6 +70,37 @@ void shouldShowTrendChart() {
6970
assertThat(jobActions.get(0).getUrlName()).isEqualTo(ECLIPSE_URL_NAME);
7071
}
7172

73+
@Test
74+
@Issue("JENKINS-75394")
75+
void shouldShowTrendChartWithCustomUrlAndIcon() {
76+
FreeStyleProject project = createFreeStyleProjectWithWorkspaceFilesWithSuffix(ECLIPSE_LOG);
77+
var tool = new Eclipse();
78+
var url = "custom-eclipse";
79+
tool.setId(url);
80+
var icon = "custom-eclipse.svg";
81+
tool.setIcon(icon);
82+
enableGenericWarnings(project, tool);
83+
84+
Run<?, ?> build = buildWithResult(project, Result.SUCCESS);
85+
assertActionProperties(project, build, url, icon);
86+
87+
project.getActions(JobAction.class);
88+
List<JobAction> jobActions = project.getActions(JobAction.class);
89+
90+
assertThatTrendChartIsHidden(jobActions.get(0)); // trend chart requires at least two builds
91+
assertThat(jobActions.get(0).getIconFileName()).isEqualTo(icon);
92+
assertThat(jobActions.get(0).getUrlName()).isEqualTo(url);
93+
94+
build = buildWithResult(project, Result.SUCCESS);
95+
assertActionProperties(project, build, url, icon);
96+
97+
jobActions = project.getActions(JobAction.class);
98+
99+
assertThatTrendChartIsVisible(jobActions.get(0));
100+
assertThat(jobActions.get(0).getIconFileName()).isEqualTo(icon);
101+
assertThat(jobActions.get(0).getUrlName()).isEqualTo(url);
102+
}
103+
72104
/**
73105
* Verifies that the aggregation trend chart is visible for a freestyle job at the top, or bottom, or hidden.
74106
*/
@@ -182,7 +214,7 @@ private FreeStyleProject createAggregationJob(final TrendChartType chart) {
182214
}
183215

184216
/**
185-
* Verifies that the side bar link is not missing if there are no issues in the latest build.
217+
* Verifies that the sidebar link is not missing if there are no issues in the latest build.
186218
*/
187219
@Test
188220
void shouldHaveSidebarLinkEvenWhenLastActionHasNoResults() {
@@ -251,6 +283,11 @@ private void assertThatAggregationChartDoesNotExists(final Actionable actionable
251283
}
252284

253285
private void assertActionProperties(final FreeStyleProject project, final Run<?, ?> build) {
286+
assertActionProperties(project, build, "eclipse", "symbol-solid/triangle-exclamation plugin-font-awesome-api");
287+
}
288+
289+
private void assertActionProperties(final FreeStyleProject project, final Run<?, ?> build,
290+
final String urlName, final String iconName) {
254291
JobAction jobAction = project.getAction(JobAction.class);
255292
assertThat(jobAction).isNotNull();
256293

@@ -260,8 +297,8 @@ private void assertActionProperties(final FreeStyleProject project, final Run<?,
260297
StaticAnalysisLabelProvider labelProvider = new Eclipse().getLabelProvider();
261298
assertThat(jobAction.getDisplayName()).isEqualTo(labelProvider.getLinkName());
262299
assertThat(jobAction.getTrendName()).isEqualTo(labelProvider.getTrendName());
263-
assertThat(jobAction.getUrlName()).isEqualTo(labelProvider.getId());
300+
assertThat(jobAction.getUrlName()).isEqualTo(urlName);
264301
assertThat(jobAction.getOwner()).isEqualTo(project);
265-
assertThat(jobAction.getIconFileName()).endsWith(labelProvider.getSmallIconUrl());
302+
assertThat(jobAction.getIconFileName()).endsWith(iconName);
266303
}
267304
}

ui-tests/src/main/java/io/jenkins/plugins/analysis/warnings/IssuesRecorder.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package io.jenkins.plugins.analysis.warnings;
22

3+
import org.openqa.selenium.WebElement;
4+
35
import java.util.List;
46
import java.util.function.Consumer;
57
import java.util.stream.Collectors;
68

7-
import org.openqa.selenium.WebElement;
8-
99
import org.jenkinsci.test.acceptance.po.AbstractStep;
1010
import org.jenkinsci.test.acceptance.po.Control;
1111
import org.jenkinsci.test.acceptance.po.Describable;
@@ -676,6 +676,7 @@ public static class StaticAnalysisTool extends PageAreaImpl {
676676
private final Control highThreshold = control("tool/highThreshold");
677677
private final Control id = control("tool/id");
678678
private final Control name = control("tool/name");
679+
private final Control icon = control("tool/icon");
679680
private final Control analysisModelId = control("tool/analysisModelId");
680681
private final Control skipSymbolicLinks = control("tool/skipSymbolicLinks");
681682

@@ -724,6 +725,20 @@ public StaticAnalysisTool setName(final String name) {
724725
return this;
725726
}
726727

728+
/**
729+
* Sets the custom name of the tool.
730+
*
731+
* @param icon
732+
* the icon
733+
*
734+
* @return this
735+
*/
736+
public StaticAnalysisTool setIcon(final String icon) {
737+
this.icon.set(icon);
738+
739+
return this;
740+
}
741+
727742
/**
728743
* Sets the pattern of the files to parse.
729744
*

0 commit comments

Comments
 (0)