From 5d87e0f429e518f0a01347ea51a3900b5d35cbf8 Mon Sep 17 00:00:00 2001 From: Luca Angemi Date: Mon, 17 Nov 2025 20:48:17 +0100 Subject: [PATCH] Make Google sheets datetime column optional (#155861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: AbĂ­lio Costa --- .../components/google_sheets/services.py | 5 ++- .../components/google_sheets/services.yaml | 5 +++ .../components/google_sheets/strings.json | 4 ++ tests/components/google_sheets/test_init.py | 37 ++++++++++++++++--- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/google_sheets/services.py b/homeassistant/components/google_sheets/services.py index c8ced10560a..84ae92027a5 100644 --- a/homeassistant/components/google_sheets/services.py +++ b/homeassistant/components/google_sheets/services.py @@ -31,6 +31,7 @@ from .const import DOMAIN if TYPE_CHECKING: from . import GoogleSheetsConfigEntry +ADD_CREATED_COLUMN = "add_created_column" DATA = "data" DATA_CONFIG_ENTRY = "config_entry" ROWS = "rows" @@ -43,6 +44,7 @@ SHEET_SERVICE_SCHEMA = vol.All( { vol.Required(DATA_CONFIG_ENTRY): ConfigEntrySelector({"integration": DOMAIN}), vol.Optional(WORKSHEET): cv.string, + vol.Optional(ADD_CREATED_COLUMN, default=True): cv.boolean, vol.Required(DATA): vol.Any(cv.ensure_list, [dict]), }, ) @@ -69,10 +71,11 @@ def _append_to_sheet(call: ServiceCall, entry: GoogleSheetsConfigEntry) -> None: worksheet = sheet.worksheet(call.data.get(WORKSHEET, sheet.sheet1.title)) columns: list[str] = next(iter(worksheet.get_values("A1:ZZ1")), []) + add_created_column = call.data[ADD_CREATED_COLUMN] now = str(datetime.now()) rows = [] for d in call.data[DATA]: - row_data = {"created": now} | d + row_data = ({"created": now} | d) if add_created_column else d row = [row_data.get(column, "") for column in columns] for key, value in row_data.items(): if key not in columns: diff --git a/homeassistant/components/google_sheets/services.yaml b/homeassistant/components/google_sheets/services.yaml index 77a21399cfa..8425a51aef7 100644 --- a/homeassistant/components/google_sheets/services.yaml +++ b/homeassistant/components/google_sheets/services.yaml @@ -9,6 +9,11 @@ append_sheet: example: "Sheet1" selector: text: + add_created_column: + required: false + default: true + selector: + boolean: data: required: true example: '{"hello": world, "cool": True, "count": 5}' diff --git a/homeassistant/components/google_sheets/strings.json b/homeassistant/components/google_sheets/strings.json index 6c5a7de0b4e..95b5b23bedc 100644 --- a/homeassistant/components/google_sheets/strings.json +++ b/homeassistant/components/google_sheets/strings.json @@ -45,6 +45,10 @@ "append_sheet": { "description": "Appends data to a worksheet in Google Sheets.", "fields": { + "add_created_column": { + "description": "Add a \"created\" column with the current date-time to the appended data.", + "name": "Add created column" + }, "config_entry": { "description": "The sheet to add data to.", "name": "Sheet" diff --git a/tests/components/google_sheets/test_init.py b/tests/components/google_sheets/test_init.py index e053bc2b8d2..a8685e2000c 100644 --- a/tests/components/google_sheets/test_init.py +++ b/tests/components/google_sheets/test_init.py @@ -6,6 +6,7 @@ import time from typing import Any from unittest.mock import patch +from freezegun import freeze_time from gspread.exceptions import APIError import pytest from requests.models import Response @@ -17,8 +18,11 @@ from homeassistant.components.application_credentials import ( ) from homeassistant.components.google_sheets.const import DOMAIN from homeassistant.components.google_sheets.services import ( + ADD_CREATED_COLUMN, + DATA, DATA_CONFIG_ENTRY, ROWS, + SERVICE_APPEND_SHEET, SERVICE_GET_SHEET, WORKSHEET, ) @@ -194,12 +198,24 @@ async def test_expired_token_refresh_failure( assert entries[0].state is expected_state +@pytest.mark.parametrize( + ("add_created_column_param", "expected_row"), + [ + ({ADD_CREATED_COLUMN: True}, ["bar", "2024-01-15 12:30:45.123456"]), + ({ADD_CREATED_COLUMN: False}, ["bar", ""]), + ({}, ["bar", "2024-01-15 12:30:45.123456"]), + ], + ids=["created_column_true", "created_column_false", "created_column_default"], +) +@freeze_time("2024-01-15 12:30:45.123456") async def test_append_sheet( hass: HomeAssistant, setup_integration: ComponentSetup, config_entry: MockConfigEntry, + add_created_column_param: dict[str, bool], + expected_row: list[str], ) -> None: - """Test service call appending to a sheet.""" + """Test created column behavior based on add_created_column parameter.""" await setup_integration() entries = hass.config_entries.async_entries(DOMAIN) @@ -207,17 +223,26 @@ async def test_append_sheet( assert entries[0].state is ConfigEntryState.LOADED with patch("homeassistant.components.google_sheets.services.Client") as mock_client: + mock_worksheet = ( + mock_client.return_value.open_by_key.return_value.worksheet.return_value + ) + mock_worksheet.get_values.return_value = [["foo", "created"]] + await hass.services.async_call( DOMAIN, - "append_sheet", + SERVICE_APPEND_SHEET, { - "config_entry": config_entry.entry_id, - "worksheet": "Sheet1", - "data": {"foo": "bar"}, + DATA_CONFIG_ENTRY: config_entry.entry_id, + WORKSHEET: "Sheet1", + DATA: {"foo": "bar"}, + **add_created_column_param, }, blocking=True, ) - assert len(mock_client.mock_calls) == 8 + + mock_worksheet.append_rows.assert_called_once() + rows_data = mock_worksheet.append_rows.call_args[0][0] + assert rows_data[0] == expected_row async def test_get_sheet(