diff options
Diffstat (limited to 'server/test/jchat_http_SUITE.erl')
-rw-r--r-- | server/test/jchat_http_SUITE.erl | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/server/test/jchat_http_SUITE.erl b/server/test/jchat_http_SUITE.erl new file mode 100644 index 0000000..5c8804f --- /dev/null +++ b/server/test/jchat_http_SUITE.erl @@ -0,0 +1,224 @@ +-module(jchat_http_SUITE). +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +%%==================================================================== +%% CT Callbacks +%%==================================================================== + +suite() -> + [{timetrap, {seconds, 30}}]. + +init_per_suite(Config) -> + % Start the application + application:ensure_all_started(jchat), + % Wait for server to start + timer:sleep(1000), + [{server_url, "http://localhost:8081"} | Config]. + +end_per_suite(_Config) -> + application:stop(jchat), + ok. + +init_per_testcase(_TestCase, Config) -> + % Clean up test data + mnesia:clear_table(user), + Config. + +end_per_testcase(_TestCase, _Config) -> + ok. + +all() -> + [test_auth_register_endpoint, + test_auth_login_endpoint, + test_auth_me_endpoint, + test_jmap_api_with_auth, + test_jmap_api_without_auth, + test_cors_headers]. + +%%==================================================================== +%% Test Cases +%%==================================================================== + +test_auth_register_endpoint(Config) -> + ServerUrl = ?config(server_url, Config), + + % Prepare registration data + Email = "test@example.com", + Password = "testpass123", + DisplayName = "Test User", + + ReqBody = jsx:encode(#{ + <<"email">> => list_to_binary(Email), + <<"password">> => list_to_binary(Password), + <<"displayName">> => list_to_binary(DisplayName) + }), + + % Make registration request + Url = ServerUrl ++ "/auth/register", + Headers = [{"content-type", "application/json"}], + + {ok, {{_Version, 201, _ReasonPhrase}, _Headers, ResponseBody}} = + httpc:request(post, {Url, Headers, "application/json", ReqBody}, [], []), + + % Parse response + ResponseMap = jsx:decode(list_to_binary(ResponseBody)), + ?assert(maps:is_key(<<"token">>, ResponseMap)), + ?assert(maps:is_key(<<"user">>, ResponseMap)), + + User = maps:get(<<"user">>, ResponseMap), + ?assertEqual(list_to_binary(Email), maps:get(<<"email">>, User)), + ?assertEqual(list_to_binary(DisplayName), maps:get(<<"displayName">>, User)). + +test_auth_login_endpoint(Config) -> + ServerUrl = ?config(server_url, Config), + + % First register a user + Email = "login.test@example.com", + Password = "logintest123", + DisplayName = "Login Test User", + + {ok, _User} = jchat_auth:register_user( + list_to_binary(Email), + list_to_binary(Password), + list_to_binary(DisplayName) + ), + + % Now test login + ReqBody = jsx:encode(#{ + <<"email">> => list_to_binary(Email), + <<"password">> => list_to_binary(Password) + }), + + Url = ServerUrl ++ "/auth/login", + Headers = [{"content-type", "application/json"}], + + {ok, {{_Version, 200, _ReasonPhrase}, _Headers, ResponseBody}} = + httpc:request(post, {Url, Headers, "application/json", ReqBody}, [], []), + + % Parse response + ResponseMap = jsx:decode(list_to_binary(ResponseBody)), + ?assert(maps:is_key(<<"token">>, ResponseMap)), + ?assert(maps:is_key(<<"user">>, ResponseMap)). + +test_auth_me_endpoint(Config) -> + ServerUrl = ?config(server_url, Config), + + % Register and login to get token + Email = "me.test@example.com", + Password = "metest123", + DisplayName = "Me Test User", + + {ok, _User} = jchat_auth:register_user( + list_to_binary(Email), + list_to_binary(Password), + list_to_binary(DisplayName) + ), + + {ok, {_AuthUser, Token}} = jchat_auth:authenticate_user( + list_to_binary(Email), + list_to_binary(Password) + ), + + % Test /auth/me endpoint + Url = ServerUrl ++ "/auth/me", + Headers = [{"authorization", "Bearer " ++ binary_to_list(Token)}], + + {ok, {{_Version, 200, _ReasonPhrase}, _Headers, ResponseBody}} = + httpc:request(get, {Url, Headers}, [], []), + + % Parse response + ResponseMap = jsx:decode(list_to_binary(ResponseBody)), + ?assert(maps:is_key(<<"user">>, ResponseMap)), + + User = maps:get(<<"user">>, ResponseMap), + ?assertEqual(list_to_binary(Email), maps:get(<<"email">>, User)). + +test_jmap_api_with_auth(Config) -> + ServerUrl = ?config(server_url, Config), + + % Register and login to get token + Email = "jmap.test@example.com", + Password = "jmaptest123", + DisplayName = "JMAP Test User", + + {ok, _User} = jchat_auth:register_user( + list_to_binary(Email), + list_to_binary(Password), + list_to_binary(DisplayName) + ), + + {ok, {_AuthUser, Token}} = jchat_auth:authenticate_user( + list_to_binary(Email), + list_to_binary(Password) + ), + + % Test JMAP API call + ReqBody = jsx:encode(#{ + <<"using">> => [<<"urn:ietf:params:jmap:core">>, <<"https://jmap.io/jchat/">>], + <<"methodCalls">> => [ + [<<"Conversation/query">>, #{ + <<"accountId">> => <<"default">>, + <<"filter">> => #{}, + <<"sort">> => [#{<<"property">> => <<"lastMessageAt">>, <<"isAscending">> => false}] + }, <<"c1">>] + ] + }), + + Url = ServerUrl ++ "/jmap/api", + Headers = [ + {"content-type", "application/json"}, + {"authorization", "Bearer " ++ binary_to_list(Token)} + ], + + {ok, {{_Version, 200, _ReasonPhrase}, _Headers, ResponseBody}} = + httpc:request(post, {Url, Headers, "application/json", ReqBody}, [], []), + + % Parse response + ResponseMap = jsx:decode(list_to_binary(ResponseBody)), + ?assert(maps:is_key(<<"methodResponses">>, ResponseMap)). + +test_jmap_api_without_auth(Config) -> + ServerUrl = ?config(server_url, Config), + + % Test JMAP API call without authentication + ReqBody = jsx:encode(#{ + <<"using">> => [<<"urn:ietf:params:jmap:core">>, <<"https://jmap.io/jchat/">>], + <<"methodCalls">> => [ + [<<"Conversation/query">>, #{ + <<"accountId">> => <<"default">>, + <<"filter">> => #{}, + <<"sort">> => [#{<<"property">> => <<"lastMessageAt">>, <<"isAscending">> => false}] + }, <<"c1">>] + ] + }), + + Url = ServerUrl ++ "/jmap/api", + Headers = [{"content-type", "application/json"}], + + {ok, {{_Version, 401, _ReasonPhrase}, _Headers, _ResponseBody}} = + httpc:request(post, {Url, Headers, "application/json", ReqBody}, [], []). + +test_cors_headers(Config) -> + ServerUrl = ?config(server_url, Config), + + % Test CORS preflight + Url = ServerUrl ++ "/auth/register", + Headers = [ + {"origin", "http://localhost:3000"}, + {"access-control-request-method", "POST"}, + {"access-control-request-headers", "content-type,authorization"} + ], + + {ok, {{_Version, StatusCode, _ReasonPhrase}, ResponseHeaders, _ResponseBody}} = + httpc:request(options, {Url, Headers}, [], []), + + % Should return 200 or 204 for OPTIONS + ?assert(StatusCode =:= 200 orelse StatusCode =:= 204), + + % Check for CORS headers + HeadersMap = maps:from_list(ResponseHeaders), + ?assert(maps:is_key("access-control-allow-origin", HeadersMap) orelse + maps:is_key("Access-Control-Allow-Origin", HeadersMap)). |