From d1d654ebac2d51e3841675faeb56480e440f622f Mon Sep 17 00:00:00 2001 From: Wolfgang Müller Date: Tue, 5 Mar 2024 18:08:09 +0100 Subject: Initial commit --- tests/api/test_circle.py | 278 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 tests/api/test_circle.py (limited to 'tests/api/test_circle.py') diff --git a/tests/api/test_circle.py b/tests/api/test_circle.py new file mode 100644 index 0000000..a03ba89 --- /dev/null +++ b/tests/api/test_circle.py @@ -0,0 +1,278 @@ +from datetime import datetime as dt +from datetime import timezone + +import pytest +from conftest import DB, Response +from hircine.db.models import Circle + + +@pytest.fixture +def query_circle(execute_id): + query = """ + query circle($id: Int!) { + circle(id: $id) { + __typename + ... on Circle { + id + name + } + ... on Error { + message + } + ... on IDNotFoundError { + id + } + } + } + """ + + return execute_id(query) + + +@pytest.fixture +def query_circles(execute): + query = """ + query circles { + circles { + __typename + count + edges { + id + name + } + } + } + """ + + return execute(query) + + +@pytest.fixture +def add_circle(execute_add): + mutation = """ + mutation addCircle($input: AddCircleInput!) { + addCircle(input: $input) { + __typename + ... on AddSuccess { + id + } + ... on Error { + message + } + ... on InvalidParameterError { + parameter + } + } + } + """ + + return execute_add(mutation) + + +@pytest.fixture +def update_circles(execute_update): + mutation = """ + mutation updateCircles($ids: [Int!]!, $input: UpdateCircleInput!) { + updateCircles(ids: $ids, input: $input) { + __typename + ... on Success { + message + } + ... on IDNotFoundError { + id + } + ... on Error { + message + } + ... on InvalidParameterError { + parameter + } + } + } + """ # noqa: E501 + + return execute_update(mutation) + + +@pytest.fixture +def delete_circles(execute_delete): + mutation = """ + mutation deleteCircles($ids: [Int!]!) { + deleteCircles(ids: $ids) { + __typename + ... on Success { + message + } + ... on Error { + message + } + ... on IDNotFoundError { + id + } + } + } + """ + + return execute_delete(mutation) + + +@pytest.mark.anyio +async def test_query_circle(query_circle, gen_circle): + circle = await DB.add(next(gen_circle)) + + response = Response(await query_circle(circle.id)) + response.assert_is("Circle") + + assert response.id == circle.id + assert response.name == circle.name + + +@pytest.mark.anyio +async def test_query_circle_fails_not_found(query_circle): + response = Response(await query_circle(1)) + response.assert_is("IDNotFoundError") + assert response.id == 1 + assert response.message == "Circle ID not found: '1'" + + +@pytest.mark.anyio +async def test_query_circles(query_circles, gen_circle): + circles = await DB.add_all(*gen_circle) + + response = Response(await query_circles()) + response.assert_is("CircleFilterResult") + + assert response.count == len(circles) + assert isinstance((response.edges), list) + assert len(response.edges) == len(circles) + + edges = iter(response.edges) + for circle in sorted(circles, key=lambda a: a.name): + edge = next(edges) + assert edge["id"] == circle.id + assert edge["name"] == circle.name + + +@pytest.mark.anyio +async def test_add_circle(add_circle): + response = Response(await add_circle({"name": "added circle"})) + response.assert_is("AddSuccess") + + circle = await DB.get(Circle, response.id) + assert circle is not None + assert circle.name == "added circle" + + +@pytest.mark.anyio +async def test_add_circle_fails_empty_parameter(add_circle): + response = Response(await add_circle({"name": ""})) + + response.assert_is("InvalidParameterError") + assert response.parameter == "name" + assert response.message == "Invalid parameter 'name': cannot be empty" + + +@pytest.mark.anyio +async def test_add_circle_fails_exists(add_circle, gen_circle): + circle = await DB.add(next(gen_circle)) + + response = Response(await add_circle({"name": circle.name})) + response.assert_is("NameExistsError") + assert response.message == "Another Circle with this name exists" + + +@pytest.mark.anyio +async def test_delete_circle(delete_circles, gen_circle): + circle = await DB.add(next(gen_circle)) + id = circle.id + + response = Response(await delete_circles(id)) + response.assert_is("DeleteSuccess") + + circle = await DB.get(Circle, id) + assert circle is None + + +@pytest.mark.anyio +async def test_delete_circle_not_found(delete_circles): + response = Response(await delete_circles(1)) + + response.assert_is("IDNotFoundError") + assert response.id == 1 + assert response.message == "Circle ID not found: '1'" + + +@pytest.mark.anyio +async def test_update_circle(update_circles, gen_circle): + circle = await DB.add(next(gen_circle)) + + input = {"name": "updated circle"} + response = Response(await update_circles(circle.id, input)) + response.assert_is("UpdateSuccess") + + circle = await DB.get(Circle, circle.id) + assert circle is not None + assert circle.name == "updated circle" + + +@pytest.mark.anyio +async def test_update_circle_fails_exists(update_circles, gen_circle): + first = await DB.add(next(gen_circle)) + second = await DB.add(next(gen_circle)) + + response = Response(await update_circles(second.id, {"name": first.name})) + response.assert_is("NameExistsError") + assert response.message == "Another Circle with this name exists" + + +@pytest.mark.anyio +async def test_update_circle_fails_not_found(update_circles): + response = Response(await update_circles(1, {"name": "updated circle"})) + + response.assert_is("IDNotFoundError") + assert response.id == 1 + assert response.message == "Circle ID not found: '1'" + + +@pytest.mark.anyio +async def test_update_circles_cannot_bulk_edit_name(update_circles, gen_circle): + first = await DB.add(next(gen_circle)) + second = await DB.add(next(gen_circle)) + + response = Response(await update_circles([first.id, second.id], {"name": "unique"})) + response.assert_is("InvalidParameterError") + + +@pytest.mark.parametrize( + "empty", + [ + None, + "", + ], + ids=[ + "none", + "empty string", + ], +) +@pytest.mark.anyio +async def test_update_circle_fails_empty_parameter(update_circles, gen_circle, empty): + circle = await DB.add(next(gen_circle)) + + response = Response(await update_circles(circle.id, {"name": empty})) + + response.assert_is("InvalidParameterError") + assert response.parameter == "name" + assert response.message == "Invalid parameter 'name': cannot be empty" + + +@pytest.mark.anyio +async def test_update_circle_changes_updated_at(update_circles): + original_circle = Circle(name="circle") + original_circle.updated_at = dt(2023, 1, 1, tzinfo=timezone.utc) + original_circle = await DB.add(original_circle) + + response = Response(await update_circles(original_circle.id, {"name": "updated"})) + response.assert_is("UpdateSuccess") + + circle = await DB.get(Circle, original_circle.id) + assert circle.updated_at > original_circle.updated_at -- cgit v1.2.3-2-gb3c3