@@ -294,6 +294,195 @@ def test_get_auth_token_none(self, mock_settings) -> None:
294294 assert token is None
295295
296296
297+ class TestAutoLogin :
298+ """Tests for automatic login functionality."""
299+
300+ def test_attempt_auto_login_no_profile (self , mock_settings ):
301+ """Test auto-login when no profile is active."""
302+ from cforge .common import attempt_auto_login
303+
304+ token = attempt_auto_login ()
305+ assert token is None
306+
307+ def test_attempt_auto_login_no_credentials (self , mock_settings ):
308+ """Test auto-login when credentials are not available."""
309+ from cforge .common import attempt_auto_login
310+ from cforge .profile_utils import AuthProfile
311+ from datetime import datetime
312+
313+ mock_profile = AuthProfile (
314+ id = "test-profile" ,
315+ name = "Test" ,
316+ email = "test@example.com" ,
317+ apiUrl = "http://localhost:4444" ,
318+ isActive = True ,
319+ createdAt = datetime .now (),
320+ )
321+
322+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
323+ with patch ("cforge.common.load_profile_credentials" , return_value = None ):
324+ token = attempt_auto_login ()
325+ assert token is None
326+
327+ def test_attempt_auto_login_missing_email (self , mock_settings ):
328+ """Test auto-login when email is missing from credentials."""
329+ from cforge .common import attempt_auto_login
330+ from cforge .profile_utils import AuthProfile
331+ from datetime import datetime
332+
333+ mock_profile = AuthProfile (
334+ id = "test-profile" ,
335+ name = "Test" ,
336+ email = "test@example.com" ,
337+ apiUrl = "http://localhost:4444" ,
338+ isActive = True ,
339+ createdAt = datetime .now (),
340+ )
341+
342+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
343+ with patch ("cforge.common.load_profile_credentials" , return_value = {"password" : "test" }):
344+ token = attempt_auto_login ()
345+ assert token is None
346+
347+ def test_attempt_auto_login_missing_password (self , mock_settings ):
348+ """Test auto-login when password is missing from credentials."""
349+ from cforge .common import attempt_auto_login
350+ from cforge .profile_utils import AuthProfile
351+ from datetime import datetime
352+
353+ mock_profile = AuthProfile (
354+ id = "test-profile" ,
355+ name = "Test" ,
356+ email = "test@example.com" ,
357+ apiUrl = "http://localhost:4444" ,
358+ isActive = True ,
359+ createdAt = datetime .now (),
360+ )
361+
362+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
363+ with patch ("cforge.common.load_profile_credentials" , return_value = {"email" : "test@example.com" }):
364+ token = attempt_auto_login ()
365+ assert token is None
366+
367+ @patch ("cforge.common.requests.post" )
368+ def test_attempt_auto_login_success (self , mock_post , mock_settings ):
369+ """Test successful auto-login."""
370+ from cforge .common import attempt_auto_login , load_token
371+ from cforge .profile_utils import AuthProfile
372+ from datetime import datetime
373+
374+ mock_profile = AuthProfile (
375+ id = "test-profile" ,
376+ name = "Test" ,
377+ email = "test@example.com" ,
378+ apiUrl = "http://localhost:4444" ,
379+ isActive = True ,
380+ createdAt = datetime .now (),
381+ )
382+
383+ # Mock successful login response
384+ mock_response = Mock ()
385+ mock_response .status_code = 200
386+ mock_response .json .return_value = {"access_token" : "auto-login-token" }
387+ mock_post .return_value = mock_response
388+
389+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
390+ with patch ("cforge.common.load_profile_credentials" , return_value = {"email" : "test@example.com" , "password" : "test-pass" }):
391+ token = attempt_auto_login ()
392+ assert token == "auto-login-token"
393+
394+ # Verify token was saved
395+ saved_token = load_token ()
396+ assert saved_token == "auto-login-token"
397+
398+ @patch ("cforge.common.requests.post" )
399+ def test_attempt_auto_login_failed_login (self , mock_post , mock_settings ):
400+ """Test auto-login when login fails."""
401+ from cforge .common import attempt_auto_login
402+ from cforge .profile_utils import AuthProfile
403+ from datetime import datetime
404+
405+ mock_profile = AuthProfile (
406+ id = "test-profile" ,
407+ name = "Test" ,
408+ email = "test@example.com" ,
409+ apiUrl = "http://localhost:4444" ,
410+ isActive = True ,
411+ createdAt = datetime .now (),
412+ )
413+
414+ # Mock failed login response
415+ mock_response = Mock ()
416+ mock_response .status_code = 401
417+ mock_post .return_value = mock_response
418+
419+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
420+ with patch ("cforge.common.load_profile_credentials" , return_value = {"email" : "test@example.com" , "password" : "wrong-pass" }):
421+ token = attempt_auto_login ()
422+ assert token is None
423+
424+ @patch ("cforge.common.requests.post" )
425+ def test_attempt_auto_login_no_token_in_response (self , mock_post , mock_settings ):
426+ """Test auto-login when response doesn't contain token."""
427+ from cforge .common import attempt_auto_login
428+ from cforge .profile_utils import AuthProfile
429+ from datetime import datetime
430+
431+ mock_profile = AuthProfile (
432+ id = "test-profile" ,
433+ name = "Test" ,
434+ email = "test@example.com" ,
435+ apiUrl = "http://localhost:4444" ,
436+ isActive = True ,
437+ createdAt = datetime .now (),
438+ )
439+
440+ # Mock response without token
441+ mock_response = Mock ()
442+ mock_response .status_code = 200
443+ mock_response .json .return_value = {}
444+ mock_post .return_value = mock_response
445+
446+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
447+ with patch ("cforge.common.load_profile_credentials" , return_value = {"email" : "test@example.com" , "password" : "test-pass" }):
448+ token = attempt_auto_login ()
449+ assert token is None
450+
451+ @patch ("cforge.common.requests.post" )
452+ def test_attempt_auto_login_request_exception (self , mock_post , mock_settings ):
453+ """Test auto-login when request raises exception."""
454+ from cforge .common import attempt_auto_login
455+ from cforge .profile_utils import AuthProfile
456+ from datetime import datetime
457+
458+ mock_profile = AuthProfile (
459+ id = "test-profile" ,
460+ name = "Test" ,
461+ email = "test@example.com" ,
462+ apiUrl = "http://localhost:4444" ,
463+ isActive = True ,
464+ createdAt = datetime .now (),
465+ )
466+
467+ # Mock request exception
468+ mock_post .side_effect = Exception ("Connection error" )
469+
470+ with patch ("cforge.common.get_active_profile" , return_value = mock_profile ):
471+ with patch ("cforge.common.load_profile_credentials" , return_value = {"email" : "test@example.com" , "password" : "test-pass" }):
472+ token = attempt_auto_login ()
473+ assert token is None
474+
475+ def test_get_auth_token_with_auto_login (self , mock_settings ):
476+ """Test that get_auth_token attempts auto-login when no token is available."""
477+ from cforge .common import get_auth_token
478+
479+ # Mock no env token and no file token, but successful auto-login
480+ with patch ("cforge.common.load_token" , return_value = None ):
481+ with patch ("cforge.common.attempt_auto_login" , return_value = "auto-token" ):
482+ token = get_auth_token ()
483+ assert token == "auto-token"
484+
485+
297486class TestErrors :
298487 """Tests for custom error classes."""
299488
0 commit comments