import asyncio
import logging
from functools import partial
from unittest import mock

import pytest

from raven_aiohttp import QueuedAioHttpTransport
from tests.utils import Logger

pytestmark = pytest.mark.asyncio


@asyncio.coroutine
def test_basic(fake_server, raven_client, wait):
    server = yield from fake_server()

    client, transport = raven_client(server, QueuedAioHttpTransport)

    try:
        1 / 0
    except ZeroDivisionError:
        client.captureException()

    yield from wait(transport)

    assert server.hits[200] == 1


@asyncio.coroutine
def test_no_keepalive(fake_server, raven_client, wait):
    transport = QueuedAioHttpTransport(keepalive=False)
    assert not hasattr(transport, '_client_session')
    yield from transport.close()

    server = yield from fake_server()

    client, transport = raven_client(server, QueuedAioHttpTransport)
    transport._keepalive = False
    session = transport._client_session

    def _client_session_factory():
        return session

    with mock.patch(
        'raven_aiohttp.QueuedAioHttpTransport._client_session_factory',
        side_effect=_client_session_factory,
    ):
        try:
            1 / 0
        except ZeroDivisionError:
            client.captureException()

        yield from wait(transport)

        assert session.closed

        assert server.hits[200] == 1


@asyncio.coroutine
def test_close_timeout(fake_server, raven_client):
    server = yield from fake_server()
    server.slop_factor = 100

    client, transport = raven_client(server, QueuedAioHttpTransport)

    try:
        1 / 0
    except ZeroDivisionError:
        client.captureException()

    yield from transport.close(timeout=0)

    assert server.hits[200] == 0


@asyncio.coroutine
def test_rate_limit(fake_server, raven_client, wait):
    server = yield from fake_server()
    server.side_effect['status'] = 429

    with Logger('sentry.errors', level=logging.ERROR) as log:
        client, transport = raven_client(server, QueuedAioHttpTransport)

        try:
            1 / 0
        except ZeroDivisionError:
            client.captureException()

        yield from wait(transport)

        assert server.hits[429] == 1