test_scoped_auth_client.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import unittest
  2. from unittest.mock import MagicMock
  3. from services.scoped_auth_client import ScopedAuthClient
  4. class TestScopedAuthClient(unittest.TestCase):
  5. def setUp(self):
  6. self.mock_transport = MagicMock()
  7. self.mock_session_store = MagicMock()
  8. self.client = ScopedAuthClient(
  9. base_url='http://test.example.com',
  10. client_type='workbuddy',
  11. session_store=self.mock_session_store,
  12. transport=self.mock_transport,
  13. timeout=10
  14. )
  15. def test_build_session_key(self):
  16. gateway_session_id = 'GWS_abc123'
  17. session_key = ScopedAuthClient.build_session_key(gateway_session_id)
  18. self.assertEqual(session_key, 'gws_GWS_abc123')
  19. def test_exchange_success(self):
  20. gateway_session_id = 'GWS_test123'
  21. auth_code = 'AC_xyz789'
  22. # Mock successful response
  23. self.mock_transport.post_json.return_value = {
  24. 'code': 'MCP_0000',
  25. 'msg': 'success',
  26. 'data': {
  27. 'mcp_token': 'MT_token123',
  28. 'admin_id': 456,
  29. 'company_id': 200,
  30. 'expire_time': '2099-12-31 23:59:59',
  31. }
  32. }
  33. result = self.client.exchange(gateway_session_id, auth_code)
  34. # Verify transport call
  35. self.mock_transport.post_json.assert_called_once_with(
  36. 'http://test.example.com/mcp/auth/exchange',
  37. {
  38. 'auth_code': auth_code,
  39. 'client_type': 'workbuddy',
  40. 'session_key': 'gws_GWS_test123',
  41. },
  42. {},
  43. 10
  44. )
  45. # Verify session store save
  46. self.mock_session_store.save.assert_called_once()
  47. save_call_args = self.mock_session_store.save.call_args
  48. self.assertEqual(save_call_args[0][0], gateway_session_id)
  49. saved_session = save_call_args[0][1]
  50. self.assertEqual(saved_session['session_key'], 'gws_GWS_test123')
  51. self.assertEqual(saved_session['mcp_token'], 'MT_token123')
  52. self.assertEqual(saved_session['admin_id'], 456)
  53. self.assertEqual(saved_session['company_id'], 200)
  54. self.assertEqual(saved_session['client_type'], 'workbuddy')
  55. self.assertEqual(saved_session['expire_time'], '2099-12-31 23:59:59')
  56. # Verify result
  57. self.assertEqual(result['code'], 'MCP_0000')
  58. def test_exchange_failure_no_token(self):
  59. gateway_session_id = 'GWS_fail'
  60. auth_code = 'AC_invalid'
  61. # Mock failure response
  62. self.mock_transport.post_json.return_value = {
  63. 'code': 'MCP_1001',
  64. 'msg': 'auth_code invalid',
  65. 'data': {}
  66. }
  67. result = self.client.exchange(gateway_session_id, auth_code)
  68. # Should not save to session store
  69. self.mock_session_store.save.assert_not_called()
  70. # Should still return the response
  71. self.assertEqual(result['code'], 'MCP_1001')
  72. def test_exchange_partial_data(self):
  73. gateway_session_id = 'GWS_partial'
  74. auth_code = 'AC_partial'
  75. # Mock response with missing admin_id and company_id
  76. self.mock_transport.post_json.return_value = {
  77. 'code': 'MCP_0000',
  78. 'msg': 'success',
  79. 'data': {
  80. 'mcp_token': 'MT_token456',
  81. 'expire_time': '2099-12-31 23:59:59',
  82. # Missing admin_id and company_id
  83. }
  84. }
  85. result = self.client.exchange(gateway_session_id, auth_code)
  86. # Should still save, with None values
  87. self.mock_session_store.save.assert_called_once()
  88. saved_session = self.mock_session_store.save.call_args[0][1]
  89. self.assertEqual(saved_session['mcp_token'], 'MT_token456')
  90. self.assertIsNone(saved_session['admin_id'])
  91. self.assertIsNone(saved_session['company_id'])
  92. def test_exchange_no_data_field(self):
  93. gateway_session_id = 'GWS_nodata'
  94. auth_code = 'AC_nodata'
  95. # Mock response without data field
  96. self.mock_transport.post_json.return_value = {
  97. 'code': 'MCP_9999',
  98. 'msg': 'error'
  99. }
  100. result = self.client.exchange(gateway_session_id, auth_code)
  101. # Should not save
  102. self.mock_session_store.save.assert_not_called()
  103. def test_exchange_strips_base_url_trailing_slash(self):
  104. client_with_slash = ScopedAuthClient(
  105. base_url='http://test.example.com/',
  106. client_type='workbuddy',
  107. session_store=self.mock_session_store,
  108. transport=self.mock_transport,
  109. timeout=10
  110. )
  111. self.mock_transport.post_json.return_value = {
  112. 'code': 'MCP_0000',
  113. 'data': {'mcp_token': 'MT_test'}
  114. }
  115. client_with_slash.exchange('GWS_test', 'AC_test')
  116. # Should call without double slash
  117. call_url = self.mock_transport.post_json.call_args[0][0]
  118. self.assertEqual(call_url, 'http://test.example.com/mcp/auth/exchange')
  119. if __name__ == '__main__':
  120. unittest.main()