from fawrapper.requests import AioRequest
from unittest import TestCase
from aiohttp import ClientSession
from unittest import mock


async def some_async_function(return_value):
    return return_value


class MockResponse:
    def __init__(self, status, json):
        self.status = status
        self._json = json

    async def json(self):
        return self._json


class MockSession:
    def __init__(self, loop=None, response=None):
        self.loop = loop
        self.response = response or MockResponse(200, {})

    async def request(self, *args, **kwargs):
        self.called_with = {'args': args, 'kwargs': kwargs}
        return self.response

    def __call__(self):
        pass

    async def __aenter__(self):
        return self

    async def __aexit__(self, *args):
        pass



class Test_AIO_Request(TestCase):

    def setUp(self):
        self.request = AioRequest(session_class=MockSession)

    def test_can_run_async_function(self):
        expected = 'test'
        returned = self.request._run(some_async_function('test'))
        self.assertEqual(expected, returned)

    def test_can_run_multiple_async_functions(self):
        expected_1 = 'test_1'
        expected_2 = 'test_2'
        returned = self.request._run(
            some_async_function(expected_1),
            some_async_function(expected_2),
        )
        returned_1, returned_2 = returned
        self.assertEqual(expected_1, returned_1)
        self.assertEqual(expected_2, returned_2)

    def test_single_get_request(self):
        url = 'http://httpbin.org/get'
        response = self.request('get', url)
        self.assertEqual(url, response.url)
        self.assertIsNotNone(response.json)
        self.assertIsInstance(response.status_code, int)
        called_with = self.request._session.called_with
        self.assertIn(url, called_with['args'])

    def test_url_list_get_request(self):
        urls = [
            'http://httpbin.org/get',
            'http://httpbin.org/get',
        ]
        response_list = self.request('get', urls)
        for each in response_list:
            self.assertIsNotNone(each.json)
            self.assertIsNotNone(each.status_code)
            self.assertIsNotNone(each.url)
