from io import BytesIO from unittest.mock import MagicMock, patch from openpyxl import Workbook from app.services.agent_asset_onlyoffice_security import ( AgentAssetOnlyOfficeValidatedSession, ) from app.services.agent_assets import AgentAssetService def test_onlyoffice_callback_delegates_downloaded_workbook_to_upload(): db = MagicMock() service = AgentAssetService(db) service._ensure_ready = MagicMock() asset = MagicMock() asset.id = "test-asset" asset.tenant_id = "tenant-a" asset.scope = "tenant" service._require_spreadsheet_rule = MagicMock(return_value=asset) current_metadata = MagicMock(file_name="test.xlsx", checksum="old-checksum") service._resolve_current_spreadsheet_meta = MagicMock( return_value=("current", current_metadata) ) new_wb = Workbook() new_ws = new_wb.active new_ws["A1"] = "new value" new_ws["B2"] = "added" new_content_bio = BytesIO() new_wb.save(new_content_bio) new_content = new_content_bio.getvalue() document_key = service._build_onlyoffice_document_key("test-asset", current_metadata) claimed = AgentAssetOnlyOfficeValidatedSession( jti="callback-jti", tenant_id="tenant-a", resource_scope="tenant", asset_id="test-asset", document_key=document_key, document_version="current", document_fingerprint="old-checksum", writable=True, actor="username:test_user", status="processing", ) session_service = MagicMock() session_service.claim_callback.return_value = claimed service._onlyoffice_session_service = MagicMock(return_value=session_service) with patch( "app.services.agent_asset_onlyoffice.download_onlyoffice_document", return_value=new_content, ) as secure_download: service.upload_rule_spreadsheet = MagicMock() payload = { "status": 2, "url": "http://onlyoffice/download", "key": document_key, } service.handle_rule_spreadsheet_onlyoffice_callback( "test-asset", version="current", payload=payload, callback_token="signed-callback-token", ) secure_download.assert_called_once_with( "http://onlyoffice/download", expected_filename="test.xlsx", ) service.upload_rule_spreadsheet.assert_called_once_with( "test-asset", filename="test.xlsx", content=new_content, actor="username:test_user", source="onlyoffice", ) session_service.finish_callback.assert_called_once_with( "callback-jti", succeeded=True, )