def setUp(self): self.no_addresses_rh = RoutingHelper("") self.zero_stations_rh = RoutingHelper("") self.zero_stations_rh.addresses = [ MockAddress( address="", postcode="", council="", uprn="", polling_station_id="", location="", ) for _ in range(3) ] self.one_station_rh = RoutingHelper("") self.one_station_rh.addresses = [ MockAddress( address="", postcode="", council="", uprn="", polling_station_id="1A", location="", ) for _ in range(3) ] self.three_stations_rh = RoutingHelper("") self.three_stations_rh.addresses = [ MockAddress( address="", postcode="", council="", uprn="", polling_station_id=f"{x}A", location="", ) for x in range(3) ]
def test_canonical_url(self): rh = RoutingHelper("CC11AA") request = mock.Mock() request.GET = QueryDict("utm_source=foo&something=other") # Could be either uprn self.assertRegex(rh.get_canonical_url(request), r"/address/10[23]/\?utm_source=foo")
def test_canonical_url_without_preserve(self): rh = RoutingHelper("AA11AA") request = mock.Mock() request.GET = QueryDict("utm_source=foo&something=other") # Could be either slug self.assertRegex(rh.get_canonical_url(request, preserve_query=False), r"/address/[12]/")
def test_make_addresses_for_postcode(self): # Before the fix, we wrongly assume that we know the polling station postcode = 'KW15 88TF' rh = RoutingHelper(postcode) endpoint = rh.get_endpoint() self.assertEqual('postcode_view', endpoint.view) # Fix the addresses outside of the districts make_addresses_for_postcode(postcode, council_id="X01000001") # Now we should get offered an address lookup rh = RoutingHelper(postcode) endpoint = rh.get_endpoint() self.assertEqual('address_select_view', endpoint.view)
def test_make_addresses_for_postcode(self): # Before the fix, we wrongly assume that we know the polling station postcode = "KW15 88TF" rh = RoutingHelper(postcode) self.assertEqual("postcode_view", rh.view) # Fix the addresses outside of the districts fixer = EdgeCaseFixer("X01000001", MockLogger()) fixer.make_addresses_for_postcode(postcode) fixer.get_address_set().save(1000) # Now we should get offered an address lookup rh = RoutingHelper(postcode) self.assertEqual("address_select_view", rh.view)
def test_polling_stations(self): rh = RoutingHelper("") # for data in [("1", "0"), ("2", "1"), ("3", "2"), ("4", "2"), ("5","")]: # Address.objects.update_or_create(pk = data[0]) # rh.addresses = [ MockAddress( address="", postcode="", council="", uprn="", polling_station_id=x, location="", ) for x in ["0", "1", "2", "2", ""] ] # Count duplicate polling stations once & Make sure we include the "blank" polling stations self.assertEqual(len(rh.addresses), 5) self.assertEqual({"0", "1", "2", ""}, rh.polling_stations)
def test_multiple_councils_view_override(self): # insert blacklist records for postcodes matching other conditions Blacklist.objects.create(postcode="AA11AA", lad="X01000001") Blacklist.objects.create(postcode="AA11AA", lad="W06000022") Blacklist.objects.create(postcode="BB11BB", lad="X01000001") Blacklist.objects.create(postcode="BB11BB", lad="W06000022") Blacklist.objects.create(postcode="CC11CC", lad="X01000001") Blacklist.objects.create(postcode="CC11CC", lad="W06000022") # check the blacklist overrides all other conditions rh = RoutingHelper("AA11AA") self.assertEqual("multiple_councils_view", rh.view) rh = RoutingHelper("BB11BB") self.assertEqual("multiple_councils_view", rh.view) rh = RoutingHelper("CC11CC") self.assertEqual("multiple_councils_view", rh.view)
def test_single_address_single_polling_station(self): postcode_base = "AA1 1AA" postcodes = [ postcode_base, postcode_base.lower(), postcode_base.replace(" ", ""), postcode_base.replace(" ", "").lower(), ] for postcode in postcodes: rh = RoutingHelper(postcode) self.assertEqual("address_view", rh.view)
def retrieve(self, requst, pk=None, format=None): postcode = pk.replace(' ', '') ret = {} ret['polling_station_known'] = False polling_station = None try: l = geocode(pk) except (PostcodeError, RateLimitError) as e: ret['error'] = e.args[0] return Response(ret) location = Point(l['wgs84_lon'], l['wgs84_lat']) ret['postcode_location'] = PointField().to_representation( location) ret['council'] = CouncilSerializer(Council.objects.get( area__covers=location)).data rh = RoutingHelper(postcode) if rh.route_type == "multiple_addresses": ret['addresses'] = [ ResidentialAddressSerializer(address, context={ 'request': self.request} ).data for address in rh.addresses ] if rh.route_type == "single_address": polling_station = rh.addresses[0] if rh.route_type == "postcode": polling_station = self.get_queryset( location=location, council=ret['council'], ) if polling_station: ret['polling_station_known'] = True ret['polling_station'] = PollingStationSerializer( polling_station, context={'request': self.request}).data if not ret['polling_station_known']: finder = CustomFinder.objects.get_custom_finder(l['gss_codes'], postcode) if finder and finder.base_url: ret['custom_finder'] = {} ret['custom_finder']['base_url'] = finder.base_url ret['custom_finder']['can_pass_postcode'] = finder.can_pass_postcode ret['custom_finder']['encoded_postcode'] = finder.encoded_postcode return Response(ret)
def get_context_data(self, postcode, **kwargs): postcode = Postcode(postcode) addresses = Address.objects.filter(postcode=postcode.with_space) unassigned_addresses = [ a for a in addresses if not a.polling_station_id ] addresses = [a for a in addresses if a.polling_station_id] return { "postcode": postcode, "addresses": addresses, "unassigned_addresses": unassigned_addresses, "routing_helper": RoutingHelper(postcode), }
def get_context_data(self, postcode, **kwargs): residential_addresses = ResidentialAddress.objects.filter( postcode=postcode) addresses = dict( Address.objects.filter(uprn__in=residential_addresses.values_list( "uprn", flat=True)).values_list("uprn", "address")) for residential_address in residential_addresses: residential_address.addressbase_address = addresses.get( residential_address.uprn) return { "postcode": postcode, "addresses": residential_addresses, "routing_helper": RoutingHelper(postcode), }
def test_multiple_councils_view_override(self): # insert blacklist records for postcodes matching other conditions Blacklist.objects.create(postcode='AA11AA', lad='X01000001') Blacklist.objects.create(postcode='AA11AA', lad='W06000022') Blacklist.objects.create(postcode='BB11BB', lad='X01000001') Blacklist.objects.create(postcode='BB11BB', lad='W06000022') Blacklist.objects.create(postcode='CC11CC', lad='X01000001') Blacklist.objects.create(postcode='CC11CC', lad='W06000022') # check the blacklist overrides all other conditions rh = RoutingHelper('AA11AA') endpoint = rh.get_endpoint() self.assertEqual('multiple_councils_view', endpoint.view) rh = RoutingHelper('BB11BB') endpoint = rh.get_endpoint() self.assertEqual('multiple_councils_view', endpoint.view) rh = RoutingHelper('CC11CC') endpoint = rh.get_endpoint() self.assertEqual('multiple_councils_view', endpoint.view)
def test_multiple_councils_lowercase_postcode(self): # check we are directed to multiple_councils_view if # postcode is attached to multiple councils in the blacklist rh = RoutingHelper("dd11dd") endpoint = rh.get_endpoint() self.assertEqual("multiple_councils_view", endpoint.view)
def test_postcode_view(self): rh = RoutingHelper("CC11CC") endpoint = rh.get_endpoint() self.assertEqual("postcode_view", endpoint.view)
def test_address_select_view(self): rh = RoutingHelper("BB11BB") endpoint = rh.get_endpoint() self.assertEqual("address_select_view", endpoint.view)
def test_address_select_view(self): rh = RoutingHelper('BB11BB') endpoint = rh.get_endpoint() self.assertEqual('address_select_view', endpoint.view)
def test_address_view(self): rh = RoutingHelper('AA11AA') endpoint = rh.get_endpoint() self.assertEqual('address_view', endpoint.view)
def test_address_select_view(self): rh = RoutingHelper("BB11BB") self.assertEqual("address_select_view", rh.view)
def retrieve(self, request, postcode=None, format=None, geocoder=geocode, log=True): postcode = Postcode(postcode) ret = {} rh = RoutingHelper(postcode) # attempt to attach point and gss_codes try: loc = geocoder(postcode) location = loc.centroid except PostcodeError as e: if rh.route_type == "single_address": loc = None location = None else: return Response({"detail": e.args[0]}, status=400) except MultipleCouncilsException: loc = None location = None ret["postcode_location"] = location # council object if rh.route_type == "multiple_councils" or not loc: # We can't assign this postcode to exactly one council council = None else: try: council = get_council(loc) except ObjectDoesNotExist: return Response({"detail": "Internal server error"}, 500) ret["council"] = council ret["addresses"] = self.generate_addresses(rh) ret["polling_station_known"] = False ret["polling_station"] = None ee = self.get_ee_wrapper(postcode) has_election = ee.has_election() if has_election: # get polling station if there is an election in this area ret["polling_station_known"] = False ret["polling_station"] = self.generate_polling_station( rh, council, location) if ret["polling_station"]: ret["polling_station_known"] = True if ret["polling_station"] and not ret["council"]: ret["council"] = ret["polling_station"].council # get custom finder (if no polling station) ret["custom_finder"] = None if not ret["polling_station_known"] and loc: ret["custom_finder"] = self.generate_custom_finder(loc, postcode) ret["metadata"] = ee.get_metadata() if request.query_params.get("all_future_ballots", None): ret["ballots"] = ee.get_all_ballots() else: ret["ballots"] = ee.get_ballots_for_next_date() # create log entry log_data = {} log_data["we_know_where_you_should_vote"] = ret[ "polling_station_known"] log_data["location"] = location log_data["council"] = council log_data["brand"] = "api" log_data["language"] = "" log_data["api_user"] = request.user log_data["has_election"] = has_election if log: if not ret["addresses"]: self.log_postcode(postcode, log_data, "api") # don't log 'address select' hits ret["report_problem_url"] = get_bug_report_url( request, ret["polling_station_known"]) serializer = PostcodeResponseSerializer(ret, read_only=True, context={"request": request}) return Response(serializer.data)
def test_multiple_polling_stations(self): rh = RoutingHelper("DD1 1DD") self.assertEqual("address_select_view", rh.view)
def test_single_address_blank_polling_station(self): # Test fixtures include a polling station, # but only address has blank station_id rh = RoutingHelper("BB1 1BB") self.assertEqual("postcode_view", rh.view)
def test_postcode_view(self): rh = RoutingHelper('CC11CC') endpoint = rh.get_endpoint() self.assertEqual('postcode_view', endpoint.view)
def test_multiple_councils_view(self): # check we are directed to multiple_councils_view if # postcode is attached to multiple councils in the blacklist rh = RoutingHelper("DD11DD") self.assertEqual("multiple_councils_view", rh.view)
def test_postcode_view(self): rh = RoutingHelper("CC11CC") self.assertEqual("postcode_view", rh.view)
def test_address_view(self): rh = RoutingHelper("AA11AA") endpoint = rh.get_endpoint() self.assertEqual("address_view", endpoint.view)
def test_address_view(self): rh = RoutingHelper("AA11AA") self.assertEqual("address_view", rh.view)
def test_multiple_councils_view(self): # check we are directed to multiple_councils_view if # postcode is attached to multiple councils in the blacklist rh = RoutingHelper('DD11DD') endpoint = rh.get_endpoint() self.assertEqual('multiple_councils_view', endpoint.view)
def test_multiple_addresses_single_polling_station(self): rh = RoutingHelper("CC1 1AA") self.assertEqual("address_view", rh.view)
def get_ee_wrapper(self, address): rh = RoutingHelper(address.postcode) if not rh.address_have_single_station: if address.location: return EveryElectionWrapper(point=address.location) return EveryElectionWrapper(postcode=address.postcode)
def test_multiple_polling_stations_with_null(self): rh = RoutingHelper("EE1 1EE") self.assertEqual("address_select_view", rh.view)