Skip to content

Commit

Permalink
use new testing helpers from magql
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Aug 3, 2024
1 parent a37e5d0 commit e0372b6
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 95 deletions.
34 changes: 21 additions & 13 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import pytest
import sqlalchemy as sa
import sqlalchemy.orm as sa_orm
from magql.testing import expect_data
from magql.testing import expect_error
from magql.testing import expect_errors
from magql.testing import expect_validation_error
from sqlalchemy.orm import column_keyed_dict
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
Expand Down Expand Up @@ -95,19 +99,23 @@ def session() -> t.Generator[sa_orm.Session, None, None]:
connection.close()


class TPExecute(t.Protocol):
def __call__(
self, source: str, variables: dict[str, t.Any] | None = None
) -> graphql.ExecutionResult: ...
class Execute:
def __init__(self, session: sa_orm.Session) -> None:
self._context = {"sa_session": session}

def expect_data(self, source, **kwargs) -> dict[str, t.Any]:
return expect_data(schema, source, context=self._context, **kwargs)

def expect_errors(self, source, **kwargs) -> list[graphql.GraphQLError]:
return expect_errors(schema, source, context=self._context, **kwargs)

def expect_error(self, source, **kwargs) -> graphql.GraphQLError:
return expect_error(schema, source, context=self._context, **kwargs)

def expect_validation_error(self, source, **kwargs) -> dict[str, t.Any]:
return expect_validation_error(schema, source, context=self._context, **kwargs)


@pytest.fixture()
def schema_execute(session: sa_orm.Session) -> TPExecute:
def schema_execute(
source: str, variables: dict[str, t.Any] | None = None
) -> graphql.ExecutionResult:
return schema.execute(
source, variables=variables, context={"sa_session": session}
)

return schema_execute
def execute(session: sa_orm.Session) -> Execute:
return Execute(session)
79 changes: 31 additions & 48 deletions tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pytest
from sqlalchemy.orm import Session

from .conftest import Execute
from .conftest import Task
from .conftest import TPExecute
from .conftest import User


Expand All @@ -17,26 +17,20 @@ def _populate_db(session: Session) -> None:
session.commit()


def test_item(schema_execute: TPExecute) -> None:
result = schema_execute("{ user_item(id: 1) { id username _display_value } }")
assert result.errors is None
assert result.data == {
"user_item": {"id": 1, "username": "a", "_display_value": "a"}
}
def test_item(execute: Execute) -> None:
result = execute.expect_data("{ user_item(id: 1) { id username _display_value } }")
assert result == {"user_item": {"id": 1, "username": "a", "_display_value": "a"}}


def test_item_missing(schema_execute: TPExecute) -> None:
def test_item_missing(execute: Execute) -> None:
"""Missing item returns None."""
result = schema_execute("{ user_item(id: 100) { id username } }")
assert result.errors is None
assert result.data == {"user_item": None}
result = execute.expect_data("{ user_item(id: 100) { id username } }")
assert result == {"user_item": None}


def test_list(schema_execute: TPExecute) -> None:
result = schema_execute("{ task_list { items { id message } total } }")
assert result.errors is None
assert result.data is not None
data = result.data["task_list"]
def test_list(execute: Execute) -> None:
result = execute.expect_data("{ task_list { items { id message } total } }")
data = result["task_list"]
items = data["items"]
assert data["total"] == 101
assert len(items) == 10
Expand All @@ -45,59 +39,48 @@ def test_list(schema_execute: TPExecute) -> None:
assert items[1]["id"] == 2


def test_filter_path(schema_execute: TPExecute) -> None:
def test_filter_path(execute: Execute) -> None:
"""Filter across relationship."""
result = schema_execute(
result = execute.expect_data(
'{ task_list(filter: { path: "user.username", op: "eq", value: "ex1" })'
" { items { message } } }"
)
assert result.errors is None
assert result.data is not None
items = result.data["task_list"]["items"]
items = result["task_list"]["items"]
assert len(items) == 1
assert items[0]["message"] == "ex1"


def test_sort_path(schema_execute: TPExecute) -> None:
def test_sort_path(execute: Execute) -> None:
"""Sort across relationship."""
result = schema_execute(
result = execute.expect_data(
'{ task_list(sort: ["-user.username", "-message"]) { items { id message } } }'
)
assert result.errors is None
assert result.data is not None
items = result.data["task_list"]["items"]
items = result["task_list"]["items"]
assert items[0]["message"] == "ex1"
assert items[1]["message"] == "a99"


def test_create(schema_execute: TPExecute) -> None:
result = schema_execute(
def test_create(execute: Execute) -> None:
result = execute.expect_data(
"""mutation { task_create(message: "b", user: 1) { id } }"""
)
assert result.errors is None
assert result.data is not None
task_id = result.data["task_create"]["id"]
result = schema_execute(
task_id = result["task_create"]["id"]
execute.expect_data(
"query($id: Int!) { task_item(id: $id) { id } }",
variables={"id": task_id},
)
assert result.data is not None


def test_update(schema_execute: TPExecute) -> None:
result = schema_execute(
def test_update(execute: Execute) -> None:
execute.expect_data(
"""mutation { task_update(id: 1, message: "updated") { id } }"""
)
assert result.errors is None
result = schema_execute("{ task_item(id: 1) { id message } }")
assert result.errors is None
assert result.data == {"task_item": {"id": 1, "message": "updated"}}


def test_delete(schema_execute: TPExecute) -> None:
result = schema_execute("""mutation { task_delete(id: 1) }""")
assert result.errors is None
assert result.data == {"task_delete": True}
result = schema_execute("{ task_item(id: 1) { id } }")
assert result.errors is None
assert result.data == {"task_item": None}
result = execute.expect_data("{ task_item(id: 1) { id message } }")
assert result == {"task_item": {"id": 1, "message": "updated"}}


def test_delete(execute: Execute) -> None:
result = execute.expect_data("""mutation { task_delete(id: 1) }""")
assert result == {"task_delete": True}
result = execute.expect_data("{ task_item(id: 1) { id } }")
assert result == {"task_item": None}
50 changes: 21 additions & 29 deletions tests/test_check_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session

from .conftest import Execute
from .conftest import Task
from .conftest import TPExecute
from .conftest import User

query = """\
Expand All @@ -19,26 +19,23 @@
"""


def test_invalid_type(schema_execute: TPExecute) -> None:
def test_invalid_type(execute: Execute) -> None:
"""An invalid type name will return an input validation error."""
result = schema_execute(query, variables={"type": "Bad", "id": "1"})
assert result.errors is not None
assert len(result.errors) == 1
assert result.errors[0].message == "magql argument validation"
assert result.errors[0].extensions is not None
assert result.errors[0].extensions["type"][0] == "Unknown type 'Bad'."
result = execute.expect_validation_error(
query, variables={"type": "Bad", "id": "1"}
)
assert result["type"][0] == "Unknown type 'Bad'."


def test_affected(session: Session, schema_execute: TPExecute) -> None:
def test_affected(session: Session, execute: Execute) -> None:
"""Deleting a task will show that its user is affected because its tasks
list will be changed.
"""
user = User(username="a", tasks=[Task(message="a")])
session.add(user)
session.commit()
result = schema_execute(query, variables={"type": "Task", "id": "1"})
assert not result.errors
assert result.data == {
result = execute.expect_data(query, variables={"type": "Task", "id": "1"})
assert result == {
"check_delete": {
"affected": [{"type": "User", "id": "1"}],
"deleted": [],
Expand All @@ -50,15 +47,14 @@ def test_affected(session: Session, schema_execute: TPExecute) -> None:
assert len(user.tasks) == 0


def test_affected_many(session: Session, schema_execute: TPExecute) -> None:
def test_affected_many(session: Session, execute: Execute) -> None:
"""Deleting a user will show that a task that references it as tagged_user
is affected instead of prevented, because tagged_user is nullable."""
task = Task(message="a", user=User(username="a"), tagged_user=User(username="b"))
session.add(task)
session.commit()
result = schema_execute(query, variables={"type": "User", "id": "2"})
assert not result.errors
assert result.data == {
result = execute.expect_data(query, variables={"type": "User", "id": "2"})
assert result == {
"check_delete": {
"affected": [{"type": "Task", "id": "1"}],
"deleted": [],
Expand All @@ -70,16 +66,15 @@ def test_affected_many(session: Session, schema_execute: TPExecute) -> None:
assert task.tagged_user is None


def test_prevented(session: Session, schema_execute: TPExecute) -> None:
def test_prevented(session: Session, execute: Execute) -> None:
"""Deleting a user with tasks will be prevented because the tasks have a
non-null reference to the user.
"""
user = User(username="a", tasks=[Task(message="a"), Task(message="b")])
session.add(user)
session.commit()
result = schema_execute(query, variables={"type": "User", "id": "1"})
assert not result.errors
assert result.data == {
result = execute.expect_data(query, variables={"type": "User", "id": "1"})
assert result == {
"check_delete": {
"affected": [],
"deleted": [],
Expand All @@ -94,7 +89,7 @@ def test_prevented(session: Session, schema_execute: TPExecute) -> None:
session.rollback()


def test_deleted(session: Session, schema_execute: TPExecute) -> None:
def test_deleted(session: Session, execute: Execute) -> None:
"""Deleting a parent task shows its child is deleted because the
relationship has delete cascade enabled. The user is also affected.
"""
Expand All @@ -103,9 +98,8 @@ def test_deleted(session: Session, schema_execute: TPExecute) -> None:
Task(message="child", user=user, parent=Task(message="parent", user=user))
)
session.commit()
result = schema_execute(query, variables={"type": "Task", "id": "1"})
assert not result.errors
assert result.data == {
result = execute.expect_data(query, variables={"type": "Task", "id": "1"})
assert result == {
"check_delete": {
"affected": [{"type": "User", "id": "1"}],
"deleted": [{"type": "Task", "id": "2"}],
Expand All @@ -117,11 +111,9 @@ def test_deleted(session: Session, schema_execute: TPExecute) -> None:
assert len(user.tasks) == 0


def test_many_empty(session: Session, schema_execute: TPExecute) -> None:
def test_many_empty(session: Session, execute: Execute) -> None:
"""If a to-many collection is empty, the check stops early."""
session.add(User(username="a"))
session.commit()
result = schema_execute(query, variables={"type": "User", "id": "1"})
assert result.data == {
"check_delete": {"affected": [], "deleted": [], "prevented": []}
}
result = execute.expect_data(query, variables={"type": "User", "id": "1"})
assert result == {"check_delete": {"affected": [], "deleted": [], "prevented": []}}
9 changes: 4 additions & 5 deletions tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from magql_sqlalchemy import ModelGroup
from magql_sqlalchemy import ModelManager

from .conftest import Execute
from .conftest import Model
from .conftest import Task
from .conftest import TPExecute
from .conftest import User


Expand All @@ -34,12 +34,11 @@ def test_group_enable_some(ref: type[DeclarativeBase] | str) -> None:
assert group.managers["Task"].search_provider is None


def test_search(session: Session, schema_execute: TPExecute) -> None:
def test_search(session: Session, execute: Execute) -> None:
session.add(Task(message="test magql", user=User(username="magql")))
session.commit()
result = schema_execute("""{ search(value: "gql") { type id value } }""")
assert result.errors is None
assert result.data == {
result = execute.expect_data("""{ search(value: "gql") { type id value } }""")
assert result == {
"search": [
{"type": "User", "id": "1", "value": "magql"},
{"type": "Task", "id": "1", "value": "test magql"},
Expand Down

0 comments on commit e0372b6

Please sign in to comment.