core/tests/components/picnic/test_services.py

213 lines
6.6 KiB
Python

"""Tests for the Picnic services."""
from unittest.mock import MagicMock, patch
import pytest
from homeassistant.components.picnic import CONF_COUNTRY_CODE, DOMAIN
from homeassistant.components.picnic.const import SERVICE_ADD_PRODUCT_TO_CART
from homeassistant.components.picnic.services import PicnicServiceException
from homeassistant.const import CONF_ACCESS_TOKEN
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
UNIQUE_ID = "295-6y3-1nf4"
def create_picnic_api_client(unique_id):
"""Create PicnicAPI mock with set response data."""
auth_token = "af3wh738j3fa28l9fa23lhiufahu7l"
auth_data = {
"user_id": unique_id,
"address": {
"street": "Teststreet",
"house_number": 123,
"house_number_ext": "b",
},
}
picnic_mock = MagicMock()
picnic_mock.session.auth_token = auth_token
picnic_mock.get_user.return_value = auth_data
return picnic_mock
async def create_picnic_config_entry(hass: HomeAssistant, unique_id):
"""Create a Picnic config entry."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_ACCESS_TOKEN: "x-original-picnic-auth-token",
CONF_COUNTRY_CODE: "NL",
},
unique_id=unique_id,
)
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry
@pytest.fixture
def picnic_api_client():
"""Return the default picnic api client."""
with patch(
"homeassistant.components.picnic.create_picnic_client"
) as create_picnic_client_mock:
picnic_client_mock = create_picnic_api_client(UNIQUE_ID)
create_picnic_client_mock.return_value = picnic_client_mock
yield picnic_client_mock
@pytest.fixture
async def picnic_config_entry(hass: HomeAssistant):
"""Generate the default Picnic config entry."""
return await create_picnic_config_entry(hass, UNIQUE_ID)
async def test_add_product_using_id(
hass: HomeAssistant,
picnic_api_client: MagicMock,
picnic_config_entry: MockConfigEntry,
) -> None:
"""Test adding a product by id."""
await hass.services.async_call(
DOMAIN,
SERVICE_ADD_PRODUCT_TO_CART,
{
"config_entry_id": picnic_config_entry.entry_id,
"product_id": "5109348572",
"amount": 3,
},
blocking=True,
)
# Check that the right method is called on the api
picnic_api_client.add_product.assert_called_with("5109348572", 3)
async def test_add_product_using_name(
hass: HomeAssistant,
picnic_api_client: MagicMock,
picnic_config_entry: MockConfigEntry,
) -> None:
"""Test adding a product by name."""
# Set the return value of the search api endpoint
picnic_api_client.search.return_value = [
{
"items": [
{
"id": "2525404",
"name": "Best tea",
"display_price": 321,
"unit_quantity": "big bags",
},
{
"id": "2525500",
"name": "Cheap tea",
"display_price": 100,
"unit_quantity": "small bags",
},
]
}
]
await hass.services.async_call(
DOMAIN,
SERVICE_ADD_PRODUCT_TO_CART,
{"config_entry_id": picnic_config_entry.entry_id, "product_name": "Tea"},
blocking=True,
)
# Check that the right method is called on the api
picnic_api_client.add_product.assert_called_with("2525404", 1)
async def test_add_product_using_name_no_results(
hass: HomeAssistant,
picnic_api_client: MagicMock,
picnic_config_entry: MockConfigEntry,
) -> None:
"""Test adding a product by name that can't be found."""
# Set the search return value and check that the right exception is raised during the service call
picnic_api_client.search.return_value = []
with pytest.raises(PicnicServiceException):
await hass.services.async_call(
DOMAIN,
SERVICE_ADD_PRODUCT_TO_CART,
{
"config_entry_id": picnic_config_entry.entry_id,
"product_name": "Random non existing product",
},
blocking=True,
)
async def test_add_product_using_name_no_named_results(
hass: HomeAssistant,
picnic_api_client: MagicMock,
picnic_config_entry: MockConfigEntry,
) -> None:
"""Test adding a product by name for which no named results are returned."""
# Set the search return value and check that the right exception is raised during the service call
picnic_api_client.search.return_value = [{"items": [{"attr": "test"}]}]
with pytest.raises(PicnicServiceException):
await hass.services.async_call(
DOMAIN,
SERVICE_ADD_PRODUCT_TO_CART,
{
"config_entry_id": picnic_config_entry.entry_id,
"product_name": "Random product",
},
blocking=True,
)
async def test_add_product_multiple_config_entries(
hass: HomeAssistant,
picnic_api_client: MagicMock,
picnic_config_entry: MockConfigEntry,
) -> None:
"""Test adding a product for a specific Picnic service while multiple are configured."""
with patch(
"homeassistant.components.picnic.create_picnic_client"
) as create_picnic_client_mock:
picnic_api_client_2 = create_picnic_api_client("3fj9-9gju-236")
create_picnic_client_mock.return_value = picnic_api_client_2
picnic_config_entry_2 = await create_picnic_config_entry(hass, "3fj9-9gju-236")
await hass.services.async_call(
DOMAIN,
SERVICE_ADD_PRODUCT_TO_CART,
{"product_id": "5109348572", "config_entry_id": picnic_config_entry_2.entry_id},
blocking=True,
)
# Check that the right method is called on the api
picnic_api_client.add_product.assert_not_called()
picnic_api_client_2.add_product.assert_called_with("5109348572", 1)
async def test_add_product_device_doesnt_exist(
hass: HomeAssistant,
picnic_api_client: MagicMock,
picnic_config_entry: MockConfigEntry,
) -> None:
"""Test adding a product for a specific Picnic service, which doesn't exist."""
with pytest.raises(ValueError):
await hass.services.async_call(
DOMAIN,
SERVICE_ADD_PRODUCT_TO_CART,
{"product_id": "5109348572", "config_entry_id": 12345},
blocking=True,
)
# Check that the right method is called on the api
picnic_api_client.add_product.assert_not_called()