def setUp(self):
        super(PresentSearchResultsUseCaseTests, self).setUp()
        self.search_repository = FakeSearchRepository()
        self.apn_repository = FakeAPNRepository()
        present_apns_with_address_use_case = PresentAPNSWithAddressUseCase(apn_repository=self.apn_repository)

        self.subject = PresentSearchResultsUseCase(search_repository=self.search_repository,
                                                   present_apns_with_address_use_case=present_apns_with_address_use_case)
class PresentSearchResultsUseCaseTests(unittest.TestCase):
    def setUp(self):
        super(PresentSearchResultsUseCaseTests, self).setUp()
        self.search_repository = FakeSearchRepository()
        self.apn_repository = FakeAPNRepository()
        present_apns_with_address_use_case = PresentAPNSWithAddressUseCase(apn_repository=self.apn_repository)

        self.subject = PresentSearchResultsUseCase(search_repository=self.search_repository,
                                                   present_apns_with_address_use_case=present_apns_with_address_use_case)

    def test_present_search_with_valid_parameters_notifies_observer_of_success(self):
        identifier = None
        search = None

        self.apn_repository.create(county='sanfrancisco',
                                   block_number='001A',
                                   lot_number='001',
                                   address='1240 Jones St #132')

        self.apn_repository.create(county='sanfrancisco',
                                   block_number='001A',
                                   lot_number='002',
                                   address='1240 Jones St #133')

        def create_success(incoming_identifier, incoming_search):
            nonlocal identifier
            nonlocal search
            identifier = incoming_identifier
            search = incoming_search

        self.search_repository.create_search(county='sanfrancisco',
                                             address='1240 Jones St',
                                             success=create_success,
                                             failure=None)
        observer = FakeObserver()
        self.subject.execute(identifier=identifier,
                             observer=observer)
        expected_search = Search(county='sanfrancisco',
                                 address='1240 Jones St')

        expected_apn_0 = APN(county='sanfrancisco',
                             block_number='001A',
                             lot_number='001',
                             address='1240 Jones St #132')
        expected_apn_1 = APN(county='sanfrancisco',
                             block_number='001A',
                             lot_number='002',
                             address='1240 Jones St #133')

        assert_searches_equal(observer.presented_search, expected_search, self)
        assert_apn_lists_equal(observer.presented_apn_results, [expected_apn_0, expected_apn_1], self)

    def test_present_search_with_a_bad_address_notifies_observer_of_success_but_no_results(self):
        identifier = None
        search = None

        self.apn_repository.create(county='sanfrancisco',
                                   block_number='001A',
                                   lot_number='001',
                                   address='1240 Jones St #132')

        self.apn_repository.create(county='sanfrancisco',
                                   block_number='001A',
                                   lot_number='002',
                                   address='1240 Jones St #133')

        def create_success(incoming_identifier, incoming_search):
            nonlocal identifier
            nonlocal search
            identifier = incoming_identifier
            search = incoming_search

        self.search_repository.create_search(county='sanfrancisco',
                                             address='1241 Jones St',
                                             success=create_success,
                                             failure=None)
        observer = FakeObserver()
        self.subject.execute(identifier=identifier,
                             observer=observer)
        expected_search = Search(county='sanfrancisco',
                                 address='1241 Jones St')

        assert_searches_equal(observer.presented_search, expected_search, self)
        assert_apn_lists_equal(observer.presented_apn_results, [], self)

    def test_present_search_with_with_valid_params_and_one_valid_result_works(self):
        identifier = None
        search = None

        self.apn_repository.create(county='sanfrancisco',
                                   block_number='001A',
                                   lot_number='001',
                                   address='1240 Jones St #132')

        self.apn_repository.create(county='sanfrancisco',
                                   block_number='001A',
                                   lot_number='002',
                                   address='1240 Jones St #133')

        def create_success(incoming_identifier, incoming_search):
            nonlocal identifier
            nonlocal search
            identifier = incoming_identifier
            search = incoming_search

        self.search_repository.create_search(county='sanfrancisco',
                                             address='1240 Jones St #133',
                                             success=create_success,
                                             failure=None)
        observer = FakeObserver()
        self.subject.execute(identifier=identifier,
                             observer=observer)
        expected_search = Search(county='sanfrancisco',
                                 address='1240 Jones St #133')
        expected_apn = APN(county='sanfrancisco',
                           block_number='001A',
                           lot_number='002',
                           address='1240 Jones St #133')

        assert_searches_equal(observer.presented_search, expected_search, self)
        assert_apn_lists_equal(observer.presented_apn_results, [expected_apn], self)

    def test_present_search_with_invalid_identifier_notifies_observer_of_failure(self):
        identifier = None
        search = None

        def create_success(incoming_identifier, incoming_search):
            nonlocal identifier
            nonlocal search
            identifier = incoming_identifier
            search = incoming_search

        self.search_repository.create_search(county='sanfrancisco',
                                      address='my special address',
                                      success=create_success,
                                      failure=None)
        observer = FakeObserver()
        self.subject.execute(identifier='silly_identifier',
                             observer=observer)
        expected_search = Search(county='sanfrancisco',
                                 address='my special address')
        self.assertEqual(observer.exception, ValueError)