Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -789,10 +789,9 @@ def __init__(
}

# Create session with the base URL
session = session or ClientSession(
base_url=endpoint,
headers=headers,
)
session = session or ClientSession(base_url=endpoint)
session.headers.update(headers)
Comment on lines +792 to +793

logger.debug(
"ConnectorClient initialized with endpoint: %s and headers: %s",
endpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,8 @@ def __init__(
}

# Create session with the base URL
session = session or ClientSession(
base_url=endpoint,
headers=headers,
)
session = session or ClientSession(base_url=endpoint)
session.headers.update(headers)
logger.debug(
"Creating UserTokenClient with endpoint: %s and headers: %s",
endpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ..conversations_base import ConversationsBase
from ..client._base_client import _BaseClient
from .._utils import _handle_request_error
from ..get_product_info import get_product_info

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -224,6 +225,13 @@ def __init__(self, endpoint: str, client: Optional[ClientSession] = None):

self._endpoint = endpoint
self._client = client or ClientSession()
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"User-Agent": get_product_info(),
}
self._client.headers.update(headers)
Comment on lines +228 to +233

self._conversations = MCSConversations(self._client, self._endpoint)
self._attachments = MCSAttachments()

Expand Down
70 changes: 70 additions & 0 deletions tests/hosting_core/connector/test_connector_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
ConnectorClient,
ConversationsOperations,
)
from microsoft_agents.hosting.core.connector.get_product_info import get_product_info
from microsoft_agents.hosting.core.connector.teams import TeamsConnectorClient
from microsoft_agents.hosting.core.header_propagation import HeaderPropagationContext


Expand Down Expand Up @@ -945,3 +947,71 @@ async def handler(request):
assert "conv_sub_id" in captured["raw_path"]
finally:
await server.close()


class TestUserAgentHeader:
"""Ensures ConnectorClient and TeamsConnectorClient send a User-Agent header."""

@pytest.mark.asyncio
async def test_connector_client_sets_user_agent_header(self):
client = ConnectorClient(endpoint="https://example.org/", token="token")
try:
assert client.client.headers["User-Agent"] == get_product_info()
finally:
await client.client.close()

@pytest.mark.asyncio
async def test_connector_client_sends_user_agent_header_on_request(self):
captured = {}

async def handler(request):
captured["user_agent"] = request.headers.get("User-Agent")
return web.json_response({"id": "activity-id-123"})

routes = [web.post("/v3/conversations/{conversation_id}/activities", handler)]
app = _create_app(routes)

server = TestServer(app)
await server.start_server()
try:
client = ConnectorClient(endpoint=str(server.make_url("/")), token="token")
await client.conversations.send_to_conversation(
"conv-1", Activity(type="message", text="hi")
)
finally:
await server.close()
await client.client.close()
Comment on lines +981 to +983

assert captured["user_agent"] == get_product_info()

@pytest.mark.asyncio
async def test_teams_connector_client_sets_user_agent_header(self):
client = TeamsConnectorClient(endpoint="https://example.org/", token="token")
try:
assert client.client.headers["User-Agent"] == get_product_info()
finally:
await client.client.close()

@pytest.mark.asyncio
async def test_teams_connector_client_sends_user_agent_header_on_request(self):
captured = {}

async def handler(request):
captured["user_agent"] = request.headers.get("User-Agent")
return web.json_response({"id": "team-1"})

routes = [web.get("/v3/teams/{team_id}", handler)]
app = _create_app(routes)

server = TestServer(app)
await server.start_server()
try:
client = TeamsConnectorClient(
endpoint=str(server.make_url("/")), token="token"
)
await client.fetch_team_details("team-1")
finally:
await server.close()
await client.client.close()

assert captured["user_agent"] == get_product_info()
55 changes: 55 additions & 0 deletions tests/hosting_core/connector/test_mcs_connector_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""Tests for MCSConnectorClient User-Agent header behavior."""

import pytest
from aiohttp import web
from aiohttp.test_utils import TestServer

from microsoft_agents.activity import Activity
from microsoft_agents.hosting.core.connector.get_product_info import get_product_info
from microsoft_agents.hosting.core.connector.mcs import MCSConnectorClient


class TestMCSConnectorClientUserAgentHeader:
"""Ensures MCSConnectorClient sends a User-Agent header.

NOTE: Unlike ConnectorClient/TeamsConnectorClient and UserTokenClient,
MCSConnectorClient does not currently set a custom "agents-sdk-py" User-Agent
header on its session or outgoing requests, so these tests currently fail.
"""

Comment on lines +16 to +22
@pytest.mark.asyncio
async def test_sets_user_agent_header(self):
client = MCSConnectorClient(endpoint="https://example.org/endpoint")
try:
assert client._client.headers.get("User-Agent") == get_product_info()
finally:
await client.close()

@pytest.mark.asyncio
async def test_sends_user_agent_header_on_request(self):
captured = {}

async def handler(request):
captured["user_agent"] = request.headers.get("User-Agent")
return web.json_response({"id": "activity-id-123"})

app = web.Application()
app.router.add_post("/endpoint", handler)
server = TestServer(app)
await server.start_server()
try:
endpoint = str(server.make_url("/endpoint"))
client = MCSConnectorClient(endpoint=endpoint)
try:
await client.conversations.send_to_conversation(
"conv-1", Activity(type="message", text="hi")
)
finally:
await client.close()
finally:
await server.close()

assert captured["user_agent"] == get_product_info()
35 changes: 35 additions & 0 deletions tests/hosting_core/connector/test_user_token_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
UserToken,
UserTokenClient,
)
from microsoft_agents.hosting.core.connector.get_product_info import get_product_info
from microsoft_agents.hosting.core.header_propagation import HeaderPropagationContext


Expand Down Expand Up @@ -407,3 +408,37 @@ async def handler(request):
await server.close()

assert exc_info.value.status == 500


class TestUserTokenClientUserAgentHeader:
"""Ensures UserTokenClient sends a User-Agent header."""

@pytest.mark.asyncio
async def test_sets_user_agent_header(self):
client = UserTokenClient("https://example.org/", token="", app_id="app-id")
try:
assert client.client.headers["User-Agent"] == get_product_info()
finally:
await client.close()

@pytest.mark.asyncio
async def test_sends_user_agent_header_on_request(self):
captured = {}

async def handler(request):
captured["user_agent"] = request.headers.get("User-Agent")
return web.json_response({"token": "token"})

app = web.Application()
app.router.add_get("/api/usertoken/GetToken", handler)
server = TestServer(app)
await server.start_server()

client = UserTokenClient(str(server.make_url("/")), token="", app_id="app-id")
try:
await client.get_user_token("user", "connection", "msteams")
finally:
await client.close()
await server.close()

assert captured["user_agent"] == get_product_info()
Loading