class CreateSearchUseCaseTests(unittest.TestCase):
    def setUp(self):
        super(CreateSearchUseCaseTests, self).setUp()
        self.repository = FakeSearchRepository()

        self.subject = CreateSearchUseCase(search_repository=self.repository)

    def test_create_search_with_valid_county_and_address_notifies_observer(self):
        observer = FakeCreateObserver()
        self.subject.execute(address="125 Jones St", county="sanfrancisco", observer=observer)

        search = None

        def fetch_success(incoming_search):
            nonlocal search
            search = incoming_search

        fetch_failure = lambda x, y: None
        self.repository.fetch_search(
            identifier=observer.created_identifier, success=fetch_success, failure=fetch_failure
        )

        expected_fetched_search = Search(county="sanfrancisco", address="125 Jones St")

        assert_searches_equal(observer.created_search, expected_fetched_search, self)
class SearchRepositoryTests(unittest.TestCase):

    def setUp(self):
        super(SearchRepositoryTests, self).setUp()
        self.subject = FakeSearchRepository()


    def test_create_search_with_valid_county_and_address(self):
        search_identifier = None
        search = None
        def create_success(incoming_search_identifier, incoming_search):
            nonlocal search_identifier
            nonlocal search
            search_identifier = incoming_search_identifier
            search = incoming_search

        failure_called = False
        def create_failure(x, y):
            nonlocal failure_called
            failure_called = True

        self.subject.create_search(county='sanfrancisco',
                                   address='125 Jones St',
                                   success=create_success,
                                   failure=create_failure)
        self.assertFalse(failure_called)
        self.assertIsNotNone(search_identifier)

        expected_search = Search(address='125 Jones St',
                                 county='sanfrancisco',)

        assert_searches_equal(search, expected_search, self)

        search = None
        def fetch_success(incoming_search):
            nonlocal search
            search = incoming_search

        exception = None
        context = None
        def fetch_failure(incoming_exception, incoming_context):
            nonlocal search
            exception = incoming_exception
            context = incoming_context

        self.subject.fetch_search(identifier=search_identifier,
                                  success=fetch_success,
                                  failure=fetch_failure)

        assert_searches_equal(search, expected_search, self)
        self.assertIsNone(exception)
        self.assertIsNone(context)
    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 setUp(self):
     super(SearchRepositoryTests, self).setUp()
     self.subject = FakeSearchRepository()
    def setUp(self):
        super(CreateSearchUseCaseTests, self).setUp()
        self.repository = FakeSearchRepository()

        self.subject = CreateSearchUseCase(search_repository=self.repository)
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)