import json
import unittest
from unittest.mock import patch
import finbot_proxy_adapter as adapter


class AdapterTests(unittest.TestCase):
    def test_reception_is_not_authentication(self):
        result = adapter.parse_response(b'{"status":"PACKAGE_RECEIVED_ALERT"}', 'application/json', 'GET')
        self.assertEqual(result['interpretation'], 'RECEPTION_ACKNOWLEDGED')
        self.assertFalse(result['exchange_authentication_verified'])

    def test_mock_commit_is_not_execution(self):
        raw = json.dumps({'status': 'VERIFIED_AND_COMMITTED', 'order_id': 'MOCK_UPSTREAM_EXECUTION_ID'}).encode()
        result = adapter.parse_response(raw, 'application/json; charset=utf-8', 'POST')
        self.assertEqual(result['interpretation'], 'MOCK_RESPONSE_RECEIVED')
        self.assertFalse(result['broker_order_verified'])
        self.assertFalse(result['ledger_commit_verified'])

    def test_html_duplicate_unknown_nonfinite_and_large_rejected(self):
        cases = [(b'<html>ok</html>', 'text/html'),
                 (b'{"status":"PACKAGE_RECEIVED_ALERT","status":"PACKAGE_RECEIVED_ALERT"}', 'application/json'),
                 (b'{"status":"PROXY_ACTIVE"}', 'application/json'),
                 (b'{"status":"PACKAGE_RECEIVED_ALERT","value":NaN}', 'application/json'),
                 (b' ' * (adapter.MAX_RESPONSE_BYTES + 1), 'application/json')]
        for raw, mime in cases:
            with self.subTest(raw=raw[:40]), self.assertRaises(adapter.ProtocolError):
                adapter.parse_response(raw, mime, 'GET')

    def test_real_looking_order_id_rejected(self):
        with self.assertRaises(adapter.ProtocolError):
            adapter.parse_response(b'{"status":"VERIFIED_AND_COMMITTED","order_id":"real-id"}', 'application/json', 'POST')

    def test_order_submission_cannot_open_transport(self):
        with patch('urllib.request.build_opener') as transport:
            with self.assertRaises(adapter.ProtocolError):
                adapter.submit_order(symbol='TEST', qty='1')
            transport.assert_not_called()

    def test_redirects_not_followed(self):
        self.assertIsNone(adapter.NoRedirect().redirect_request(None, None, 302, '', {}, 'https://example.com'))


if __name__ == '__main__':
    unittest.main()
