# Path: scraper/search_commands.py
# class SearchCommands(ConcurrentBase):
# 
#     _NOTIFICATION_MSG_TEMPLATE = 'SearchCommands: finished generating %s'
#     FINISHED_FIND_INMATES = _NOTIFICATION_MSG_TEMPLATE % 'find inmates commands'
#     FINISHED_CHECK_OF_RECENTLY_DISCHARGED_INMATES = \
#         _NOTIFICATION_MSG_TEMPLATE % 'check of recently discharged inmates commands'
#     FINISHED_UPDATE_INMATES_STATUS = _NOTIFICATION_MSG_TEMPLATE % 'update inmates status'
# 
#     def __init__(self, inmate_scraper, monitor):
#         super(SearchCommands, self).__init__(monitor)
#         self._inmate_scraper = inmate_scraper
# 
#     def check_if_really_discharged(self, discharged_inmates_ids):
#         self._put(self._check_if_really_discharged, discharged_inmates_ids)
# 
#     def _check_if_really_discharged(self, discharged_inmates_ids):
#         for discharged_inmate_id in discharged_inmates_ids:
#             self._inmate_scraper.resurrect_if_found(discharged_inmate_id)
#         self._notify(self.FINISHED_CHECK_OF_RECENTLY_DISCHARGED_INMATES)
# 
#     def find_inmates(self, exclude_list=None, number_to_fetch=MAX_INMATE_NUMBER, start_date=None):
#         if exclude_list is None:
#             exclude_list = []
#         if start_date is None:
#             start_date = yesterday()
#         self._put(self._find_inmates, {'excluded_inmates': exclude_list, 'number_to_fetch': number_to_fetch,
#                                        'start_date': start_date})
# 
#     def _find_inmates(self, args):
#         excluded_inmates = set(args['excluded_inmates'])
#         cur_date = args['start_date']
#         while cur_date <= yesterday():
#             for inmate_id in _jail_ids(cur_date, args['number_to_fetch']):
#                 if inmate_id not in excluded_inmates:
#                     self._inmate_scraper.create_if_exists(inmate_id)
#             cur_date += ONE_DAY
#         self._notify(self.FINISHED_FIND_INMATES)
# 
#     def update_inmates_status(self, active_inmates_ids):
#         self._put(self._update_inmates_status, active_inmates_ids)
# 
#     def _update_inmates_status(self, active_inmates_ids):
#         for inmate_id in active_inmates_ids:
#             self._inmate_scraper.update_inmate_status(inmate_id)
#         self._notify(self.FINISHED_UPDATE_INMATES_STATUS)


from mock import Mock, call
from datetime import date, timedelta
from scraper.search_commands import SearchCommands
        monitor = Mock()
        search_commands = SearchCommands(inmate_scraper, monitor)
        search_commands.update_inmates_status(jail_ids)
        assert inmate_scraper.update_inmate_status.call_args_list == expected
        assert monitor.notify.call_args_list == [call(search_commands.__class__,
                                                      search_commands.FINISHED_UPDATE_INMATES_STATUS)]

    def test_find_missing_inmates(self):
        number_to_fetch = 3
        number_days_to_fetch = 4
        start_date = date.today() - ONE_DAY * number_days_to_fetch
        jail_ids = []
        excluded_jail_ids = []
        for day_index in range(number_days_to_fetch):
            daily_jail_ids = gen_inmate_ids(start_date + ONE_DAY * day_index, number_to_fetch)
            excluded_jail_ids.append(daily_jail_ids.pop((day_index + 1) % number_to_fetch))
            jail_ids.extend(daily_jail_ids)
        expected = map(lambda x: call(x), jail_ids)
        inmate_scraper = Mock()
        monitor = Mock()
        search_commands = SearchCommands(inmate_scraper, monitor)
        search_commands.find_inmates(excluded_jail_ids, number_to_fetch=number_to_fetch, start_date=start_date)
        assert inmate_scraper.create_if_exists.call_args_list == expected
        assert monitor.notify.call_args_list == [call(search_commands.__class__, search_commands.FINISHED_FIND_INMATES)]

    def test_check_if_really_discharged(self):
        number_to_fetch = 3
        expected = expect_jail_id_calls(number_to_fetch)
        inmate_scraper = Mock()
        monitor = Mock()

# Path: scraper/search_commands.py
# class SearchCommands(ConcurrentBase):
# 
#     _NOTIFICATION_MSG_TEMPLATE = 'SearchCommands: finished generating %s'
#     FINISHED_FIND_INMATES = _NOTIFICATION_MSG_TEMPLATE % 'find inmates commands'
#     FINISHED_CHECK_OF_RECENTLY_DISCHARGED_INMATES = \
#         _NOTIFICATION_MSG_TEMPLATE % 'check of recently discharged inmates commands'
#     FINISHED_UPDATE_INMATES_STATUS = _NOTIFICATION_MSG_TEMPLATE % 'update inmates status'
# 
#     def __init__(self, inmate_scraper, monitor):
#         super(SearchCommands, self).__init__(monitor)
#         self._inmate_scraper = inmate_scraper
# 
#     def check_if_really_discharged(self, discharged_inmates_ids):
#         self._put(self._check_if_really_discharged, discharged_inmates_ids)
# 
#     def _check_if_really_discharged(self, discharged_inmates_ids):
#         for discharged_inmate_id in discharged_inmates_ids:
#             self._inmate_scraper.resurrect_if_found(discharged_inmate_id)
#         self._notify(self.FINISHED_CHECK_OF_RECENTLY_DISCHARGED_INMATES)
# 
#     def find_inmates(self, exclude_list=None, number_to_fetch=MAX_INMATE_NUMBER, start_date=None):
#         if exclude_list is None:
#             exclude_list = []
#         if start_date is None:
#             start_date = yesterday()
#         self._put(self._find_inmates, {'excluded_inmates': exclude_list, 'number_to_fetch': number_to_fetch,
#                                        'start_date': start_date})
# 
#     def _find_inmates(self, args):
#         excluded_inmates = set(args['excluded_inmates'])
#         cur_date = args['start_date']
#         while cur_date <= yesterday():
#             for inmate_id in _jail_ids(cur_date, args['number_to_fetch']):
#                 if inmate_id not in excluded_inmates:
#                     self._inmate_scraper.create_if_exists(inmate_id)
#             cur_date += ONE_DAY
#         self._notify(self.FINISHED_FIND_INMATES)
# 
#     def update_inmates_status(self, active_inmates_ids):
#         self._put(self._update_inmates_status, active_inmates_ids)
# 
#     def _update_inmates_status(self, active_inmates_ids):
#         for inmate_id in active_inmates_ids:
#             self._inmate_scraper.update_inmate_status(inmate_id)
#         self._notify(self.FINISHED_UPDATE_INMATES_STATUS)


# Path: tests/scraper/test_search_commands.py
from mock import Mock, call
from datetime import date, timedelta
from scraper.search_commands import SearchCommands

        monitor = Mock()
        search_commands = SearchCommands(inmate_scraper, monitor)
        search_commands.update_inmates_status(jail_ids)
        assert inmate_scraper.update_inmate_status.call_args_list == expected
        assert monitor.notify.call_args_list == [call(search_commands.__class__,
                                                      search_commands.FINISHED_UPDATE_INMATES_STATUS)]

    def test_find_missing_inmates(self):
        number_to_fetch = 3
        number_days_to_fetch = 4
        start_date = date.today() - ONE_DAY * number_days_to_fetch
        jail_ids = []
        excluded_jail_ids = []
        for day_index in range(number_days_to_fetch):
            daily_jail_ids = gen_inmate_ids(start_date + ONE_DAY * day_index, number_to_fetch)
            excluded_jail_ids.append(daily_jail_ids.pop((day_index + 1) % number_to_fetch))
            jail_ids.extend(daily_jail_ids)
        expected = map(lambda x: call(x), jail_ids)
        inmate_scraper = Mock()
        monitor = Mock()
        search_commands = SearchCommands(inmate_scraper, monitor)
        search_commands.find_inmates(excluded_jail_ids, number_to_fetch=number_to_fetch, start_date=start_date)
        assert inmate_scraper.create_if_exists.call_args_list == expected
        assert monitor.notify.call_args_list == [call(search_commands.__class__, search_commands.FINISHED_FIND_INMATES)]

    def test_check_if_really_discharged(self):
        number_to_fetch = 3
        expected = expect_jail_id_calls(number_to_fetch)
        inmate_scraper = Mock()
        monitor = Mock()

        search_commands = SearchCommands(inmate_scraper, monitor)