diff --git a/core/src/main/java/hudson/model/Api.java b/core/src/main/java/hudson/model/Api.java index 8a6ffc90a1..63f73317f9 100644 --- a/core/src/main/java/hudson/model/Api.java +++ b/core/src/main/java/hudson/model/Api.java @@ -111,30 +111,27 @@ public class Api extends AbstractModelObject { } List list = dom.selectNodes(xpath); - if(list.isEmpty()) { - // XPath didn't match + if (wrapper!=null) { + Element root = DocumentFactory.getInstance().createElement(wrapper); + for (Object o : list) { + if (o instanceof String) { + root.addText(o.toString()); + } else { + root.add(((org.dom4j.Node)o).detach()); + } + } + result = root; + } else if (list.isEmpty()) { rsp.setStatus(HttpServletResponse.SC_NOT_FOUND); rsp.getWriter().print(Messages.Api_NoXPathMatch(xpath)); return; - } - if(list.size()>1) { - if(wrapper!=null) { - Element root = DocumentFactory.getInstance().createElement(wrapper); - for (Object o : list) { - if(o instanceof String) - root.addText(o.toString()); - else - root.add(((org.dom4j.Node)o).detach()); - } - result = root; - } else { - // XPath didn't match - rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - rsp.getWriter().print(Messages.Api_MultipleMatch(xpath,list.size())); - return; - } - } else + } else if (list.size() > 1) { + rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + rsp.getWriter().print(Messages.Api_MultipleMatch(xpath,list.size())); + return; + } else { result = list.get(0); + } } catch (DocumentException e) { throw new IOException2(e); } diff --git a/test/src/test/java/hudson/model/ApiTest.java b/test/src/test/java/hudson/model/ApiTest.java index 46232fb5f0..e37cdda655 100644 --- a/test/src/test/java/hudson/model/ApiTest.java +++ b/test/src/test/java/hudson/model/ApiTest.java @@ -23,6 +23,8 @@ */ package hudson.model; +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.Page; import org.jvnet.hudson.test.HudsonTestCase; import org.jvnet.hudson.test.Bug; @@ -30,8 +32,52 @@ import org.jvnet.hudson.test.Bug; * @author Kohsuke Kawaguchi */ public class ApiTest extends HudsonTestCase { + @Bug(2828) public void testXPath() throws Exception { new WebClient().goTo("api/xml?xpath=/*[1]","application/xml"); } + + @Bug(3267) + public void testWrappedZeroItems() throws Exception { + Page page = new WebClient().goTo("api/xml?wrapper=root&xpath=/hudson/nonexistent", "application/xml"); + assertEquals("", page.getWebResponse().getContentAsString()); + } + + @Bug(3267) + public void testWrappedOneItem() throws Exception { + Page page = new WebClient().goTo("api/xml?wrapper=root&xpath=/hudson/view/name", "application/xml"); + assertEquals("All", page.getWebResponse().getContentAsString()); + } + + public void testWrappedMultipleItems() throws Exception { + createFreeStyleProject(); + createFreeStyleProject(); + Page page = new WebClient().goTo("api/xml?wrapper=root&xpath=/hudson/job/name", "application/xml"); + assertEquals("test0test1", page.getWebResponse().getContentAsString()); + } + + public void testUnwrappedZeroItems() throws Exception { + try { + new WebClient().goTo("api/xml?xpath=/hudson/nonexistent", "application/xml"); + } catch (FailingHttpStatusCodeException x) { + assertEquals(404, x.getStatusCode()); + } + } + + public void testUnwrappedOneItem() throws Exception { + Page page = new WebClient().goTo("api/xml?xpath=/hudson/view/name", "application/xml"); + assertEquals("All", page.getWebResponse().getContentAsString()); + } + + public void testUnwrappedMultipleItems() throws Exception { + createFreeStyleProject(); + createFreeStyleProject(); + try { + new WebClient().goTo("api/xml?xpath=/hudson/job/name", "application/xml"); + } catch (FailingHttpStatusCodeException x) { + assertEquals(500, x.getStatusCode()); + } + } + }