aboutsummaryrefslogtreecommitdiff
path: root/server/test/jchat_auth_SUITE.erl
diff options
context:
space:
mode:
authorCalvin Morrison <calvin@pobox.com>2025-09-03 21:15:36 -0400
committerCalvin Morrison <calvin@pobox.com>2025-09-03 21:15:36 -0400
commit49fa5aa2a127bdf8924d02bf77e5086b39c7a447 (patch)
tree61d86a7705dacc9fddccc29fa79d075d83ab8059 /server/test/jchat_auth_SUITE.erl
i vibe coded itHEADmaster
Diffstat (limited to 'server/test/jchat_auth_SUITE.erl')
-rw-r--r--server/test/jchat_auth_SUITE.erl188
1 files changed, 188 insertions, 0 deletions
diff --git a/server/test/jchat_auth_SUITE.erl b/server/test/jchat_auth_SUITE.erl
new file mode 100644
index 0000000..91e7cbc
--- /dev/null
+++ b/server/test/jchat_auth_SUITE.erl
@@ -0,0 +1,188 @@
+-module(jchat_auth_SUITE).
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("../src/jchat.hrl").
+
+%%====================================================================
+%% CT Callbacks
+%%====================================================================
+
+suite() ->
+ [{timetrap, {seconds, 30}}].
+
+init_per_suite(Config) ->
+ % Start the application
+ application:ensure_all_started(jchat),
+ % Wait a bit for server to start
+ timer:sleep(1000),
+ Config.
+
+end_per_suite(_Config) ->
+ application:stop(jchat),
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ % Clean up any existing test data
+ mnesia:clear_table(user),
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_user_registration,
+ test_user_login,
+ test_duplicate_email_registration,
+ test_invalid_login,
+ test_jwt_token_validation,
+ test_jmap_api_authentication,
+ test_password_hashing,
+ test_user_creation_flow].
+
+%%====================================================================
+%% Test Cases
+%%====================================================================
+
+test_user_registration(_Config) ->
+ Email = <<"test@example.com">>,
+ Password = <<"testpass123">>,
+ DisplayName = <<"Test User">>,
+
+ % Test user registration
+ {ok, User} = jchat_auth:register_user(Email, Password, DisplayName),
+
+ % Verify user fields
+ ?assertEqual(Email, User#user.email),
+ ?assertEqual(DisplayName, User#user.display_name),
+ ?assert(is_binary(User#user.id)),
+ ?assert(is_binary(User#user.password_hash)),
+ ?assertNotEqual(Password, User#user.password_hash),
+ ?assertEqual(true, User#user.is_active),
+ ?assertEqual(<<"local">>, User#user.auth_provider).
+
+test_user_login(_Config) ->
+ Email = <<"test@example.com">>,
+ Password = <<"testpass123">>,
+ DisplayName = <<"Test User">>,
+
+ % Register user first
+ {ok, _User} = jchat_auth:register_user(Email, Password, DisplayName),
+
+ % Test login
+ {ok, {AuthUser, Token}} = jchat_auth:authenticate_user(Email, Password),
+
+ % Verify user and token
+ ?assertEqual(Email, AuthUser#user.email),
+ ?assert(is_binary(Token)),
+ ?assert(byte_size(Token) > 0).
+
+test_duplicate_email_registration(_Config) ->
+ Email = <<"test@example.com">>,
+ Password = <<"testpass123">>,
+ DisplayName = <<"Test User">>,
+
+ % Register user first time
+ {ok, _User} = jchat_auth:register_user(Email, Password, DisplayName),
+
+ % Try to register same email again
+ Result = jchat_auth:register_user(Email, Password, DisplayName),
+ ?assertMatch({error, _}, Result).
+
+test_invalid_login(_Config) ->
+ Email = <<"test@example.com">>,
+ Password = <<"testpass123">>,
+ WrongPassword = <<"wrongpass">>,
+ DisplayName = <<"Test User">>,
+
+ % Register user
+ {ok, _User} = jchat_auth:register_user(Email, Password, DisplayName),
+
+ % Try login with wrong password
+ Result = jchat_auth:authenticate_user(Email, WrongPassword),
+ ?assertMatch({error, _}, Result),
+
+ % Try login with non-existent email
+ Result2 = jchat_auth:authenticate_user(<<"nonexistent@example.com">>, Password),
+ ?assertMatch({error, _}, Result2).
+
+test_jwt_token_validation(_Config) ->
+ Email = <<"test@example.com">>,
+ Password = <<"testpass123">>,
+ DisplayName = <<"Test User">>,
+
+ % Register and login
+ {ok, _User} = jchat_auth:register_user(Email, Password, DisplayName),
+ {ok, {AuthUser, Token}} = jchat_auth:authenticate_user(Email, Password),
+
+ % Validate token
+ {ok, ValidatedUser} = jchat_auth:validate_token(Token),
+ ?assertEqual(AuthUser#user.id, ValidatedUser#user.id),
+ ?assertEqual(AuthUser#user.email, ValidatedUser#user.email),
+
+ % Test invalid token
+ InvalidToken = <<"invalid.token.here">>,
+ Result = jchat_auth:validate_token(InvalidToken),
+ ?assertMatch({error, _}, Result).
+
+test_jmap_api_authentication(_Config) ->
+ Email = <<"test@example.com">>,
+ Password = <<"testpass123">>,
+ DisplayName = <<"Test User">>,
+
+ % Register and login
+ {ok, _User} = jchat_auth:register_user(Email, Password, DisplayName),
+ {ok, {_AuthUser, Token}} = jchat_auth:authenticate_user(Email, Password),
+
+ % Create mock request with auth header
+ AuthHeader = <<"Bearer ", Token/binary>>,
+
+ % Test authentication context creation
+ {ok, AuthContext} = jchat_auth:create_auth_context(AuthHeader),
+ ?assertMatch(#{user := _, account_id := _}, AuthContext),
+
+ User = maps:get(user, AuthContext),
+ ?assertEqual(Email, User#user.email).
+
+test_password_hashing(_Config) ->
+ Password1 = <<"password123">>,
+ Password2 = <<"password123">>,
+ Password3 = <<"differentpass">>,
+
+ % Hash the same password twice
+ Hash1 = jchat_auth:hash_password(Password1),
+ Hash2 = jchat_auth:hash_password(Password2),
+
+ % Hashes should be different (salt makes them unique)
+ ?assertNotEqual(Hash1, Hash2),
+
+ % But both should verify correctly
+ ?assert(jchat_auth:verify_password(Password1, Hash1)),
+ ?assert(jchat_auth:verify_password(Password2, Hash2)),
+
+ % Wrong password should not verify
+ ?assertNot(jchat_auth:verify_password(Password3, Hash1)).
+
+test_user_creation_flow(_Config) ->
+ % Test the full user creation flow including database storage
+ Email = <<"flow.test@example.com">>,
+ Password = <<"flowtest123">>,
+ DisplayName = <<"Flow Test User">>,
+
+ % Register user (this should create in database)
+ {ok, User} = jchat_auth:register_user(Email, Password, DisplayName),
+ UserId = User#user.id,
+
+ % Verify user exists in database
+ {ok, DbUser} = jchat_db:get_user_by_id(UserId),
+ ?assertEqual(Email, DbUser#user.email),
+ ?assertEqual(DisplayName, DbUser#user.display_name),
+
+ % Verify user can be found by email
+ {ok, EmailUser} = jchat_db:get_user_by_email(Email),
+ ?assertEqual(UserId, EmailUser#user.id),
+
+ % Test login retrieves the same user
+ {ok, {LoginUser, _Token}} = jchat_auth:authenticate_user(Email, Password),
+ ?assertEqual(UserId, LoginUser#user.id).