def test_get_search_google_down(address_string_request, smarty_streets_response): """Failed search with a GET request""" precinct = baker.make("app.Precinct") ztp = baker.make("app.Zip9ToPrecinct", precinct=precinct, zip9=SAMPLE_ZIP9) pl = baker.make("app.PollingLocation") ppl = baker.make("app.PrecinctToPollingLocation", location=pl, precinct=precinct) # Google throws a 400 error, which only happens if something is wrong responses.add(responses.GET, GOOGLE_GEOCODE_URL_GENERIC, status=400) # Should fall back to this SS backup responses.add(responses.GET, SMARTY_URL_GENERIC, json=smarty_streets_response, status=200) response = post_string_search(address_string_request) assert response.status_code == 200 json_body = response.json() assert json_body["match_type"] == "MATCH_ZIP9" check_search_log(True) assert json_body["home_address"]
def test_search_by_string_ss_fallback_success(address_string_request, smarty_streets_response, google_geocode_response_no_zip9): """Search by string; Google doesn't return zip9; no address match; smartystreets fallback finds zip9; find match""" precinct = baker.make("app.Precinct") ztp = baker.make("app.Zip9ToPrecinct", precinct=precinct, zip9=SAMPLE_ZIP9) pl = baker.make("app.PollingLocation") ppl = baker.make("app.PrecinctToPollingLocation", location=pl, precinct=precinct) responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_response_no_zip9, status=200, ) responses.add(responses.GET, SMARTY_URL_GENERIC, json=smarty_streets_response, status=200) response = post_string_search(address_string_request) assert response.status_code == 200 json_body = response.json() assert json_body["match_type"] == "MATCH_ZIP9" check_search_log(True) assert json_body["home_address"] assert json_body["result_url"]
def test_nv_early_fail_precinct(nv_ev_zip9_request): responses.add(responses.GET, SMARTY_URL_GENERIC, json=[], status=200) response = post_address_search(nv_ev_zip9_request) assert response.status_code == 200 json_body = response.json() assert json_body.get("early_vote_locations") is None assert len(json_body["errors"]) == 1 check_search_log(success=False)
def test_nv_early_fail_location(nv_ev_zip9_request): responses.add(responses.GET, SMARTY_URL_GENERIC, json=[], status=200) precinct = baker.make("app.Precinct") ztp = baker.make("app.Zip9ToPrecinct", zip9="123456789", precinct=precinct) response = post_address_search(nv_ev_zip9_request) assert response.status_code == 200 json_body = response.json() assert json_body.get("early_vote_locations") is None assert len(json_body["errors"]) >= 1 check_search_log(success=False)
def test_nc_early_fail(): responses.add(responses.GET, SMARTY_URL_GENERIC, json=[], status=200) req = {"state": "NC", "county": "Franklin", "latitude": "33", "longitude": "-113"} response = post_address_search(req) assert response.status_code == 200 json_body = response.json() assert len(json_body["errors"]) >= 1 check_search_log(success=False) assert not json_body.get("polling_locations") assert not json_body.get("early_vote_locations")
def test_search_by_string_failure(google_geocode_bad_response): address_str = "123 alkdfjaskdfjjk st" request = {"search_string": address_str} responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_bad_response, status=200, ) response = post_string_search(request) assert response.status_code == 400 json_body = response.json() assert json_body["error_message"] == "Could not parse address" check_search_log(False)
def test_search_google_civic(google_civic_response_ut): """Address components search -- call out to Google Civic for results""" address_request = { "address": { "street_number": "1985", "street": "S 1200 E", "city": "Salt Lake City", "state": "UT", "zip5": "84105", "county": "Salt Lake County", } } responses.add(responses.GET, SMARTY_URL_GENERIC, json=[], status=200) responses.add( responses.GET, GOOGLE_CIVIC_URL_GENERIC, json=google_civic_response_ut, status=200, ) response = post_address_search(address_request) assert response.status_code == 200 json_body = response.json() assert json_body == EXPECTED_RESPONSE_1 search_log = check_search_log(True) # ID is non-deterministic so don't use it in comparison log_dict = model_to_dict(search_log) del log_dict["id"] assert log_dict == EXPECTED_SEARCH_LOG_1
def test_search_google_civic_string_search( google_civic_response_ut, google_geocode_response ): """String search -- call out to Google Civic for results""" search_string = "1985 S 1200 E, Salt Lake City UT 84105" address_request = {"search_string": search_string} responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_response, status=200, ) responses.add(responses.GET, SMARTY_URL_GENERIC, json=[], status=200) responses.add( responses.GET, GOOGLE_CIVIC_URL_GENERIC, json=google_civic_response_ut, status=200, ) response = get_string_search(address_request) assert response.status_code == 200 json_body = response.json() assert json_body == EXPECTED_RESPONSE_2 search_log = check_search_log(True) # ID is non-deterministic so don't use it in comparison log_dict = model_to_dict(search_log) del log_dict["id"] assert log_dict == EXPECTED_SEARCH_LOG_2
def test_search_metadata(google_geocode_response): """Make sure metadata from GET request gets into search log correctly""" precinct = baker.make("app.Precinct") ztp = baker.make("app.Zip9ToPrecinct", precinct=precinct, zip9=SAMPLE_ZIP9) pl = baker.make("app.PollingLocation") ppl = baker.make("app.PrecinctToPollingLocation", location=pl, precinct=precinct) responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_response, status=200, ) url = "/api/v1/search/string?search_string=fake%20address&phone_number=1112223333&[email protected]&source=mc&asdf=1234" response = Client().get(url) assert response.status_code == 200 search_log = check_search_log(True) assert search_log.search_string == "fake address" assert search_log.heap_id == "1112223333" assert search_log.source == "mc" other_data = search_log.other_data assert other_data["email"] == "*****@*****.**" assert other_data["phone_number"] == "1112223333" assert other_data["asdf"] == "1234"
def assert_fail(response, status_code, message, search_status): assert response.status_code == status_code json_body = response.json() json_body = json_body.get("errors")[0] assert json_body["error_message"] == message log = check_search_log(False) assert log.search_status == search_status
def test_nv_early_success_with_lat_long(nv_ev_zip9_request): precinct = baker.make("app.Precinct", county="Clark") ztp = baker.make("app.Zip9ToPrecinct", zip9="123456789", precinct=precinct) pl0 = baker.make("app.EarlyVoteLocation", latitude="35", longitude="-115") pl1 = baker.make("app.EarlyVoteLocation", latitude="37", longitude="-117") pl2 = baker.make( "app.EarlyVoteLocation", latitude="34", longitude="-114", dates_hours="Sa 2/15 10AM - 6PM, Tu 2/18 2PM - 8PM", ) pl3 = baker.make( "app.EarlyVoteLocation", latitude="36", longitude="-116", dates_hours="Sa 2/15 10AM - 6PM, Su 2/16 1PM - 5PM, Mo 2/17 10AM - 6PM, Tu 2/18 8AM - 8PM", ) ppl0 = baker.make("app.PrecinctToEVLocation", location=pl0, precinct=precinct) ppl1 = baker.make("app.PrecinctToEVLocation", location=pl1, precinct=precinct) ppl2 = baker.make("app.PrecinctToEVLocation", location=pl2, precinct=precinct) ppl3 = baker.make("app.PrecinctToEVLocation", location=pl3, precinct=precinct) pl_reg = baker.make("app.PollingLocation") ppl_reg = baker.make( "app.PrecinctToPollingLocation", location=pl_reg, precinct=precinct ) nv_ev_zip9_request["latitude"] = "33" nv_ev_zip9_request["longitude"] = "-113" response = post_address_search(nv_ev_zip9_request) assert response.status_code == 200 json_body = response.json() assert len(json_body["errors"]) == 0 check_search_log(success=True) # Check regular polling location assert len(json_body["polling_locations"]) == 1 assert json_body["polling_locations"][0]["location_name"] == pl_reg.location_name # Check that early vote locations returned are in correct sorted order assert len(json_body["early_vote_locations"]) == 4 early_locations = json_body["early_vote_locations"] assert float(early_locations[0].get("latitude")) == 34 assert float(early_locations[1].get("latitude")) == 35 assert float(early_locations[2].get("latitude")) == 36 assert float(early_locations[3].get("latitude")) == 37
def assert_success(response, match_type): assert response.status_code == 200 json_body = response.json() assert json_body["match_type"] == match_type assert json_body["home_address"] log = check_search_log(True) assert log.source == "web" assert log.search_id == "1234abcd" assert log.heap_id == "heap123" assert log.other_data.get("latitude")
def test_nc_early_success_with_lat_long(): responses.add(responses.GET, SMARTY_URL_GENERIC, json=[], status=200) county_name = "Franklin" pl0 = baker.make("app.EarlyVoteLocation", latitude="35", longitude="-115") pl1 = baker.make("app.EarlyVoteLocation", latitude="34", longitude="-114") pl2 = baker.make( "app.EarlyVoteLocation", latitude="37", longitude="-117", dates_hours="Sa 2/15 10AM - 6PM, Tu 2/18 2PM - 8PM", ) ppl0 = baker.make( "app.CountyToEVLocation", location=pl0, county=county_name, state_code="NC" ) ppl1 = baker.make( "app.CountyToEVLocation", location=pl1, county=county_name, state_code="NC" ) ppl2 = baker.make( "app.CountyToEVLocation", location=pl2, county=county_name, state_code="NC" ) req = {"state": "NC", "county": "FRANKLIN", "latitude": "33", "longitude": "-113"} response = post_address_search(req) assert response.status_code == 200 json_body = response.json() assert len(json_body["errors"]) == 0 check_search_log(success=True) # Check regular polling location assert not json_body.get("polling_locations") # Check that early vote locations returned are in correct sorted order assert len(json_body["early_vote_locations"]) == 3 early_locations = json_body["early_vote_locations"] assert float(early_locations[0].get("latitude")) == 34 assert float(early_locations[1].get("latitude")) == 35 assert float(early_locations[2].get("latitude")) == 37
def test_get_search_by_string_success(address_string_request, google_geocode_response): """Successful search with a GET request""" precinct = baker.make("app.Precinct") ztp = baker.make("app.Zip9ToPrecinct", precinct=precinct, zip9=SAMPLE_ZIP9) pl = baker.make("app.PollingLocation") ppl = baker.make("app.PrecinctToPollingLocation", location=pl, precinct=precinct) responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_response, status=200, ) response = get_string_search(address_string_request) assert response.status_code == 200 json_body = response.json() assert json_body["match_type"] == "MATCH_ZIP9" check_search_log(True) assert json_body["home_address"] assert json_body["result_url"]
def test_full_req_response(): precinct = baker.make( "app.Precinct", county="Clark", van_precinct_id=1617386, state_code="NV", fips="32003", precinct_code="3775", ) ztp = baker.make("app.Zip9ToPrecinct", zip9="891455373", precinct=precinct) pl0 = baker.make( "app.EarlyVoteLocation", location_id=8975760059578666627, location_name="CSN Charleston Campus, B Lobby", address="6375 W. Charleston Blvd.", city="Las Vegas", state_code="NV", zip="89146", dates_hours="Tu 2/18 8AM - 8PM", latitude="36.157265000", longitude="-115.232410000", ) pl1 = baker.make( "app.EarlyVoteLocation", location_id=1710710949278043919, location_name="UAW Local 3555", address="4310 Cameron St #11", city="Las Vegas", state_code="NV", zip="89103", dates_hours= "Sa 2/15 10AM - 6PM, Su 2/16 1PM - 5PM, Mo 2/17 10AM - 6PM, Tu 2/18 8AM - 8PM", latitude="36.111626800", longitude="-115.203850000", ) pl2 = baker.make( "app.EarlyVoteLocation", location_id=8323362047760264661, location_name="Temple Sinai", address="9001 Hillpointe Road", city="Las Vegas", state_code="NV", zip="89134", dates_hours="Sa 2/15 1PM - 6PM, Tu 2/18 10AM - 6PM", latitude="36.198949000", longitude="-115.292760000", ) ppl0 = baker.make("app.PrecinctToEVLocation", location=pl0, precinct=precinct) ppl1 = baker.make("app.PrecinctToEVLocation", location=pl1, precinct=precinct) ppl2 = baker.make("app.PrecinctToEVLocation", location=pl2, precinct=precinct) pl_reg = baker.make( "app.PollingLocation", location_id=6709390971067927642, location_name="Caucus Day Location - WALTER JOHNSON MIDDLE SCHOOL", address="7701 DUCHARME AVE", city="LAS VEGAS", state_code="NV", zip="89145", dates_hours= "Caucus Registration Opens at 10AM, Registration Closes at 12PM", latitude="36.168378000", longitude="-115.262055000", ) ppl_reg = baker.make("app.PrecinctToPollingLocation", location=pl_reg, precinct=precinct) request = { "address": { "street_number": "425", "street": "Warmside Dr", "city": "Las Vegas", "state": "NV", "zip5": "89145", "zip9": "891455373", "county": "Clark County", "latitude": 36.16741459999999, "longitude": -115.2447459, }, "metadata": { "query_params": "", "source": "web", "normalized_by_google": True, "autocomplete_selected": True, "heap_id": "8135830208496912", "pollaris_search_id": "18658113641015635837", }, } expected_response = { "errors": [], "precinct": { "van_precinct_id": 1617386, "state_code": "NV", "county": "Clark", "fips": "32003", "precinct_code": "3775", }, "match_type": "MATCH_ZIP9", "early_vote_locations": [ { "location_id": 8975760059578666627, "location_name": "CSN Charleston Campus, B Lobby", "address": "6375 W. Charleston Blvd.", "city": "Las Vegas", "state_code": "NV", "zip": "89146", "dates_hours": "Tu 2/18 8AM - 8PM", "latitude": "36.157265000", "longitude": "-115.232410000", "distance": 0.9825520301190909, }, { "location_id": 8323362047760264661, "location_name": "Temple Sinai", "address": "9001 Hillpointe Road", "city": "Las Vegas", "state_code": "NV", "zip": "89134", "dates_hours": "Sa 2/15 1PM - 6PM, Tu 2/18 10AM - 6PM", "latitude": "36.198949000", "longitude": "-115.292760000", "distance": 3.453980218009656, }, { "location_id": 1710710949278043919, "location_name": "UAW Local 3555", "address": "4310 Cameron St #11", "city": "Las Vegas", "state_code": "NV", "zip": "89103", "dates_hours": "Sa 2/15 10AM - 6PM, Su 2/16 1PM - 5PM, Mo 2/17 10AM - 6PM, Tu 2/18 8AM - 8PM", "latitude": "36.111626800", "longitude": "-115.203850000", "distance": 4.4750926279083, }, ], "polling_locations": [{ "location_id": 6709390971067927642, "location_name": "Caucus Day Location - WALTER JOHNSON MIDDLE SCHOOL", "address": "7701 DUCHARME AVE", "city": "LAS VEGAS", "state_code": "NV", "zip": "89145", "dates_hours": "Caucus Registration Opens at 10AM, Registration Closes at 12PM", "latitude": "36.168378000", "longitude": "-115.262055000", }], "home_address": { "street_number": "425", "street": "Warmside Dr", "city": "Las Vegas", "state": "NV", "zip5": "89145", "zip9": "891455373", "county": "Clark County", "latitude": 36.16741459999999, "longitude": -115.2447459, }, "pollaris_search_id": "18658113641015635837", } expected_search_log = { "heap_id": "8135830208496912", "autocomplete_selected": True, "search_status": "MATCH_ZIP9", "street": "Warmside Dr", "referrer": "http://test-referrer", "success": True, "zip9": "891455373", "street_number": "425", "zip5": "89145", "precinct": 1617386, "city": "Las Vegas", "other_data": { "latitude": 36.16741459999999, "longitude": -115.2447459, "query_params": "", "normalized_by_google": True, }, "county": "Clark County", "state_code": "NV", "search_string": None, "source": "web", "search_id": "18658113641015635837", } actual_response = post_address_search( request, HTTP_REFERER="http://test-referrer").json() assert actual_response == expected_response log = check_search_log(True) log_dict = model_to_dict(log) # ID is non-deterministic so don't use it in comparison del log_dict["id"] assert log_dict == expected_search_log
def test_search_string_success(google_geocode_response_nv): precinct = baker.make("app.Precinct") ztp = baker.make("app.Zip9ToPrecinct", zip9="891455373", precinct=precinct) el0 = baker.make("app.EarlyVoteLocation", latitude="35", longitude="-115") el1 = baker.make("app.EarlyVoteLocation", latitude="37", longitude="-117") el2 = baker.make("app.EarlyVoteLocation", latitude="34", longitude="-114") el3 = baker.make("app.EarlyVoteLocation", latitude="36", longitude="-116") baker.make("app.PrecinctToEVLocation", location=el0, precinct=precinct) baker.make("app.PrecinctToEVLocation", location=el1, precinct=precinct) baker.make("app.PrecinctToEVLocation", location=el2, precinct=precinct) baker.make("app.PrecinctToEVLocation", location=el3, precinct=precinct) pl0 = baker.make("app.PollingLocation", latitude="35", longitude="-115") pl1 = baker.make("app.PollingLocation", latitude="37", longitude="-117") pl2 = baker.make("app.PollingLocation", latitude="34", longitude="-114") pl3 = baker.make("app.PollingLocation", latitude="36", longitude="-116") baker.make("app.PrecinctToPollingLocation", location=pl0, precinct=precinct) baker.make("app.PrecinctToPollingLocation", location=pl1, precinct=precinct) baker.make("app.PrecinctToPollingLocation", location=pl2, precinct=precinct) baker.make("app.PrecinctToPollingLocation", location=pl3, precinct=precinct) responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_response_nv, status=200, ) addr_string = "425 warmside dr, las vegas nv 89147" response = get_string_search({"search_string": addr_string}) assert response.status_code == 200 json_body = response.json() assert len(json_body["errors"]) == 0 check_search_log(success=True) assert json_body["home_address"] assert json_body["result_url"] # Check that early vote locations returned are in correct sorted order assert len(json_body["early_vote_locations"]) == 4 early_locations = json_body["early_vote_locations"] assert float(early_locations[0].get("latitude")) == 34 assert float(early_locations[1].get("latitude")) == 35 assert float(early_locations[2].get("latitude")) == 36 assert float(early_locations[3].get("latitude")) == 37 # Check regular polling locations assert len(json_body["polling_locations"]) == 4 polling_locations = json_body["polling_locations"] assert float(polling_locations[0].get("latitude")) == 34 assert float(polling_locations[1].get("latitude")) == 35 assert float(polling_locations[2].get("latitude")) == 36 assert float(polling_locations[3].get("latitude")) == 37
def test_full_req_response_string(google_geocode_response_no_zip9, smarty_streets_response): responses.add( responses.GET, GOOGLE_GEOCODE_URL_GENERIC, json=google_geocode_response_no_zip9, status=200, ) responses.add(responses.GET, SMARTY_URL_GENERIC, json=smarty_streets_response, status=200) precinct = baker.make( "app.Precinct", county="Suffolk", van_precinct_id=12345678, state_code="MA", fips="32003", precinct_code="3775", ) ztp = baker.make("app.Zip9ToPrecinct", zip9="021293533", precinct=precinct) pl_reg = baker.make( "app.PollingLocation", location_id=6709390971067927642, location_name="Boston Public Library", address="7701 DUCHARME AVE", city="BOSTON", state_code="MA", zip="02139", dates_hours="8am-8pm", ) ppl_reg = baker.make("app.PrecinctToPollingLocation", location=pl_reg, precinct=precinct) request = { "search_string": "123 Main St, Charlestown MA", "metadata": { "query_params": "", "source": "web", "normalized_by_google": True, "autocomplete_selected": True, "heap_id": "8135830208496912", "pollaris_search_id": "18658113641015635837", }, } expected_response = { "errors": [], "precinct": { "van_precinct_id": 12345678, "state_code": "MA", "county": "Suffolk", "fips": "32003", "precinct_code": "3775", }, "match_type": "MATCH_ZIP9", "polling_locations": [{ "location_id": 6709390971067927642, "location_name": "Boston Public Library", "address": "7701 DUCHARME AVE", "city": "BOSTON", "state_code": "MA", "zip": "02139", "dates_hours": "8am-8pm", "latitude": None, "longitude": None, }], "home_address": { "street_number": "123", "street": "Main St", "city": "Boston", "state": "MA", "zip5": "02129", "county": "Suffolk County", "latitude": 42.3744875, "longitude": -71.06347439999999, "google_place_id": "ChIJd_ueCe1w44kRD_KFuN5w5nA", "postal_code_suffix": None, }, "pollaris_search_id": "18658113641015635837", "result_url": "https://elizabethwarren.com/vote?id=ChIJd_ueCe1w44kRD_KFuN5w5nA", } expected_search_log = { "heap_id": "8135830208496912", "autocomplete_selected": True, "search_status": "MATCH_ZIP9", "street": "Main St", "referrer": "http://test-referrer", "success": True, "zip9": None, "street_number": "123", "zip5": "02129", "precinct": 12345678, "city": "Boston", "other_data": { "latitude": 42.3744875, "longitude": -71.06347439999999, "query_params": "", "normalized_by_google": True, "smartystreets_called": True, }, "county": "Suffolk County", "state_code": "MA", "search_string": "123 Main St, Charlestown MA", "source": "web", "search_id": "18658113641015635837", } actual_response = post_string_search( request, HTTP_REFERER="http://test-referrer").json() assert actual_response == expected_response log = check_search_log(True) log_dict = model_to_dict(log) # ID is non-deterministic so don't use it in comparison del log_dict["id"] assert log_dict == expected_search_log