Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9343905
D7817.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Subscribers
None
D7817.diff
View Options
diff --git a/swh/graphql/resolvers/origin.py b/swh/graphql/resolvers/origin.py
--- a/swh/graphql/resolvers/origin.py
+++ b/swh/graphql/resolvers/origin.py
@@ -1,3 +1,8 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
from swh.graphql.backends import archive
from .base_connection import BaseConnection
diff --git a/swh/graphql/server.py b/swh/graphql/server.py
--- a/swh/graphql/server.py
+++ b/swh/graphql/server.py
@@ -1,3 +1,8 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
import os
from typing import Any, Dict, Optional
@@ -58,7 +63,8 @@
config_path = os.environ.get("SWH_CONFIG_FILENAME")
graphql_cfg = load_and_check_config(config_path)
- if graphql_cfg.get("server-type") == "asgi":
+ server_type = graphql_cfg.get("server-type")
+ if server_type == "asgi":
from ariadne.asgi import GraphQL
application = GraphQL(schema)
diff --git a/swh/graphql/tests/conftest.py b/swh/graphql/tests/conftest.py
new file mode 100644
--- /dev/null
+++ b/swh/graphql/tests/conftest.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+
+from ariadne import graphql_sync
+from flask import Flask, jsonify, request
+import pytest
+
+from swh.graphql import server as app_server
+from swh.graphql.app import schema
+from swh.storage import get_storage as get_swhstorage
+
+from .data import populate_dummy_data
+
+
+@pytest.fixture
+def storage():
+ storage = get_swhstorage(cls="memory")
+ # set the global var to use the in-memory storage
+ app_server.storage = storage
+ # populate the in-memory storage
+ populate_dummy_data(storage)
+
+
+@pytest.fixture
+def test_app(storage):
+ app = Flask(__name__)
+
+ @app.route("/", methods=["POST"])
+ def graphql_server():
+ # GraphQL queries are always sent as POST
+ data = request.get_json()
+ success, result = graphql_sync(
+ schema, data, context_value=request, debug=app.debug
+ )
+ status_code = 200 if success else 400
+ return jsonify(result), status_code
+
+ yield app
+
+
+@pytest.fixture
+def client(test_app):
+ with test_app.test_client() as client:
+ yield client
diff --git a/swh/graphql/tests/data.py b/swh/graphql/tests/data.py
new file mode 100644
--- /dev/null
+++ b/swh/graphql/tests/data.py
@@ -0,0 +1,105 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+# This module will be removed once the test data
+# generation in SWH-wb moved to a shared location
+# or to a new test data project
+
+from datetime import timedelta
+
+from swh.model.model import Origin, OriginVisit, OriginVisitStatus, Snapshot
+from swh.storage.utils import now
+
+
+def populate_dummy_data(storage):
+ origins = get_origins()
+ visits = get_visits(origins)
+ snapshots = get_snapshots()
+ status = get_visit_status(visits, snapshots)
+
+ storage.origin_add(origins)
+ storage.origin_visit_add(visits)
+ storage.snapshot_add(snapshots)
+ storage.origin_visit_status_add(status)
+
+
+def get_origins():
+ # Return two dummy origins
+ return [
+ Origin(url="http://example.com/forge1"),
+ Origin(url="http://example.com/forge2"),
+ ]
+
+
+def get_visits(origins):
+ # Return two visits each for an origin
+ origin1, origin2 = origins
+ return [
+ OriginVisit(
+ origin=origin1.url,
+ date=now() - timedelta(minutes=200),
+ type="git",
+ visit=1,
+ ),
+ OriginVisit(
+ origin=origin1.url,
+ date=now(),
+ type="git",
+ visit=2,
+ ),
+ OriginVisit(
+ origin=origin2.url,
+ date=now() - timedelta(minutes=500),
+ type="hg",
+ visit=1,
+ ),
+ OriginVisit(
+ origin=origin2.url,
+ date=now(),
+ type="hg",
+ visit=2,
+ ),
+ ]
+
+
+def get_visit_status(visits, snapshots):
+ # Return one status per visit, adding only empty statpshots for now
+ visit1, visit2, visit3, visit4 = visits
+ (empty_snapshot,) = snapshots
+ return [
+ OriginVisitStatus(
+ origin=visit1.origin,
+ visit=visit1.visit,
+ date=visit1.date,
+ status="full",
+ snapshot=empty_snapshot.id,
+ ),
+ OriginVisitStatus(
+ origin=visit2.origin,
+ visit=visit2.visit,
+ date=visit1.date,
+ status="full",
+ snapshot=empty_snapshot.id,
+ ),
+ OriginVisitStatus(
+ origin=visit3.origin,
+ visit=visit3.visit,
+ date=visit3.date,
+ status="full",
+ snapshot=empty_snapshot.id,
+ ),
+ OriginVisitStatus(
+ origin=visit4.origin,
+ visit=visit4.visit,
+ date=visit4.date,
+ status="full",
+ snapshot=empty_snapshot.id,
+ ),
+ ]
+
+
+def get_snapshots():
+ empty_snapshot = Snapshot(branches={})
+ return [empty_snapshot]
diff --git a/swh/graphql/tests/functional/test_origin_connection.py b/swh/graphql/tests/functional/test_origin_connection.py
new file mode 100644
--- /dev/null
+++ b/swh/graphql/tests/functional/test_origin_connection.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+from .utils import get_query_response
+
+
+def test_get(client):
+ query_str = """
+ {
+ origins(first: 10) {
+ nodes {
+ url
+ }
+ }
+ }
+ """
+ data, _ = get_query_response(client, query_str)
+ assert len(data["origins"]["nodes"]) == 2
+
+
+def test_get_filter_by_pattern(client):
+ query_str = """
+ {
+ origins(first: 10, urlPattern: "forge1") {
+ nodes {
+ url
+ }
+ }
+ }
+ """
+ data, _ = get_query_response(client, query_str)
+ assert len(data["origins"]["nodes"]) == 1
+
+
+def test_basic_pagination(client):
+ query_str = """
+ {
+ origins(first: 2) {
+ nodes {
+ id
+ }
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ }
+ }
+ """
+
+ data, _ = get_query_response(client, query_str)
+ assert len(data["origins"]["nodes"]) == 2
+ assert data["origins"]["pageInfo"] == {"hasNextPage": False, "endCursor": None}
diff --git a/swh/graphql/tests/functional/test_origin_node.py b/swh/graphql/tests/functional/test_origin_node.py
new file mode 100644
--- /dev/null
+++ b/swh/graphql/tests/functional/test_origin_node.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+from .utils import get_query_response
+
+
+def test_invalid_get(client):
+ query_str = """
+ {
+ origin(url: "http://example.com/forge1/") {
+ url
+ }
+ }
+ """
+ data, errors = get_query_response(client, query_str)
+ assert data["origin"] is None
+ assert len(errors) == 1
+ assert errors[0]["message"] == "Requested object is not available"
+
+
+def test_get(client):
+ query_str = """
+ {
+ origin(url: "http://example.com/forge1") {
+ url
+ id
+ visits(first: 10) {
+ nodes {
+ id
+ }
+ }
+ latestVisit {
+ visitId
+ }
+ snapshots(first: 2) {
+ nodes {
+ id
+ }
+ }
+ }
+ }
+ """
+ data, _ = get_query_response(client, query_str)
+ origin = data["origin"]
+ assert origin["url"] == "http://example.com/forge1"
+ assert len(origin["visits"]["nodes"]) == 2
+ assert origin["latestVisit"]["visitId"] == 2
+ assert len(origin["snapshots"]["nodes"]) == 1
diff --git a/swh/graphql/tests/functional/utils.py b/swh/graphql/tests/functional/utils.py
new file mode 100644
--- /dev/null
+++ b/swh/graphql/tests/functional/utils.py
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+import json
+
+
+def get_query_response(client, query_str):
+ response = client.post("/", json={"query": query_str})
+ assert response.status_code == 200, response.data
+ result = json.loads(response.data)
+ return result.get("data"), result.get("errors")
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 3, 1:57 PM (3 d, 3 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3223577
Attached To
D7817: Add first set of functional tests
Event Timeline
Log In to Comment