diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 51832084..9df18f99 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,7 +58,7 @@ jobs: if: ${{ matrix.python == '3.10' }} uses: actions/upload-artifact@v3 with: - name: graphene-sqlalchemy-coverage + name: graphene-coverage path: coverage.xml if-no-files-found: error - name: Upload coverage.xml to codecov diff --git a/Makefile b/Makefile index c78e2b4f..08947707 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ help: install-dev: pip install -e ".[dev]" +.PHONY: test ## Run tests test: py.test graphene examples diff --git a/graphene/relay/tests/test_custom_global_id.py b/graphene/relay/tests/test_custom_global_id.py index d2c6586b..c1bf0fb4 100644 --- a/graphene/relay/tests/test_custom_global_id.py +++ b/graphene/relay/tests/test_custom_global_id.py @@ -216,3 +216,110 @@ class TestCustomGlobalID: assert not result.errors assert result.data["user"]["id"] == self.user_list[1]["id"] assert result.data["user"]["name"] == self.user_list[1]["name"] + + +class TestIncompleteCustomGlobalID: + def setup(self): + self.user_list = [ + {"id": 1, "name": "First"}, + {"id": 2, "name": "Second"}, + {"id": 3, "name": "Third"}, + {"id": 4, "name": "Fourth"}, + ] + self.users = {user["id"]: user for user in self.user_list} + + def test_must_define_to_global_id(self): + """ + Test that if the `to_global_id` method is not defined, we can query the object, but we can't request its ID. + """ + + class CustomGlobalIDType(BaseGlobalIDType): + graphene_type = Int + + @classmethod + def resolve_global_id(cls, info, global_id): + _type = info.return_type.graphene_type._meta.name + return _type, global_id + + class CustomNode(Node): + class Meta: + global_id_type = CustomGlobalIDType + + class User(ObjectType): + class Meta: + interfaces = [CustomNode] + + name = String() + + @classmethod + def get_node(cls, _type, _id): + return self.users[_id] + + class RootQuery(ObjectType): + user = CustomNode.Field(User) + + self.schema = Schema(query=RootQuery, types=[User]) + self.graphql_schema = self.schema.graphql_schema + + query = """query { + user(id: 2) { + name + } + }""" + result = graphql_sync(self.graphql_schema, query) + assert not result.errors + assert result.data["user"]["name"] == self.user_list[1]["name"] + + query = """query { + user(id: 2) { + id + name + } + }""" + result = graphql_sync(self.graphql_schema, query) + assert result.errors is not None + assert len(result.errors) == 1 + assert result.errors[0].path == ["user", "id"] + + def test_must_define_resolve_global_id(self): + """ + Test that if the `resolve_global_id` method is not defined, we can't query the object by ID. + """ + + class CustomGlobalIDType(BaseGlobalIDType): + graphene_type = Int + + @classmethod + def to_global_id(cls, _type, _id): + return _id + + class CustomNode(Node): + class Meta: + global_id_type = CustomGlobalIDType + + class User(ObjectType): + class Meta: + interfaces = [CustomNode] + + name = String() + + @classmethod + def get_node(cls, _type, _id): + return self.users[_id] + + class RootQuery(ObjectType): + user = CustomNode.Field(User) + + self.schema = Schema(query=RootQuery, types=[User]) + self.graphql_schema = self.schema.graphql_schema + + query = """query { + user(id: 2) { + id + name + } + }""" + result = graphql_sync(self.graphql_schema, query) + assert result.errors is not None + assert len(result.errors) == 1 + assert result.errors[0].path == ["user"] diff --git a/graphene/relay/tests/test_node.py b/graphene/relay/tests/test_node.py index 6b310fde..e7564566 100644 --- a/graphene/relay/tests/test_node.py +++ b/graphene/relay/tests/test_node.py @@ -55,6 +55,7 @@ def test_node_good(): assert "id" in MyNode._meta.fields assert is_node(MyNode) assert not is_node(object) + assert not is_node("node") def test_node_query():