import pytest
from django.test import Client
from django.urls import reverse
from hypothesis import given, strategies as st

from .models import Teil

names = st.text(alphabet=st.characters(exclude_categories=["C"]), min_size=1)


@given(data=names)
def test_submitted_data_ends_up_in_database(data, session: Client):
    with pytest.raises(Teil.DoesNotExist):
        Teil.objects.get(name=data)

    response = session.post(reverse("collector:enter"), data={"new_name": data})
    assert response.status_code == 302
    assert Teil.objects.get(name=data)


@given(data=names)
def test_entering_same_name_twice_does_not_change_database_entry(data, session: Client):
    assert not Teil.objects.filter(name=data).exists()

    response = session.post(reverse("collector:enter"), data={"new_name": data})
    assert response.status_code == 302
    assert Teil.objects.filter(name=data).count() == 1

    response = session.post(reverse("collector:enter"), data={"new_name": data})
    assert response.status_code == 302
    assert Teil.objects.filter(name=data).count() == 1


@pytest.mark.parametrize(
    "http_method,expected_status",
    [
        ("GET", 405),
        ("PATCH", 405),
        ("POST", 302),
        ("PUT", 405),
    ],
)
def test_enter_endpoint_accepts_only_post_requests(
    client: Client, http_method: str, expected_status: int, random_name
):
    request_method = getattr(client, http_method.lower())

    response = request_method(
        reverse("collector:enter"), data={"new_name": random_name(8)}
    )
    assert response.status_code == expected_status