diff --git a/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/ProjectWidget.java b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/ProjectWidget.java index df8eec624..abe2eafdd 100644 --- a/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/ProjectWidget.java +++ b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/ProjectWidget.java @@ -37,5 +37,9 @@ public ProjectWidget(String projectOfInterest) { this.projectOfInterest = projectOfInterest; } + public Question multiConfigBadgeNames() { + return new ProjectMultiConfigWidget(); + } + private final String projectOfInterest; } diff --git a/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/project_widget/ProjectMultiConfigWidget.java b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/project_widget/ProjectMultiConfigWidget.java new file mode 100644 index 000000000..bedc0bda2 --- /dev/null +++ b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/questions/project_widget/ProjectMultiConfigWidget.java @@ -0,0 +1,18 @@ +package com.smartcodeltd.jenkinsci.plugins.build_monitor.questions.project_widget; + +import com.smartcodeltd.jenkinsci.plugins.build_monitor.user_interface.BuildMonitorDashboard; +import net.serenitybdd.screenplay.Actor; +import net.serenitybdd.screenplay.Question; +import net.serenitybdd.screenplay.questions.Text; +import net.serenitybdd.screenplay.targets.Target; + +public class ProjectMultiConfigWidget implements Question { + + @Override + public String answeredBy(Actor actor) { + Target multiConfigBadge1 = BuildMonitorDashboard.Multi_Config_1; + Target multiConfigBadge2 = BuildMonitorDashboard.Multi_Config_2; + + return Text.of(multiConfigBadge1).viewedBy(actor).resolve() + ":::" + Text.of(multiConfigBadge2).viewedBy(actor).resolve(); + } +} diff --git a/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/tasks/configuration/DisplayMultiConfig.java b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/tasks/configuration/DisplayMultiConfig.java new file mode 100644 index 000000000..4b223e860 --- /dev/null +++ b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/tasks/configuration/DisplayMultiConfig.java @@ -0,0 +1,23 @@ +package com.smartcodeltd.jenkinsci.plugins.build_monitor.tasks.configuration; +import net.serenitybdd.screenplay.Actor; +import net.serenitybdd.screenplay.Task; +import net.serenitybdd.screenplay.jenkins.actions.Choose; +import net.serenitybdd.screenplay.jenkins.user_interface.ViewConfigurationPage; +import net.thucydides.core.annotations.Step; + +import static net.serenitybdd.screenplay.Tasks.instrumented; + +public class DisplayMultiConfig implements Task{ + + public static Task usingDisplayMultiConfigCheckbox() { + return instrumented(DisplayMultiConfig.class); + } + + @Step("{0} clicks the Display Multi-Config Jobs checkbox") + @Override + public void performAs(T actor) { + actor.attemptsTo( + Choose.the(ViewConfigurationPage.Display_Multi_Config_Jobs) + ); + } +} diff --git a/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/user_interface/BuildMonitorDashboard.java b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/user_interface/BuildMonitorDashboard.java index 5ab694143..d65350754 100644 --- a/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/user_interface/BuildMonitorDashboard.java +++ b/build-monitor-acceptance/src/main/java/com/smartcodeltd/jenkinsci/plugins/build_monitor/user_interface/BuildMonitorDashboard.java @@ -11,6 +11,9 @@ public class BuildMonitorDashboard { public static final Target Project_Widget_Badges = Target.the("Project Widget Badges").locatedBy("//li[header/h2[.='{0}']]//*[@class='badges']"); public static final Target Project_Widget_Pipeline_Stages = Target.the("Project Widget Builds").locatedBy("//li[header/h2[.='{0}']]//*[contains(@class, 'build-stages')]"); + public static final Target Multi_Config_1 = Target.the("Multi Config Badge One").locatedBy("//*[@id='multiproject-1']/header/h2/a"); + public static final Target Multi_Config_2 = Target.the("Multi Config Badge Two").locatedBy("//*[@id='multiproject-2']/header/h2/a"); + public static final Target Control_Panel = Target.the("Control Panel").locatedBy("//label[@for='settings-toggle']"); public static final Target Show_Badges = Target.the("Show Badges Toggle").locatedBy("//input[@id='settings-show-badges']"); } diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/HaveAMultiConfigProjectCreated.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/HaveAMultiConfigProjectCreated.java new file mode 100644 index 000000000..ce160bd67 --- /dev/null +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/HaveAMultiConfigProjectCreated.java @@ -0,0 +1,43 @@ +package net.serenitybdd.screenplay.jenkins; + + +import net.serenitybdd.screenplay.Actor; +import net.serenitybdd.screenplay.Task; +import net.serenitybdd.screenplay.actions.Click; +import net.serenitybdd.screenplay.jenkins.tasks.CreateAMultiConfigurationProject; +import net.serenitybdd.screenplay.jenkins.tasks.configuration.TodoList; +import net.thucydides.core.annotations.Step; + +import static net.serenitybdd.screenplay.Tasks.instrumented; +import static net.serenitybdd.screenplay.jenkins.user_interface.navigation.SidePanel.Back_to_Dashboard; + +public class HaveAMultiConfigProjectCreated implements Task{ + + public static HaveAMultiConfigProjectCreated called(String name) { + return instrumented(HaveAMultiConfigProjectCreated.class, name); + } + + public Task andConfigureItTo(Task... configurationTasks) { + this.requiredConfiguration.addAll(configurationTasks); + + return this; + } + + @Step("{0} creates the '#projectName' pipeline") + @Override + public void performAs(T actor) { + actor.attemptsTo( + CreateAMultiConfigurationProject.called(projectName) + .andConfigureItTo(requiredConfiguration), + Click.on(Back_to_Dashboard) + ); + } + + public HaveAMultiConfigProjectCreated (String projectName) { + this.projectName = projectName; + } + + + private final String projectName; + private final TodoList requiredConfiguration = TodoList.empty(); +} diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAMultiConfigurationProject.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAMultiConfigurationProject.java new file mode 100644 index 000000000..6112bc5f9 --- /dev/null +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAMultiConfigurationProject.java @@ -0,0 +1,41 @@ +package net.serenitybdd.screenplay.jenkins.tasks; + +import net.serenitybdd.screenplay.Actor; +import net.serenitybdd.screenplay.Task; +import net.serenitybdd.screenplay.jenkins.tasks.configuration.AddAxis; +import net.serenitybdd.screenplay.jenkins.tasks.configuration.TodoList; +import net.serenitybdd.screenplay.jenkins.user_interface.NewJobPage; +import net.thucydides.core.annotations.Step; + +import static net.serenitybdd.screenplay.Tasks.instrumented; + +public class CreateAMultiConfigurationProject implements Task { + + public static CreateAMultiConfigurationProject called(String name) { + return instrumented(CreateAMultiConfigurationProject.class, name); + } + + public CreateAMultiConfigurationProject andConfigureItTo(Task configurationTask) { + this.configureTheProject.add(configurationTask); + + return this; + } + + @Step("{0} creates a 'Multi-Configuration' called '#name'") + @Override + public void performAs(T actor) { + actor.attemptsTo( + CreateAProject.called(name) + .ofType(NewJobPage.Multi_Configuration_Project) + .andConfigureItTo(configureTheProject) + ); + } + + public CreateAMultiConfigurationProject(String jobName) { + this.name = jobName; + } + + private final String name; + private final TodoList configureTheProject = TodoList.empty(); + +} diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAProject.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAProject.java index d246f8f76..3202cb63f 100644 --- a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAProject.java +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/CreateAProject.java @@ -48,7 +48,7 @@ public CreateAProject(String jobName) { this.name = jobName; } - private final String name; - private final TodoList configureTheProject = TodoList.empty(); - private Target projectType; + private final String name; + private final TodoList configureTheProject = TodoList.empty(); + private Target projectType; } \ No newline at end of file diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/configuration/AddAxis.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/configuration/AddAxis.java new file mode 100644 index 000000000..6d02c43b5 --- /dev/null +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/configuration/AddAxis.java @@ -0,0 +1,35 @@ +package net.serenitybdd.screenplay.jenkins.tasks.configuration; + +import net.serenitybdd.screenplay.actions.Click; +import net.serenitybdd.screenplay.actions.Enter; +import net.serenitybdd.screenplay.jenkins.targets.Link; +import net.serenitybdd.screenplay.jenkins.user_interface.ProjectConfigurationPage; +import net.serenitybdd.screenplay.jenkins.user_interface.EditUserDefinedAxis; +import net.serenitybdd.screenplay.Actor; +import net.serenitybdd.screenplay.Task; +import net.serenitybdd.screenplayx.actions.Scroll; +import net.thucydides.core.annotations.Step; + +public class AddAxis implements Task { + public static Task of(Axis axis) { + return new AddAxis(axis); + } + + @Step("{0} configures Multi-Configuration project axis") + @Override + public void performAs(T actor) { + actor.attemptsTo( + Scroll.to(ProjectConfigurationPage.Add_Axis), + Click.on(ProjectConfigurationPage.Add_Axis), + Click.on(Link.called("User-defined Axis")), + Enter.theValue(axis.getName()).into(EditUserDefinedAxis.EditAxisName), + Enter.theValue(axis.getValues()).into(EditUserDefinedAxis.EditAxisVals) + ); + } + + public AddAxis(Axis axis) { + this.axis = axis; + } + + private Axis axis; +} diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/configuration/Axis.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/configuration/Axis.java new file mode 100644 index 000000000..539cbe28b --- /dev/null +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/tasks/configuration/Axis.java @@ -0,0 +1,25 @@ +package net.serenitybdd.screenplay.jenkins.tasks.configuration; + +public class Axis { + + private String name; + private String[] values; + + public Axis(String name, String[] values) { + this.name = name; + this.values = values; + } + + public String getName() { + return this.name; + } + + public String getValues() { + String dimensions = ""; + for(String val : values) { + dimensions += val + " "; + } + + return dimensions; + } +} diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/EditUserDefinedAxis.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/EditUserDefinedAxis.java new file mode 100644 index 000000000..b103230e1 --- /dev/null +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/EditUserDefinedAxis.java @@ -0,0 +1,8 @@ +package net.serenitybdd.screenplay.jenkins.user_interface; + +import net.serenitybdd.screenplay.targets.Target; + +public class EditUserDefinedAxis { + public static final Target EditAxisName = Target.the("code editor").locatedBy("(//div[@descriptorid='hudson.matrix.TextAxis']//input[@class='setting-input validated '])"); + public static final Target EditAxisVals = Target.the("code editor").locatedBy("(//div[@descriptorid='hudson.matrix.TextAxis']//input[@class='setting-input'])"); +} \ No newline at end of file diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/NewJobPage.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/NewJobPage.java index 65571ccbb..296b3d45c 100644 --- a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/NewJobPage.java +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/NewJobPage.java @@ -8,8 +8,9 @@ @DefaultUrl("/newJob") public class NewJobPage extends PageObject { - public static final Target Item_Name_Field = Setting.defining("Item name"); - public static final Target Freestyle_Project = RadioButton.withLabel("Freestyle project"); - public static final Target Pipeline = RadioButton.withLabel("Pipeline"); - public static final Target External_Project = RadioButton.withLabel("External Job"); + public static final Target Item_Name_Field = Setting.defining("Item name"); + public static final Target Freestyle_Project = RadioButton.withLabel("Freestyle project"); + public static final Target Pipeline = RadioButton.withLabel("Pipeline"); + public static final Target External_Project = RadioButton.withLabel("External Job"); + public static final Target Multi_Configuration_Project = RadioButton.withLabel("Multi-configuration project"); } \ No newline at end of file diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ProjectConfigurationPage.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ProjectConfigurationPage.java index 8d265eaf3..84e613a7b 100644 --- a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ProjectConfigurationPage.java +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ProjectConfigurationPage.java @@ -5,7 +5,8 @@ import net.serenitybdd.screenplay.targets.Target; public class ProjectConfigurationPage { - public static final Target Execute_Concurrent_Builds = Checkbox.withLabel("Execute concurrent builds if necessary"); - public static final Target Add_Build_Step = Button.called("Add build step"); - public static final Target Add_Post_Build_Action = Button.called("Add post-build action"); + public static final Target Execute_Concurrent_Builds = Checkbox.withLabel("Execute concurrent builds if necessary"); + public static final Target Add_Build_Step = Button.called("Add build step"); + public static final Target Add_Post_Build_Action = Button.called("Add post-build action"); + public static final Target Add_Axis = Button.called("Add axis"); } diff --git a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ViewConfigurationPage.java b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ViewConfigurationPage.java index 0abf3c224..ac0e3bba4 100644 --- a/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ViewConfigurationPage.java +++ b/build-monitor-acceptance/src/main/java/net/serenitybdd/screenplay/jenkins/user_interface/ViewConfigurationPage.java @@ -8,4 +8,5 @@ public class ViewConfigurationPage { public static final Target Recurse_In_Subfolders = Target.the("the 'Recurse in subfolders' option").locatedBy("#recurse"); public static final Target Use_Regular_Expression = Checkbox.withLabel("Use a regular expression to include jobs into the view"); public static final Target Regular_Expression = Target.the("the 'Regular expression' field").located(By.name("includeRegex")); + public static final Target Display_Multi_Config_Jobs = Target.the("the 'Show multiple configuration jobs' option").locatedBy("#multiConfig"); } \ No newline at end of file diff --git a/build-monitor-acceptance/src/test/java/features/ShouldDisplayMultiConfigJobs.java b/build-monitor-acceptance/src/test/java/features/ShouldDisplayMultiConfigJobs.java new file mode 100644 index 000000000..3431da7d5 --- /dev/null +++ b/build-monitor-acceptance/src/test/java/features/ShouldDisplayMultiConfigJobs.java @@ -0,0 +1,60 @@ +package features; + +import com.smartcodeltd.jenkinsci.plugins.build_monitor.questions.ProjectWidget; +import com.smartcodeltd.jenkinsci.plugins.build_monitor.tasks.ConfigureEmptyBuildMonitorView; +import com.smartcodeltd.jenkinsci.plugins.build_monitor.tasks.CreateABuildMonitorView; +import com.smartcodeltd.jenkinsci.plugins.build_monitor.tasks.configuration.DisplayAllProjects; +import com.smartcodeltd.jenkinsci.plugins.build_monitor.tasks.configuration.DisplayMultiConfig; +import environment.JenkinsSandbox; +import net.serenitybdd.integration.jenkins.JenkinsInstance; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.serenitybdd.screenplay.Actor; +import net.serenitybdd.screenplay.abilities.BrowseTheWeb; +import net.serenitybdd.screenplay.jenkins.HaveAMultiConfigProjectCreated; +import net.serenitybdd.screenplay.jenkins.tasks.configuration.AddAxis; +import net.serenitybdd.screenplay.jenkins.tasks.configuration.Axis; +import net.serenitybdd.screenplayx.actions.Navigate; +import net.thucydides.core.annotations.Managed; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.WebDriver; + +import static net.serenitybdd.screenplay.GivenWhenThen.*; +import static org.hamcrest.Matchers.is; + +@RunWith(SerenityRunner.class) +public class ShouldDisplayMultiConfigJobs { + + Actor mason = Actor.named("Mason"); + + Axis numbers = new Axis("Numbers", new String[] {"1", "2"}); + + @Managed public WebDriver hisBrowser; + + @Rule + public JenkinsInstance jenkins = JenkinsSandbox.configure().create(); + + @Before + public void actorCanBrowseTheWeb() { + mason.can(BrowseTheWeb.with(hisBrowser)); + } + + @Test + public void displaying_two_configuration_widgets() throws Exception { + + givenThat(mason).wasAbleTo( + Navigate.to(jenkins.url()), + HaveAMultiConfigProjectCreated.called("MultiProject") + .andConfigureItTo(AddAxis.of(numbers)) + ); + + when(mason).attemptsTo( + CreateABuildMonitorView.called("Build Monitor"), + ConfigureEmptyBuildMonitorView.to(DisplayMultiConfig.usingDisplayMultiConfigCheckbox(), DisplayAllProjects.usingARegularExpression()) + ); + + then(mason).should(seeThat(ProjectWidget.of("MultiProject").multiConfigBadgeNames(), is("MultiProject » 1:::MultiProject » 2"))); + } +} diff --git a/build-monitor-plugin/pom.xml b/build-monitor-plugin/pom.xml index 2f5a7a57a..7629e2fc8 100644 --- a/build-monitor-plugin/pom.xml +++ b/build-monitor-plugin/pom.xml @@ -145,6 +145,12 @@ 2.1.10 true + + org.jenkins-ci.plugins + matrix-project + 1.2.1 + true + com.sonyericsson.jenkins.plugins.bfa build-failure-analyzer @@ -302,7 +308,7 @@ version={{ version }} - file://${project.basedir}/target/classes/build-monitor.properties + ${project.baseUri}/target/classes/build-monitor.properties diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java index 12e065443..df7f83ee9 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java @@ -55,6 +55,8 @@ public class BuildMonitorView extends ListView { private String title; + private static final StaticJenkinsAPIs jenkinsAPIs = new StaticJenkinsAPIs(); + /** * @param name Name of the view to be displayed on the Views tab * @param title Title to be displayed on the Build Monitor; defaults to 'name' if not set @@ -96,6 +98,11 @@ public boolean isDisplayCommitters() { return currentConfig().shouldDisplayCommitters(); } + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public boolean isDisplayMultiConfigJob() { + return currentConfig().shouldDisplayMultiConfigJobs(); + } + private static final BuildMonitorInstallation installation = new BuildMonitorInstallation(); @SuppressWarnings("unused") // used in index.jelly @@ -121,6 +128,7 @@ protected void submit(StaplerRequest req) throws ServletException, IOException, currentConfig().setDisplayCommitters(json.optBoolean("displayCommitters", true)); currentConfig().setBuildFailureAnalyzerDisplayedField(req.getParameter("buildFailureAnalyzerDisplayedField")); + currentConfig().setDisplayMultiConfigJobs(req.getParameter("displayMultiConfigJobs")); try { currentConfig().setOrder(orderIn(requestedOrdering)); @@ -158,7 +166,7 @@ private List jobViews() { Collections.sort(projects, currentConfig().getOrder()); for (Job project : projects) { - jobs.add(views.viewOf(project)); + jobs.addAll(views.viewsOf(project)); } return jobs; @@ -210,6 +218,11 @@ private void migrateFromOldToNewConfigFormat() { return (Comparator>) Class.forName(packageName + requestedOrdering).newInstance(); } + @SuppressWarnings("unused") // Used in configure-entries.jelly + public Boolean containsMatrixProjectPlugin() { + return jenkinsAPIs.hasPlugin("matrix-project"); + } + private Config config; @Deprecated // use Config instead diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java index c10b3296f..a146fa9ff 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java @@ -11,6 +11,7 @@ public class Config { private boolean displayCommitters; + private boolean displayMultiConfigJobs; private BuildFailureAnalyzerDisplayedField buildFailureAnalyzerDisplayedField; public static Config defaultConfig() { @@ -48,6 +49,18 @@ public boolean shouldDisplayCommitters() { public void setDisplayCommitters(boolean flag) { this.displayCommitters = flag; } + + public void setDisplayMultiConfigJobs(String key) { + if(key == null) { + this.displayMultiConfigJobs = false; + } else { + this.displayMultiConfigJobs = true; + } + } + + public boolean shouldDisplayMultiConfigJobs() { + return this.displayMultiConfigJobs; + } @Override public String toString() { diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobView.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobView.java index 4c992340d..bb2fa11b8 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobView.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobView.java @@ -1,7 +1,6 @@ package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel; import com.google.common.base.Objects; -import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.smartcodeltd.jenkinsci.plugins.buildmonitor.facade.RelativeLocation; import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.duration.Duration; @@ -13,11 +12,13 @@ import org.codehaus.jackson.map.annotate.JsonSerialize; +import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import static com.google.common.collect.Lists.newArrayList; +import static hudson.Util.filter; import static java.lang.String.format; /** @@ -32,8 +33,15 @@ public class JobView { private final List features = newArrayList(); - public static JobView of(Job job, List features, boolean isPipelineJob) { - return new JobView(job, features, isPipelineJob, RelativeLocation.of(job), new Date()); + // A Feature() instance may add to this list if it is designed to create multiple widgets from a single Job() + private final List jobs = newArrayList(); + + public static List of(Job job, List features, boolean isPipelineJob) { + List displayJobs = new ArrayList(); + + displayJobs.add(new JobView(job, features, isPipelineJob, RelativeLocation.of(job), new Date())); + + return displayJobs; } public JobView(Job job, List features, boolean isPipelineJob, RelativeLocation relative, Date systemTime) { @@ -45,8 +53,19 @@ public JobView(Job job, List features, boolean isPipelineJob, Rel for (Feature feature : features) { this.features.add(feature.of(this)); } + + for (Feature feature : features) { + this.jobs.addAll(feature.jobs(this, job)); + } + + // All instances of Feature() get the first opportunity to + if (this.jobs.isEmpty()) { + this.jobs.add(this); + } } + public List getJobs() { return ImmutableList.copyOf(jobs); } + public List features() { return ImmutableList.copyOf(features); } diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViewSerialiser.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViewSerialiser.java index cdd44f47f..f8e7f7770 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViewSerialiser.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViewSerialiser.java @@ -6,30 +6,35 @@ import org.codehaus.jackson.map.SerializerProvider; import java.io.IOException; +import java.util.List; /** * @author Jan Molak */ public class JobViewSerialiser extends JsonSerializer { @Override - public void serialize(JobView job, JsonGenerator jgen, SerializerProvider provider) throws IOException { - jgen.writeStartObject(); - jgen.writeObjectField("name", job.name()); - jgen.writeObjectField("url", job.url()); - jgen.writeObjectField("status", job.status()); - jgen.writeObjectField("hashCode", job.hashCode()); - jgen.writeObjectField("progress", job.progress()); - jgen.writeObjectField("estimatedDuration", job.estimatedDuration()); - - for (Feature feature : job.features()) { - Object serialised = feature.asJson(); - - if (serialised != null) { - jgen.writeObjectField(nameOf(serialised), serialised); + public void serialize(JobView parentJob, JsonGenerator jgen, SerializerProvider provider) throws IOException { + List jobs = parentJob.getJobs(); + + for(JobView job : jobs) { + jgen.writeStartObject(); + jgen.writeObjectField("name", job.name()); + jgen.writeObjectField("url", job.url()); + jgen.writeObjectField("status", job.status()); + jgen.writeObjectField("hashCode", job.hashCode()); + jgen.writeObjectField("progress", job.progress()); + jgen.writeObjectField("estimatedDuration", job.estimatedDuration()); + + for (Feature feature : job.features()) { + Object serialised = feature.asJson(); + + if (serialised != null) { + jgen.writeObjectField(nameOf(serialised), serialised); + } } - } - jgen.writeEndObject(); + jgen.writeEndObject(); + } } private String nameOf(Object serialised) { diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViews.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViews.java index 9b0c3accc..2ac64bac7 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViews.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/JobViews.java @@ -3,6 +3,7 @@ import com.smartcodeltd.jenkinsci.plugins.buildmonitor.facade.StaticJenkinsAPIs; import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.features.*; import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.features.headline.HeadlineConfig; +import hudson.matrix.MatrixProject; import hudson.model.Job; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -18,6 +19,7 @@ public class JobViews { private static final String Build_Failure_Analyzer = "build-failure-analyzer"; private static final String Groovy_Post_Build = "groovy-postbuild"; private static final String Pipeline = "workflow-aggregator"; + private static final String Matrix_Project = "matrix-project"; private final StaticJenkinsAPIs jenkins; private final com.smartcodeltd.jenkinsci.plugins.buildmonitor.Config config; @@ -27,7 +29,7 @@ public JobViews(StaticJenkinsAPIs jenkins, com.smartcodeltd.jenkinsci.plugins.bu this.config = config; } - public JobView viewOf(Job job) { + public List viewsOf(Job job) { List viewFeatures = newArrayList(); // todo: a more elegant way of assembling the features would be nice @@ -47,8 +49,13 @@ public JobView viewOf(Job job) { viewFeatures.add(new HasBadges()); } + if (jenkins.hasPlugin(Matrix_Project) && job instanceof MatrixProject && config.shouldDisplayMultiConfigJobs()) { + viewFeatures.add(new ShowMatrixConfigurations()); + } + boolean isPipelineJob = jenkins.hasPlugin(Pipeline) && job instanceof WorkflowJob; + return JobView.of(job, viewFeatures, isPipelineJob); } } diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/BaseFeature.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/BaseFeature.java new file mode 100644 index 000000000..89a6848e1 --- /dev/null +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/BaseFeature.java @@ -0,0 +1,29 @@ +package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.features; + +import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.JobView; +import hudson.model.Job; + +import java.util.Arrays; +import java.util.List; + +public abstract class BaseFeature implements Feature { + private JobView job; + + @Override + public BaseFeature of(JobView jobView) { + this.job = jobView; + + return this; + } + + @Override + public JSON asJson() { + return null; + } + + @Override + public List jobs(JobView parentJobView, Job parentJob) { + /* Can override this if a feature can create multiple jobviews */ + return Arrays.asList(); + } +} diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeClaimed.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeClaimed.java index b6d503924..bf96e9fc8 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeClaimed.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeClaimed.java @@ -5,7 +5,7 @@ import hudson.plugins.claim.ClaimBuildAction; import org.codehaus.jackson.annotate.JsonProperty; -public class CanBeClaimed implements Feature { +public class CanBeClaimed extends BaseFeature { private JobView job; @Override diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeDiagnosedForProblems.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeDiagnosedForProblems.java index 7c726a6ba..5667d147d 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeDiagnosedForProblems.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanBeDiagnosedForProblems.java @@ -12,7 +12,7 @@ import static com.google.common.collect.Lists.newArrayList; -public class CanBeDiagnosedForProblems implements Feature { +public class CanBeDiagnosedForProblems extends BaseFeature { private JobView job; private BuildFailureAnalyzerDisplayedField displayedField; diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/Feature.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/Feature.java index 913ebd359..e5cb2e18b 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/Feature.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/Feature.java @@ -1,10 +1,15 @@ package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.features; import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.JobView; +import hudson.model.Job; + +import java.util.List; /** * @author Jan Molak */ public interface Feature extends SerialisableAsJsonObjectCalled { F of(JobView jobView); + + List jobs(JobView parentJobView, Job parentJob); } diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasBadges.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasBadges.java index cdfce71d1..cc9e6bd33 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasBadges.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasBadges.java @@ -17,7 +17,7 @@ /** * @author Daniel Beland */ -public class HasBadges implements Feature { +public class HasBadges extends BaseFeature { private ActionFilter filter = new ActionFilter(); private JobView job; diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasHeadline.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasHeadline.java index ee338d83d..f24aee289 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasHeadline.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/HasHeadline.java @@ -13,7 +13,7 @@ /** * @author Jan Molak */ -public class HasHeadline implements Feature { +public class HasHeadline extends BaseFeature { private final HeadlineConfig config; private JobView job; diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsCurrentBuildsDetails.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsCurrentBuildsDetails.java index 93c025239..ace3c5ff5 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsCurrentBuildsDetails.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsCurrentBuildsDetails.java @@ -17,7 +17,7 @@ /** * @author Jan Molak */ -public class KnowsCurrentBuildsDetails implements Feature { +public class KnowsCurrentBuildsDetails extends BaseFeature { private JobView job; public KnowsCurrentBuildsDetails(/* config */) { diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsLastCompletedBuildDetails.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsLastCompletedBuildDetails.java index a768592ff..d20eb142a 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsLastCompletedBuildDetails.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/KnowsLastCompletedBuildDetails.java @@ -8,7 +8,7 @@ /** * @author Jan Molak */ -public class KnowsLastCompletedBuildDetails implements Feature { +public class KnowsLastCompletedBuildDetails extends BaseFeature { private JobView job; public KnowsLastCompletedBuildDetails(/* config */) { diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/ShowMatrixConfigurations.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/ShowMatrixConfigurations.java new file mode 100644 index 000000000..f93c9460e --- /dev/null +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/ShowMatrixConfigurations.java @@ -0,0 +1,39 @@ +package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.features; + +import com.smartcodeltd.jenkinsci.plugins.buildmonitor.facade.RelativeLocation; +import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.JobView; +import hudson.matrix.MatrixConfiguration; +import hudson.matrix.MatrixProject; +import hudson.model.Job; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static hudson.Util.filter; + +public class ShowMatrixConfigurations extends BaseFeature { + private JobView job; + + @Override + public ShowMatrixConfigurations of(JobView jobView) { + this.job = jobView; + + return this; + } + + @Override + public List jobs(JobView parentJobView, Job parentJob) { + List subJobs = new ArrayList(); + + List matrixConfigurations = parentJob instanceof MatrixProject + ? filter(parentJob.getAllJobs(), MatrixConfiguration.class) + : new ArrayList(); + + for (Job matrixConfiguration : matrixConfigurations) { + subJobs.add(new JobView(matrixConfiguration, parentJobView.features(), false, RelativeLocation.of(matrixConfiguration), new Date())); + } + + return subJobs; + } +} diff --git a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly index 3c39f5625..471a507e4 100644 --- a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly +++ b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly @@ -67,6 +67,12 @@ + + + + + + diff --git a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/help-showMatrixProjectConfigurations.html b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/help-showMatrixProjectConfigurations.html new file mode 100644 index 000000000..b743f02da --- /dev/null +++ b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/help-showMatrixProjectConfigurations.html @@ -0,0 +1,4 @@ +
+ If selected the Build View Monitor will show all build configurations for any multi-configuration project + included in the view. The parent multi-configuration job will not be shown. +
\ No newline at end of file diff --git a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanShowMatrixConfigurationsTest.java b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanShowMatrixConfigurationsTest.java new file mode 100644 index 000000000..a99300399 --- /dev/null +++ b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/features/CanShowMatrixConfigurationsTest.java @@ -0,0 +1,35 @@ +package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.features; + +import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.JobView; +import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.syntacticsugar.JobStateRecipe; +import com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.syntacticsugar.MatrixConfigurationStateRecipe; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Arrays; +import java.util.List; + +import static com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.syntacticsugar.Sugar.*; +import static hudson.model.Result.SUCCESS; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class CanShowMatrixConfigurationsTest { + private JobView job; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void should_know_if_a_failing_build_has_been_claimed() throws Exception { + List matrixConfigurations = Arrays.asList( + new MatrixConfigurationStateRecipe().withName("A").whereTheLast(build().finishedWith(SUCCESS)), + new MatrixConfigurationStateRecipe().withName("B").whereTheLast(build().finishedWith(SUCCESS)) + ); + + job = a(jobView().which(new ShowMatrixConfigurations()).of(a(matrixProject(matrixConfigurations)))); + + assertThat(job.getJobs().size(), is(2)); + } +} diff --git a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/JobStateRecipe.java b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/JobStateRecipe.java index 86964d54b..0bdfdd6ba 100644 --- a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/JobStateRecipe.java +++ b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/JobStateRecipe.java @@ -22,7 +22,7 @@ * @author Jan Molak */ public class JobStateRecipe implements Supplier> { - private Job job; + protected Job job; private RunList runList; private Stack buildHistory = new Stack(); private List allBuilds = new ArrayList(); diff --git a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/MatrixConfigurationStateRecipe.java b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/MatrixConfigurationStateRecipe.java new file mode 100644 index 000000000..30d74edef --- /dev/null +++ b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/MatrixConfigurationStateRecipe.java @@ -0,0 +1,20 @@ +package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.syntacticsugar; + +import hudson.matrix.MatrixConfiguration; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MatrixConfigurationStateRecipe extends JobStateRecipe { + public MatrixConfigurationStateRecipe() { + super(); + job = mock(MatrixConfiguration.class); + } + + @Override + public MatrixConfigurationStateRecipe withName(String name) { + when(job.getName()).thenReturn(name); + + return this; + } +} \ No newline at end of file diff --git a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/MatrixProjectStateRecipe.java b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/MatrixProjectStateRecipe.java new file mode 100644 index 000000000..8f922d938 --- /dev/null +++ b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/MatrixProjectStateRecipe.java @@ -0,0 +1,34 @@ +package com.smartcodeltd.jenkinsci.plugins.buildmonitor.viewmodel.syntacticsugar; + +import hudson.matrix.MatrixProject; +import hudson.model.Job; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.mockito.Mockito.mock; + +class MatrixProjectStateRecipe extends JobStateRecipe { + private List matrixConfigurationStateRecipes; + + public MatrixProjectStateRecipe(List matrixConfigurationStateRecipes) { + super(); + + job = mock(MatrixProject.class); + this.matrixConfigurationStateRecipes = matrixConfigurationStateRecipes; + + Mockito.doReturn(extractJobs(this.matrixConfigurationStateRecipes)).when(job).getAllJobs(); + } + + private Collection> extractJobs(List matrixConfigurationStateRecipes) { + List> jobs = new ArrayList>(); + + for (JobStateRecipe matrixConfigurationStateRecipe : matrixConfigurationStateRecipes) { + jobs.add(matrixConfigurationStateRecipe.job); + } + + return jobs; + } +} \ No newline at end of file diff --git a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/Sugar.java b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/Sugar.java index 6ae71025e..6637f5e96 100644 --- a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/Sugar.java +++ b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/viewmodel/syntacticsugar/Sugar.java @@ -4,6 +4,8 @@ import com.smartcodeltd.jenkinsci.plugins.buildmonitor.Config; import com.smartcodeltd.jenkinsci.plugins.buildmonitor.facade.RelativeLocation; +import java.util.List; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -17,6 +19,10 @@ public static JobStateRecipe job() { return new JobStateRecipe(); } + public static JobStateRecipe matrixProject(List matrixConfigurationStateRecipes) { + return new MatrixProjectStateRecipe(matrixConfigurationStateRecipes); + } + public static BuildStateRecipe build() { return new BuildStateRecipe(); }