Changeset View
Changeset View
Standalone View
Standalone View
swh/graphql/tests/functional/test_pagination.py
# Copyright (C) 2022 The Software Heritage developers | # Copyright (C) 2022 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
from ..data import get_origins | from ..data import get_origins | ||||
from .utils import get_query_response | from .utils import get_query_response | ||||
# Using Origin object to run functional tests for pagination | # Using Origin object to run functional tests for pagination | ||||
def test_pagination(client): | def get_origin_nodes(client, first=1, after=""): | ||||
# requesting the max number of nodes available | |||||
# endCursor must be None | |||||
query_str = f""" | |||||
{{ | |||||
origins(first: {len(get_origins())}) {{ | |||||
nodes {{ | |||||
id | |||||
}} | |||||
pageInfo {{ | |||||
hasNextPage | |||||
endCursor | |||||
}} | |||||
}} | |||||
}} | |||||
""" | |||||
data, _ = get_query_response(client, query_str) | |||||
assert len(data["origins"]["nodes"]) == len(get_origins()) | |||||
assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None} | |||||
def get_first_node(client): | |||||
query_str = """ | query_str = """ | ||||
{ | { | ||||
origins(first: 1) { | origins(first: %s, %s) { | ||||
nodes { | nodes { | ||||
id | id | ||||
} | } | ||||
pageInfo { | pageInfo { | ||||
hasNextPage | hasNextPage | ||||
endCursor | endCursor | ||||
} | } | ||||
} | } | ||||
} | } | ||||
""" | """ % ( | ||||
data, _ = get_query_response(client, query_str) | first, | ||||
return data["origins"] | after, | ||||
) | |||||
return get_query_response(client, query_str) | |||||
def test_pagination(client): | |||||
# requesting the max number of nodes available | |||||
# endCursor must be None | |||||
data, _ = get_origin_nodes(client, len(get_origins())) | |||||
assert len(data["origins"]["nodes"]) == len(get_origins()) | |||||
assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None} | |||||
def test_first_arg(client): | def test_first_arg(client): | ||||
origins = get_first_node(client) | data, _ = get_origin_nodes(client, 1) | ||||
assert len(origins["nodes"]) == 1 | assert len(data["origins"]["nodes"]) == 1 | ||||
assert origins["pageInfo"]["hasNextPage"] is True | assert data["origins"]["pageInfo"]["hasNextPage"] is True | ||||
def test_invalid_first_arg(client): | |||||
data, errors = get_origin_nodes(client, -1) | |||||
assert data["origins"] is None | |||||
assert (len(errors)) == 2 # one error for origins and anotehr one for pageInfo | |||||
assert ( | |||||
errors[0]["message"] | |||||
== "Error in pagination input: Value for argument 'first' is either too big or invalid" | |||||
) | |||||
def test_too_big_first_arg(client): | |||||
data, errors = get_origin_nodes(client, 1001) # max page size is 1000 | |||||
assert data["origins"] is None | |||||
assert (len(errors)) == 2 | |||||
assert ( | |||||
errors[0]["message"] | |||||
== "Error in pagination input: Value for argument 'first' is either too big or invalid" | |||||
) | |||||
def test_after_arg(client): | def test_after_arg(client): | ||||
origins = get_first_node(client) | first_data, _ = get_origin_nodes(client) | ||||
end_cursor = origins["pageInfo"]["endCursor"] | end_cursor = first_data["origins"]["pageInfo"]["endCursor"] | ||||
query_str = f""" | # get again with endcursor as the after argument | ||||
{{ | data, _ = get_origin_nodes(client, 1, f'after: "{end_cursor}"') | ||||
origins(first: 1, after: "{end_cursor}") {{ | |||||
nodes {{ | |||||
id | |||||
}} | |||||
pageInfo {{ | |||||
hasNextPage | |||||
endCursor | |||||
}} | |||||
}} | |||||
}} | |||||
""" | |||||
data, _ = get_query_response(client, query_str) | |||||
assert len(data["origins"]["nodes"]) == 1 | assert len(data["origins"]["nodes"]) == 1 | ||||
assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None} | assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None} | ||||
def test_invalid_after_arg(client): | |||||
data, errors = get_origin_nodes(client, 1, 'after: "invalid"') | |||||
assert data["origins"] is None | |||||
assert (len(errors)) == 2 | |||||
assert ( | |||||
errors[0]["message"] | |||||
== "Error in pagination input: Invalid value for argument 'after'" | |||||
) | |||||
def test_edge_cursor(client): | def test_edge_cursor(client): | ||||
origins = get_first_node(client) | origins = get_origin_nodes(client)[0]["origins"] | ||||
# end cursor here must be the item cursor for the second item | # end cursor here must be the item cursor for the second item | ||||
end_cursor = origins["pageInfo"]["endCursor"] | end_cursor = origins["pageInfo"]["endCursor"] | ||||
query_str = f""" | query_str = ( | ||||
{{ | """ | ||||
origins(first: 1, after: "{end_cursor}") {{ | { | ||||
edges {{ | origins(first: 1, after: "%s") { | ||||
edges { | |||||
cursor | cursor | ||||
node {{ | node { | ||||
id | id | ||||
}} | } | ||||
}} | } | ||||
nodes {{ | nodes { | ||||
id | id | ||||
}} | } | ||||
}} | } | ||||
}} | } | ||||
""" | """ | ||||
% end_cursor | |||||
) | |||||
data, _ = get_query_response(client, query_str) | data, _ = get_query_response(client, query_str) | ||||
origins = data["origins"] | origins = data["origins"] | ||||
assert [edge["node"] for edge in origins["edges"]] == origins["nodes"] | assert [edge["node"] for edge in origins["edges"]] == origins["nodes"] | ||||
assert origins["edges"][0]["cursor"] == end_cursor | assert origins["edges"][0]["cursor"] == end_cursor |