diff --git a/plants/services/__init__.py b/plants/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plants/services/perenual.py b/plants/services/perenual.py new file mode 100644 index 0000000..ce94494 --- /dev/null +++ b/plants/services/perenual.py @@ -0,0 +1,20 @@ +import requests +from django.conf import settings + +_BASE = 'https://perenual.com/api' + + +def search_species(query): + """Query Perenual species-list endpoint. Returns list of result dicts or [] on any error.""" + if not settings.PERENUAL_API_KEY: + return [] + try: + resp = requests.get( + f'{_BASE}/species-list', + params={'q': query, 'key': settings.PERENUAL_API_KEY}, + timeout=5, + ) + resp.raise_for_status() + return resp.json().get('data', []) + except Exception: + return [] diff --git a/plants/tests/test_perenual.py b/plants/tests/test_perenual.py new file mode 100644 index 0000000..81219bc --- /dev/null +++ b/plants/tests/test_perenual.py @@ -0,0 +1,40 @@ +import pytest +from unittest.mock import patch, MagicMock +from plants.services.perenual import search_species + + +def test_search_returns_empty_without_api_key(settings): + settings.PERENUAL_API_KEY = '' + results = search_species('rose') + assert results == [] + + +def test_search_returns_data(settings): + settings.PERENUAL_API_KEY = 'test-key' + mock_resp = MagicMock() + mock_resp.json.return_value = { + 'data': [{'id': 1, 'common_name': 'Rose', 'scientific_name': ['Rosa multiflora']}] + } + mock_resp.raise_for_status = MagicMock() + + with patch('plants.services.perenual.requests.get', return_value=mock_resp): + results = search_species('rose') + + assert len(results) == 1 + assert results[0]['common_name'] == 'Rose' + + +def test_search_returns_empty_on_timeout(settings): + settings.PERENUAL_API_KEY = 'test-key' + with patch('plants.services.perenual.requests.get', side_effect=Exception('timeout')): + results = search_species('rose') + assert results == [] + + +def test_search_returns_empty_on_bad_status(settings): + settings.PERENUAL_API_KEY = 'test-key' + mock_resp = MagicMock() + mock_resp.raise_for_status.side_effect = Exception('404') + with patch('plants.services.perenual.requests.get', return_value=mock_resp): + results = search_species('rose') + assert results == []