Repository: couchdb-couch Updated Branches: refs/heads/master 6997c3c23 -> 7dca41578
Adding test suite for trancated _update COUCHDB-3158 Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/570376b4 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/570376b4 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/570376b4 Branch: refs/heads/master Commit: 570376b47cf661804891597329b4b662fafb6a74 Parents: 6997c3c Author: ILYA Khlopotov <iil...@apache.org> Authored: Thu Sep 22 16:11:02 2016 -0700 Committer: ILYA Khlopotov <iil...@apache.org> Committed: Wed Oct 5 09:29:51 2016 -0700 ---------------------------------------------------------------------- test/couchdb_mrview_tests.erl | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/570376b4/test/couchdb_mrview_tests.erl ---------------------------------------------------------------------- diff --git a/test/couchdb_mrview_tests.erl b/test/couchdb_mrview_tests.erl new file mode 100644 index 0000000..fa9ba70 --- /dev/null +++ b/test/couchdb_mrview_tests.erl @@ -0,0 +1,165 @@ +% 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. + +-module(couchdb_mrview_tests). + +-include_lib("couch/include/couch_eunit.hrl"). +-include_lib("couch/include/couch_db.hrl"). + + + +-define(DDOC, {[ + {<<"_id">>, <<"_design/foo">>}, + {<<"shows">>, {[ + {<<"bar">>, <<"function(doc, req) {return '<h1>wosh</h1>';}">>} + ]}}, + {<<"updates">>, {[ + {<<"report">>, <<"function(doc, req) {" + "var data = JSON.parse(req.body); " + "return ['test', data];" + "}">>} + ]}} +]}). + +-define(USER, "admin"). +-define(PASS, "pass"). +-define(AUTH, {basic_auth, {?USER, ?PASS}}). + + +start() -> + Ctx = test_util:start_couch([chttpd]), + ok = config:set("admins", ?USER, ?PASS, _Persist=false), + Ctx. + +setup(PortType) -> + ok = meck:new(mochiweb_socket, [passthrough]), + ok = meck:expect(mochiweb_socket, recv, fun mochiweb_socket_recv/3), + + DbName = ?tempdb(), + ok = create_db(PortType, DbName), + + Host = host_url(PortType), + upload_ddoc(Host, ?b2l(DbName)), + {Host, ?b2l(DbName)}. + +teardown(Ctx) -> + ok = config:delete("admins", ?USER, _Persist=false), + test_util:stop_couch(Ctx). + +teardown(PortType, {_Host, DbName}) -> + (catch meck:unload(mochiweb_socket)), + delete_db(PortType, ?l2b(DbName)), + ok. + +mrview_update_test_() -> + { + "Check show functionality", + { + setup, + fun start/0, fun teardown/1, + [ + make_test_case(clustered, [fun should_return_invalid_request_body/2]), + make_test_case(backdoor, [fun should_return_invalid_request_body/2]) + ] + } + }. + +make_test_case(Mod, Funs) -> + { + lists:flatten(io_lib:format("~s", [Mod])), + {foreachx, fun setup/1, fun teardown/2, [{Mod, Fun} || Fun <- Funs]} + }. + +should_return_invalid_request_body(PortType, {Host, DbName}) -> + ?_test(begin + ok = create_doc(PortType, ?l2b(DbName), <<"doc_id">>, {[]}), + ReqUrl = Host ++ "/" ++ DbName ++ "/_design/foo/_update/report/doc_id", + {ok, Status, _Headers, Body} = + test_request:post(ReqUrl, [?AUTH], <<"{truncated}">>), + {Props} = jiffy:decode(Body), + ?assertEqual( + <<"bad_request">>, couch_util:get_value(<<"error">>, Props)), + ?assertEqual( + <<"Invalid request body">>, couch_util:get_value(<<"reason">>, Props)), + ?assertEqual(400, Status), + ok + end). + +create_doc(backdoor, DbName, Id, Body) -> + JsonDoc = couch_util:json_apply_field({<<"_id">>, Id}, Body), + Doc = couch_doc:from_json_obj(JsonDoc), + {ok, Db} = couch_db:open(DbName, [?ADMIN_CTX]), + {ok, _} = couch_db:update_docs(Db, [Doc]), + couch_db:ensure_full_commit(Db), + couch_db:close(Db); +create_doc(clustered, DbName, Id, Body) -> + JsonDoc = couch_util:json_apply_field({<<"_id">>, Id}, Body), + Doc = couch_doc:from_json_obj(JsonDoc), + {ok, _} = fabric:update_docs(DbName, [Doc], [?ADMIN_CTX]), + ok. + +create_db(backdoor, DbName) -> + {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]), + couch_db:close(Db); +create_db(clustered, DbName) -> + {ok, Status, _, _} = test_request:put(db_url(DbName), [?AUTH], ""), + assert_success(create_db, Status), + ok. + +delete_db(backdoor, DbName) -> + couch_server:delete(DbName, [?ADMIN_CTX]); +delete_db(clustered, DbName) -> + {ok, Status, _, _} = test_request:delete(db_url(DbName), [?AUTH]), + assert_success(delete_db, Status), + ok. + +assert_success(create_db, Status) -> + ?assert(lists:member(Status, [201, 202])); +assert_success(delete_db, Status) -> + ?assert(lists:member(Status, [200, 202])). + + +host_url(PortType) -> + "http://" ++ bind_address(PortType) ++ ":" ++ port(PortType). + +bind_address(PortType) -> + config:get(section(PortType), "bind_address", "127.0.0.1"). + +section(backdoor) -> "http"; +section(clustered) -> "chttpd". + +db_url(DbName) when is_binary(DbName) -> + db_url(binary_to_list(DbName)); +db_url(DbName) when is_list(DbName) -> + host_url(clustered) ++ "/" ++ DbName. + +port(clustered) -> + integer_to_list(mochiweb_socket_server:get(chttpd, port)); +port(backdoor) -> + integer_to_list(mochiweb_socket_server:get(couch_httpd, port)). + + +upload_ddoc(Host, DbName) -> + Url = Host ++ "/" ++ DbName ++ "/_design/foo", + Body = couch_util:json_encode(?DDOC), + {ok, 201, _Resp, _Body} = test_request:put(Url, [?AUTH], Body), + ok. + +mochiweb_socket_recv(Sock, Len, Timeout) -> + case meck:passthrough([Sock, Len, Timeout]) of + {ok, <<"{truncated}">>} -> + {error, closed}; + {ok, Data} -> + {ok, Data}; + Else -> + Else + end.