Skip to content
Snippets Groups Projects
test_resolver.py 5.26 KiB
Newer Older
Tomás Fox's avatar
Tomás Fox committed
import pytest

from django.db.models import Prefetch
Tomás Fox's avatar
Tomás Fox committed
import graphene_django_optimizer as gql_optimizer

from .graphql_utils import create_resolve_info
from .models import (
    Item,
)
from .schema import schema
from .test_utils import assert_query_equality


Tomás Fox's avatar
Tomás Fox committed
# @pytest.mark.django_db
Tomás Fox's avatar
Tomás Fox committed
def test_should_optimize_non_django_field_if_it_has_an_optimization_hint_in_the_resolver():
Tomás Fox's avatar
Tomás Fox committed
    # parent = Item.objects.create(name='foo')
    # Item.objects.create(name='bar', parent=parent)
    # Item.objects.create(name='foobar', parent=parent)
Tomás Fox's avatar
Tomás Fox committed
    info = create_resolve_info(schema, '''
        query {
            items(name: "foo") {
                id
Tomás Fox's avatar
Tomás Fox committed
                childrenNames
            }
        }
    ''')
    qs = Item.objects.filter(name='foo')
    items = gql_optimizer.query(qs, info)
    optimized_items = qs.prefetch_related(
        Prefetch(
            'children',
            queryset=Item.objects.only('id', 'parent_id'),
        ),
    )
Tomás Fox's avatar
Tomás Fox committed
    assert_query_equality(items, optimized_items)
Tomás Fox's avatar
Tomás Fox committed
# @pytest.mark.django_db
def test_should_optimize_with_prefetch_related_as_a_string():
Tomás Fox's avatar
Tomás Fox committed
    # parent = Item.objects.create(name='foo')
    # Item.objects.create(name='bar', parent=parent)
    # Item.objects.create(name='foobar', parent=parent)
    info = create_resolve_info(schema, '''
        query {
            items(name: "foo") {
                id
                auxChildrenNames
            }
        }
    ''')
    qs = Item.objects.filter(name='foo')
    items = gql_optimizer.query(qs, info)
    optimized_items = qs.prefetch_related('children')
    assert_query_equality(items, optimized_items)


def test_should_optimize_with_prefetch_related_as_a_function():
Tomás Fox's avatar
Tomás Fox committed
    # parent = Item.objects.create(name='foo')
    # Item.objects.create(name='bar', parent=parent)
    # Item.objects.create(name='foobar', parent=parent)
    info = create_resolve_info(schema, '''
        query {
            items(name: "foo") {
                id
                filteredChildren(name: "bar") {
                    id
                }
            }
        }
    ''')
    qs = Item.objects.filter(name='foo')
    items = gql_optimizer.query(qs, info)
    optimized_items = qs.prefetch_related(
        Prefetch(
            'children',
            queryset=Item.objects.filter(name='bar'),
            to_attr='gql_filtered_children_bar',
        ),
    )
    assert_query_equality(items, optimized_items)


QUERY_CONNECTION_NESTED_INPUT_OBJECT = '''
    query($filters: ItemFilterInput) {
        items(name: "foo") {
            id
            foo
            childrenCustomFiltered(filterInput: $filters) {
                edges {
                    node {
                        id
                        value
                    }
    }
'''


@pytest.mark.parametrize("variables, expected_gte", [
    ({"filters": {'value': {'gte': 11}}}, 11),
    ({}, 0),
])
@pytest.mark.django_db
def test_should_optimize_with_prefetch_related_as_a_function_with_object_input(
    variables, expected_gte
):
    """This test attempt to provide a nested object as a variable and a null value
    as a filter. The objective is to ensure null and nested objects are properly
    resolved.
    """

    query = QUERY_CONNECTION_NESTED_INPUT_OBJECT
    info = create_resolve_info(schema, query, variables=variables)

    optimized_items = Item.objects.prefetch_related(
            queryset=Item.objects.only('id', 'value').filter(value__gte=expected_gte),
            to_attr='gql_custom_filtered_children',
        ),
    )

    items = gql_optimizer.query(Item.objects, info)
    assert_query_equality(items, optimized_items)


@pytest.mark.django_db
def test_should_return_valid_result_with_prefetch_related_as_a_function():
    parent = Item.objects.create(id=1, name='foo')
    Item.objects.create(id=2, name='bar', parent=parent)
    Item.objects.create(id=3, name='foobar', parent=parent)
    result = schema.execute('''
        query {
            items(name: "foo") {
                id
                filteredChildren(name: "bar") {
                    id
Tomás Fox's avatar
Tomás Fox committed
    assert not result.errors
    assert result.data['items'][0]['filteredChildren'][0]['id'] == 'SXRlbVR5cGU6Mg=='
    assert result.data['items'][0]['filteredChildren'][0]['parentId'] == 'SXRlbVR5cGU6MQ=='


@pytest.mark.django_db
def test_should_return_valid_result_with_prefetch_related_as_a_function_using_variable():
    parent = Item.objects.create(id=1, name='foo')
    Item.objects.create(id=2, name='bar', parent=parent)
    Item.objects.create(id=3, name='foobar', parent=parent)
    result = schema.execute('''
        query Foo ($name: String!) {
            items(name: "foo") {
                id
                foo
                filteredChildren(name: $name) {
                    id
                    foo
                }
            }
        }
    ''', variables={'name': 'bar'})
    assert not result.errors
    assert result.data['items'][0]['filteredChildren'][0]['id'] == 'SXRlbVR5cGU6Mg=='
    assert result.data['items'][0]['filteredChildren'][0]['parentId'] == 'SXRlbVR5cGU6MQ=='