Skip to content

Commit e3e2bcc

Browse files
committed
test(teams): cover multi-file delivery + tighten skip-log
Self-review (two adversarial reviewers) found: - MEDIUM: multi-file handling untested — mutation showed return attachments[:1] (drop all but first) and reversed() both passed green, so a regression that drops/reorders artifacts would merge undetected, defeating the parity goal. Added test_multiple_files_attached_in_order (N files -> N attachments, input order) + test_partial_skip_preserves_surviving_files (good/bad/good -> survivors in order). Mutation-verified: [:1] now FAILS the multi-file test. - LOW: the skip test's log assertion was hollow (post_message emits an unconditional 'send (message)' debug, so it passed even if the skip branch logged nothing). Now asserts the SPECIFIC 'unsupported data' skip log.
1 parent 34d172a commit e3e2bcc

1 file changed

Lines changed: 57 additions & 1 deletion

File tree

tests/test_teams_adapter.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,63 @@ async def test_file_with_unresolvable_data_is_skipped(self):
831831
payload = adapter._teams_send.call_args.args[1]
832832
# no attachments key added when every file was skipped
833833
assert "attachments" not in payload
834-
assert logger.debug.called
834+
# assert the SPECIFIC skip log fired — not just that some debug log happened
835+
# (post_message emits an unconditional "send (message)" debug, so a bare
836+
# logger.debug.called check would pass even if the skip branch logged nothing).
837+
skip_logged = any(
838+
call.args and "skipping file with unsupported data" in str(call.args[0])
839+
for call in logger.debug.call_args_list
840+
)
841+
assert skip_logged, "a skipped file must emit the 'unsupported data' debug log"
842+
843+
@pytest.mark.asyncio
844+
async def test_multiple_files_attached_in_order(self):
845+
"""N files -> N attachments, in input order. Closes the gap where
846+
``return attachments[:1]`` (drop all but first) or a reorder would
847+
otherwise merge green — both directly defeat multi-artifact parity.
848+
"""
849+
from chat_sdk.types import FileUpload, PostableMarkdown
850+
851+
adapter = _make_adapter(app_id="test-app-id", logger=_make_logger())
852+
adapter._teams_send = AsyncMock(return_value={"id": "m", "type": "message"})
853+
854+
message = PostableMarkdown(
855+
markdown="three files",
856+
files=[
857+
FileUpload(data=b"aaa", filename="a.csv", mime_type="text/csv"),
858+
FileUpload(data=b"\x89PNG", filename="b.png", mime_type="image/png"),
859+
FileUpload(data=b"%PDF", filename="c.pdf", mime_type="application/pdf"),
860+
],
861+
)
862+
await adapter.post_message(self._thread_id(adapter), message)
863+
864+
attachments = adapter._teams_send.call_args.args[1]["attachments"]
865+
assert [a["name"] for a in attachments] == ["a.csv", "b.png", "c.pdf"]
866+
assert [a["contentType"] for a in attachments] == ["text/csv", "image/png", "application/pdf"]
867+
assert all(a["contentUrl"].startswith("data:") for a in attachments)
868+
869+
@pytest.mark.asyncio
870+
async def test_partial_skip_preserves_surviving_files_in_order(self):
871+
"""A good/bad/good batch drops only the unresolvable file; survivors keep
872+
input order. No single-file test covers partial-skip-with-survivors.
873+
"""
874+
from chat_sdk.types import FileUpload, PostableMarkdown
875+
876+
adapter = _make_adapter(app_id="test-app-id", logger=_make_logger())
877+
adapter._teams_send = AsyncMock(return_value={"id": "m", "type": "message"})
878+
879+
message = PostableMarkdown(
880+
markdown="good bad good",
881+
files=[
882+
FileUpload(data=b"first", filename="first.csv", mime_type="text/csv"),
883+
FileUpload(data="not-bytes", filename="bad.bin", mime_type="application/octet-stream"), # type: ignore[arg-type]
884+
FileUpload(data=b"third", filename="third.csv", mime_type="text/csv"),
885+
],
886+
)
887+
await adapter.post_message(self._thread_id(adapter), message)
888+
889+
attachments = adapter._teams_send.call_args.args[1]["attachments"]
890+
assert [a["name"] for a in attachments] == ["first.csv", "third.csv"]
835891

836892

837893
class TestDeleteMessage:

0 commit comments

Comments
 (0)