#!/usr/bin/env python3 """ Unit tests for CrossFitBooker authentication methods using AuthHandler """ import pytest import os import sys import requests from unittest.mock import patch, Mock # Add the parent directory to the path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from crossfit_booker import CrossFitBooker from auth import AuthHandler class TestCrossFitBookerAuthHeaders: """Test cases for get_auth_headers method""" def test_get_auth_headers_without_token(self): """Test headers without auth token""" with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() headers = booker.get_auth_headers() assert "Authorization" not in headers assert headers["User-Agent"] == "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:140.0) Gecko/20100101 Firefox/140.0" def test_get_auth_headers_with_token(self): """Test headers with auth token""" with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() booker.auth_handler.auth_token = "test_token_123" headers = booker.get_auth_headers() assert headers["Authorization"] == "Bearer test_token_123" class TestCrossFitBookerLogin: """Test cases for login method""" @patch('requests.Session.post') def test_login_success(self, mock_post): """Test successful login flow""" # Mock first login response mock_response1 = Mock() mock_response1.ok = True mock_response1.json.return_value = { "data": { "user": { "id_user": "12345" } } } # Mock second login response mock_response2 = Mock() mock_response2.ok = True mock_response2.json.return_value = { "token": "test_bearer_token" } mock_post.side_effect = [mock_response1, mock_response2] with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() result = booker.login() assert result is True assert booker.auth_handler.user_id == "12345" assert booker.auth_handler.auth_token == "test_bearer_token" @patch('requests.Session.post') def test_login_first_step_failure(self, mock_post): """Test login failure on first step""" mock_response = Mock() mock_response.ok = False mock_response.status_code = 400 mock_response.text = "Bad Request" mock_post.return_value = mock_response with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() result = booker.login() assert result is False assert booker.auth_handler.user_id is None assert booker.auth_handler.auth_token is None @patch('requests.Session.post') def test_login_second_step_failure(self, mock_post): """Test login failure on second step""" # First response succeeds mock_response1 = Mock() mock_response1.ok = True mock_response1.json.return_value = { "data": { "user": { "id_user": "12345" } } } # Second response fails mock_response2 = Mock() mock_response2.ok = False mock_response2.status_code = 401 mock_post.side_effect = [mock_response1, mock_response2] with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() result = booker.login() assert result is False @patch('requests.Session.post') def test_login_json_parsing_error(self, mock_post): """Test login with JSON parsing error""" mock_response = Mock() mock_response.ok = True mock_response.json.side_effect = ValueError("Invalid JSON") mock_post.return_value = mock_response with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() result = booker.login() assert result is False @patch('requests.Session.post') def test_login_request_exception(self, mock_post): """Test login with request exception""" mock_post.side_effect = requests.exceptions.ConnectionError("Network error") with patch.dict(os.environ, { 'CROSSFIT_USERNAME': 'test_user', 'CROSSFIT_PASSWORD': 'test_pass' }): booker = CrossFitBooker() result = booker.login() assert result is False if __name__ == "__main__": pytest.main([__file__, "-v"])