diff --git a/pysnc/asyncio/record.py b/pysnc/asyncio/record.py index 69cb9c1..f252794 100644 --- a/pysnc/asyncio/record.py +++ b/pysnc/asyncio/record.py @@ -119,11 +119,13 @@ async def get(self, name, value=None) -> bool: # type: ignore[override] """ Get a single record, accepting two values. If one value is passed, assumed to be sys_id. If two values are passed in, the first value is the column name to be used. Can return multiple records. + Previous results are cleared, including when no matching record is found. :param value: the ``sys_id`` or the field to query :param value2: the field value :return: ``True`` or ``False`` based on success """ + self._clear_results() if value is None: try: response = await self._client.table_api.get(self, name) diff --git a/pysnc/record.py b/pysnc/record.py index 988959e..3a0d854 100644 --- a/pysnc/record.py +++ b/pysnc/record.py @@ -599,15 +599,25 @@ def on_resp(r): elif code == 401: raise AuthenticationException(response.json()['error']) + def _clear_results(self): + self.__results = [] + self.__current = -1 + self.__total = None + self.__page = -1 + self.__is_iter = False + self.__is_new_record = False + def get(self, name, value=None) -> bool: """ Get a single record, accepting two values. If one value is passed, assumed to be sys_id. If two values are passed in, the first value is the column name to be used. Can return multiple records. + Previous results are cleared, including when no matching record is found. :param value: the ``sys_id`` or the field to query :param value2: the field value :return: ``True`` or ``False`` based on success """ + self._clear_results() if value is None: try: response = self._client.table_api.get(self, name) diff --git a/test/test_snc_get_state.py b/test/test_snc_get_state.py new file mode 100644 index 0000000..9268f94 --- /dev/null +++ b/test/test_snc_get_state.py @@ -0,0 +1,86 @@ +import asyncio +from types import SimpleNamespace +from unittest.mock import AsyncMock, Mock + +import pytest + +from pysnc.record import GlideRecord +from pysnc.asyncio.record import AsyncGlideRecord +from pysnc.exceptions import NoRecordException, NotFoundException + + +@pytest.fixture(params=[False, True], ids=["sync", "async"]) +def record(request): + api = SimpleNamespace( + get=AsyncMock() if request.param else Mock(), + list=AsyncMock() if request.param else Mock(), + ) + cls = AsyncGlideRecord if request.param else GlideRecord + gr = cls(SimpleNamespace(table_api=api), "incident") + + def get(*args): + result = gr.get(*args) + return asyncio.run(result) if request.param else result + + return gr, api, get + + +@pytest.mark.parametrize("initialized", [False, True]) +def test_missing_sys_id_clears_previous_record(record, initialized): + gr, api, get = record + if initialized: + gr.initialize() + gr.short_description = "old value" + else: + api.get.return_value = Mock( + json=Mock(return_value={"result": {"sys_id": "old", "short_description": "old value"}}) + ) + assert get("old") + api.get.side_effect = NotFoundException("not found") + + assert get("missing") is False + assert len(gr) == 0 + assert gr.has_next() is False + assert gr.is_new_record() is False + with pytest.raises(NoRecordException): + gr.get_value("short_description") + + +def test_empty_field_lookup_clears_previous_record(record): + gr, api, get = record + gr.initialize() + gr.short_description = "old value" + api.list.return_value = Mock(status_code=200, headers={"X-Total-Count": "0"}, + json=Mock(return_value={"result": []})) + + assert get("number", "missing") is False + assert gr.has_next() is False + assert len(gr) == 0 + with pytest.raises(NoRecordException): + gr.get_value("short_description") + + +def test_successful_field_lookup_replaces_previous_record(record): + gr, api, get = record + gr.initialize() + gr.short_description = "old value" + api.list.return_value = Mock(status_code=200, headers={"X-Total-Count": "1"}, + json=Mock(return_value={"result": [{"sys_id": "new"}]})) + + assert get("number", "new") is True + assert gr.get_value("sys_id") == "new" + assert gr.get_value("short_description") is None + assert len(gr) == 1 + assert gr.is_new_record() is False + + +def test_successful_lookup_after_missing_record(record): + gr, api, get = record + api.get.side_effect = [ + NotFoundException("not found"), + Mock(json=Mock(return_value={"result": {"sys_id": "new"}})), + ] + assert get("missing") is False + assert get("new") is True + assert gr.get_value("sys_id") == "new" + assert len(gr) == 1