diff --git a/swh/graphql/tests/functional/test_branch_connection.py b/swh/graphql/tests/functional/test_branch_connection.py --- a/swh/graphql/tests/functional/test_branch_connection.py +++ b/swh/graphql/tests/functional/test_branch_connection.py @@ -8,13 +8,13 @@ from . import utils -def get_branches(client, swhid: str, first: int, **args) -> tuple: - args["first"] = first - params = utils.get_query_params_from_args(**args) +def get_branches(client, variables) -> tuple: query_str = """ - { - snapshot(swhid: "%s") { - branches(%s) { + query getSnapshot($swhid: SWHID!, $first: Int!, $after: String, $types: [BranchTargetType], + $nameInclude: String, $excludePrefix: String) { + snapshot(swhid: $swhid) { + branches(first: $first, after: $after, types: $types, nameInclude: $nameInclude, + nameExcludePrefix: $excludePrefix ) { pageInfo { endCursor } @@ -53,16 +53,15 @@ } } } - """ % ( - swhid, - params, - ) - return utils.get_query_response(client, query_str) + """ + return utils.get_query_response(client, query_str, variables=variables) def test_get_data(client): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, errors = get_branches(client, swhid, 10, types="[revision]") + data, errors = get_branches( + client, variables={"swhid": swhid, "first": 10, "types": ["revision"]} + ) assert len(data["snapshot"]["branches"]["nodes"]) == 1 # filter 'type' will return a single revision object and is used to assert data node = data["snapshot"]["branches"]["nodes"][0] @@ -78,7 +77,9 @@ def test_get_branches_with_alias(client): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, _ = get_branches(client, swhid, 10, types="[alias]") + data, _ = get_branches( + client, variables={"swhid": swhid, "first": 10, "types": ["alias"]} + ) node = data["snapshot"]["branches"]["nodes"][0] assert node == { "name": {"text": "target/alias"}, @@ -99,7 +100,9 @@ ) def test_get_type_filter(client, filter_type, count, target_type, swhid_pattern): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, _ = get_branches(client, swhid, 10, types=f"[{filter_type}]") + data, _ = get_branches( + client, variables={"swhid": swhid, "first": 10, "types": [filter_type]} + ) assert len(data["snapshot"]["branches"]["nodes"]) == count for node in data["snapshot"]["branches"]["nodes"]: assert node["target"]["__typename"] == target_type @@ -109,20 +112,24 @@ @pytest.mark.parametrize( "filter_types, count", [ - ("revision, release", 2), - ("revision, snapshot, release", 3), + (["revision", "release"], 2), + (["revision", "snapshot", "release"], 3), ], ) def test_get_type_filter_multiple(client, filter_types, count): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, _ = get_branches(client, swhid, 10, types=f"[{filter_types}]") + data, _ = get_branches( + client, variables={"swhid": swhid, "first": 10, "types": filter_types} + ) assert len(data["snapshot"]["branches"]["nodes"]) == count @pytest.mark.parametrize("name", ["rel", "rev", "non-exist"]) def test_get_name_include_filter(client, name): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, _ = get_branches(client, swhid, 10, nameInclude=f'"{name}"') + data, _ = get_branches( + client, variables={"swhid": swhid, "first": 10, "nameInclude": name} + ) for node in data["snapshot"]["branches"]["nodes"]: assert name in node["name"]["text"] @@ -130,7 +137,9 @@ @pytest.mark.parametrize("name", ["target", "target/dir"]) def test_get_name_exclude_prefix_filter(client, name): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, _ = get_branches(client, swhid, 10, nameExcludePrefix=f'"{name}"') + data, _ = get_branches( + client, variables={"swhid": swhid, "first": 10, "excludePrefix": name} + ) for node in data["snapshot"]["branches"]["nodes"]: assert not node["name"]["text"].startswith(name) @@ -138,16 +147,18 @@ @pytest.mark.parametrize("count", [1, 2]) def test_get_first_arg(client, count): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - data, _ = get_branches(client, swhid, first=count) + data, _ = get_branches(client, variables={"swhid": swhid, "first": count}) assert len(data["snapshot"]["branches"]["nodes"]) == count def test_get_after_arg(client): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" - first_data, _ = get_branches(client, swhid, first=1) + first_data, _ = get_branches(client, variables={"swhid": swhid, "first": 1}) end_cursor = first_data["snapshot"]["branches"]["pageInfo"]["endCursor"] node_name = first_data["snapshot"]["branches"]["nodes"][0]["name"]["text"] - second_data, _ = get_branches(client, swhid, first=3, after=f'"{end_cursor}"') + second_data, _ = get_branches( + client, variables={"swhid": swhid, "first": 3, "after": end_cursor} + ) branches = second_data["snapshot"]["branches"] assert len(branches["nodes"]) == 3 assert branches["edges"][0]["cursor"] == end_cursor diff --git a/swh/graphql/tests/functional/test_content.py b/swh/graphql/tests/functional/test_content.py --- a/swh/graphql/tests/functional/test_content.py +++ b/swh/graphql/tests/functional/test_content.py @@ -12,8 +12,8 @@ @pytest.mark.parametrize("content", get_contents()) def test_get_content_with_swhid(client, content): query_str = """ - { - content(swhid: "%s") { + query getContent($swhid: SWHID!) { + content(swhid: $swhid) { swhid checksum { blake2s256 @@ -38,7 +38,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % content.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(content.swhid())} + ) archive_url = "https://archive.softwareheritage.org/api/1/" response = { "swhid": str(content.swhid()), @@ -63,34 +65,36 @@ @pytest.mark.parametrize("content", get_contents()) def test_get_content_with_hash(client, content): query_str = """ - { - contentByHash(checksums: ["blake2s256:%s", "sha1:%s", "sha1_git:%s", "sha256:%s"]) { + query getContent($checksums: [ContentHash]!) { + contentByHash(checksums: $checksums) { swhid } } """ data, _ = utils.get_query_response( client, - query_str - % ( - content.blake2s256.hex(), - content.sha1.hex(), - content.sha1_git.hex(), - content.sha256.hex(), - ), + query_str, + variables={ + "checksums": [ + f"blake2s256:{content.blake2s256.hex()}", + f"sha1:{content.sha1.hex()}", + f"sha1_git:{content.sha1_git.hex()}", + f"sha256:{content.sha256.hex()}", + ] + }, ) assert data["contentByHash"] == {"swhid": str(content.swhid())} def test_get_content_with_invalid_swhid(client): query_str = """ - { - content(swhid: "swh:1:cnt:invalid") { + query getContent($swhid: SWHID!) { + content(swhid: $swhid) { swhid } } """ - errors = utils.get_error_response(client, query_str) + errors = utils.get_error_response(client, query_str, variables={"swhid": "invalid"}) # API will throw an error in case of an invalid SWHID assert len(errors) == 1 assert "Input error: Invalid SWHID" in errors[0]["message"] @@ -99,21 +103,23 @@ def test_get_content_with_invalid_hashes(client): content = get_contents()[0] query_str = """ - { - contentByHash(checksums: ["blake2s256:%s", "sha1:%s", "sha1_git:%s", "sha256:%s"]) { + query getContent($checksums: [ContentHash]!) { + contentByHash(checksums: $checksums) { swhid } } """ errors = utils.get_error_response( client, - query_str - % ( - "invalid", # Only one hash is invalid - content.sha1.hex(), - content.sha1_git.hex(), - content.sha256.hex(), - ), + query_str, + variables={ + "checksums": [ + "invalid", # Only one hash is invalid + f"sha1:{content.sha1.hex()}", + f"sha1_git:{content.sha1_git.hex()}", + f"sha256:{content.sha256.hex()}", + ] + }, ) # API will throw an error in case of an invalid content hash assert len(errors) == 1 @@ -123,13 +129,16 @@ def test_get_content_with_invalid_hash_algorithm(client): content = get_contents()[0] query_str = """ - { - contentByHash(checksums: ["test:%s"]) { + query getContent($checksums: [ContentHash]!) { + contentByHash(checksums: $checksums) { swhid } } """ - errors = utils.get_error_response(client, query_str % content.sha1.hex()) + data, errors = utils.get_query_response( + client, query_str, variables={"checksums": [f"test:{content.sha1.hex()}"]} + ) + assert data is None assert len(errors) == 1 assert "Input error: Invalid hash algorithm" in errors[0]["message"] @@ -138,8 +147,8 @@ # SWHID of a test dir with a file entry directory_swhid = "swh:1:dir:87b339104f7dc2a8163dec988445e3987995545f" query_str = """ - { - directory(swhid: "%s") { + query getDirectory($swhid: SWHID!) { + directory(swhid: $swhid) { swhid entries(first: 2) { nodes { @@ -155,7 +164,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % directory_swhid) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": directory_swhid} + ) content_obj = data["directory"]["entries"]["nodes"][1]["target"] assert content_obj == { "length": 4, @@ -166,10 +177,15 @@ def test_get_content_with_unknown_swhid(client): unknown_sha1 = "1" * 40 query_str = """ - { - content(swhid: "swh:1:cnt:%s") { + query getDirectory($swhid: SWHID!) { + content(swhid: $swhid) { swhid } } """ - utils.assert_missing_object(client, query_str % unknown_sha1, "content") + utils.assert_missing_object( + client, + query_str, + obj_type="content", + variables={"swhid": f"swh:1:cnt:{unknown_sha1}"}, + ) diff --git a/swh/graphql/tests/functional/test_directory.py b/swh/graphql/tests/functional/test_directory.py --- a/swh/graphql/tests/functional/test_directory.py +++ b/swh/graphql/tests/functional/test_directory.py @@ -12,25 +12,29 @@ @pytest.mark.parametrize("directory", get_directories()) def test_get_directory(client, directory): query_str = """ - { - directory(swhid: "%s") { + query getDirectory($swhid: SWHID!) { + directory(swhid: $swhid) { swhid } } """ - data, _ = utils.get_query_response(client, query_str % directory.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(directory.swhid())} + ) assert data["directory"] == {"swhid": str(directory.swhid())} def test_get_directory_with_invalid_swhid(client): query_str = """ - { - directory(swhid: "swh:1:dir:invalid") { + query getDirectory($swhid: SWHID!) { + directory(swhid: $swhid) { swhid } } """ - errors = utils.get_error_response(client, query_str) + errors = utils.get_error_response( + client, query_str, variables={"swhid": "swh:1:dir:invalid"} + ) # API will throw an error in case of an invalid SWHID assert len(errors) == 1 assert "Input error: Invalid SWHID" in errors[0]["message"] @@ -38,8 +42,8 @@ def test_get_revision_directory(client): query_str = """ - { - revision(swhid: "swh:1:rev:66c7c1cd9673275037140f2abff7b7b11fc9439c") { + query getRevision($swhid: SWHID!) { + revision(swhid: $swhid) { swhid directory { swhid @@ -47,7 +51,11 @@ } } """ - data, _ = utils.get_query_response(client, query_str) + data, _ = utils.get_query_response( + client, + query_str, + variables={"swhid": "swh:1:rev:66c7c1cd9673275037140f2abff7b7b11fc9439c"}, + ) assert data["revision"]["directory"] == { "swhid": "swh:1:dir:0101010101010101010101010101010101010101" } @@ -57,8 +65,8 @@ # TargetDirectoryNode is returned from snapshotbranch, release # and directory entry nodes. Release node is used for testing here query_str = """ - { - release(swhid: "swh:1:rel:ee4d20e80af850cc0f417d25dc5073792c5010d2") { + query getRelease($swhid: SWHID!) { + release(swhid: $swhid) { swhid target { ...on Directory { @@ -68,7 +76,11 @@ } } """ - data, _ = utils.get_query_response(client, query_str) + data, _ = utils.get_query_response( + client, + query_str, + variables={"swhid": "swh:1:rel:ee4d20e80af850cc0f417d25dc5073792c5010d2"}, + ) assert data["release"]["target"] == { "swhid": "swh:1:dir:0505050505050505050505050505050505050505" } @@ -77,10 +89,15 @@ def test_get_directory_with_unknown_swhid(client): unknown_sha1 = "1" * 40 query_str = """ - { - directory(swhid: "swh:1:dir:%s") { + query getDirectory($swhid: SWHID!) { + directory(swhid: $swhid) { swhid } } """ - utils.assert_missing_object(client, query_str % unknown_sha1, "directory") + utils.assert_missing_object( + client, + query_str, + obj_type="directory", + variables={"swhid": f"swh:1:dir:{unknown_sha1}"}, + ) diff --git a/swh/graphql/tests/functional/test_directory_entry.py b/swh/graphql/tests/functional/test_directory_entry.py --- a/swh/graphql/tests/functional/test_directory_entry.py +++ b/swh/graphql/tests/functional/test_directory_entry.py @@ -21,8 +21,8 @@ directory = get_directories()[0] path = "missing" query_str = """ - { - directoryEntry(directorySwhid: "%s", path: "%s") { + query getDirEntry($swhid: SWHID!, $path: String!) { + directoryEntry(directorySwhid: $swhid, path: $path) { name { text } @@ -34,11 +34,13 @@ } } } - """ % ( - directory.swhid(), - path, + """ + utils.assert_missing_object( + client, + query_str, + "directoryEntry", + variables={"swhid": str(directory.swhid()), "path": path}, ) - utils.assert_missing_object(client, query_str, "directoryEntry") @pytest.mark.parametrize( @@ -47,8 +49,8 @@ def test_get_directory_entry(client, directory): storage = server.get_storage() query_str = """ - { - directoryEntry(directorySwhid: "%s", path: "%s") { + query getDirEntry($swhid: SWHID!, $path: String!) { + directoryEntry(directorySwhid: $swhid, path: $path) { name { text } @@ -68,13 +70,10 @@ } """ for entry in storage.directory_ls(directory.id, recursive=True): - query = query_str % ( - directory.swhid(), - entry["name"].decode(), - ) data, _ = utils.get_query_response( client, - query, + query_str, + variables={"swhid": str(directory.swhid()), "path": entry["name"].decode()}, ) swhid = None if entry["type"] == "file" and entry["sha1_git"] is not None: @@ -99,8 +98,8 @@ @pytest.mark.parametrize("directory", get_directories()) def test_get_directory_entry_connection(client, directory): query_str = """ - { - directory(swhid: "%s") { + query getDirectory($swhid: SWHID!) { + directory(swhid: $swhid) { swhid entries { nodes { @@ -113,7 +112,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % directory.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(directory.swhid())} + ) directory_entries = data["directory"]["entries"]["nodes"] assert len(directory_entries) == len(directory.entries) output = [ @@ -130,10 +131,10 @@ for dir_entry in storage.directory_ls(directory.id): name_include = dir_entry["name"][:-1].decode() query_str = """ - { - directory(swhid: "%s") { + query getDirectory($swhid: SWHID!, $nameInclude: String) { + directory(swhid: $swhid) { swhid - entries(nameInclude: "%s") { + entries(nameInclude: $nameInclude) { nodes { targetType name { @@ -143,11 +144,12 @@ } } } - """ % ( - directory.swhid(), - name_include, + """ + data, _ = utils.get_query_response( + client, + query_str, + variables={"swhid": str(directory.swhid()), "nameInclude": name_include}, ) - data, _ = utils.get_query_response(client, query_str) for entry in data["directory"]["entries"]["nodes"]: assert name_include in entry["name"]["text"] assert entry["targetType"] == get_target_type(dir_entry["type"]) diff --git a/swh/graphql/tests/functional/test_origin_connection.py b/swh/graphql/tests/functional/test_origin_connection.py --- a/swh/graphql/tests/functional/test_origin_connection.py +++ b/swh/graphql/tests/functional/test_origin_connection.py @@ -3,16 +3,18 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +from typing import Optional + from . import utils from ..data import get_origins -def get_origins_from_api(client, first: int, **args) -> tuple: - args["first"] = first - params = utils.get_query_params_from_args(**args) +def get_origins_from_api( + client, first: int, urlPattern: Optional[str] = None, **args +) -> tuple: query_str = """ - { - origins(%s) { + query getOrigins($first: Int!, $urlPattern: String) { + origins(first: $first, urlPattern: $urlPattern) { nodes { url } @@ -22,24 +24,26 @@ } } } - """ % ( - params, + """ + return utils.get_query_response( + client, query_str, variables={"first": first, "urlPattern": urlPattern} ) - return utils.get_query_response(client, query_str) def test_get(client, storage): - data, _ = get_origins_from_api(client, 10) + data, _ = get_origins_from_api(client, first=10) assert len(data["origins"]["nodes"]) == len(get_origins()) def test_get_filter_by_pattern(client): - data, _ = get_origins_from_api(client, 10, urlPattern='"somewhere.org/den"') + data, _ = get_origins_from_api(client, first=10, urlPattern='"somewhere.org/den"') assert len(data["origins"]["nodes"]) == 1 def test_get_filter_by_non_existing_pattern(client): - data, _ = get_origins_from_api(client, 10, urlPattern='"somewhere.org/den/test/"') + data, _ = get_origins_from_api( + client, first=10, urlPattern='"somewhere.org/den/test/"' + ) assert len(data["origins"]["nodes"]) == 0 diff --git a/swh/graphql/tests/functional/test_origin_node.py b/swh/graphql/tests/functional/test_origin_node.py --- a/swh/graphql/tests/functional/test_origin_node.py +++ b/swh/graphql/tests/functional/test_origin_node.py @@ -5,27 +5,26 @@ import pytest +from . import utils from ..data import get_origins -from .utils import assert_missing_object, get_query_response def test_invalid_get(client): query_str = """ - { + query getOrigin { origin(url: "http://example.com/non-existing") { url } } """ - assert_missing_object(client, query_str, "origin") + utils.assert_missing_object(client, query_str, "origin") @pytest.mark.parametrize("origin", get_origins()) def test_get(client, storage, origin): - query_str = ( - """ - { - origin(url: "%s") { + query_str = """ + query getOrigin($url: String!) { + origin(url: $url) { url id visits(first: 10) { @@ -44,10 +43,9 @@ } } """ - % origin.url - ) - response, _ = get_query_response(client, query_str) + variables = {"url": origin.url} + response, _ = utils.get_query_response(client, query_str, variables) data_origin = response["origin"] storage_origin = storage.origin_get([origin.url])[0] visits_and_statuses = storage.origin_visit_get_with_statuses(origin.url).results @@ -61,40 +59,48 @@ def test_latest_visit_type_filter(client): query_str = """ - { - origin(url: "%s") { - latestVisit(visitType: "%s") { + query getOrigin($url: String!, $visitType: String!) { + origin(url: $url) { + latestVisit(visitType: $visitType) { visitId } } } """ - data, _ = get_query_response(client, query_str % (get_origins()[0].url, "git")) + data, _ = utils.get_query_response( + client, query_str, variables={"url": get_origins()[0].url, "visitType": "git"} + ) assert data["origin"] == {"latestVisit": {"visitId": 3}} - data, _ = get_query_response(client, query_str % (get_origins()[0].url, "hg")) + data, _ = utils.get_query_response( + client, query_str, variables={"url": get_origins()[0].url, "visitType": "hg"} + ) assert data["origin"] == {"latestVisit": None} def test_latest_visit_require_snapshot_filter(client): query_str = """ - { - origin(url: "%s") { - latestVisit(requireSnapshot: %s) { + query getOrigin($url: String!, $requireSnapshot: Boolean!) { + origin(url: $url) { + latestVisit(requireSnapshot: $requireSnapshot) { visitId } } } """ - data, _ = get_query_response(client, query_str % (get_origins()[1].url, "true")) + data, _ = utils.get_query_response( + client, + query_str, + variables={"url": get_origins()[1].url, "requireSnapshot": True}, + ) assert data["origin"] == {"latestVisit": {"visitId": 2}} def test_latest_visit_allowed_statuses_filter(client): query_str = """ - { - origin(url: "%s") { - latestVisit(allowedStatuses: [partial]) { + query getOrigin($url: String!, $allowedStatuses: [VisitStatusState!]!) { + origin(url: $url) { + latestVisit(allowedStatuses: $allowedStatuses) { visitId statuses { nodes { @@ -105,7 +111,11 @@ } } """ - data, _ = get_query_response(client, query_str % (get_origins()[1].url)) + data, _ = utils.get_query_response( + client, + query_str, + variables={"url": get_origins()[1].url, "allowedStatuses": ["partial"]}, + ) assert data["origin"] == { "latestVisit": {"statuses": {"nodes": [{"status": "partial"}]}, "visitId": 2} } diff --git a/swh/graphql/tests/functional/test_pagination.py b/swh/graphql/tests/functional/test_pagination.py --- a/swh/graphql/tests/functional/test_pagination.py +++ b/swh/graphql/tests/functional/test_pagination.py @@ -3,15 +3,15 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +from . import utils from ..data import get_origins -from .utils import get_query_response # Using Origin object to run functional tests for pagination -def get_origin_nodes(client, first=1, after=""): +def get_origin_nodes(client, first, after=""): query_str = """ - { - origins(first: %s, %s) { + query getOrigins($first: Int!, $after: String) { + origins(first: $first, after: $after) { nodes { id } @@ -21,29 +21,28 @@ } } } - """ % ( - first, - after, + """ + return utils.get_query_response( + client, query_str, variables={"first": first, "after": 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())) + data, _ = get_origin_nodes(client, first=len(get_origins())) assert len(data["origins"]["nodes"]) == len(get_origins()) assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None} def test_first_arg(client): - data, _ = get_origin_nodes(client, 1) + data, _ = get_origin_nodes(client, first=1) assert len(data["origins"]["nodes"]) == 1 assert data["origins"]["pageInfo"]["hasNextPage"] is True def test_invalid_first_arg(client): - data, errors = get_origin_nodes(client, -1) + data, errors = get_origin_nodes(client, first=-1) assert data["origins"] is None assert (len(errors)) == 2 # one error for origins and anotehr one for pageInfo assert ( @@ -53,7 +52,7 @@ def test_too_big_first_arg(client): - data, errors = get_origin_nodes(client, 1001) # max page size is 1000 + data, errors = get_origin_nodes(client, first=1001) # max page size is 1000 assert data["origins"] is None assert (len(errors)) == 2 assert ( @@ -63,16 +62,16 @@ def test_after_arg(client): - first_data, _ = get_origin_nodes(client) + first_data, _ = get_origin_nodes(client, first=1) end_cursor = first_data["origins"]["pageInfo"]["endCursor"] # get again with endcursor as the after argument - data, _ = get_origin_nodes(client, 1, f'after: "{end_cursor}"') + data, _ = get_origin_nodes(client, first=1, after=end_cursor) assert len(data["origins"]["nodes"]) == 1 assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None} def test_invalid_after_arg(client): - data, errors = get_origin_nodes(client, 1, 'after: "invalid"') + data, errors = get_origin_nodes(client, first=1, after="invalid") assert data["origins"] is None assert (len(errors)) == 2 assert ( @@ -81,14 +80,13 @@ def test_edge_cursor(client): - origins = get_origin_nodes(client)[0]["origins"] + origins = get_origin_nodes(client, first=1)[0]["origins"] # end cursor here must be the item cursor for the second item end_cursor = origins["pageInfo"]["endCursor"] - query_str = ( - """ - { - origins(first: 1, after: "%s") { + query_str = """ + query getOrigins($first: Int!, $after: String) { + origins(first: $first, after: $after) { edges { cursor node { @@ -101,9 +99,9 @@ } } """ - % end_cursor + data, _ = utils.get_query_response( + client, query_str, variables={"first": 1, "after": end_cursor} ) - data, _ = get_query_response(client, query_str) origins = data["origins"] assert [edge["node"] for edge in origins["edges"]] == origins["nodes"] assert origins["edges"][0]["cursor"] == end_cursor diff --git a/swh/graphql/tests/functional/test_release_node.py b/swh/graphql/tests/functional/test_release_node.py --- a/swh/graphql/tests/functional/test_release_node.py +++ b/swh/graphql/tests/functional/test_release_node.py @@ -21,10 +21,9 @@ @pytest.mark.parametrize("release", get_releases()) def test_get_release(client, release): - query_str = ( - """ - { - release(swhid: "%s") { + query_str = """ + query getRelease($swhid: SWHID!) { + release(swhid: $swhid) { swhid name { text @@ -49,9 +48,9 @@ } } """ - % release.swhid() + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(release.swhid())} ) - data, _ = utils.get_query_response(client, query_str) assert data["release"] == { "swhid": str(release.swhid()), @@ -74,22 +73,25 @@ def test_get_release_with_invalid_swhid(client): query_str = """ - { - release(swhid: "swh:1:rel:invalid") { + query getRelease($swhid: SWHID!) { + release(swhid: $swhid) { swhid } } """ - errors = utils.get_error_response(client, query_str) + errors = utils.get_error_response( + client, query_str, variables={"swhid": "swh:1:rel:invalid"} + ) # API will throw an error in case of an invalid SWHID assert len(errors) == 1 + assert "Expected type 'SWHID'. Input error: Invalid SWHID" in errors[0]["message"] @pytest.mark.parametrize("release_with_target", get_releases_with_target()) def test_get_release_targets(client, release_with_target): query_str = """ - { - release(swhid: "%s") { + query getRelease($swhid: SWHID!) { + release(swhid: $swhid) { targetType target { ...on Revision { @@ -108,7 +110,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % release_with_target.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(release_with_target.swhid())} + ) if release_with_target.target_type == ObjectType.REVISION: target_swhid = get_revisions()[0].swhid() @@ -132,8 +136,8 @@ # ie: both swhid and message will be available in the response swhid = get_releases_with_target()[0].swhid() query_str = """ - { - release(swhid: "%s") { + query getRelease($swhid: SWHID!) { + release(swhid: $swhid) { targetType target { ...on Revision { @@ -155,7 +159,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % swhid) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(swhid)} + ) assert data["release"] == { "target": { "message": {"text": "hello"}, @@ -168,10 +174,15 @@ def test_get_release_with_unknown_swhid(client): unknown_sha1 = "1" * 40 query_str = """ - { - release(swhid: "swh:1:rel:%s") { + query getRelease($swhid: SWHID!) { + release(swhid: $swhid) { swhid } } """ - utils.assert_missing_object(client, query_str % unknown_sha1, "release") + utils.assert_missing_object( + client, + query_str, + obj_type="release", + variables={"swhid": f"swh:1:rel:{unknown_sha1}"}, + ) diff --git a/swh/graphql/tests/functional/test_revision.py b/swh/graphql/tests/functional/test_revision.py --- a/swh/graphql/tests/functional/test_revision.py +++ b/swh/graphql/tests/functional/test_revision.py @@ -14,8 +14,8 @@ @pytest.mark.parametrize("revision", get_revisions()) def test_get_revision(client, revision): query_str = """ - { - revision(swhid: "%s") { + query getRevision($swhid: SWHID!) { + revision(swhid: $swhid) { swhid message { text @@ -50,7 +50,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % revision.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(revision.swhid())} + ) assert data["revision"] == { "swhid": str(revision.swhid()), "message": {"text": revision.message.decode()}, @@ -74,13 +76,15 @@ def test_get_revision_with_invalid_swhid(client): query_str = """ - { - revision(swhid: "swh:1:cnt:invalid") { + query getRevision($swhid: SWHID!) { + revision(swhid: $swhid) { swhid } } """ - errors = utils.get_error_response(client, query_str) + errors = utils.get_error_response( + client, query_str, variables={"swhid": "swh:1:cnt:invalid"} + ) # API will throw an error in case of an invalid SWHID assert len(errors) == 1 assert "Input error: Invalid SWHID" in errors[0]["message"] @@ -90,8 +94,8 @@ # SWHID of a snapshot with revision as target snapshot_swhid = "swh:1:snp:9e78d7105c5e0f886487511e2a92377b4ee4c32a" query_str = """ - { - snapshot(swhid: "%s") { + query getSnapshot($swhid: SWHID!) { + snapshot(swhid: $swhid) { branches(first: 1, types: [revision]) { nodes { targetType @@ -105,7 +109,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % snapshot_swhid) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": snapshot_swhid} + ) revision_obj = data["snapshot"]["branches"]["nodes"][0]["target"] assert revision_obj == { "swhid": "swh:1:rev:66c7c1cd9673275037140f2abff7b7b11fc9439c" @@ -115,8 +121,8 @@ def test_get_revision_log(client): revision_swhid = get_revisions_with_parents()[0].swhid() query_str = """ - { - revision(swhid: "%s") { + query getRevision($swhid: SWHID!) { + revision(swhid: $swhid) { swhid revisionLog(first: 3) { nodes { @@ -126,7 +132,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % revision_swhid) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(revision_swhid)} + ) assert data["revision"]["revisionLog"] == { "nodes": [ {"swhid": str(revision_swhid)}, @@ -139,8 +147,8 @@ def test_get_revision_parents(client): revision_swhid = get_revisions_with_parents()[0].swhid() query_str = """ - { - revision(swhid: "%s") { + query getRevision($swhid: SWHID!) { + revision(swhid: $swhid) { swhid parents { nodes { @@ -150,7 +158,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % revision_swhid) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(revision_swhid)} + ) assert data["revision"]["parents"] == { "nodes": [ @@ -163,10 +173,15 @@ def test_get_revision_with_unknown_swhid(client): unknown_sha1 = "1" * 40 query_str = """ - { - revision(swhid: "swh:1:rev:%s") { + query getRevision($swhid: SWHID!) { + revision(swhid: $swhid) { swhid } } """ - utils.assert_missing_object(client, query_str % unknown_sha1, "revision") + utils.assert_missing_object( + client, + query_str, + obj_type="revision", + variables={"swhid": f"swh:1:rev:{unknown_sha1}"}, + ) diff --git a/swh/graphql/tests/functional/test_search.py b/swh/graphql/tests/functional/test_search.py --- a/swh/graphql/tests/functional/test_search.py +++ b/swh/graphql/tests/functional/test_search.py @@ -8,8 +8,8 @@ def test_search_origins(client): query_str = """ - { - search(query: "fox", first: 1) { + query doSearch($query: String!, $first: Int!) { + search(query: $query, first: $first) { nodes { targetType target { @@ -28,7 +28,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str) + data, _ = utils.get_query_response( + client, query_str, variables={"query": "fox", "first": 1} + ) assert len(data["search"]["nodes"]) == 1 assert data == { "search": { @@ -48,8 +50,8 @@ def test_search_missing_url(client): query_str = """ - { - search(query: "missing-fox", first: 1) { + query doSearch($query: String!, $first: Int!) { + search(query: $query, first: $first) { nodes { targetType } @@ -60,5 +62,7 @@ } } """ - data, _ = utils.get_query_response(client, query_str) + data, _ = utils.get_query_response( + client, query_str, variables={"query": "missing-fox", "first": 1} + ) assert len(data["search"]["nodes"]) == 0 diff --git a/swh/graphql/tests/functional/test_snapshot_node.py b/swh/graphql/tests/functional/test_snapshot_node.py --- a/swh/graphql/tests/functional/test_snapshot_node.py +++ b/swh/graphql/tests/functional/test_snapshot_node.py @@ -5,15 +5,15 @@ import pytest +from . import utils from ..data import get_snapshots -from .utils import assert_missing_object, get_error_response, get_query_response @pytest.mark.parametrize("snapshot", get_snapshots()) def test_get_snapshot(client, snapshot): query_str = """ - { - snapshot(swhid: "%s") { + query getSnapshot($swhid: SWHID!) { + snapshot(swhid: $swhid) { id swhid branches(first:5) { @@ -27,7 +27,9 @@ } } """ - data, _ = get_query_response(client, query_str % snapshot.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(snapshot.swhid())} + ) assert data["snapshot"]["swhid"] == str(snapshot.swhid()) assert data["snapshot"]["id"] == snapshot.id.hex() assert len(data["snapshot"]["branches"]["nodes"]) == len(snapshot.branches) @@ -35,23 +37,30 @@ def test_get_snapshot_missing_swhid(client): query_str = """ - { - snapshot(swhid: "swh:1:snp:0949d7a8c96347dba09be8d79085b8207f345412") { + query getSnapshot($swhid: SWHID!) { + snapshot(swhid: $swhid) { swhid } } """ - assert_missing_object(client, query_str, "snapshot") + utils.assert_missing_object( + client, + query_str, + obj_type="snapshot", + variables={"swhid": "swh:1:snp:0949d7a8c96347dba09be8d79085b8207f345412"}, + ) def test_get_snapshot_invalid_swhid(client): query_str = """ - { - snapshot(swhid: "swh:1:snp:invalid") { + query getSnapshot($swhid: SWHID!) { + snapshot(swhid: $swhid) { swhid } } """ - errors = get_error_response(client, query_str) + errors = utils.get_error_response( + client, query_str, variables={"swhid": "swh:1:snp:invalid"} + ) assert len(errors) == 1 assert "Input error: Invalid SWHID" in errors[0]["message"] diff --git a/swh/graphql/tests/functional/test_swhid_resolve.py b/swh/graphql/tests/functional/test_swhid_resolve.py --- a/swh/graphql/tests/functional/test_swhid_resolve.py +++ b/swh/graphql/tests/functional/test_swhid_resolve.py @@ -17,15 +17,17 @@ def test_invalid_swhid(client): query_str = """ - { - resolveSwhid(swhid: "swh:1:dir:dae0d245988b472abd30a4f968b919d0019b6c7") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType } } } """ - errors = utils.get_error_response(client, query_str) + errors = utils.get_error_response( + client, query_str, variables={"swhid": "swh:1:dir:invalid"} + ) # API will throw an error in case of an invalid SWHID assert len(errors) == 1 assert "Input error: Invalid SWHID" in errors[0]["message"] @@ -43,15 +45,15 @@ ) def test_missing_swhid(client, swhid): query_str = """ - { - resolveSwhid(swhid: "%s") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType } } } """ - data, _ = utils.get_query_response(client, query_str % swhid) + data, _ = utils.get_query_response(client, query_str, variables={"swhid": swhid}) # API will return an empty list in case of a valid, non existing SWHID assert data == {"resolveSwhid": {"nodes": []}} @@ -59,8 +61,8 @@ @pytest.mark.parametrize("snapshot", get_snapshots()) def test_snapshot_swhid_resolve(client, snapshot): query_str = """ - { - resolveSwhid(swhid: "%s") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType target { @@ -73,7 +75,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % snapshot.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(snapshot.swhid())} + ) assert data == { "resolveSwhid": { "nodes": [ @@ -92,8 +96,8 @@ @pytest.mark.parametrize("revision", get_revisions()) def test_revision_swhid_resolve(client, revision): query_str = """ - { - resolveSwhid(swhid: "%s") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType target { @@ -106,7 +110,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % revision.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(revision.swhid())} + ) assert data == { "resolveSwhid": { "nodes": [ @@ -125,8 +131,8 @@ @pytest.mark.parametrize("release", get_releases()) def test_release_swhid_resolve(client, release): query_str = """ - { - resolveSwhid(swhid: "%s") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType target { @@ -139,7 +145,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % release.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(release.swhid())} + ) assert data == { "resolveSwhid": { "nodes": [ @@ -158,8 +166,8 @@ @pytest.mark.parametrize("directory", get_directories()) def test_directory_swhid_resolve(client, directory): query_str = """ - { - resolveSwhid(swhid: "%s") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType target { @@ -172,7 +180,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % directory.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(directory.swhid())} + ) assert data == { "resolveSwhid": { "nodes": [ @@ -191,8 +201,8 @@ @pytest.mark.parametrize("content", get_contents()) def test_content_swhid_resolve(client, content): query_str = """ - { - resolveSwhid(swhid: "%s") { + query resolve($swhid: SWHID!) { + resolveSwhid(swhid: $swhid) { nodes { targetType target { @@ -205,7 +215,9 @@ } } """ - data, _ = utils.get_query_response(client, query_str % content.swhid()) + data, _ = utils.get_query_response( + client, query_str, variables={"swhid": str(content.swhid())} + ) assert data == { "resolveSwhid": { "nodes": [ diff --git a/swh/graphql/tests/functional/test_visit_node.py b/swh/graphql/tests/functional/test_visit_node.py --- a/swh/graphql/tests/functional/test_visit_node.py +++ b/swh/graphql/tests/functional/test_visit_node.py @@ -5,15 +5,15 @@ import pytest +from . import utils from ..data import get_origins -from .utils import assert_missing_object, get_query_response @pytest.mark.parametrize("origin", get_origins()) def test_get_visit(client, storage, origin): query_str = """ - { - visit(originUrl: "%s", visitId: %s) { + query getVisit($origin: String!, $visitId: Int!) { + visit(originUrl: $origin, visitId: $visitId) { visitId date type @@ -38,7 +38,9 @@ for vws in visits_and_statuses: visit = vws.visit statuses = vws.statuses - data, _ = get_query_response(client, query_str % (origin.url, visit.visit)) + data, _ = utils.get_query_response( + client, query_str, variables={"origin": origin.url, "visitId": visit.visit} + ) assert data["visit"] == { "visitId": visit.visit, "type": visit.type, @@ -63,13 +65,13 @@ } } """ - assert_missing_object(client, query_str, "visit") + utils.assert_missing_object(client, query_str, "visit") def test_get_latest_visit_status_filter_by_status_return_null(client): query_str = """ - { - visit(originUrl: "%s", visitId: %s) { + query getVisit($origin: String!, $visitId: Int!) { + visit(originUrl: $origin, visitId: $visitId) { visitId date type @@ -78,11 +80,10 @@ } } } - """ % ( - get_origins()[0].url, - 1, + """ + data, err = utils.get_query_response( + client, query_str, variables={"origin": get_origins()[0].url, "visitId": 1} ) - data, err = get_query_response(client, query_str) assert err is None assert data == { "visit": { @@ -96,8 +97,8 @@ def test_get_latest_visit_status_filter_by_type(client): query_str = """ - { - visit(originUrl: "%s", visitId: %s) { + query getVisit($origin: String!, $visitId: Int!) { + visit(originUrl: $origin, visitId: $visitId) { visitId date type @@ -107,11 +108,10 @@ } } } - """ % ( - get_origins()[0].url, - 1, + """ + data, err = utils.get_query_response( + client, query_str, variables={"origin": get_origins()[0].url, "visitId": 1} ) - data, err = get_query_response(client, query_str) assert err is None assert data == { "visit": { @@ -128,8 +128,8 @@ def test_get_latest_visit_status_filter_by_snapshot(client): query_str = """ - { - visit(originUrl: "%s", visitId: %s) { + query getVisit($origin: String!, $visitId: Int!) { + visit(originUrl: $origin, visitId: $visitId) { visitId date type @@ -142,11 +142,10 @@ } } } - """ % ( - get_origins()[1].url, - 2, + """ + data, err = utils.get_query_response( + client, query_str, variables={"origin": get_origins()[1].url, "visitId": 2} ) - data, err = get_query_response(client, query_str) assert err is None assert data == { "visit": { diff --git a/swh/graphql/tests/functional/test_visit_status.py b/swh/graphql/tests/functional/test_visit_status.py --- a/swh/graphql/tests/functional/test_visit_status.py +++ b/swh/graphql/tests/functional/test_visit_status.py @@ -5,8 +5,8 @@ import pytest +from . import utils from ..data import get_origins, get_visit_status, get_visits -from .utils import get_query_response @pytest.mark.parametrize( @@ -14,8 +14,8 @@ ) def test_get_visit_status(client, visit, visit_status): query_str = """ - { - visit(originUrl: "%s", visitId: %s) { + query getVisit($origin: String!, $visitId: Int!) { + visit(originUrl: $origin, visitId: $visitId) { statuses(first: 3) { nodes { status @@ -28,11 +28,10 @@ } } } - """ % ( - visit.origin, - visit.visit, + """ + data, _ = utils.get_query_response( + client, query_str, variables={"origin": visit.origin, "visitId": visit.visit} ) - data, _ = get_query_response(client, query_str) assert data["visit"]["statuses"]["nodes"][0] == { "date": visit_status.date.isoformat(), "snapshot": {"swhid": f"swh:1:snp:{visit_status.snapshot.hex()}"} @@ -46,8 +45,8 @@ def test_visit_status_pagination(client): # visit status is using a different cursor, hence separate test query_str = """ - { - visit(originUrl: "%s", visitId: %s) { + query getVisit($origin: String!, $visitId: Int!) { + visit(originUrl: $origin, visitId: $visitId) { statuses(first: 1) { pageInfo { hasNextPage @@ -62,17 +61,16 @@ } } } - """ % ( - get_origins()[0].url, - 1, + """ + data, _ = utils.get_query_response( + client, query_str, variables={"origin": get_origins()[0].url, "visitId": 1} ) - data, _ = get_query_response(client, query_str) # request again with the endcursor end_cursor = data["visit"]["statuses"]["pageInfo"]["endCursor"] query_str = """ - { - visit(originUrl: "%s", visitId: %s) { - statuses(first: 1, after: "%s") { + query getVisit($origin: String!, $visitId: Int!, $after: String) { + visit(originUrl: $origin, visitId: $visitId) { + statuses(first: 1, after: $after) { pageInfo { hasNextPage endCursor @@ -86,12 +84,12 @@ } } } - """ % ( - get_origins()[0].url, - 1, - end_cursor, + """ + data, _ = utils.get_query_response( + client, + query_str, + variables={"origin": get_origins()[0].url, "visitId": 1, "after": end_cursor}, ) - data, _ = get_query_response(client, query_str) assert data["visit"]["statuses"] == { "edges": [ { diff --git a/swh/graphql/tests/functional/utils.py b/swh/graphql/tests/functional/utils.py --- a/swh/graphql/tests/functional/utils.py +++ b/swh/graphql/tests/functional/utils.py @@ -4,34 +4,35 @@ # See top-level LICENSE file for more information import json -from typing import Dict, Tuple +from typing import Any, Dict, Optional, Tuple +from ariadne import gql -def get_response(client, query_str: str): - return client.post("/", json={"query": query_str}) - -def get_query_response(client, query_str: str) -> Tuple[Dict, Dict]: - response = get_response(client, query_str) +def get_query_response( + client, query_str: str, variables: Optional[Dict[str, Any]] = None +) -> Tuple[Dict, Dict]: + query = gql(query_str) + response = client.post("/", json={"query": query, "variables": variables}) assert response.status_code == 200, response.data result = json.loads(response.data) return result.get("data"), result.get("errors") -def assert_missing_object(client, query_str: str, obj_type: str) -> None: - data, errors = get_query_response(client, query_str) +def assert_missing_object( + client, query_str: str, obj_type: str, variables=None +) -> None: + data, errors = get_query_response(client, query_str, variables=variables) assert data[obj_type] is None assert len(errors) == 1 assert errors[0]["message"] == "Object error: Requested object is not available" assert errors[0]["path"] == [obj_type] -def get_error_response(client, query_str: str, error_code: int = 400) -> Dict: - response = get_response(client, query_str) - assert response.status_code == error_code - return json.loads(response.data)["errors"] - - -def get_query_params_from_args(**args) -> str: - # build a GraphQL query parameters string from arguments - return ",".join([f"{key}: {val}" for (key, val) in args.items()]) +def get_error_response( + client, query_str: str, variables: Optional[Dict[str, Any]] = None +) -> Dict: + data, errors = get_query_response(client, query_str, variables=variables) + assert data is None + assert len(errors) > 0 + return errors