aboutsummaryrefslogtreecommitdiff
path: root/server/test/jchat_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'server/test/jchat_SUITE.erl')
-rw-r--r--server/test/jchat_SUITE.erl252
1 files changed, 252 insertions, 0 deletions
diff --git a/server/test/jchat_SUITE.erl b/server/test/jchat_SUITE.erl
new file mode 100644
index 0000000..ab6f375
--- /dev/null
+++ b/server/test/jchat_SUITE.erl
@@ -0,0 +1,252 @@
+-module(jchat_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include("../src/jchat.hrl").
+
+%% CT callbacks
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([test_session_endpoint/1,
+ test_core_echo/1,
+ test_conversation_create/1,
+ test_conversation_get/1,
+ test_message_create/1,
+ test_message_get/1,
+ test_invalid_method/1,
+ test_invalid_json/1,
+ test_unknown_capability/1]).
+
+all() ->
+ [test_session_endpoint,
+ test_core_echo,
+ test_conversation_create,
+ test_conversation_get,
+ test_message_create,
+ test_message_get,
+ test_invalid_method,
+ test_invalid_json,
+ test_unknown_capability].
+
+init_per_suite(Config) ->
+ % Start the application
+ application:ensure_all_started(jchat),
+ timer:sleep(1000), % Allow startup
+ Config.
+
+end_per_suite(_Config) ->
+ application:stop(jchat),
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%% Test cases
+
+test_session_endpoint(_Config) ->
+ URL = "http://localhost:8080/jmap/session",
+ {ok, {{_, 200, _}, Headers, Body}} = httpc:request(get, {URL, []}, [], []),
+
+ % Check content type
+ {"content-type", "application/json"} = lists:keyfind("content-type", 1, Headers),
+
+ % Parse and validate session object
+ {ok, Session} = jchat_utils:json_decode(list_to_binary(Body)),
+
+ % Validate required fields
+ true = maps:is_key(<<"capabilities">>, Session),
+ true = maps:is_key(<<"accounts">>, Session),
+ true = maps:is_key(<<"apiUrl">>, Session),
+
+ % Check chat capability
+ Capabilities = maps:get(<<"capabilities">>, Session),
+ true = maps:is_key(<<"urn:ietf:params:jmap:chat">>, Capabilities).
+
+test_core_echo(_Config) ->
+ Request = #{
+ <<"using">> => [<<"urn:ietf:params:jmap:core">>],
+ <<"methodCalls">> => [
+ [<<"Core/echo">>, #{<<"hello">> => <<"world">>}, <<"c1">>]
+ ]
+ },
+
+ Response = make_jmap_request(Request),
+
+ MethodResponses = maps:get(<<"methodResponses">>, Response),
+ [EchoResponse] = MethodResponses,
+ [<<"Core/echo">>, Args, <<"c1">>] = EchoResponse,
+
+ <<"world">> = maps:get(<<"hello">>, Args).
+
+test_conversation_create(_Config) ->
+ Request = #{
+ <<"using">> => [<<"urn:ietf:params:jmap:core">>, <<"urn:ietf:params:jmap:chat">>],
+ <<"methodCalls">> => [
+ [<<"Conversation/set">>, #{
+ <<"accountId">> => <<"default">>,
+ <<"create">> => #{
+ <<"conv1">> => #{
+ <<"title">> => <<"Test Conversation">>,
+ <<"participantIds">> => [<<"user1">>, <<"user2">>]
+ }
+ }
+ }, <<"c1">>]
+ ]
+ },
+
+ Response = make_jmap_request(Request),
+
+ MethodResponses = maps:get(<<"methodResponses">>, Response),
+ [SetResponse] = MethodResponses,
+ [<<"Conversation/set">>, Args, <<"c1">>] = SetResponse,
+
+ Created = maps:get(<<"created">>, Args),
+ true = maps:is_key(<<"conv1">>, Created).
+
+test_conversation_get(_Config) ->
+ % First create a conversation
+ {ok, Conv} = jchat_db:create_conversation(<<"test-conv-1">>, #{
+ title => <<"Test Conversation">>,
+ participant_ids => [<<"user1">>]
+ }),
+
+ Request = #{
+ <<"using">> => [<<"urn:ietf:params:jmap:core">>, <<"urn:ietf:params:jmap:chat">>],
+ <<"methodCalls">> => [
+ [<<"Conversation/get">>, #{
+ <<"accountId">> => <<"default">>,
+ <<"ids">> => [<<"test-conv-1">>]
+ }, <<"c1">>]
+ ]
+ },
+
+ Response = make_jmap_request(Request),
+
+ MethodResponses = maps:get(<<"methodResponses">>, Response),
+ [GetResponse] = MethodResponses,
+ [<<"Conversation/get">>, Args, <<"c1">>] = GetResponse,
+
+ List = maps:get(<<"list">>, Args),
+ [ConvData] = List,
+ <<"test-conv-1">> = maps:get(<<"id">>, ConvData).
+
+test_message_create(_Config) ->
+ % First create a conversation
+ {ok, _Conv} = jchat_db:create_conversation(<<"test-conv-2">>, #{
+ title => <<"Message Test Conversation">>,
+ participant_ids => [<<"user1">>]
+ }),
+
+ Request = #{
+ <<"using">> => [<<"urn:ietf:params:jmap:core">>, <<"urn:ietf:params:jmap:chat">>],
+ <<"methodCalls">> => [
+ [<<"Message/set">>, #{
+ <<"accountId">> => <<"default">>,
+ <<"create">> => #{
+ <<"msg1">> => #{
+ <<"conversationId">> => <<"test-conv-2">>,
+ <<"body">> => <<"Hello, World!">>,
+ <<"senderId">> => <<"user1">>
+ }
+ }
+ }, <<"c1">>]
+ ]
+ },
+
+ Response = make_jmap_request(Request),
+
+ MethodResponses = maps:get(<<"methodResponses">>, Response),
+ [SetResponse] = MethodResponses,
+ [<<"Message/set">>, Args, <<"c1">>] = SetResponse,
+
+ Created = maps:get(<<"created">>, Args),
+ true = maps:is_key(<<"msg1">>, Created).
+
+test_message_get(_Config) ->
+ % Create conversation and message
+ {ok, _Conv} = jchat_db:create_conversation(<<"test-conv-3">>, #{
+ title => <<"Get Test Conversation">>,
+ participant_ids => [<<"user1">>]
+ }),
+ {ok, _Msg} = jchat_db:create_message(<<"test-msg-1">>, #{
+ conversation_id => <<"test-conv-3">>,
+ sender_id => <<"user1">>,
+ body => <<"Test message">>
+ }),
+
+ Request = #{
+ <<"using">> => [<<"urn:ietf:params:jmap:core">>, <<"urn:ietf:params:jmap:chat">>],
+ <<"methodCalls">> => [
+ [<<"Message/get">>, #{
+ <<"accountId">> => <<"default">>,
+ <<"ids">> => [<<"test-msg-1">>]
+ }, <<"c1">>]
+ ]
+ },
+
+ Response = make_jmap_request(Request),
+
+ MethodResponses = maps:get(<<"methodResponses">>, Response),
+ [GetResponse] = MethodResponses,
+ [<<"Message/get">>, Args, <<"c1">>] = GetResponse,
+
+ List = maps:get(<<"list">>, Args),
+ [MsgData] = List,
+ <<"test-msg-1">> = maps:get(<<"id">>, MsgData).
+
+test_invalid_method(_Config) ->
+ Request = #{
+ <<"using">> => [<<"urn:ietf:params:jmap:core">>],
+ <<"methodCalls">> => [
+ [<<"Invalid/method">>, #{}, <<"c1">>]
+ ]
+ },
+
+ Response = make_jmap_request(Request),
+
+ MethodResponses = maps:get(<<"methodResponses">>, Response),
+ [ErrorResponse] = MethodResponses,
+ [<<"error">>, ErrorArgs, <<"c1">>] = ErrorResponse,
+
+ <<"unknownMethod">> = maps:get(<<"type">>, ErrorArgs).
+
+test_invalid_json(_Config) ->
+ URL = "http://localhost:8080/jmap/api",
+ InvalidJSON = "{ invalid json",
+
+ {ok, {{_, 400, _}, _Headers, Body}} = httpc:request(post,
+ {URL, [], "application/json", InvalidJSON}, [], []),
+
+ {ok, ErrorResponse} = jchat_utils:json_decode(list_to_binary(Body)),
+ <<"urn:ietf:params:jmap:error:notJSON">> = maps:get(<<"type">>, ErrorResponse).
+
+test_unknown_capability(_Config) ->
+ Request = #{
+ <<"using">> => [<<"unknown:capability">>],
+ <<"methodCalls">> => []
+ },
+
+ RequestJSON = jchat_utils:json_encode(Request),
+ URL = "http://localhost:8080/jmap/api",
+
+ {ok, {{_, 400, _}, _Headers, Body}} = httpc:request(post,
+ {URL, [], "application/json", RequestJSON}, [], []),
+
+ {ok, ErrorResponse} = jchat_utils:json_decode(list_to_binary(Body)),
+ <<"urn:ietf:params:jmap:error:unknownCapability">> = maps:get(<<"type">>, ErrorResponse).
+
+%% Helper functions
+
+make_jmap_request(Request) ->
+ RequestJSON = jchat_utils:json_encode(Request),
+ URL = "http://localhost:8080/jmap/api",
+
+ {ok, {{_, 200, _}, _Headers, Body}} = httpc:request(post,
+ {URL, [], "application/json", RequestJSON}, [], []),
+
+ {ok, Response} = jchat_utils:json_decode(list_to_binary(Body)),
+ Response.