diff --git a/core/src/main/java/hudson/model/ListView.java b/core/src/main/java/hudson/model/ListView.java index 32e3779e3042cdd27b54bf7c5ff4f5e9ab56567d..be1483df66ba4bd216e5ba4155d17b970e185ec3 100644 --- a/core/src/main/java/hudson/model/ListView.java +++ b/core/src/main/java/hudson/model/ListView.java @@ -319,16 +319,26 @@ public class ListView extends View implements DirectlyModifiableView { } } + private boolean needToAddToCurrentView(StaplerRequest req) throws ServletException { + String json = req.getParameter("json"); + if (json != null && json.length() > 0) { + // Submitted via UI + JSONObject form = req.getSubmittedForm(); + return form.has("addToCurrentView") && form.getBoolean("addToCurrentView"); + } else { + // Submitted via API + return true; + } + } + @Override @RequirePOST public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - JSONObject form = req.getSubmittedForm(); - boolean addToCurrentView = form.has("addToCurrentView") && form.getBoolean("addToCurrentView"); ItemGroup ig = getOwnerItemGroup(); if (ig instanceof ModifiableItemGroup) { TopLevelItem item = ((ModifiableItemGroup)ig).doCreateItem(req, rsp); if (item!=null) { - if (addToCurrentView) { + if (needToAddToCurrentView(req)) { synchronized (this) { jobNames.add(item.getRelativeNameFrom(getOwnerItemGroup())); } diff --git a/test/src/test/java/hudson/model/ListViewTest.java b/test/src/test/java/hudson/model/ListViewTest.java index b2dd439b0b19ea239ebddb68312ed04ccebeec72..589a83daa2be5858f7ae570d9006fe070960633c 100644 --- a/test/src/test/java/hudson/model/ListViewTest.java +++ b/test/src/test/java/hudson/model/ListViewTest.java @@ -37,27 +37,41 @@ import hudson.security.AuthorizationStrategy; import hudson.security.Permission; import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; + import org.acegisecurity.Authentication; import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import org.apache.commons.io.IOUtils; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestName; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; import org.jvnet.hudson.test.MockFolder; import org.jvnet.hudson.test.recipes.LocalData; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; import org.xml.sax.SAXException; public class ListViewTest { @Rule public JenkinsRule j = new JenkinsRule(); + @Rule public TestName testName = new TestName(); + @Issue("JENKINS-15309") @LocalData @Test public void nullJobNames() throws Exception { @@ -225,6 +239,26 @@ public class ListViewTest { } assertEquals(Collections.singletonList(p), v.getItems()); } + + @Issue("JENKINS-41128") + @Test public void addJobUsingAPI() throws Exception { + ListView v = new ListView("view", j.jenkins); + j.jenkins.addView(v); + StaplerRequest req = mock(StaplerRequest.class); + StaplerResponse rsp = mock(StaplerResponse.class); + + String configXml = IOUtils.toString(getClass().getResourceAsStream(String.format("%s/%s/config.xml", getClass().getSimpleName(), testName.getMethodName())), "UTF-8"); + + when(req.getMethod()).thenReturn("POST"); + when(req.getParameter("name")).thenReturn("job1"); + when(req.getInputStream()).thenReturn(new Stream(IOUtils.toInputStream(configXml))); + when(req.getContentType()).thenReturn("application/xml"); + v.doCreateItem(req, rsp); + List items = v.getItems(); + assertEquals(1, items.size()); + assertEquals("job1", items.get(0).getName()); + } + private static class AllButViewsAuthorizationStrategy extends AuthorizationStrategy { @Override public ACL getRootACL() { return UNSECURED.getRootACL(); @@ -241,4 +275,29 @@ public class ListViewTest { } } + private static class Stream extends ServletInputStream { + private final InputStream inner; + + public Stream(final InputStream inner) { + this.inner = inner; + } + + @Override + public int read() throws IOException { + return inner.read(); + } + @Override + public boolean isFinished() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isReady() { + throw new UnsupportedOperationException(); + } + @Override + public void setReadListener(ReadListener readListener) { + throw new UnsupportedOperationException(); + } + } + } diff --git a/test/src/test/resources/hudson/model/ListViewTest/addJobUsingAPI/config.xml b/test/src/test/resources/hudson/model/ListViewTest/addJobUsingAPI/config.xml new file mode 100644 index 0000000000000000000000000000000000000000..ff565b6b94a419fedf6eb7a5fc13e2af54ba27f3 --- /dev/null +++ b/test/src/test/resources/hudson/model/ListViewTest/addJobUsingAPI/config.xml @@ -0,0 +1,16 @@ + + + + false + + + true + false + false + false + + false + + + +