Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fairgraph/kgobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ def from_id(
if follow_links is not None:
raise NotImplementedError
data = client.instance_from_full_uri(uri, use_cache=use_cache, release_status=release_status)
if data is None:
return None
type_ = data["@type"]
if isinstance(type_, list):
assert len(type_) == 1
Expand Down
27 changes: 27 additions & 0 deletions test/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from fairgraph.caching import generate_cache_key
from fairgraph.errors import CannotBuildExistenceQuery
from fairgraph.base import ErrorHandling
from .utils import mock_client

import pytest

Expand Down Expand Up @@ -669,3 +670,29 @@ def test_repr(self):
uri = "https://kg.ebrains.eu/api/instances/00000000-0000-0000-0000-000000001234"
proxy = KGProxy(MockKGObject, uri)
assert repr(proxy) == 'KGProxy([MockKGObject], id="00000000-0000-0000-0000-000000001234")'


class TestFromId:
"""KGObject.from_id() on the base class, where the type is not known up front."""

nonexistent = "https://kg.ebrains.eu/api/instances/11111111-2222-3333-4444-555555555555"
existing = "http://example.org/00000000-0000-0000-0000-000000000000"

def test_returns_none_for_nonexistent_id(self, mock_client, mocker):
# Regression test for #115. instance_from_full_uri() returns None for an instance
# that does not exist or is not accessible. The typed path (from_uri) handles that
# and returns None, as from_id's docstring promises, but the untyped path indexed
# into the result regardless and raised
# "TypeError: 'NoneType' object is not subscriptable".
mocker.patch.object(mock_client, "instance_from_full_uri", return_value=None)

assert KGObject.from_id(self.nonexistent, mock_client, release_status="any") is None

def test_still_resolves_an_existing_id(self, mock_client):
# Companion to the above: the None guard must not swallow the success path.
# The mock client returns a Model instance for this URI, so from_id should look
# the type up in the registry and build the corresponding class.
obj = KGObject.from_id(self.existing, mock_client, release_status="any")

assert obj is not None
assert obj.__class__.__name__ == "Model"