Skip to main content
Glama
test_bulk_style_operations.py10.5 kB
""" Tests for bulk style operations (text and paragraph styling). Tests the _prepare_apply_text_style_request and _prepare_apply_paragraph_style_request functions with focus on tab_id handling. """ import pytest from unittest.mock import MagicMock, patch from google_docs_mcp.api.documents import ( _prepare_apply_text_style_request, _prepare_apply_paragraph_style_request, ) from fastmcp.exceptions import ToolError class TestPrepareApplyTextStyleRequest: """Tests for _prepare_apply_text_style_request function.""" def test_basic_text_style_by_range(self): """Should prepare text style request with range.""" op_dict = { "start_index": 1, "end_index": 10, "bold": True, "italic": True, } request = _prepare_apply_text_style_request(op_dict, None, None) assert "updateTextStyle" in request assert request["updateTextStyle"]["range"]["startIndex"] == 1 assert request["updateTextStyle"]["range"]["endIndex"] == 10 assert request["updateTextStyle"]["textStyle"]["bold"] == True assert request["updateTextStyle"]["textStyle"]["italic"] == True assert "tabId" not in request["updateTextStyle"]["range"] def test_text_style_with_tab_id(self): """Should include tab_id in range when provided.""" op_dict = { "start_index": 1, "end_index": 10, "bold": True, "tab_id": "tab123", } request = _prepare_apply_text_style_request(op_dict, None, None) assert request["updateTextStyle"]["range"]["tabId"] == "tab123" def test_text_style_with_default_tab_id(self): """Should use default tab_id when not specified in operation.""" op_dict = { "start_index": 1, "end_index": 10, "bold": True, } request = _prepare_apply_text_style_request(op_dict, None, "default_tab") assert request["updateTextStyle"]["range"]["tabId"] == "default_tab" def test_text_style_operation_overrides_default_tab_id(self): """Should use operation tab_id over default.""" op_dict = { "start_index": 1, "end_index": 10, "bold": True, "tab_id": "op_tab", } request = _prepare_apply_text_style_request(op_dict, None, "default_tab") assert request["updateTextStyle"]["range"]["tabId"] == "op_tab" def test_text_style_with_color(self): """Should handle foreground and background colors.""" op_dict = { "start_index": 1, "end_index": 10, "foreground_color": "#FF0000", "background_color": "#FFFF00", } request = _prepare_apply_text_style_request(op_dict, None, None) assert "foregroundColor" in request["updateTextStyle"]["textStyle"] assert "backgroundColor" in request["updateTextStyle"]["textStyle"] def test_text_style_with_font(self): """Should handle font size and family.""" op_dict = { "start_index": 1, "end_index": 10, "font_size": 14, "font_family": "Arial", } request = _prepare_apply_text_style_request(op_dict, None, None) assert request["updateTextStyle"]["textStyle"]["fontSize"]["magnitude"] == 14 assert request["updateTextStyle"]["textStyle"]["weightedFontFamily"]["fontFamily"] == "Arial" def test_text_style_missing_range(self): """Should raise error when range is not provided.""" op_dict = { "bold": True, } with pytest.raises(ToolError) as exc_info: _prepare_apply_text_style_request(op_dict, None, None) assert "start_index" in str(exc_info.value) or "end_index" in str(exc_info.value) @patch("google_docs_mcp.api.helpers.find_text_range") @patch("google_docs_mcp.api.documents.get_docs_client") def test_text_style_by_text_search(self, mock_get_docs, mock_find_text): """Should find text and apply styling.""" # Mock finding text from google_docs_mcp.types import TextRange mock_find_text.return_value = TextRange(start_index=5, end_index=15) document = {"documentId": "doc123"} op_dict = { "text_to_find": "Hello World", "bold": True, } request = _prepare_apply_text_style_request(op_dict, document, None) assert request["updateTextStyle"]["range"]["startIndex"] == 5 assert request["updateTextStyle"]["range"]["endIndex"] == 15 assert request["updateTextStyle"]["textStyle"]["bold"] == True class TestPrepareApplyParagraphStyleRequest: """Tests for _prepare_apply_paragraph_style_request function.""" def test_basic_paragraph_style_by_range(self): """Should prepare paragraph style request with range.""" op_dict = { "start_index": 1, "end_index": 55, "alignment": "CENTER", "named_style_type": "TITLE", } request = _prepare_apply_paragraph_style_request(op_dict, None, None) assert "updateParagraphStyle" in request assert request["updateParagraphStyle"]["range"]["startIndex"] == 1 assert request["updateParagraphStyle"]["range"]["endIndex"] == 55 assert request["updateParagraphStyle"]["paragraphStyle"]["alignment"] == "CENTER" assert request["updateParagraphStyle"]["paragraphStyle"]["namedStyleType"] == "TITLE" assert "tabId" not in request["updateParagraphStyle"]["range"] def test_paragraph_style_with_tab_id(self): """Should include tab_id in range when provided.""" op_dict = { "start_index": 1, "end_index": 55, "alignment": "CENTER", "tab_id": "tab123", } request = _prepare_apply_paragraph_style_request(op_dict, None, None) assert request["updateParagraphStyle"]["range"]["tabId"] == "tab123" def test_paragraph_style_with_default_tab_id(self): """Should use default tab_id when not specified in operation.""" op_dict = { "start_index": 1, "end_index": 55, "alignment": "CENTER", } request = _prepare_apply_paragraph_style_request(op_dict, None, "default_tab") assert request["updateParagraphStyle"]["range"]["tabId"] == "default_tab" def test_paragraph_style_operation_overrides_default_tab_id(self): """Should use operation tab_id over default.""" op_dict = { "start_index": 1, "end_index": 55, "alignment": "CENTER", "tab_id": "op_tab", } request = _prepare_apply_paragraph_style_request(op_dict, None, "default_tab") assert request["updateParagraphStyle"]["range"]["tabId"] == "op_tab" def test_paragraph_style_with_spacing(self): """Should handle paragraph spacing.""" op_dict = { "start_index": 1, "end_index": 55, "space_above": 36.0, "space_below": 18.0, } request = _prepare_apply_paragraph_style_request(op_dict, None, None) assert "spaceAbove" in request["updateParagraphStyle"]["paragraphStyle"] assert "spaceBelow" in request["updateParagraphStyle"]["paragraphStyle"] def test_paragraph_style_with_indentation(self): """Should handle paragraph indentation.""" op_dict = { "start_index": 1, "end_index": 55, "indent_start": 36.0, "indent_end": 18.0, } request = _prepare_apply_paragraph_style_request(op_dict, None, None) assert "indentStart" in request["updateParagraphStyle"]["paragraphStyle"] assert "indentEnd" in request["updateParagraphStyle"]["paragraphStyle"] def test_paragraph_style_missing_range(self): """Should raise error when range is not provided and no other targeting method.""" op_dict = { "alignment": "CENTER", } with pytest.raises(ToolError) as exc_info: _prepare_apply_paragraph_style_request(op_dict, None, None) assert "start_index" in str(exc_info.value) or "end_index" in str(exc_info.value) or "text_to_find" in str(exc_info.value) @patch("google_docs_mcp.api.helpers.get_paragraph_range_from_document") @patch("google_docs_mcp.api.helpers.find_text_range") @patch("google_docs_mcp.api.documents.get_docs_client") def test_paragraph_style_by_text_search(self, mock_get_docs, mock_find_text, mock_get_para): """Should find text, locate containing paragraph, and apply styling.""" from google_docs_mcp.types import TextRange # Mock finding text mock_find_text.return_value = TextRange(start_index=10, end_index=20) # Mock finding paragraph (returns TextRange with paragraph boundaries) mock_get_para.return_value = TextRange(start_index=1, end_index=55) document = {"documentId": "doc123"} op_dict = { "text_to_find": "Title Text", "alignment": "CENTER", "named_style_type": "TITLE", } request = _prepare_apply_paragraph_style_request(op_dict, document, None) # Should apply to the paragraph range, not the text range assert request["updateParagraphStyle"]["range"]["startIndex"] == 1 assert request["updateParagraphStyle"]["range"]["endIndex"] == 55 assert request["updateParagraphStyle"]["paragraphStyle"]["alignment"] == "CENTER" @patch("google_docs_mcp.api.helpers.get_paragraph_range_from_document") def test_paragraph_style_by_index(self, mock_get_para): """Should find paragraph containing index and apply styling.""" from google_docs_mcp.types import TextRange # Mock finding paragraph (returns TextRange with paragraph boundaries) mock_get_para.return_value = TextRange(start_index=1, end_index=55) document = {"documentId": "doc123"} op_dict = { "index_within_paragraph": 25, "alignment": "CENTER", } request = _prepare_apply_paragraph_style_request(op_dict, document, None) assert request["updateParagraphStyle"]["range"]["startIndex"] == 1 assert request["updateParagraphStyle"]["range"]["endIndex"] == 55

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nickweedon/google-docs-mcp-docker'

If you have feedback or need assistance with the MCP directory API, please join our Discord server