Skip to content

test(gateway/teams): patch TypingActivityInput on the loaded adapter module - #18979

Closed
Sanjays2402 wants to merge 1 commit into
NousResearch:mainfrom
Sanjays2402:fix/main-ci-teams-typing-test-patches-input
Closed

test(gateway/teams): patch TypingActivityInput on the loaded adapter module#18979
Sanjays2402 wants to merge 1 commit into
NousResearch:mainfrom
Sanjays2402:fix/main-ci-teams-typing-test-patches-input

Conversation

@Sanjays2402

Copy link
Copy Markdown
Contributor

Summary

Fixes one Tests failure observed on main (and therefore propagating to every open PR):

FAILED tests/gateway/test_teams.py::TestTeamsSend::test_send_typing
  AssertionError: Expected send to have been awaited once. Awaited 0 times.

Reference run: 25250051126 on 5d3be898a.

Root cause

TypingActivityInput is conditionally imported from the microsoft_teams SDK in plugins/platforms/teams/adapter.py:

try:
    from microsoft_teams.api.activities.typing import TypingActivityInput
    ...
    TEAMS_SDK_AVAILABLE = True
except ImportError:
    TEAMS_SDK_AVAILABLE = False
    TypingActivityInput = None  # type: ignore[assignment,misc]

The Teams SDK isn't a tracked extra in pyproject.toml (no [teams] extra, not in [messaging] either), so on a CI worker doing uv pip install -e ".[all,dev]" the SDK is absent → TypingActivityInput is None.

send_typing then does:

async def send_typing(self, chat_id, metadata=None):
    if not self._app: return
    try:
        await self._app.send(chat_id, TypingActivityInput())  # ← TypeError
    except Exception:
        pass  # swallowed

…which raises TypeError: 'NoneType' object is not callable, gets silently swallowed by the broad except, and mock_app.send never awaits.

Why my first attempt didn't work

I initially tried patch("plugins.platforms.teams.adapter.TypingActivityInput", ...), but the test loads the adapter via:

_teams_mod = load_plugin_adapter("teams")  # mangled name 'plugin_adapter_teams'

…which gives the test a different module instance than plugins.platforms.teams.adapter. Patching the dotted path patches the wrong module.

Fix

patch.object(_teams_mod, "TypingActivityInput", ...) — patch the actual loaded module the test is exercising:

with patch.object(
    _teams_mod, "TypingActivityInput",
    new=MagicMock(return_value=MagicMock()),
):
    await adapter.send_typing("conv-id")

Validation

$ pytest tests/gateway/test_teams.py -q
34 passed in 1.79s

Scope

  • ✅ No production code change (test-only fix)
  • ✅ All 34 Teams tests pass
  • ✅ Behavioural assertions intact (send awaited once, with the right chat_id)

Out of scope

The other ~11 main-CI failures — separate focused PRs (#18972, #18974, #18977 already up).

…module

`TestTeamsSend::test_send_typing` was failing on `main` with:

    AssertionError: Expected send to have been awaited once. Awaited 0 times.

Root cause: `TypingActivityInput` is conditionally imported from the
`microsoft_teams` SDK in `plugins/platforms/teams/adapter.py`. When
the SDK isn't installed in the test environment, the import block
falls through and `TypingActivityInput` is bound to `None`. The
adapter's `send_typing` then calls `TypingActivityInput()` \u2192 raises
`TypeError: 'NoneType' object is not callable` \u2192 swallowed by the
broad `except Exception: pass`. Net: `mock_app.send` is never awaited.

Patch in a callable stand-in so the call path under test actually
runs. The adapter is loaded under a mangled module name by
`load_plugin_adapter("teams")` (\u2192 `plugin_adapter_teams`), so target
the loaded module object directly via `patch.object(_teams_mod, ...)`
rather than the dotted `plugins.platforms.teams.adapter` path \u2014 which
is a *different* module instance and does not affect the one the test
actually exercises.

Re-confirmed:

    $ pytest tests/gateway/test_teams.py -q
    34 passed in 1.79s

No production code change. Fixes the failure observed on `main`
(run 25250051126):

`tests/gateway/test_teams.py::TestTeamsSend::test_send_typing`
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for chasing down the Teams typing-test failure. An automated hermes-sweeper review found that current main already carries an equivalent test-side fix.

Evidence:

  • tests/gateway/test_teams.py:168 loads the Teams adapter through load_plugin_adapter("teams") into _teams_mod, matching the PR's point that this is the module instance the test actually exercises.
  • tests/gateway/test_teams.py:173-178 restores _teams_mod.TypingActivityInput from the mocked SDK module when the adapter import left it as None, so test_send_typing no longer silently no-ops through the adapter's broad exception handler.
  • The underlying adapter path is the same one described here: plugins/platforms/teams/adapter.py:1014 calls TypingActivityInput() before self._app.send(...).
  • Implementing commit: 2333b7a7ec682c999d9bfa9dd96ce8c293c86330 (fix(tests): patch TypingActivityInput after mock on Python <3.12), included in v2026.5.7 and later tags.

Closing as implemented on main.

@teknium1 teknium1 closed this Jun 11, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have sweeper:implemented-on-main Sweeper: behavior already present on current main type/test Test coverage or test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants