package com.github.dreamhead.moco; import com.google.common.net.HttpHeaders; import org.apache.http.Header; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.client.HttpResponseException; import org.apache.http.client.fluent.Request; import org.junit.Test; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.concurrent.TimeUnit; import static com.github.dreamhead.moco.HttpProtocolVersion.VERSION_1_0; import static com.github.dreamhead.moco.Moco.and; import static com.github.dreamhead.moco.Moco.by; import static com.github.dreamhead.moco.Moco.contain; import static com.github.dreamhead.moco.Moco.endsWith; import static com.github.dreamhead.moco.Moco.eq; import static com.github.dreamhead.moco.Moco.exist; import static com.github.dreamhead.moco.Moco.file; import static com.github.dreamhead.moco.Moco.header; import static com.github.dreamhead.moco.Moco.latency; import static com.github.dreamhead.moco.Moco.match; import static com.github.dreamhead.moco.Moco.method; import static com.github.dreamhead.moco.Moco.not; import static com.github.dreamhead.moco.Moco.or; import static com.github.dreamhead.moco.Moco.pathResource; import static com.github.dreamhead.moco.Moco.query; import static com.github.dreamhead.moco.Moco.seq; import static com.github.dreamhead.moco.Moco.startsWith; import static com.github.dreamhead.moco.Moco.status; import static com.github.dreamhead.moco.Moco.text; import static com.github.dreamhead.moco.Moco.uri; import static com.github.dreamhead.moco.Moco.version; import static com.github.dreamhead.moco.Moco.with; import static com.github.dreamhead.moco.Runner.running; import static com.github.dreamhead.moco.helper.RemoteTestUtils.remoteUrl; import static com.github.dreamhead.moco.helper.RemoteTestUtils.root; import static com.google.common.collect.ImmutableMultimap.of; import static com.google.common.io.Files.toByteArray; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.greaterThan; import static org.junit.Assert.assertThat; public class MocoTest extends AbstractMocoHttpTest { @Test public void should_return_expected_response() throws Exception { server.response("foo"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(root()), is("foo")); } }); } @Test public void should_return_expected_response_with_text_api() throws Exception { server.response(text("foo")); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(root()), is("foo")); } }); } @Test public void should_return_expected_response_with_content_api() throws Exception { server.response(with("foo")); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(root()), is("foo")); } }); } @Test public void should_return_expected_response_from_file() throws Exception { server.response(file("src/test/resources/foo.response")); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(root()), is("foo.response")); } }); } @Test public void should_return_expected_response_from_file_with_charset() throws Exception { server.response(file("src/test/resources/gbk.response", Charset.forName("GBK"))); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.getAsBytes(root()), is(toByteArray(new File("src/test/resources/gbk.response")))); } }); } @Test public void should_return_expected_response_from_path_resource() throws Exception { server.response(pathResource("foo.response")); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(root()), is("foo.response")); } }); } @Test public void should_return_expected_response_from_path_resource_with_charset() throws Exception { server.response(pathResource("gbk.response", Charset.forName("GBK"))); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.getAsBytes(root()), is(toByteArray(new File("src/test/resources/gbk.response")))); } }); } @Test public void should_return_expected_response_based_on_path_resource() throws Exception { server.request(by(pathResource("foo.request"))).response("foo"); running(server, new Runnable() { @Override public void run() throws Exception { InputStream stream = this.getClass().getClassLoader().getResourceAsStream("foo.request"); assertThat(helper.postStream(root(), stream), is("foo")); } }); } @Test(expected = HttpResponseException.class) public void should_throw_exception_for_unknown_request() throws Exception { running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(root()), is("bar")); } }); } @Test public void should_return_expected_response_based_on_specified_request() throws Exception { server.request(by("foo")).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.postContent(root(), "foo"), is("bar")); } }); } @Test public void should_return_expected_response_based_on_specified_request_with_text_api() throws Exception { server.request(by(text("foo"))).response(text("bar")); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.postContent(root(), "foo"), is("bar")); } }); } @Test public void should_match_request_with_charset_from_file() throws Exception { server.request(by(file("src/test/resources/gbk.response", Charset.forName("GBK")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.postBytes(root(), toByteArray(new File("src/test/resources/gbk.response"))), is("bar")); } }); } @Test public void should_return_expected_response_based_on_specified_uri() throws Exception { server.request(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); } @Test public void should_match_request_based_on_multiple_matchers() throws Exception { server.request(and(by("foo"), by(uri("/foo")))).response(text("bar")); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.postContent(remoteUrl("/foo"), "foo"), is("bar")); } }); } @Test(expected = HttpResponseException.class) public void should_throw_exception_even_if_match_one_of_conditions() throws Exception { server.request(and(by("foo"), by(uri("/foo")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { helper.get(remoteUrl("/foo")); } }); } @Test public void should_match_request_based_on_either_matcher() throws Exception { server.request(or(by("foo"), by(uri("/foo")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.postContent(remoteUrl("/foo"), "foo"), is("bar")); } }); } @Test public void should_match_request_based_on_not_matcher() throws Exception { server.request(not(by(uri("/foo")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/bar")), is("bar")); } }); } @Test public void should_match_request_based_on_simplified_either_matcher() throws Exception { server.request(by("foo"), by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.postContent(root(), "foo"), is("bar")); } }); } @Test public void should_match_get_method_by_method_api_with_http_method() throws Exception { server.request(and(by(uri("/foo")), by(method(HttpMethod.GET)))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); } @Test public void should_match_get_method_by_method_api() throws Exception { server.request(and(by(uri("/foo")), by(method("get")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); } @Test(expected = HttpResponseException.class) public void should_not_response_for_get_while_http_method_is_not_get() throws Exception { server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { helper.postContent(remoteUrl("/foo"), ""); } }); } @Test public void should_match_put_method_via_api() throws Exception { server.request(and(by(uri("/foo")), by(method("put")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { Request request = Request.Put(remoteUrl("/foo")); assertThat(helper.executeAsString(request), is("bar")); } }); } @Test public void should_match_delete_method_via_api() throws Exception { server.request(and(by(uri("/foo")), by(method("delete")))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { Request request = Request.Delete(remoteUrl("/foo")); String response = helper.executeAsString(request); assertThat(response, is("bar")); } }); } @Test(expected = HttpResponseException.class) public void should_not_response_for_post_while_http_method_is_not_post() throws Exception { server.post(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { helper.get(remoteUrl("/foo")); } }); } @Test public void should_return_content_one_by_one() throws Exception { server.request(by(uri("/foo"))).response(seq("bar", "blah")); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("blah")); assertThat(helper.get(remoteUrl("/foo")), is("blah")); } }); } @Test public void should_return_content_one_by_one_with_text_api() throws Exception { server.request(by(uri("/foo"))).response(seq(text("bar"), text("blah"))); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("blah")); assertThat(helper.get(remoteUrl("/foo")), is("blah")); } }); } @Test public void should_return_response_one_by_one() throws Exception { server.request(by(uri("/foo"))).response(seq(status(302), status(302), status(200))); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.getForStatus(remoteUrl("/foo")), is(302)); assertThat(helper.getForStatus(remoteUrl("/foo")), is(302)); assertThat(helper.getForStatus(remoteUrl("/foo")), is(200)); } }); } @Test public void should_match() throws Exception { server.request(match(uri("/\\w*/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/bar/foo")), is("bar")); assertThat(helper.get(remoteUrl("/blah/foo")), is("bar")); } }); } @Test public void should_match_method() throws Exception { server.request(match(method("get|post"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/bar/foo")), is("bar")); assertThat(helper.postContent(remoteUrl("/blah/foo"), "content"), is("bar")); } }); } @Test public void should_match_header() throws Exception { server.request(match(header("foo"), "bar|blah")).response("header"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.getWithHeader(root(), of("foo", "bar")), is("header")); assertThat(helper.getWithHeader(root(), of("foo", "blah")), is("header")); } }); } @Test public void should_exist_header() throws Exception { server.request(exist(header("foo"))).response("header"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.getWithHeader(root(), of("foo", "bar")), is("header")); assertThat(helper.getWithHeader(root(), of("foo", "blah")), is("header")); } }); } @Test public void should_exist_query() throws Exception { server.request(exist(query("foo"))).response("query"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/path?foo")), is("query")); assertThat(helper.get(remoteUrl("/other?foo")), is("query")); } }); } @Test public void should_starts_with() throws Exception { server.request(startsWith(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo/a")), is("bar")); assertThat(helper.get(remoteUrl("/foo/b")), is("bar")); } }); } @Test public void should_starts_with_for_resource() throws Exception { server.request(startsWith(header("foo"), "bar")).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.getWithHeader(root(), of("foo", "barA")), is("bar")); assertThat(helper.getWithHeader(root(), of("foo", "barB")), is("bar")); } }); } @Test public void should_ends_with() throws Exception { server.request(endsWith(uri("foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/a/foo")), is("bar")); assertThat(helper.get(remoteUrl("/b/foo")), is("bar")); } }); } @Test public void should_ends_with_for_resource() throws Exception { server.request(endsWith(header("foo"), "bar")).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.getWithHeader(root(), of("foo", "Abar")), is("bar")); assertThat(helper.getWithHeader(root(), of("foo", "Bbar")), is("bar")); } }); } @Test public void should_contain() throws Exception { server.request(contain(uri("foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/a/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo/a")), is("bar")); } }); } @Test public void should_contain_for_resource() throws Exception { server.request(contain(header("foo"), "bar")).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.getWithHeader(root(), of("foo", "Abar")), is("bar")); assertThat(helper.getWithHeader(root(), of("foo", "barA")), is("bar")); } }); } @Test public void should_eq_header() throws Exception { server.request(eq(header("foo"), "bar")).response("blah"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.getWithHeader(root(), of("foo", "bar")), is("blah")); } }); } @Test(expected = HttpResponseException.class) public void should_throw_exception_without_specified_header() throws Exception { server.request(eq(header("foo"), "bar")).response("blah"); running(server, new Runnable() { @Override public void run() throws IOException { helper.get(remoteUrl("/foo")); } }); } @Test public void should_return_expected_response_for_multiple_specified_query() throws Exception { server.request(and(by(uri("/foo")), eq(query("param"), "blah"))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo?param=multiple¶m=blah")), is("bar")); } }); } @Test public void should_return_expected_response_for_specified_query() throws Exception { server.request(and(by(uri("/foo")), eq(query("param"), "blah"))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo?param=blah")), is("bar")); } }); } @Test public void should_return_expected_response_for_empty_query() throws Exception { server.request(and(by(uri("/foo")), eq(query("param"), ""))).response("bar"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.get(remoteUrl("/foo?param")), is("bar")); } }); } @Test public void should_match_version() throws Exception { server.request(by(version(VERSION_1_0))).response("foo"); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.getWithVersion(root(), HttpVersion.HTTP_1_0), is("foo")); } }); } @Test public void should_return_expected_version() throws Exception { server.response(version(VERSION_1_0)); running(server, new Runnable() { @Override public void run() throws IOException { ProtocolVersion version = helper.getResponse(root()).getProtocolVersion(); assertThat(version.getMajor(), is(1)); assertThat(version.getMinor(), is(0)); } }); } @Test public void should_return_excepted_version_with_version_api() throws Exception { server.response(version(VERSION_1_0)); running(server, new Runnable() { @Override public void run() throws IOException { ProtocolVersion version = helper.getResponse(root()).getProtocolVersion(); assertThat(version.getMajor(), is(1)); assertThat(version.getMinor(), is(0)); } }); } @Test public void should_return_expected_status_code() throws Exception { server.response(status(200)); running(server, new Runnable() { @Override public void run() throws IOException { assertThat(helper.getForStatus(root()), is(200)); } }); } @Test public void should_return_expected_header() throws Exception { server.response(header(HttpHeaders.CONTENT_TYPE, "application/json")); running(server, new Runnable() { @Override public void run() throws IOException { String value = helper.getResponse(root()).getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue(); assertThat(value, is("application/json")); } }); } @Test public void should_return_multiple_expected_header() throws Exception { server.response(header(HttpHeaders.CONTENT_TYPE, "application/json"), header("foo", "bar")); running(server, new Runnable() { @Override public void run() throws IOException { String json = helper.getResponse(root()).getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue(); assertThat(json, is("application/json")); String bar = helper.getResponse(root()).getFirstHeader("foo").getValue(); assertThat(bar, is("bar")); } }); } @Test public void should_wait_for_awhile() throws Exception { final long latency = 1000; final long delta = 200; server.response(latency(latency, TimeUnit.MILLISECONDS)); running(server, new Runnable() { @Override public void run() throws IOException { long start = System.currentTimeMillis(); helper.get(root()); int code = helper.getForStatus(root()); long stop = System.currentTimeMillis(); long gap = stop - start + delta; assertThat(gap, greaterThan(latency)); assertThat(code, is(200)); } }); } @Test public void should_wait_for_awhile_with_time_unit() throws Exception { final long delta = 200; server.response(latency(1, TimeUnit.SECONDS)); running(server, new Runnable() { @Override public void run() throws IOException { long start = System.currentTimeMillis(); helper.get(root()); int code = helper.getForStatus(root()); long stop = System.currentTimeMillis(); long gap = stop - start + delta; assertThat(gap, greaterThan(TimeUnit.SECONDS.toMillis(1))); assertThat(code, is(200)); } }); } @Test public void should_return_same_http_version_without_specified_version() throws Exception { server.response("foobar"); running(server, new Runnable() { @Override public void run() throws IOException { ProtocolVersion version10 = helper.execute(Request.Get(root()) .version(HttpVersion.HTTP_1_0)) .getProtocolVersion(); assertThat(version10.getMajor(), is(1)); assertThat(version10.getMinor(), is(0)); ProtocolVersion version11 = helper.execute(Request.Get(root()) .version(HttpVersion.HTTP_1_1)) .getProtocolVersion(); assertThat(version11.getMajor(), is(1)); assertThat(version11.getMinor(), is(1)); } }); } @Test public void should_return_same_http_version_without_specified_version_for_error_response() throws Exception { running(server, new Runnable() { @Override public void run() throws IOException { ProtocolVersion version10 = helper.execute(Request.Get(root()) .version(HttpVersion.HTTP_1_0)) .getProtocolVersion(); assertThat(version10.getMajor(), is(1)); assertThat(version10.getMinor(), is(0)); ProtocolVersion version11 = helper.execute(Request.Get(root()) .version(HttpVersion.HTTP_1_1)) .getProtocolVersion(); assertThat(version11.getMajor(), is(1)); assertThat(version11.getMinor(), is(1)); } }); } @Test public void should_return_default_content_type() throws Exception { server.response(with("foo")); running(server, new Runnable() { @Override public void run() throws Exception { Header header = helper.getResponse(root()).getFirstHeader(HttpHeaders.CONTENT_TYPE); assertThat(header.getValue(), is("text/plain; charset=utf-8")); } }); } @Test public void should_return_specified_content_type() throws Exception { server.response(with("foo"), header(HttpHeaders.CONTENT_TYPE, "text/html")); running(server, new Runnable() { @Override public void run() throws Exception { Header header = helper.getResponse(root()).getFirstHeader(HttpHeaders.CONTENT_TYPE); assertThat(header.getValue(), is("text/html")); } }); } @Test public void should_return_specified_content_type_no_matter_order() throws Exception { server.response(header(HttpHeaders.CONTENT_TYPE, "text/html"), with("foo")); running(server, new Runnable() { @Override public void run() throws Exception { Header header = helper.getResponse(root()).getFirstHeader(HttpHeaders.CONTENT_TYPE); assertThat(header.getValue(), is("text/html")); } }); } @Test public void should_return_specified_content_type_with_case_insensitive() throws Exception { server.response(header("content-type", "text/html"), with("foo")); running(server, new Runnable() { @Override public void run() throws Exception { Header[] headers = helper.getResponse(root()).getHeaders(HttpHeaders.CONTENT_TYPE); assertThat(headers.length, is(1)); } }); } }