# Path: fmiapi/fmirequesthandler.py
# class FMIRequestHandler:
#     """
#     This class takes a data request and splits it to multiple http-requests if required and
#     does the request by using FMIRequest class.
#     """
# 
#     def __init__(self, api_key):
#         self._api_key = api_key
#         self._FMI_request = FMIRequest(self._api_key)
#         self._callbackFunction = None
# 
#     def request(self, params, max_timespan, progress_callback=None):
#         requests = self._divide_to_multiple_requests(params, max_timespan)
#         return self._execute_requests(requests, progress_callback)
# 
#     def _execute_requests(self, requests, progress_callback):
#         all_requests = len(requests)
#         responses = []
#         for i, r in enumerate(requests):
#             try:
#                 responses.append(self._do_request(r))
#                 if progress_callback is not None:
#                     progress_callback(i, all_requests)
#             except RequestException as e:
#                 # If result is 400, hope that the next request in batch will work. Raise other errors normally.
#                 # Handles case where beginning of a multipart request won't contain data
#                 # FIXME: Could be done in a way where after new lowerlimit is found, a new batch of requests is calculated instead of doing
#                 # FIXME: bunch of useless requests.
#                 print('Exception on request', e)
#                 if e.error_code != 400:
#                     raise e
#                 if progress_callback is not None:
#                     progress_callback(i, all_requests)
# 
#         return responses
# 
#     def _do_request(self, request):
#         return self._FMI_request.get(request)
# 
#     @staticmethod
#     def _divide_to_multiple_requests(params, max_timespan):
#         requests = []
#         done = False
#         i = 0
#         while not done:
#             request_params = copy.copy(params)
#             request_params["starttime"] += datetime.timedelta(hours=max_timespan)*i
#             request_params["endtime"] = request_params["starttime"] + datetime.timedelta(hours=max_timespan)
# 
#             # This additional minute to starting time is to prevent requests from fetching same time twice in
#             # the splitting point. Otherwise previous request's last time will be fetched as first in the next.
#             # FMI's service recognizes minutes as smallest significate time step so seconds or milliseconds could not
#             # be used.
#             if i > 0:
#                 request_params["starttime"] += datetime.timedelta(minutes=1)
# 
#             requests.append(request_params)
# 
#             if request_params["endtime"] > params["endtime"]:
#                 done = True
#                 request_params["endtime"] = params["endtime"]
#             i += 1
#         return requests
# 
# Path: fmiapi/fmierrors.py
# class RequestException(Exception):
# 
#     def __init__(self, text, error_code, html=""):
#         self.error_code = 0
#         self.message = text
#         self.error_code = error_code
#         self.html = html
# 
#     def __str__(self):
#         if self.html != "":
#             return self.html
#         else:
#             return self.message


from fmiapi.fmirequesthandler import FMIRequestHandler
from datetime import datetime
from tests.testUtils import *
from unittest import mock
from unittest.mock import call
from fmiapi.fmierrors import RequestException
import pytz
import pytest
                                   datetime(2011, 1, 23, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone))

        expected = [create_daily_query(datetime(2010, 1, 1, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone),
                                       datetime(2011, 1, 8, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone)),
                    create_daily_query(datetime(2011, 1, 8, hour=0, minute=2, second=0, microsecond=0, tzinfo=timezone),
                                       datetime(2011, 1, 23, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone))]

        expected_calls = [call(expected[0]), call(expected[1])]
        mock_instance = mock_fmirequest.return_value
        mock_instance.get.return_value = 'data'

        handler = FMIRequestHandler('apikey')
        result = handler.request(query, max_timespan=_DAILY_REQUEST_MAX_RANGE_HOURS, progress_callback=None)

        mock_instance.get.assert_has_calls(expected_calls)
        assert_equal(2, mock_instance.get.call_count)
        assert_equal(2, len(result))

    @mock.patch('fmiapi.fmirequesthandler.FMIRequest', spec=True)
    def should_return_available_data_if_first_part_of_request_does_not_exist(mock_fmirequest):
        query = create_daily_query(datetime(2010, 1, 1, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone),
                                   datetime(2011, 1, 23, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone))

        expected = [create_daily_query(datetime(2010, 1, 1, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone),
                                       datetime(2011, 1, 8, hour=0, minute=1, second=0, microsecond=0,
                                                tzinfo=timezone))]

        expected_calls = [call(expected[0])]
        # On first request throw exception with code 400, then return return value normally
        # Simulates query where first part is not available, but second is

# Path: fmiapi/fmirequesthandler.py
# class FMIRequestHandler:
#     """
#     This class takes a data request and splits it to multiple http-requests if required and
#     does the request by using FMIRequest class.
#     """
# 
#     def __init__(self, api_key):
#         self._api_key = api_key
#         self._FMI_request = FMIRequest(self._api_key)
#         self._callbackFunction = None
# 
#     def request(self, params, max_timespan, progress_callback=None):
#         requests = self._divide_to_multiple_requests(params, max_timespan)
#         return self._execute_requests(requests, progress_callback)
# 
#     def _execute_requests(self, requests, progress_callback):
#         all_requests = len(requests)
#         responses = []
#         for i, r in enumerate(requests):
#             try:
#                 responses.append(self._do_request(r))
#                 if progress_callback is not None:
#                     progress_callback(i, all_requests)
#             except RequestException as e:
#                 # If result is 400, hope that the next request in batch will work. Raise other errors normally.
#                 # Handles case where beginning of a multipart request won't contain data
#                 # FIXME: Could be done in a way where after new lowerlimit is found, a new batch of requests is calculated instead of doing
#                 # FIXME: bunch of useless requests.
#                 print('Exception on request', e)
#                 if e.error_code != 400:
#                     raise e
#                 if progress_callback is not None:
#                     progress_callback(i, all_requests)
# 
#         return responses
# 
#     def _do_request(self, request):
#         return self._FMI_request.get(request)
# 
#     @staticmethod
#     def _divide_to_multiple_requests(params, max_timespan):
#         requests = []
#         done = False
#         i = 0
#         while not done:
#             request_params = copy.copy(params)
#             request_params["starttime"] += datetime.timedelta(hours=max_timespan)*i
#             request_params["endtime"] = request_params["starttime"] + datetime.timedelta(hours=max_timespan)
# 
#             # This additional minute to starting time is to prevent requests from fetching same time twice in
#             # the splitting point. Otherwise previous request's last time will be fetched as first in the next.
#             # FMI's service recognizes minutes as smallest significate time step so seconds or milliseconds could not
#             # be used.
#             if i > 0:
#                 request_params["starttime"] += datetime.timedelta(minutes=1)
# 
#             requests.append(request_params)
# 
#             if request_params["endtime"] > params["endtime"]:
#                 done = True
#                 request_params["endtime"] = params["endtime"]
#             i += 1
#         return requests
# 
# Path: fmiapi/fmierrors.py
# class RequestException(Exception):
# 
#     def __init__(self, text, error_code, html=""):
#         self.error_code = 0
#         self.message = text
#         self.error_code = error_code
#         self.html = html
# 
#     def __str__(self):
#         if self.html != "":
#             return self.html
#         else:
#             return self.message


# Path: tests/fmiapi/test_fmirequesthandler.py
from fmiapi.fmirequesthandler import FMIRequestHandler
from datetime import datetime
from tests.testUtils import *
from unittest import mock
from unittest.mock import call
from fmiapi.fmierrors import RequestException
import pytz
import pytest

                                   datetime(2011, 1, 23, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone))

        expected = [create_daily_query(datetime(2010, 1, 1, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone),
                                       datetime(2011, 1, 8, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone)),
                    create_daily_query(datetime(2011, 1, 8, hour=0, minute=2, second=0, microsecond=0, tzinfo=timezone),
                                       datetime(2011, 1, 23, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone))]

        expected_calls = [call(expected[0]), call(expected[1])]
        mock_instance = mock_fmirequest.return_value
        mock_instance.get.return_value = 'data'

        handler = FMIRequestHandler('apikey')
        result = handler.request(query, max_timespan=_DAILY_REQUEST_MAX_RANGE_HOURS, progress_callback=None)

        mock_instance.get.assert_has_calls(expected_calls)
        assert_equal(2, mock_instance.get.call_count)
        assert_equal(2, len(result))

    @mock.patch('fmiapi.fmirequesthandler.FMIRequest', spec=True)
    def should_return_available_data_if_first_part_of_request_does_not_exist(mock_fmirequest):
        query = create_daily_query(datetime(2010, 1, 1, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone),
                                   datetime(2011, 1, 23, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone))

        expected = [create_daily_query(datetime(2010, 1, 1, hour=0, minute=1, second=0, microsecond=0, tzinfo=timezone),
                                       datetime(2011, 1, 8, hour=0, minute=1, second=0, microsecond=0,
                                                tzinfo=timezone))]

        expected_calls = [call(expected[0])]
        # On first request throw exception with code 400, then return return value normally
        # Simulates query where first part is not available, but second is

        mock_fmirequest.return_value.get.side_effect = [RequestException('error', 400), mock.DEFAULT]