Skip to content

Commit 54a4051

Browse files
updated unit tests
1 parent 7ec3f00 commit 54a4051

File tree

7 files changed

+995
-87
lines changed

7 files changed

+995
-87
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import pytest
2+
from unittest.mock import patch, AsyncMock
3+
4+
from backend.agents.agent_factory import AgentFactory
5+
6+
7+
class TestAgentFactory:
8+
"""Test suite for AgentFactory class."""
9+
10+
@pytest.fixture
11+
def reset_singleton(self):
12+
"""Fixture to reset the singleton between tests"""
13+
original_instance = AgentFactory._instance
14+
AgentFactory._instance = None
15+
yield
16+
AgentFactory._instance = original_instance
17+
18+
@pytest.mark.asyncio
19+
@patch("backend.agents.agent_factory.AzureAIAgent")
20+
@patch("backend.agents.agent_factory.DefaultAzureCredential")
21+
@patch("backend.agents.agent_factory.AzureAIAgentSettings")
22+
async def test_get_instance_creates_agent_when_none_exists(
23+
self, mock_settings, mock_credential, mock_agent, reset_singleton
24+
):
25+
"""Test that get_instance creates a new agent when none exists."""
26+
# Arrange
27+
mock_agent_instance = AsyncMock()
28+
mock_agent.return_value = mock_agent_instance
29+
mock_client = AsyncMock()
30+
mock_agent.create_client.return_value = mock_client
31+
32+
# Act
33+
result = await AgentFactory.get_instance()
34+
35+
# Assert
36+
assert result is not None
37+
assert AgentFactory._instance is not None
38+
assert AgentFactory._instance is result
39+
assert mock_agent.create_client.called
40+
assert mock_agent.called
41+
42+
@pytest.mark.asyncio
43+
async def test_get_instance_returns_existing_agent(self, reset_singleton):
44+
"""Test that get_instance returns existing agent when one exists."""
45+
# Arrange
46+
mock_instance = AsyncMock()
47+
AgentFactory._instance = mock_instance
48+
49+
# Act
50+
result = await AgentFactory.get_instance()
51+
52+
# Assert
53+
assert result is mock_instance
54+
55+
@pytest.mark.asyncio
56+
async def test_multiple_calls_return_same_instance(self, reset_singleton):
57+
"""Test that multiple calls to get_instance return the same instance."""
58+
# Arrange
59+
mock_agent = AsyncMock()
60+
mock_client = AsyncMock()
61+
mock_agent_definition = AsyncMock()
62+
mock_agent_instance = AsyncMock()
63+
64+
with patch("backend.agents.agent_factory.AzureAIAgent") as mock_agent_class:
65+
mock_agent_class.create_client.return_value = mock_client
66+
mock_client.agents.create_agent = AsyncMock(return_value=mock_agent_definition)
67+
mock_agent_class.return_value = mock_agent_instance
68+
69+
with patch("backend.agents.agent_factory.DefaultAzureCredential"):
70+
with patch("backend.agents.agent_factory.AzureAIAgentSettings"):
71+
# Act
72+
instance1 = await AgentFactory.get_instance()
73+
instance2 = await AgentFactory.get_instance()
74+
75+
# Assert
76+
assert instance1 is instance2
77+
78+
@pytest.mark.asyncio
79+
async def test_delete_instance_when_none_exists(self, reset_singleton):
80+
"""Test that delete_instance handles when no agent exists."""
81+
# Arrange
82+
AgentFactory._instance = None
83+
84+
# Act
85+
await AgentFactory.delete_instance()
86+
87+
# Assert
88+
assert AgentFactory._instance is None
89+
90+
@pytest.mark.asyncio
91+
async def test_delete_instance_removes_existing_agent(self, reset_singleton):
92+
"""Test that delete_instance properly removes an existing agent."""
93+
# Arrange
94+
mock_agent = AsyncMock()
95+
mock_agent.client = AsyncMock()
96+
mock_agent.id = "test-agent-id"
97+
AgentFactory._instance = mock_agent
98+
99+
# Act
100+
await AgentFactory.delete_instance()
101+
102+
# Assert
103+
assert AgentFactory._instance is None
104+
mock_agent.client.agents.delete_agent.assert_called_once_with(mock_agent.id)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import pytest
2+
from unittest.mock import patch, MagicMock
3+
from backend.common.event_utils import track_event_if_configured
4+
5+
@patch("backend.common.event_utils.track_event")
6+
@patch("backend.common.event_utils.config")
7+
@patch("backend.common.event_utils.logging")
8+
def test_track_event_when_configured(mock_logging, mock_config, mock_track_event):
9+
# Setup
10+
mock_config.APPLICATIONINSIGHTS_CONNECTION_STRING = "mock_connection_string"
11+
event_name = "test_event"
12+
event_data = {"key": "value"}
13+
14+
# Execute
15+
track_event_if_configured(event_name, event_data)
16+
17+
# Verify
18+
mock_track_event.assert_called_once_with(event_name, event_data)
19+
mock_logging.warning.assert_not_called()
20+
21+
22+
@patch("backend.common.event_utils.track_event")
23+
@patch("backend.common.event_utils.config")
24+
@patch("backend.common.event_utils.logging")
25+
def test_track_event_when_not_configured(mock_logging, mock_config, mock_track_event):
26+
# Setup
27+
mock_config.APPLICATIONINSIGHTS_CONNECTION_STRING = None
28+
event_name = "test_event"
29+
event_data = {"key": "value"}
30+
31+
# Execute
32+
track_event_if_configured(event_name, event_data)
33+
34+
# Verify
35+
mock_track_event.assert_not_called()
36+
mock_logging.warning.assert_called_once_with(
37+
f"Skipping track_event for {event_name} as Application Insights is not configured"
38+
)
39+
40+
41+
@patch("backend.common.event_utils.track_event")
42+
@patch("backend.common.event_utils.config")
43+
@patch("backend.common.event_utils.logging")
44+
def test_track_event_attribute_error(mock_logging, mock_config, mock_track_event):
45+
# Setup
46+
mock_config.APPLICATIONINSIGHTS_CONNECTION_STRING = "mock_connection_string"
47+
mock_track_event.side_effect = AttributeError("ProxyLogger has no attribute 'resource'")
48+
event_name = "test_event"
49+
event_data = {"key": "value"}
50+
51+
# Execute
52+
track_event_if_configured(event_name, event_data)
53+
54+
# Verify
55+
mock_track_event.assert_called_once_with(event_name, event_data)
56+
mock_logging.warning.assert_called_once_with(
57+
"ProxyLogger error in track_event: ProxyLogger has no attribute 'resource'"
58+
)
59+
60+
61+
@patch("backend.common.event_utils.track_event")
62+
@patch("backend.common.event_utils.config")
63+
@patch("backend.common.event_utils.logging")
64+
def test_track_event_general_exception(mock_logging, mock_config, mock_track_event):
65+
# Setup
66+
mock_config.APPLICATIONINSIGHTS_CONNECTION_STRING = "mock_connection_string"
67+
mock_track_event.side_effect = Exception("Something went wrong")
68+
event_name = "test_event"
69+
event_data = {"key": "value"}
70+
71+
# Execute
72+
track_event_if_configured(event_name, event_data)
73+
74+
# Verify
75+
mock_track_event.assert_called_once_with(event_name, event_data)
76+
mock_logging.warning.assert_called_once_with(
77+
"Error in track_event: Something went wrong"
78+
)

src/App/tests/common/test_utils.py renamed to src/App/tests/backend/common/test_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def test_parse_multi_columns(input_str, expected):
4343
assert parse_multi_columns(input_str) == expected
4444

4545

46-
@patch("backend.utils.requests.get")
46+
@patch("backend.common.utils.requests.get")
4747
def test_fetch_user_groups(mock_get):
4848
mock_response = MagicMock()
4949
mock_response.status_code = 200
@@ -63,8 +63,8 @@ def test_fetch_user_groups(mock_get):
6363
assert user_groups == [{"id": "group1"}, {"id": "group1"}]
6464

6565

66-
@patch("backend.utils.fetchUserGroups")
67-
@patch("backend.utils.AZURE_SEARCH_PERMITTED_GROUPS_COLUMN", "your_column")
66+
@patch("backend.common.utils.fetchUserGroups")
67+
@patch("backend.common.utils.AZURE_SEARCH_PERMITTED_GROUPS_COLUMN", "your_column")
6868
def test_generate_filter_string(mock_fetch_user_groups):
6969
mock_fetch_user_groups.return_value = [{"id": "group1"}, {"id": "group2"}]
7070
filter_string = generateFilterString("fake_token")

0 commit comments

Comments
 (0)