summaryrefslogblamecommitdiffstatshomepage
path: root/tests/api/test_artist.py
blob: fa5801205d13f112f81a4306d8df76f254b55609 (plain) (tree)
1
2
3
4
5
6




                                   
 
















































































































































































































































































                                                                                        
from datetime import datetime as dt
from datetime import timezone

import pytest
from conftest import DB, Response

from hircine.db.models import Artist


@pytest.fixture
def query_artist(execute_id):
    query = """
    query artist($id: Int!) {
        artist(id: $id) {
            __typename
            ... on Artist {
                id
                name
            }
            ... on Error {
                message
            }
            ... on IDNotFoundError {
                id
            }
        }
    }
    """

    return execute_id(query)


@pytest.fixture
def query_artists(execute):
    query = """
    query artists {
        artists {
            __typename
            count
            edges {
                id
                name
            }
        }
    }
    """

    return execute(query)


@pytest.fixture
def add_artist(execute_add):
    mutation = """
    mutation addArtist($input: AddArtistInput!) {
        addArtist(input: $input) {
            __typename
            ... on AddSuccess {
                id
            }
            ... on Error {
                message
            }
            ... on InvalidParameterError {
                parameter
            }
        }
    }
    """

    return execute_add(mutation)


@pytest.fixture
def update_artists(execute_update):
    mutation = """
    mutation updateArtists($ids: [Int!]!, $input: UpdateArtistInput!) {
        updateArtists(ids: $ids, input: $input) {
            __typename
            ... on Success {
                message
            }
            ... on Error {
                message
            }
            ... on IDNotFoundError {
                id
            }
            ... on InvalidParameterError {
                parameter
            }
        }
    }
    """  # noqa: E501

    return execute_update(mutation)


@pytest.fixture
def delete_artists(execute_delete):
    mutation = """
    mutation deleteArtists($ids: [Int!]!) {
        deleteArtists(ids: $ids) {
            __typename
            ... on Success {
                message
            }
            ... on Error {
                message
            }
            ... on IDNotFoundError {
                id
            }
        }
    }
    """

    return execute_delete(mutation)


@pytest.mark.anyio
async def test_query_artist(query_artist, gen_artist):
    artist = await DB.add(next(gen_artist))

    response = Response(await query_artist(artist.id))
    response.assert_is("Artist")

    assert response.id == artist.id
    assert response.name == artist.name


@pytest.mark.anyio
async def test_query_artist_fails_not_found(query_artist):
    response = Response(await query_artist(1))
    response.assert_is("IDNotFoundError")
    assert response.id == 1
    assert response.message == "Artist ID not found: '1'"


@pytest.mark.anyio
async def test_query_artists(query_artists, gen_artist):
    artists = await DB.add_all(*gen_artist)

    response = Response(await query_artists())
    response.assert_is("ArtistFilterResult")

    assert response.count == len(artists)
    assert isinstance((response.edges), list)
    assert len(response.edges) == len(artists)

    edges = iter(response.edges)
    for artist in sorted(artists, key=lambda a: a.name):
        edge = next(edges)
        assert edge["id"] == artist.id
        assert edge["name"] == artist.name


@pytest.mark.anyio
async def test_add_artist(add_artist):
    response = Response(await add_artist({"name": "added artist"}))
    response.assert_is("AddSuccess")

    artist = await DB.get(Artist, response.id)
    assert artist is not None
    assert artist.name == "added artist"


@pytest.mark.anyio
async def test_add_artist_fails_empty_parameter(add_artist):
    response = Response(await add_artist({"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_artist_fails_exists(add_artist, gen_artist):
    artist = await DB.add(next(gen_artist))

    response = Response(await add_artist({"name": artist.name}))
    response.assert_is("NameExistsError")
    assert response.message == "Another Artist with this name exists"


@pytest.mark.anyio
async def test_delete_artist(delete_artists, gen_artist):
    artist = await DB.add(next(gen_artist))
    id = artist.id

    response = Response(await delete_artists(id))
    response.assert_is("DeleteSuccess")

    artist = await DB.get(Artist, id)
    assert artist is None


@pytest.mark.anyio
async def test_delete_artist_not_found(delete_artists):
    response = Response(await delete_artists(1))

    response.assert_is("IDNotFoundError")
    assert response.id == 1
    assert response.message == "Artist ID not found: '1'"


@pytest.mark.anyio
async def test_update_artist(update_artists, gen_artist):
    artist = await DB.add(next(gen_artist))

    input = {"name": "updated artist"}
    response = Response(await update_artists(artist.id, input))
    response.assert_is("UpdateSuccess")

    artist = await DB.get(Artist, artist.id)
    assert artist is not None
    assert artist.name == "updated artist"


@pytest.mark.anyio
async def test_update_artist_fails_exists(update_artists, gen_artist):
    first = await DB.add(next(gen_artist))
    second = await DB.add(next(gen_artist))

    response = Response(await update_artists(second.id, {"name": first.name}))
    response.assert_is("NameExistsError")
    assert response.message == "Another Artist with this name exists"


@pytest.mark.anyio
async def test_update_artist_fails_not_found(update_artists):
    response = Response(await update_artists(1, {"name": "updated artist"}))

    response.assert_is("IDNotFoundError")
    assert response.id == 1
    assert response.message == "Artist ID not found: '1'"


@pytest.mark.anyio
async def test_update_artists_cannot_bulk_edit_name(update_artists, gen_artist):
    first = await DB.add(next(gen_artist))
    second = await DB.add(next(gen_artist))

    response = Response(await update_artists([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_artist_fails_empty_parameter(update_artists, gen_artist, empty):
    artist = await DB.add(next(gen_artist))

    response = Response(await update_artists(artist.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_artist_changes_updated_at(update_artists):
    original_artist = Artist(name="artist")
    original_artist.updated_at = dt(2023, 1, 1, tzinfo=timezone.utc)
    original_artist = await DB.add(original_artist)

    response = Response(await update_artists(original_artist.id, {"name": "updated"}))
    response.assert_is("UpdateSuccess")

    artist = await DB.get(Artist, original_artist.id)
    assert artist.updated_at > original_artist.updated_at