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 PresentAPNUseCaseTests(unittest.TestCase):
    def setUp(self):
        super(PresentAPNUseCaseTests, self).setUp()
        self.repository = FakeAPNRepository()

        self.subject = PresentAPNUseCase(repository=self.repository)

    def test_present_apn_with_valid_identifier_notifies_observer(self):
        self.repository.create(county='sanfrancisco',
                               block_number='asdf',
                               lot_number='zxcv',
                               address='my special address')
        valid_apn_identifier = APNIdentifier(county='sanfrancisco',
                                             block_number='asdf',
                                             lot_number='zxcv')
        observer = FakeObserver()
        self.subject.execute(apn_identifier=valid_apn_identifier,
                             observer=observer)
        expected_apn = APN(county='sanfrancisco',
                           block_number='asdf',
                           lot_number='zxcv',
                           address='my special address')
        assert_apns_equal(observer.presented_apn, expected_apn, self)
        assert_apn_identifiers_equal(observer.presented_apn_identifier, valid_apn_identifier, self)

    def test_present_apn_with_invalid_identifier_notifies_observer(self):
        self.repository.create(county='sanfrancisco',
                               block_number='asdf',
                               lot_number='zxcv',
                               address='my special address')
        invalid_apn_identifier = APNIdentifier(county='la',
                                               block_number='asdf',
                                               lot_number='zxcv')
        observer = FakeObserver()
        self.subject.execute(apn_identifier=invalid_apn_identifier,
                             observer=observer)
        self.assertEqual(observer.exception, ValueError)
        self.assertIsNotNone(observer.context)
        assert_apn_identifiers_equal(observer.presented_apn_identifier, invalid_apn_identifier, self)
class APNRepositoryTests(unittest.TestCase):

    def setUp(self):
        super(APNRepositoryTests, self).setUp()
        self.subject = FakeAPNRepository()

    def test_fetch_apn_with_valid_identifier(self):
        self.subject.create(county='sanfrancisco',
                            block_number='0253A',
                            lot_number='086',
                            address='My special address')

        valid_apn_identifier = APNIdentifier(county='sanfrancisco',
                                             block_number='0253A',
                                             lot_number='086')
        apn = None

        def success(incoming_apn):
            nonlocal apn
            apn = incoming_apn

        def failure(x, y, z):
            return None

        self.subject.fetch_apn(apn_identifier=valid_apn_identifier,
                               success=success,
                               failure=failure)

        expected_apn = APN(county='sanfrancisco',
                           block_number='0253A',
                           lot_number='086',
                           address='My special address')

        assert_apns_equal(apn=apn,
                          other_apn=expected_apn,
                          test_case=self)

    def test_fetch_apn_with_invalid_county(self):
        self.subject.create(county='sanfrancisco',
                            block_number='0253A',
                            lot_number='086',
                            address='My special address')

        invalid_apn_identifier = APNIdentifier(county='la',
                                               block_number='0253A',
                                               lot_number='086')
        apn = None

        def success(incoming_apn):
            nonlocal apn
            apn = incoming_apn

        exception = None
        apn_identifier = None

        def failure(incoming_exception,
                    incoming_apn_identifier):
            nonlocal exception
            nonlocal apn_identifier
            exception = incoming_exception
            apn_identifier = incoming_apn_identifier

        self.subject.fetch_apn(apn_identifier=invalid_apn_identifier,
                               success=success,
                               failure=failure)

        self.assertIsNone(apn)
        self.assertEqual(exception, ValueError)
        assert_apn_identifiers_equal(apn_identifier, invalid_apn_identifier, self)

    def test_fetch_apns_list_with_valid_parameters(self):
        self.subject.create(county='sanfrancisco',
                            block_number='0253A',
                            lot_number='086',
                            address='My special address')

        apn_list = None

        def success(incoming_apn_list):
            nonlocal apn_list
            apn_list = incoming_apn_list

        self.subject.fetch_apn_list(address='My spec',
                                    county='sanfrancisco',
                                    success=success,
                                    failure=None)
        expected_apn = APN(county='sanfrancisco',
                            block_number='0253A',
                            lot_number='086',
                            address='My special address')
        assert_apn_lists_equal(apn_list, [expected_apn], self)

    def test_fetch_apns_list_with_valid_address_but_invalid_county(self):
        self.subject.create(county='sanfrancisco',
                            block_number='0253A',
                            lot_number='086',
                            address='My special address')
        apn_list = None

        def success(incoming_apn_list):
            nonlocal apn_list
            apn_list = incoming_apn_list

        self.subject.fetch_apn_list(address='My spec',
                                    county='losangeles',
                                    success=success,
                                    failure=None)
        assert_apn_lists_equal(apn_list, [], self)
 def setUp(self):
     super(APNRepositoryTests, self).setUp()
     self.subject = FakeAPNRepository()
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)
    def setUp(self):
        super(PresentAPNUseCaseTests, self).setUp()
        self.repository = FakeAPNRepository()

        self.subject = PresentAPNUseCase(repository=self.repository)