@Test
  public void codecRoundTrip() {
    codec.defineCommand("buy", POST, "/:sessionId/fruit/:fruit/size/:size");

    Command original =
        new Command(
            new SessionId("session123"),
            "buy",
            ImmutableMap.of("fruit", "apple", "size", "large", "color", "red", "rotten", "false"));
    HttpRequest request = codec.encode(original);
    Command decoded = codec.decode(request);

    assertThat(decoded.getName(), is(original.getName()));
    assertThat(decoded.getSessionId(), is(original.getSessionId()));
    assertThat(decoded.getParameters(), is((Map) original.getParameters()));
  }
  @Test
  public void removesSessionIdFromParameterMap() throws URISyntaxException {
    HttpRequest request = new HttpRequest(GET, "/foo/bar/baz");
    codec.defineCommand("foo", GET, "/foo/:sessionId/baz");

    Command decoded = codec.decode(request);
    assertThat(decoded.getSessionId(), is(new SessionId("bar")));
    assertThat(decoded.getParameters().isEmpty(), is(true));
  }
  @Test
  public void canDecodeCommandWithNoParameters() throws URISyntaxException {
    HttpRequest request = new HttpRequest(GET, "/foo/bar/baz");
    codec.defineCommand("foo", GET, "/foo/bar/baz");

    Command decoded = codec.decode(request);
    assertThat(decoded.getName(), is("foo"));
    assertThat(decoded.getSessionId(), is(nullValue()));
    assertThat(decoded.getParameters().isEmpty(), is(true));
  }
  @Test
  public void decodingUsesUtf8IfNoEncodingSpecified() {
    codec.defineCommand("num", POST, "/one");

    byte[] data = "{\"char\":\"水\"}".getBytes(UTF_8);
    HttpRequest request = new HttpRequest(POST, "/one");
    request.setHeader(CONTENT_TYPE, JSON_UTF_8.withoutParameters().toString());
    request.setHeader(CONTENT_LENGTH, String.valueOf(data.length));
    request.setContent(data);

    Command command = codec.decode(request);
    assertThat((String) command.getParameters().get("char"), is("水"));
  }
  @Test
  public void extractsAllParametersFromUrl() throws URISyntaxException {
    HttpRequest request = new HttpRequest(GET, "/fruit/apple/size/large");
    codec.defineCommand("pick", GET, "/fruit/:fruit/size/:size");

    Command decoded = codec.decode(request);
    assertThat(
        decoded.getParameters(),
        is(
            (Map)
                ImmutableMap.of(
                    "fruit", "apple",
                    "size", "large")));
  }
  @Test
  public void extractsAllPrameters() throws JSONException, URISyntaxException {
    String data =
        new JSONObject()
            .put("sessionId", "sessionX")
            .put("fruit", "apple")
            .put("color", "red")
            .put("size", "large")
            .toString();

    HttpRequest request = new HttpRequest(POST, "/fruit/apple/size/large");
    request.setContent(data.getBytes(UTF_8));
    codec.defineCommand("pick", POST, "/fruit/:fruit/size/:size");

    Command decoded = codec.decode(request);
    assertThat(
        decoded.getParameters(),
        is((Map) ImmutableMap.of("fruit", "apple", "size", "large", "color", "red")));
  }