public class UriBuilderTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.NetTest";
    }

    public void testBasicFlow() {
        String expected = "http://user:pwd@localhost:8888/server/root/resource;class=2;class=5;class=6" +
                "/child;group=A;subGroup=A.1;subGroup=A.2?age=12&name=Aa&name=Zz#first";

        String uri = UriBuilder.newInstance()
                .scheme("http")
                .user("user")
                .password("pwd")
                .host("localhost")
                .port(8888)
                .path("server")
                .segment("root", "resource")
                .matrixParam("class", 2, 5, 6)
                .segment("child")
                .matrixParam("group", "A")
                .matrixParam("subGroup", "A.1", "A.2")
                .queryParam("age", 12)
                .queryParam("name", "Aa", "Zz")
                .fragment("first")
                .build().toString();

        assertEquals(expected, uri);
    }

    public void testCommaSeparatedStrategy() {
        String expected = "/server/root;class=2,5,6" +
                "/child;group=A;subGroup=A.1,A.2?age=12&name=Aa,Zz#first";

        String uri = UriBuilder.fromPath("server")
                .multivaluedParamComposition(MultivaluedParamComposition.COMMA_SEPARATED_VALUE)
                .segment("root")
                .matrixParam("class", 2, 5, 6)
                .segment("child")
                .matrixParam("group", "A")
                .matrixParam("subGroup", "A.1", "A.2")
                .queryParam("age", 12)
                .queryParam("name", "Aa", "Zz")
                .fragment("first")
                .build().toString();

        assertEquals(expected, uri);
    }

    public void testTemplateParams() {
        String expected = "http://user:pwd@localhost:8888/server/root/any;class=2;class=5;class=6" +
                "/child;group=A;subGroup=A.1;subGroup=A.2?age=12&name=Aa&name=Zz#firstserver";

        String uri = UriBuilder.newInstance()
                .scheme("http")
                .user("user")
                .password("pwd")
                .host("localhost")
                .port(8888)
                .path("{a}/{b}")
                .segment("{c}")
                .matrixParam("class", 2, 5, 6)
                .segment("child")
                .matrixParam("group", "A")
                .matrixParam("subGroup", "A.1", "A.2")
                .queryParam("age", 12)
                .queryParam("name", "Aa", "Zz")
                .fragment("{d}{a}")
                .build("server", "root", "any", "first").toString();

        assertEquals(expected, uri);
    }

    public void testInsufficientTemplateParams() {
        try {
            assertNull(UriBuilder.newInstance()
                    .path("{a}/{b}")
                    .segment("{c}")
                    .fragment("{d}{a}")
                    .build("server", "root", "any").toString());
        } catch (UriBuilderException e) {
            assertNotNull(e);
        }
    }
} public class ContentTypeAcceptPatternsTest extends GWTTestCase {

    final String uri = "/person";
    final Person person = new Person(1, "John Doe", 6.3, new Date(329356800));
    final String serializedResponse = "{\"id\":1, \"name\":\"John Doe\", \"weight\":6.3, \"birthday\":329356800}";
    final PersonSerdes personSerdes = new PersonSerdes();

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testWildcardBothParts() {
        personSerdes.setAcceptPatterns("*/*");
        personSerdes.setContentTypePatterns("*/*");

        prepareStub("application/json");
        final Requestor requestor = getRequestor();

        final boolean[] callbackSuccessCalled = new boolean[1];

        try {
            requestor.request(uri).payload(person).post(Person.class).done(new DoneCallback<Person>() {
                @Override
                public void onDone(Person person) {
                    callbackSuccessCalled[0] = true;
                }
            });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNull(e);
        }

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testWildcardFirstPart() {
        personSerdes.setAcceptPatterns("*/json");
        personSerdes.setContentTypePatterns("*/json");

        prepareStub("application/json");
        final Requestor requestor = getRequestor();

        final boolean[] callbackSuccessCalled = new boolean[1];

        try {
            requestor.request(uri).contentType("anything/json").accept("anything/json").payload(person)
                    .post(Person.class).done(new DoneCallback<Person>() {
                @Override
                public void onDone(Person person) {
                    callbackSuccessCalled[0] = true;
                }
            });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNull(e);
        }

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testWildcardLastPart() {
        personSerdes.setAcceptPatterns("application/*");
        personSerdes.setContentTypePatterns("application/*");

        prepareStub("application/json");
        final Requestor requestor = getRequestor();

        final boolean[] callbackSuccessCalled = new boolean[1];

        try {
            requestor.request(uri)
                    .contentType("application/anything")
                    .accept("application/anything")
                    .payload(person).post(Person.class).done(new DoneCallback<Person>() {
                @Override
                public void onDone(Person person) {
                    callbackSuccessCalled[0] = true;
                }
            });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNull(e);
        }

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testAcceptInvalidFirstPart() {
        personSerdes.setAcceptPatterns("anything/json");
        personSerdes.setContentTypePatterns("application/json");

        prepareStub("application/json");
        Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[2];
        try {
            requestor.request(uri)
                    .contentType("application/json")
                    .accept("application/json")
                    .payload(person).post(Person.class)
                    .done(new DoneCallback<Person>() {
                        @Override
                        public void onDone(Person person) {
                            callbackCalled[0] = true;
                        }
                    });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNotNull(e);
        }

        assertFalse(callbackCalled[0]);

        callbackCalled[1] = false;
        personSerdes.setAcceptPatterns("application/json");

        prepareStub("anything/json");
        requestor = getRequestor();

        try {
            requestor.request(uri)
                    .contentType("anything/json")
                    .accept("application/json")
                    .payload(person).post(Person.class)
                    .done(new DoneCallback<Person>() {
                        @Override
                        public void onDone(Person person) {
                            callbackCalled[0] = true;
                        }
                    });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNotNull(e);
        }

        assertFalse(callbackCalled[0]);
    }

    public void testAcceptInvalidLastPart() {
        personSerdes.setAcceptPatterns("application/xml");
        personSerdes.setContentTypePatterns("application/json");

        prepareStub("application/json");
        Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[2];

        try {
            requestor.request(uri)
                    .contentType("application/json")
                    .accept("application/json")
                    .payload(person).post(Person.class)
                    .done(new DoneCallback<Person>() {
                        @Override
                        public void onDone(Person person) {
                            callbackCalled[0] = true;
                        }
                    });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNotNull(e);
        }

        assertFalse(callbackCalled[0]);

        callbackCalled[1] = false;
        personSerdes.setAcceptPatterns("application/json");

        prepareStub("application/xml");
        requestor = getRequestor();

        try {
            requestor.request(uri)
                    .contentType("application/xml")
                    .accept("application/json")
                    .payload(person).post(Person.class)
                    .done(new DoneCallback<Person>() {
                        @Override
                        public void onDone(Person person) {
                            callbackCalled[0] = true;
                        }
                    });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            // This piece of code should not be called
            assertNotNull(e);
        }

        assertFalse(callbackCalled[0]);
    }

    public void testContentTypeInvalidBothParts() {
        personSerdes.setAcceptPatterns("application/json");
        personSerdes.setContentTypePatterns("app/js");

        prepareStub("application/json");
        Requestor requestor = getRequestor();

        final boolean[] callbackSuccessCalled = new boolean[1];

        try {
            requestor.request(uri)
                    .contentType("application/json")
                    .accept("application/json")
                    .payload(person).post(Person.class)
                    .done(new DoneCallback<Person>() {
                        @Override
                        public void onDone(Person person) {
                            callbackSuccessCalled[0] = true;
                        }
                    });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            assertNotNull(e);
        }

        assertFalse(callbackSuccessCalled[0]);

        personSerdes.setContentTypePatterns("application/json");

        prepareStub("application/json");
        requestor = getRequestor();

        try {
            requestor.request(uri)
                    .contentType("app/js")
                    .accept("application/json")
                    .payload(person).post(Person.class)
                    .done(new DoneCallback<Person>() {
                        @Override
                        public void onDone(Person person) {
                            callbackSuccessCalled[0] = true;
                        }
                    });
            ServerStub.triggerPendingRequest();
        } catch (SerializationException e) {
            assertNotNull(e);
        }

        assertFalse(callbackSuccessCalled[0]);
    }

    private Requestor getRequestor() {
        final Requestor requestor = GWT.create(Requestor.class);
        requestor.registerSerdes(Person.class, personSerdes);
        return requestor;
    }

    private void prepareStub(String responseContentType) {
        ServerStub.clearStub();
        ServerStub.responseFor(uri, ResponseMock.of(serializedResponse, 200, "OK",
                new ContentTypeHeader(responseContentType)));
    }
} public class GeneratedJsonSerdesTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testGeneratedSingleDeserialization() {
        final Animal stuart = new Animal("Stuart", 3);

        final Requestor requestor = getRequestor();

        final String uri = "/animal";

        final String serialized = "{\"name\":\"Stuart\",\"age\":3}";

        ServerStub.responseFor(uri, ResponseMock.of(serialized, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackDoneCalled = new boolean[1];

        requestor.request(uri).get(Animal.class)
                .done(new DoneCallback<Animal>() {
                    @Override
                    public void onDone(Animal animal) {
                        callbackDoneCalled[0] = true;
                        assertEquals(stuart, animal);
                    }
                });

        ServerStub.triggerPendingRequest();

        assertTrue(callbackDoneCalled[0]);
    }

    public void testGeneratedArrayListDeserialization() {
        final Animal stuart = new Animal("Stuart", 3);
        final Animal march = new Animal("March", 5);
        final List<Animal> list = new ArrayList<Animal>();
        list.add(stuart); list.add(march);

        final Requestor requestor = getRequestor();

        final String uri = "/animals";

        final String serialized = "[{\"name\":\"Stuart\",\"age\":3},{\"name\":\"March\",\"age\":5}]";

        ServerStub.responseFor(uri, ResponseMock.of(serialized, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackDoneCalled = new boolean[1];

        requestor.request(uri).get(Animal.class, ArrayList.class)
                .done(new DoneCallback<Collection<Animal>>() {
                    @Override
                    public void onDone(Collection<Animal> animals) {
                        callbackDoneCalled[0] = true;
                        ArrayList<Animal> arrayList = (ArrayList<Animal>) animals;
                        assertTrue(Arrays.equals(list.toArray(), arrayList.toArray()));
                    }
                });

        ServerStub.triggerPendingRequest();

        assertTrue(callbackDoneCalled[0]);
    }

    public void testGeneratedCustomListDeserialization() {
        final Animal stuart = new Animal("Stuart", 3);
        final Animal march = new Animal("March", 5);
        final List<Animal> list = new ArrayList<Animal>();
        list.add(stuart); list.add(march);

        final Requestor requestor = getRequestor();

        final String uri = "/animals";

        final String serialized = "[{\"name\":\"Stuart\",\"age\":3},{\"name\":\"March\",\"age\":5}]";

        ServerStub.responseFor(uri, ResponseMock.of(serialized, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackDoneCalled = new boolean[1];

        requestor.request(uri).get(Animal.class, JsArrayList.class)
                .done(new DoneCallback<Collection<Animal>>() {
                    @Override
                    public void onDone(Collection<Animal> animals) {
                        callbackDoneCalled[0] = true;
                        JsArrayList<Animal> arrayList = (JsArrayList<Animal>) animals;
                        assertTrue(Arrays.equals(list.toArray(), arrayList.toArray()));
                    }
                });

        ServerStub.triggerPendingRequest();

        assertTrue(callbackDoneCalled[0]);
    }

    public void testGeneratedSingleSerialization() {
        final Animal stuart = new Animal("Stuart", 3);

        final Requestor requestor = getRequestor();

        final String uri = "/animal";

        final String serialized = "{\"name\":\"Stuart\",\"age\":3}";

        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackDoneCalled = new boolean[1];

        requestor.request(uri).payload(stuart).post()
                .done(new DoneCallback<Void>() {
                    @Override
                    public void onDone(Void ignored) {
                        callbackDoneCalled[0] = true;
                    }
                });

        ServerStub.triggerPendingRequest();

        assertTrue(callbackDoneCalled[0]);
        assertEquals(serialized, ServerStub.getRequestData(uri).getData());
    }

    public void testGeneratedArrayListSerialization() {
        final Animal stuart = new Animal("Stuart", 3);
        final Animal march = new Animal("March", 5);
        final List<Animal> list = new ArrayList<Animal>();
        list.add(stuart); list.add(march);

        final Requestor requestor = getRequestor();

        final String uri = "/animals";

        final String serialized = "[{\"name\":\"Stuart\",\"age\":3},{\"name\":\"March\",\"age\":5}]";

        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackDoneCalled = new boolean[1];

        requestor.request(uri).payload(list).post()
                .done(new DoneCallback<Void>() {
                    @Override
                    public void onDone(Void ignored) {
                        callbackDoneCalled[0] = true;
                    }
                });

        ServerStub.triggerPendingRequest();

        assertTrue(callbackDoneCalled[0]);
        assertEquals(serialized, ServerStub.getRequestData(uri).getData());
    }

    public void testGeneratedCustomListSerialization() {
        final Animal stuart = new Animal("Stuart", 3);
        final Animal march = new Animal("March", 5);
        final List<Animal> list = new JsArrayList<Animal>();
        list.add(stuart); list.add(march);

        final Requestor requestor = getRequestor();

        final String uri = "/animals";

        final String serialized = "[{\"name\":\"Stuart\",\"age\":3},{\"name\":\"March\",\"age\":5}]";

        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackDoneCalled = new boolean[1];

        requestor.request(uri).payload(list).post()
                .done(new DoneCallback<Void>() {
                    @Override
                    public void onDone(Void ignored) {
                        callbackDoneCalled[0] = true;
                    }
                });

        ServerStub.triggerPendingRequest();

        assertTrue(callbackDoneCalled[0]);
        assertEquals(serialized, ServerStub.getRequestData(uri).getData());
    }

    private Requestor getRequestor() {
        ServerStub.clearStub();
        return GWT.create(Requestor.class);
    }

    /**
     * Class to auto-generate serializer.
     */
    @Json({"app*/json*", "*/javascript*" })
    public static class Animal {

        private String name;
        private Integer age;

        public Animal() {
        }

        public Animal(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof Animal)) {
                return false;
            }

            final Animal animal = (Animal) o;

            if (age != null ? !age.equals(animal.age) : animal.age != null) {
                return false;
            }
            if (name != null ? !name.equals(animal.name) : animal.name != null) {
                return false;
            }

            return true;
        }

        @Override
        public int hashCode() {
            int result = name != null ? name.hashCode() : 0;
            result = 31 * result + (age != null ? age.hashCode() : 0);
            return result;
        }
    }
} public class MultipleHeaderTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testGetValue() {
        final String expected = "a/b, x/y+z";
        final MultivaluedHeader header = new MultivaluedHeader("name", "a/b", "x/y+z");
        assertEquals(expected, header.getValue());
    }
} public class MultipleSerdesByClassTest extends GWTTestCase {

    final String uri = "/book";

    final List<Book> bookList = new ArrayList<>(2);
    final Book firstBook = new Book(1, "RESTful Web Services", "Leonard Richardson");
    final Book secondBook = new Book(2, "Agile Software Development: Principles, Patterns and Practices",
            "Robert C. Martin");

    final String firstBookSerializedAsXml = "<book>" +
            "<id>1</id>" +
            "<title>RESTful Web Services</title>" +
            "<author>Leonard Richardson</author>" +
            "</book>";
    final String secondBookSerializedAsXml = "<book>" +
            "<id>2</id>" +
            "<title>Agile Software Development: Principles, Patterns and Practices</title>" +
            "<author>Robert C. Martin</author>" +
            "</book>";

    final String bookArraySerializedAsXml = "<books>" +
            firstBookSerializedAsXml + secondBookSerializedAsXml +
            "</books>";

    final String firstBookSerializedAsJson = "{\"id\":1,\"title\":\"RESTful Web Services\",\"author\":\"Leonard " +
            "Richardson\"}";

    final String secondBookSerializedAsJson = "{\"id\":2,\"title\":\"Agile Software Development: Principles, " +
            "Patterns and Practices\",\"author\":\"Robert C. Martin\"}";

    final String bookArraySerializedAsJson = "[" + firstBookSerializedAsJson + "," + secondBookSerializedAsJson + "]";

    final Serdes<Book> jsonSerdes = new BookJsonSerdes();
    final Serdes<Book> xmlSerdes = new BookXmlSerdes();

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    @Override
    public void gwtSetUp() throws Exception {
        bookList.add(firstBook);
        bookList.add(secondBook);
    }

    public void testXmlDeserializingMatching() {
        prepareStub("application/xml", firstBookSerializedAsXml);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[3];

        requestor.request(uri).get(Book.class).fail(new FailCallback<Throwable>() {
            @Override
            public void onFail(Throwable throwable) {
                callbackCalled[0] = true;
            }
        }).done(new DoneCallback<Book>() {
            @Override
            public void onDone(Book book) {
                callbackCalled[1] = true;
                assertEquals(firstBook, book);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    public void testJsonDeserializingMatching() {
        prepareStub("application/json", firstBookSerializedAsJson);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[3];

        requestor.request(uri).get(Book.class).fail(new FailCallback<Throwable>() {
            @Override
            public void onFail(Throwable throwable) {
                callbackCalled[0] = true;
            }
        }).done(new DoneCallback<Book>() {
            @Override
            public void onDone(Book book) {
                callbackCalled[1] = true;
                assertEquals(firstBook, book);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    public void testXmlArrayDeserializingMatching() {
        prepareStub("application/xml", bookArraySerializedAsXml);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[3];

        requestor.request(uri).get(Book.class, List.class).fail(new FailCallback<Throwable>() {
            @Override
            public void onFail(Throwable throwable) {
                callbackCalled[0] = true;
            }
        }).done(new DoneCallback<Collection<Book>>() {
            @Override
            public void onDone(Collection<Book> books) {
                callbackCalled[1] = true;
                assertEquals(bookList, books);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    public void testJsonArrayDeserializingMatching() {
        prepareStub("application/json", bookArraySerializedAsJson);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[3];

        requestor.request(uri).get(Book.class, List.class).fail(new FailCallback<Throwable>() {
            @Override
            public void onFail(Throwable throwable) {
                callbackCalled[0] = true;
            }
        }).done(new DoneCallback<Collection<Book>>() {
            @Override
            public void onDone(Collection<Book> books) {
                callbackCalled[1] = true;
                assertEquals(bookList, books);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    public void testXmlSerializingMatching() {
        prepareStub("text/plain", "response ignored");
        final Requestor requestor = getRequestor();

        requestor.request(uri).contentType("application/xml").payload(firstBook).post();
        ServerStub.triggerPendingRequest();

        assertEquals(firstBookSerializedAsXml, ServerStub.getRequestData(uri).getData());
    }

    public void testXmlArraySerializingMatching() {
        prepareStub("text/plain", "response ignored");
        final Requestor requestor = getRequestor();

        requestor.request(uri).contentType("application/xml").payload(bookList).post();
        ServerStub.triggerPendingRequest();

        assertEquals(bookArraySerializedAsXml, ServerStub.getRequestData(uri).getData());
    }

    public void testJsonSerializingMatching() {
        prepareStub("text/plain", "response ignored");
        final Requestor requestor = getRequestor();

        requestor.request(uri).contentType("application/json").payload(firstBook).post();
        ServerStub.triggerPendingRequest();

        assertEquals(firstBookSerializedAsJson, ServerStub.getRequestData(uri).getData());
    }

    public void testJsonArraySerializingMatching() {
        prepareStub("text/plain", "response ignored");
        final Requestor requestor = getRequestor();

        requestor.request(uri).contentType("application/json").payload(bookList).post();
        ServerStub.triggerPendingRequest();

        assertEquals(bookArraySerializedAsJson, ServerStub.getRequestData(uri).getData());
    }

    private Requestor getRequestor() {
        final Requestor requestor = GWT.create(Requestor.class);
        requestor.registerSerdes(Book.class, jsonSerdes);
        requestor.registerSerdes(Book.class, xmlSerdes);
        return requestor;
    }

    private void prepareStub(String responseContentType, String serializedResponse) {
        ServerStub.clearStub();
        ServerStub.responseFor(uri, ResponseMock.of(serializedResponse, 200, "OK",
                new ContentTypeHeader(responseContentType)));
    }
} public class QualityFactorHeaderTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testGetValue() {
        final String expected = "a/b, x/y+z; 0.2, k/l, n/m; 0.6";

        final QualityFactorHeader header = new QualityFactorHeader("name",
                new QualityFactorHeader.Value("a/b"),
                new QualityFactorHeader.Value(0.2, "x/y+z"),
                new QualityFactorHeader.Value("k/l"),
                new QualityFactorHeader.Value(0.6, "n/m"));

        assertEquals(expected, header.getValue());
    }
} public class RequestTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testCustomObjectArraySerializationDeserialization() {
        final Requestor requestor = getRequestor();
        requestor.registerSerdes(Person.class, new JsonObjectSerdes<Person>(Person.class) {

            @Override
            public Person readJson(JsonRecordReader reader, DeserializationContext context) {
                return new Person(reader.readInteger("id"),
                        reader.readString("name"),
                        reader.readDouble("weight"),
                        new Date(reader.readLong("birthday")));
            }

            @Override
            public String serialize(Person person, SerializationContext context) {
                // Directly build json using string concatenation in order to increase performance.
                return "{" + "\"id\":" + person.getId() + ", \"name\":\"" + person.getName() + "\", " +
                        "\"weight\":" + person.getWeight() + ", \"birthday\":" + person.getBirthday().getTime() + "}";
            }

            @Override
            public void writeJson(Person person, JsonRecordWriter writer, SerializationContext context) {
                // Ignored, as #serialize was overridden in order to improve serialization performance.
            }
        });

        final String uri = "/person";

        final Person p1 = new Person(1, "John Doe", 6.3, new Date(329356800));
        final Person p2 = new Person(2, "Alice", 5.87, new Date(355343600));
        final List<Person> persons = Arrays.asList(p1, p2);

        final String serializedArray = "[{\"id\":1, \"name\":\"John Doe\", \"weight\":6.3, \"birthday\":329356800},"
                + "{\"id\":2, \"name\":\"Alice\", \"weight\":5.87, \"birthday\":355343600}]";

        ServerStub.responseFor(uri, ResponseMock.of(serializedArray, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).payload(persons).post(Person.class, List.class)
                .done(new DoneCallback<Collection<Person>>() {
                    @Override
                    public void onDone(Collection<Person> result) {
                        assertTrue(Arrays.equals(persons.toArray(), result.toArray()));
                        callbackSuccessCalled[0] = true;
                    }
                });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
        assertEquals(serializedArray, ServerStub.getRequestData(uri).getData());
    }

    public void testCustomObjectRequest() {
        final Requestor requestor = getRequestor();
        requestor.registerSerdes(Person.class, new JsonObjectSerdes<Person>(Person.class) {

            @Override
            public Person readJson(JsonRecordReader reader, DeserializationContext context) {
                return new Person(reader.readInteger("id"),
                        reader.readString("name"),
                        reader.readDouble("weight"),
                        new Date(reader.readLong("birthday")));
            }

            @Override
            public void writeJson(Person person, JsonRecordWriter writer, SerializationContext context) {
                writer.writeInt("id", person.getId())
                        .writeString("name", person.getName())
                        .writeDouble("weight", person.getWeight())
                        .writeDouble("birthday", person.getBirthday().getTime());
            }
        });

        final String uri = "/person";

        final Person person = new Person(1, "John Doe", 6.3, new Date(329356800));
        final String serializedResponse = "{\"id\":1, \"name\":\"John Doe\", \"weight\":6.3, \"birthday\":329356800}";

        ServerStub.responseFor(uri, ResponseMock.of(serializedResponse, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).get(Person.class).done(new DoneCallback<Person>() {
            @Override
            public void onDone(Person result) {
                assertEquals(person, result);
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testCustomObjectSerialization() {
        final Requestor requestor = getRequestor();
        requestor.registerSerdes(Person.class, new PersonSerdes());

        final String uri = "/person";

        final Person person = new Person(1, "John Doe", 6.3, new Date(329356800));
        final String serializedRequest = "{\"id\":1,\"name\":\"John Doe\",\"weight\":6.3,\"birthday\":329356800}";

        ServerStub.responseFor(uri, ResponseMock.of(serializedRequest, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).payload(person).post(Person.class).done(new DoneCallback<Person>() {
            @Override
            public void onDone(Person result) {
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
        assertEquals(serializedRequest, ServerStub.getRequestData(uri).getData());
    }

    public void testAwaysCallbackExecutionOnFailure() {
        final Requestor requestor = getRequestor();

        final String uri = "/failure";

        ServerStub.responseFor(uri,
                ResponseMock.of("not found", 404, "NOT FOUND", new ContentTypeHeader("plain/text")));
        ServerStub.setReturnSuccess(false);
        final boolean[] executed = new boolean[1];

        requestor.request("/notValid").get().always(new AlwaysCallback<Void, Throwable>() {
            @Override
            public void onAlways(Promise.State state, Void resolved, Throwable rejected) {
                executed[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(executed[0]);
    }

    public void testAwaysCallbackExecutionOnSuccess() {

        final Requestor requestor = getRequestor();

        final String uri = "/success";

        ServerStub.responseFor(uri, ResponseMock.of("success", 200, "OK", new ContentTypeHeader("plain/text")));

        final boolean[] executed = new boolean[1];

        requestor.request(uri).get().always(new AlwaysCallback<Void, Throwable>() {
            @Override
            public void onAlways(Promise.State state, Void resolved, Throwable rejected) {
                executed[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(executed[0]);
    }

    public void testOverlayArrayRequest() {
        final Requestor requestor = getRequestor();

        final String uri = "/person-jso-array";

        final PersonJso p1 = PersonJso.create(1, "John Doe", 6.3, new Date(329356800));
        final PersonJso p2 = PersonJso.create(2, "Alice", 5.87, new Date(355343600));

        final JsArray<PersonJso> persons = JsArray.create();
        persons.push(p1);
        persons.push(p2);

        final String serializedResp = "[{\"id\": 1, \"name\": \"John Doe\", \"weight\": 6.3, \"birthday\": 329356800},"
                + "{\"id\": 2, \"name\": \"Alice\", \"weight\": 5.87, \"birthday\": 355343600}]";

        ServerStub.responseFor(uri, ResponseMock.of(serializedResp, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

//        requestor.get(uri, PersonJso.class, new ListAsyncCallback<PersonJso>() {
//            @Override
//            public void onFailure(Throwable caught) {
//            }
//
//            @Override
//            public void onSuccess(List<PersonJso> result) {
//                JsArray<PersonJso> resultArray = ((JsArrayList<PersonJso>) result).asJsArray();
//                assertEquals(Overlays.stringify(persons), Overlays.stringify(resultArray));
//                callbackSuccessCalled[0] = true;
//            }
//        });

        requestor.request(uri).get(PersonJso.class, List.class).done(new DoneCallback<Collection<PersonJso>>() {
            @Override
            public void onDone(Collection<PersonJso> result) {
                JsArray<PersonJso> resultArray = ((JsArrayList<PersonJso>) result).asJsArray();
                assertEquals(Overlays.stringify(persons), Overlays.stringify(resultArray));
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testOverlayRequest() {
        final Requestor requestor = getRequestor();

        final String uri = "/person-jso";

        final PersonJso person = PersonJso.create(1, "John Doe", 6.3, new Date(329356800));
        final String serializedResp = "{ \"id\" : 1, \"name\":\"John Doe\",\"weight\" :6.3,  \"birthday\": 329356800}";

        ServerStub.responseFor(uri, ResponseMock.of(serializedResp, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).get(PersonJso.class).done(new DoneCallback<PersonJso>() {
            @Override
            public void onDone(PersonJso result) {
                assertEquals(Overlays.stringify(person), Overlays.stringify(result));
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testRequestHeaders() {
        final Requestor requestor = getRequestor();

        final String uri = "/person-jso";

        final PersonJso person = PersonJso.create(1, "John Doe", 6.3, new Date(329356800));
        final String serializedResp = "{ \"id\" : 1, \"name\":\"John Doe\",\"weight\" :6.3,  \"birthday\": 329356800}";

        ServerStub.responseFor(uri, ResponseMock.of(serializedResp, 200, "OK",
                new ContentTypeHeader("application/json")));

        requestor.request(uri).payload(person).post(PersonJso.class);
        ServerStub.triggerPendingRequest();

        // On #post execution, request mock should be set from requestor
        final RequestMock requestMock = ServerStub.getRequestData(uri);
        assertNotNull(requestMock);
        assertNotNull(requestMock.getHeaders());

        boolean contentTypeHeaderOk = false;
        boolean acceptHeaderOk = false;
        for (Header header : requestMock.getHeaders()) {
            if (header.getName().equals("Content-Type")) {
                contentTypeHeaderOk = header.getValue().equals("application/json");
            } else if (header.getName().equals("Accept")) {
                acceptHeaderOk = header.getValue().equals("application/json");
            }
        }
        assertTrue(contentTypeHeaderOk);
        assertTrue(acceptHeaderOk);
    }

    public void testStringArrayRequest() {
        final Requestor requestor = getRequestor();

        final String uri = "/string-array";
        final String[] response = {"Some", "string", "array", "response"};
        final String irregularStringArray = " [ \"Some\", \"string\" ,  \"array\", \"response\" ]  ";
        ServerStub.responseFor(uri, ResponseMock.of(irregularStringArray, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).get(String.class, List.class).done(new DoneCallback<Collection<String>>() {
            @Override
            public void onDone(Collection<String> result) {
                assertTrue(Arrays.equals(result.toArray(), response));
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testStringRequest() {
        final Requestor requestor = getRequestor();

        final String uri = "/string";
        final String response = "Some string response";
        final String serializedResponse = "\"Some string response\"";
        ServerStub.responseFor(uri, ResponseMock.of(serializedResponse, 200, "OK",
                new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).get(String.class).done(new DoneCallback<String>() {
            @Override
            public void onDone(String result) {
                assertEquals(response, result);
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testVoidRequest() {
        final Requestor requestor = getRequestor();

        final String uri = "/void";
        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK", new ContentTypeHeader("application/json")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).get().done(new DoneCallback<Void>() {
            @Override
            public void onDone(Void result) {
                assertNull(result);
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    public void testFormDataRequest() {
        final Requestor requestor = getRequestor();

        final String uri = "/form";
        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK", new ContentTypeHeader("text/plain")));

        final FormData formData = FormData.builder().put("name", "John Doe").put("age", 1, 2, 3.5).build();
        final String serialized = "name=John+Doe&age=1&age=2&age=3.5";

        requestor.request(uri).contentType(FormParam.CONTENT_TYPE).payload(formData).post();

        final RequestMock requestMock = ServerStub.getRequestData(uri);
        assertEquals(serialized, requestMock.getData());
    }

    public void testResponseResult() {
        final Requestor requestor = getRequestor();

        final String uri = "/response";
        final String responseText = "response text";
        ServerStub.responseFor(uri, ResponseMock.of(responseText, 200, "OK", new ContentTypeHeader("text/plain")));

        final boolean[] callbackSuccessCalled = new boolean[1];

        requestor.request(uri).get(Response.class).done(new DoneCallback<Response>() {
            @Override
            public void onDone(Response result) {
                assertEquals(responseText, result.getText());
                assertEquals(200, result.getStatusCode());
                callbackSuccessCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbackSuccessCalled[0]);
    }

    private Requestor getRequestor() {
        ServerStub.clearStub();
        return GWT.create(Requestor.class);
    }
} public class SerializerAndDeserializerPrecedenceTest extends GWTTestCase {

    final String uri = "/string";
    final String string = "text response";
    final String serializedResponseAsJson = "\"text response\"";
    final String serializedResponseAsText = "text response";

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testJsonDeserializing() {
        prepareStub("application/json", serializedResponseAsJson);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[2];

        requestor.request(uri).get(String.class).done(new DoneCallback<String>() {
            public void onDone(String result) {
                callbackCalled[1] = true;
                assertEquals(string, result);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    public void testTextPlainDeserializing() {
        prepareStub("text/plain", serializedResponseAsText);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[2];

        requestor.request(uri).get(String.class).done(new DoneCallback<String>() {
            public void onDone(String result) {
                callbackCalled[1] = true;
                assertEquals(string, result);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    public void testNotMappedDeserializing() {
        // As TextDeserializer matches */*, this response should be deserialized by it.
        prepareStub("content-type/not-mapped", serializedResponseAsText);
        final Requestor requestor = getRequestor();

        final boolean[] callbackCalled = new boolean[2];

        requestor.request(uri).get(String.class).done(new DoneCallback<String>() {
            public void onDone(String result) {
                callbackCalled[1] = true;
                assertEquals(string, result);
            }
        });
        ServerStub.triggerPendingRequest();

        assertFalse(callbackCalled[0]);
        assertTrue(callbackCalled[1]);
    }

    private Requestor getRequestor() {
        return GWT.create(Requestor.class);
    }

    private void prepareStub(String responseContentType, String serializedResponse) {
        ServerStub.clearStub();
        ServerStub.responseFor(uri, ResponseMock.of(serializedResponse, 200, "OK",
                new ContentTypeHeader(responseContentType)));
    }
} public class SimpleHeaderWithParameterTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testGetValue() {
        final String expected = "text/html; charset=ISO-8859-4";
        final SimpleHeaderWithParameter header = new SimpleHeaderWithParameter("Content-Type", "text/html",
                new SimpleHeaderWithParameter.Param("charset", "ISO-8859-4"));
        assertEquals(expected, header.getValue());
    }
} public class RestTest extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "org.turbogwt.net.http.HttpTest";
    }

    public void testCreate() {
        ServerStub.clearStub();

        final Requestor requestor = new RequestorImpl();
        requestor.registerSerdes(Book.class, BookJsonSerdes.getInstance());

        final String uri = "/server/books";

        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK", new ContentTypeHeader("application/json")));

        final String expected = "{\"id\":1,\"title\":\"RESTful Web Services\",\"author\":\"Leonard Richardson\"}";

        final boolean[] callbacksCalled = new boolean[1];
        final Book data = new Book(1, "RESTful Web Services", "Leonard Richardson");

        requestor.request(uri).payload(data).post().done(new DoneCallback<Void>() {
            @Override
            public void onDone(Void aVoid) {
                callbacksCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbacksCalled[0]);
        assertEquals(expected, ServerStub.getRequestData(uri).getData());
        assertEquals(RequestBuilder.POST, ServerStub.getRequestData(uri).getMethod());
    }

    public void testDelete() {
        ServerStub.clearStub();

        final Requestor requestor = new RequestorImpl();

        final String uri = "/server/books/1";

        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK", new ContentTypeHeader("application/json")));

        requestor.request(uri).delete(); // You can optionally dismiss any server response
        ServerStub.triggerPendingRequest();

        assertEquals(RequestBuilder.DELETE, ServerStub.getRequestData(uri).getMethod());
    }

    public void testGetAll() {
        ServerStub.clearStub();

        final Requestor requestor = new RequestorImpl();
        requestor.registerSerdes(Book.class, BookJsonSerdes.getInstance());

        final String uri = "/server/books";

      final String responseText = "[{\"id\":1, \"title\":\"RESTful Web Services\", \"author\":\"Leonard Richardson\"}"
                + ", {\"id\":2, \"title\":\"Agile Software Development: Principles, Patterns, and Practices\", "
                + "\"author\":\"Robert C. Martin\"}]";
        ServerStub.responseFor(uri, ResponseMock.of(responseText, 200, "OK",
                new ContentTypeHeader("application/json")));

        final List<Book> expected = new ArrayList<>(2);
        expected.add(new Book(1, "RESTful Web Services", "Leonard Richardson"));
        expected.add(new Book(2, "Agile Software Development: Principles, Patterns, and Practices",
                "Robert C. Martin"));

        final boolean[] callbacksCalled = new boolean[1];

        requestor.request(uri).get(Book.class, List.class).done(new DoneCallback<Collection<Book>>() {
            @Override
            public void onDone(Collection<Book> books) {
                callbacksCalled[0] = true;
                assertEquals(expected, books);
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbacksCalled[0]);
        assertEquals(RequestBuilder.GET, ServerStub.getRequestData(uri).getMethod());
    }

    public void testGetOne() {
        ServerStub.clearStub();

        final Requestor requestor = new RequestorImpl();
        requestor.registerSerdes(Book.class, BookJsonSerdes.getInstance());

        final String uri = "/server/books/1";

      final String responseText = "{\"id\":1, \"title\":\"RESTful Web Services\", \"author\":\"Leonard Richardson\"}";
        ServerStub.responseFor(uri, ResponseMock.of(responseText, 200, "OK",
                new ContentTypeHeader("application/json")));

        final Book expected = new Book(1, "RESTful Web Services", "Leonard Richardson");

        final boolean[] callbacksCalled = new boolean[1];

        requestor.request(uri).get(Book.class).done(new DoneCallback<Book>() {
            @Override
            public void onDone(Book book) {
                callbacksCalled[0] = true;
                assertEquals(expected, book);
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbacksCalled[0]);
        assertEquals(RequestBuilder.GET, ServerStub.getRequestData(uri).getMethod());
    }

    public void testUpdate() {
        ServerStub.clearStub();

        final Requestor requestor = new RequestorImpl();
        requestor.registerSerdes(Book.class, BookJsonSerdes.getInstance());

        final String uri = "/server/books/1";

        ServerStub.responseFor(uri, ResponseMock.of(null, 200, "OK", new ContentTypeHeader("application/json")));

        final String expected = "{\"id\":1,\"title\":\"RESTful Web Services\",\"author\":\"Leonard Richardson\"}";

        final boolean[] callbacksCalled = new boolean[1];
        final Book data = new Book(1, "RESTful Web Services", "Leonard Richardson");

        requestor.request(uri).payload(data).put().done(new DoneCallback<Void>() {
            @Override
            public void onDone(Void result) {
                callbacksCalled[0] = true;
            }
        });
        ServerStub.triggerPendingRequest();

        assertTrue(callbacksCalled[0]);
        assertEquals(expected, ServerStub.getRequestData(uri).getData());
        assertEquals(RequestBuilder.PUT, ServerStub.getRequestData(uri).getMethod());
    }
}
import com.google.gwt.junit.tools.GWTTestSuite;
import junit.framework.Test;
import org.turbogwt.net.client.UriBuilderTest;
import org.turbogwt.net.http.client.ContentTypeAcceptPatternsTest;
import org.turbogwt.net.http.client.GeneratedJsonSerdesTest;
import org.turbogwt.net.http.client.MultipleHeaderTest;
import org.turbogwt.net.http.client.MultipleSerdesByClassTest;
import org.turbogwt.net.http.client.QualityFactorHeaderTest;
import org.turbogwt.net.http.client.RequestTest;
import org.turbogwt.net.http.client.SerializerAndDeserializerPrecedenceTest;
import org.turbogwt.net.http.client.SimpleHeaderWithParameterTest;
import org.turbogwt.net.http.client.books.RestTest;
/*
 * Copyright 2014 Grow Bit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.turbogwt.net.http;




/**
 * @author Danilo Reinert
 */
public class HttpGwtTestSuite {

    public static Test suite() {
        GWTTestSuite suite = new GWTTestSuite("Http Test Suite");

        suite.addTestSuite(MultipleHeaderTest.class);
        suite.addTestSuite(QualityFactorHeaderTest.class);
        suite.addTestSuite(SimpleHeaderWithParameterTest.class);

        suite.addTestSuite(UriBuilderTest.class);
        suite.addTestSuite(RequestTest.class);