package org.kohsuke.stapler;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.HttpMethod;
import com.gargoylesoftware.htmlunit.TextPage;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequestSettings;
import org.kohsuke.stapler.test.JettyTestCase;
import org.kohsuke.stapler.verb.GET;
import org.kohsuke.stapler.verb.POST;

import java.net.URL;

/**
 * @author Kohsuke Kawaguchi
 */
public class DispatcherTest extends JettyTestCase {

    public final IndexDispatchByName indexDispatchByName = new IndexDispatchByName();

    public class IndexDispatchByName {
        @WebMethod(name="")
        public HttpResponse doHelloWorld() {
            return HttpResponses.plainText("Hello world");
        }
    }

    /**
     * Makes sure @WebMethod(name="") has the intended effect of occupying the root of the object in the URL space.
     */
    public void testIndexDispatchByName() throws Exception {
        WebClient wc = new WebClient();
        TextPage p = wc.getPage(new URL(url, "indexDispatchByName"));
        assertEquals("Hello world\n", p.getContent());
    }


    //===================================================================


    public final VerbMatch verbMatch = new VerbMatch();

    public class VerbMatch {
        @WebMethod(name="") @GET
        public HttpResponse doGet() {
            return HttpResponses.plainText("Got GET");
        }

        @WebMethod(name="") @POST
        public HttpResponse doPost() {
            return HttpResponses.plainText("Got POST");
        }
    }

    /**
     * Tests the dispatching of WebMethod based on verb
     */
    public void testVerbMatch() throws Exception {
        WebClient wc = new WebClient();

        check(wc, HttpMethod.GET);
        check(wc, HttpMethod.POST);
        try {
            check(wc, HttpMethod.DELETE);
            fail("There's no route for DELETE");
        } catch (FailingHttpStatusCodeException e) {
            assertEquals(404, e.getStatusCode());
        }
    }

    private void check(WebClient wc, HttpMethod m) throws java.io.IOException {
        TextPage p = wc.getPage(new WebRequestSettings(new URL(url, "verbMatch/"), m));
        assertEquals("Got "+m.name()+"\n", p.getContent());
    }


    //===================================================================


    public final ArbitraryWebMethodName arbitraryWebMethodName = new ArbitraryWebMethodName();

    public class ArbitraryWebMethodName {
        @WebMethod(name="")
        public HttpResponse notDoPrefix() {
            return HttpResponses.plainText("I'm index");
        }

        // this method is implicitly web method by its name
        public HttpResponse doTheNeedful() {
            return HttpResponses.plainText("DTN");
        }
    }


    public void testArbitraryWebMethodName() throws Exception {
        WebClient wc = new WebClient();
        TextPage p = wc.getPage(new URL(url, "arbitraryWebMethodName"));
        assertEquals("I'm index\n", p.getContent());

        p = wc.getPage(new URL(url, "arbitraryWebMethodName/theNeedful"));
        assertEquals("DTN\n", p.getContent());

    }
}
@@ -293,16 +293,58 @@
 ttings;%0A
+import org.kohsuke.stapler.json.JsonBody;%0A
 import o
@@ -3230,19 +3230,1170 @@
 ontent());%0A%0A
+    %7D%0A%0A%0A    //===================================================================%0A%0A%0A    public final InterceptorStage interceptorStage = new InterceptorStage();%0A%0A    public class InterceptorStage %7B%0A        @POST%0A        public HttpResponse doFoo(@JsonBody Point body) %7B%0A            return HttpResponses.plainText(body.x+%22,%22+body.y);%0A        %7D%0A    %7D%0A%0A    public static class Point %7B%0A        public int x,y;%0A    %7D%0A%0A    /**%0A     * POST annotation selection needs to happen before databinding of the parameter happens.%0A     */%0A    public void testInterceptorStage() throws Exception %7B%0A        WebClient wc = new WebClient();%0A        try %7B%0A            wc.getPage(new URL(url, %22interceptorStage/foo%22));%0A            fail(%22Expected 404%22);%0A        %7D catch (FailingHttpStatusCodeException e) %7B%0A            assertEquals(404, e.getStatusCode());%0A        %7D%0A%0A        WebRequestSettings req = new WebRequestSettings(new URL(url, %22interceptorStage/foo%22), HttpMethod.POST);%0A        req.setAdditionalHeader(%22Content-Type%22,%22application/json%22);%0A        req.setRequestBody(%22%7Bx:3,y:5%7D%22);%0A        TextPage p = wc.getPage(req);%0A        assertEquals(%223,5%5Cn%22,p.getContent());%0A%0A
     %7D%0A%7D

test case to reproduce the problem