import json
from unittest import TestCase

from tornado_stub_client import reset, stub
from tornado_stub_client.collection import RequestCollection


class CommandsTest(TestCase):
    """the stub() command is actually a class who's initializer returns
    itself, so we can do stub().and_return() in a ruby rspec mock fashion
    """

    def setUp(self):
        reset()

    def test_init_stub(self):
        s = stub("/hello")
        self.assertIsInstance(s, stub)
        self.assertEqual(s.request.url, "/hello")

    def test_init_add_and_return(self):
        st = stub("/hello")
        req = st.request
        st = st.and_return(body=b"foobar body")
        response = st.response_partial(req)
        self.assertEqual(response.code, 200)
        self.assertEqual(response.body, b"foobar body")
        self.assertEqual(response.request.url, "/hello")

    def test_stub_no_return_doesnt_add_to_collection(self):
        st = stub("/hello")
        self.assertIsNotNone(st.request)
        resp_partial = RequestCollection.find(st.request)
        self.assertIsNone(resp_partial)

    def test_stub_with_method(self):
        st = stub("/hello", method="POST").and_return(body=b"anything")
        resp_partial = RequestCollection.find(st.request)
        self.assertIsNotNone(resp_partial)

    def test_return_with_body_json(self):
        st = stub("/hello").and_return(body_json={'name': 'somebody'})
        resp_partial = RequestCollection.find(st.request)
        resp = resp_partial(st.request)
        self.assertEqual(json.loads(resp.body.decode()).get('name'), 'somebody')

    def test_no_body(self):
        st = stub("/hello").and_return(body=None)
        resp_partial = RequestCollection.find(st.request)
        resp = resp_partial(st.request)
        self.assertEqual(resp.body, b'')

    def test_no_return_args(self):
        st = stub("/hello").and_return()
        resp_partial = RequestCollection.find(st.request)
        resp = resp_partial(st.request)
        self.assertEqual(resp.body, b'')

    def test_set_response_code_in_stub(self):
        st = stub("/hello").and_return(code=418)
        resp_partial = RequestCollection.find(st.request)
        resp = resp_partial(st.request)
        self.assertEqual(resp.code, 418)
