def home(request): """ The main page of Goose. Shows the search form, validate it and redirect to "results" if it's correct. """ base_template = "base.html" if request.method == "POST": form = SearchForm(request.POST) if form.is_valid(): form.clean() user_latitude = form.cleaned_data["latitude"] user_longitude = form.cleaned_data["longitude"] calculated_address = form.cleaned_data["calculated_address"] request.session["search_form"] = { "user_latitude": user_latitude, "user_longitude": user_longitude, "user_address": calculated_address, "radius": form.cleaned_data["radius"], "search_preset_id": form.cleaned_data["search_preset"].id, "no_private": form.cleaned_data["no_private"], } return redirect("results") else: form = SearchForm() return render(request, "search/home.html", locals())
def test_form_validation_invalid(self): # Address and coordinates. form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "Fridtjof Nansens plass, Oslo", "radius": "800", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) self.assertFalse(form.is_valid()) # Neither address nor coordinates. form_data = { "user_latitude": "", "user_longitude": "", "user_address": "", "radius": "800", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) # No radius. form_data = { "user_latitude": "", "user_longitude": "", "user_address": "Fridtjof Nansens plass, Oslo", "radius": "", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) self.assertFalse(form.is_valid()) # Invalid search preset. form_data = { "user_latitude": "", "user_longitude": "", "user_address": "Fridtjof Nansens plass, Oslo", "radius": "500", "search_preset": "9999", "no_private": "on" } form = SearchForm(form_data) self.assertFalse(form.is_valid()) # Invalid address. form_data = { "user_latitude": "", "user_longitude": "", "user_address": "Fridof Nansens plass, Oslo", "radius": "500", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) form.is_valid() with self.assertRaises(ValidationError): form.clean(mocking_parameters="invalid_address") return
def test_light_search(self): form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "", "radius": "500", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) if not form.is_valid(): self.fail("Validation of the form failed.") form.clean() response = self.client.post('/light/', data=form_data, follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "base_light.html") self.assertContains(response, "Voici votre localisation ") self.assertContains(response, "Latitude : 64.14624") self.assertContains(response, "Longitude : -21.94259") self.assertContains(response, "Adresse : ") self.assertContains( response, 'Recherche : "Boulangerie / Pâtisserie"') self.assertContains(response, " dans un rayon de 500 mètres.") self.assertContains(response, "Exclusion des résultats à accès privé.") self.assertContains(response, "Nom : City Hall of Reykjavik") self.assertContains(response, "Distance : 11990937 mètres") self.assertContains(response, "Direction : 107,6° E →") self.assertContains(response, ('Téléphone : <a href="tel:+354 411 1111">' '+354 411 1111</a>')) self.assertContains(response, 'Adresse estimée : ') # Same test, but including private results. form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "", "radius": "500", "search_preset": self.search_preset_id, "no_private": "False" } form = SearchForm(form_data) if not form.is_valid(): self.fail("Validation of the form failed.") form.clean() response = self.client.post('/light/', data=form_data, follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "base_light.html") self.assertContains(response, "Inclusion des résultats à accès privé.") return
def test_results_page(self): form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "", "radius": "500", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) if not form.is_valid(): self.fail("La validation du formulaire a échoué.") form.clean() response = self.client.post('/', data=form_data, follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "base.html") self.assertContains(response, "Voici votre localisation ") self.assertContains(response, "Latitude : 64.14624") self.assertContains(response, "Longitude : -21.94259") self.assertContains(response, "Adresse : ") self.assertContains( response, 'Recherche : "Boulangerie / Pâtisserie"') self.assertContains(response, " dans un rayon de 500 mètres.") self.assertContains(response, "Exclusion des résultats à accès privé.") # Same test, but including private results. form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "", "radius": "500", "search_preset": self.search_preset_id, "no_private": "False" } form = SearchForm(form_data) if not form.is_valid(): self.fail("La validation du formulaire a échoué.") form.clean() response = self.client.post('/', data=form_data, follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "base.html") self.assertContains(response, "Voici votre localisation ") self.assertContains(response, "Latitude : 64.14624") self.assertContains(response, "Longitude : -21.94259") self.assertContains(response, "Adresse : ") self.assertContains( response, 'Recherche : "Boulangerie / Pâtisserie"') self.assertContains(response, " dans un rayon de 500 mètres.") self.assertContains(response, "Inclusion des résultats à accès privé.") return
def test_js_variables(self): form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "", "radius": "500", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) if not form.is_valid(): self.fail("Validation of the form failed.") form.clean() response = self.client.post('/', data=form_data, follow=True) self.assertEqual(response.status_code, 200) self.assertContains(response, "var userLatitude = 64.14624;") self.assertContains(response, "var userLongitude = -21.94259;") self.assertContains(response, "var radius = 500;") self.assertContains( response, "var searchPresetId = {};".format(self.search_preset_id)) self.assertContains(response, "var noPrivate = true;") return
def test_session_data(self): form_data = { "user_latitude": "64.14624", "user_longitude": "-21.94259", "user_address": "", "radius": "500", "search_preset": self.search_preset_id, "no_private": "on" } form = SearchForm(form_data) if not form.is_valid(): self.fail("Validation of the form failed.") form.clean() response = self.client.post('/', form_data, follow=True) self.assertEqual(response.status_code, 200) session = self.client.session self.assertEqual(type(session["search_form"]["user_latitude"]), float) self.assertEqual(type(session["search_form"]["user_longitude"]), float) self.assertEqual(type(session["search_form"]["user_address"]), str) self.assertEqual(session["search_form"]["radius"], 500) self.assertEqual(session["search_form"]["search_preset_id"], self.search_preset_id) self.assertEqual(session["search_form"]["no_private"], True) return
def light_home(request): """ The main page of the light version of Goose. The results are displayed on the same page to avoid a redirection. """ base_template = "base_light.html" get_params = ( request.GET.get("sp"), request.GET.get("lat"), request.GET.get("lon"), request.GET.get("radius"), request.GET.get("no_private") ) if request.method != "POST" and not all(get_params): form = SearchForm() return render(request, "search/home.html", locals()) if not all(get_params): form = SearchForm(request.POST) if not form.is_valid(): return render(request, "search/home.html", locals()) form.clean() was_limited = getattr(request, 'limited', False) errors = [] if all(get_params): use_get_params = True get_params_valid = True try: search_preset_id = int(get_params[0]) search_preset = SearchPreset.objects.get(id=search_preset_id) except (SearchPreset.DoesNotExist, ValueError): get_params_valid = False errors.append(_("L'ID de l'objet de votre recherche est invalide.")) search_preset_id = 0 search_preset = None try: user_latitude = float(get_params[1]) user_longitude = float(get_params[2]) except ValueError: get_params_valid = False errors.append(_("Vos coordonnées sont invalides.")) user_latitude = 0.0 user_longitude = 0.0 if settings.TESTING: mocking_parameters = request.GET.get("mocking_parameters") else: mocking_parameters = None user_address = user_address = utils.get_address( coords=(float(user_latitude), float(user_longitude)), mocking_parameters=mocking_parameters ) if user_address: user_address = escape(user_address[1]) else: user_address = _("Adresse inconnue") # Does not set "get_params_valid" to False, because # the address is not useful for searching. errors.append(_( "Vos coordonnées n'ont pas permis de trouver votre " "adresse actuelle." )) try: radius = int(get_params[3]) radius_extreme_values = settings.GOOSE_META["radius_extreme_values"] if radius % 10 != 0 or not ( radius_extreme_values[0] <= radius <= radius_extreme_values[1] ): raise ValueError except ValueError: get_params_valid = False errors.append(_("Le rayon de recherche demandé est invalide.")) radius = 0 no_private = get_params[4] == '1' else: use_get_params = False get_params_valid = None search_preset = form.cleaned_data["search_preset"] user_latitude = form.cleaned_data["latitude"] user_longitude = form.cleaned_data["longitude"] user_address = escape(form.cleaned_data["calculated_address"]) radius = form.cleaned_data["radius"] no_private = form.cleaned_data["no_private"] user_coords = (user_latitude, user_longitude) if search_preset: if no_private: search_description = (_( '"{search_preset}" dans un rayon de {radius} mètres. ' 'Exclusion des résultats à accès privé.' )) else: search_description = (_( '"{search_preset}" dans un rayon de {radius} mètres. ' 'Inclusion des résultats à accès privé.' )) search_description = search_description.format( search_preset=search_preset.name, radius=radius ) else: search_description = _("Paramètres invalides.") if was_limited: error.append('\n' + _( "Trop de requêtes ont été faites en trop peu de temps. " "Merci d'attendre quelques secondes avant de raffraichir la page." )) error_msg = '<br/>\n'.join(errors) permalink = utils.get_permalink(request, use_get_params, search_preset.id, user_latitude, user_longitude, radius, no_private) if use_get_params and not get_params_valid: return render(request, "search/light_results.html", { "user_coords": user_coords, "user_address": user_address, "search_description": search_description, "permalink": permalink, "error_msg": error_msg }) timezone_name = tf.timezone_at(lat=user_latitude, lng=user_longitude) if timezone_name is None: timezone_name = tf.closest_timezone_at(lat=user_latitude, lng=user_longitude) if timezone_name is None: timezone_name = 'UTC' results = [] error_msg = '' try: results = utils.get_results( search_preset, user_coords, radius, no_private, timezone_name ) utils.get_all_addresses(results) debug_logger.debug("Request successfull!") except geopy.exc.GeopyError as e: error_msg = _( "Une erreur s'est produite lors de l'acquisition " "de vos coordonnées. Vous pouvez essayer de recharger " "la page dans quelques instants." ) debug_msg = str(e) debug_logger.debug("Geopy error: {}".format(str(e))) except overpass.OverpassError as e: error_msg = _( "Une erreur s'est produite lors de la requête vers " "les serveurs d'OpenStreetMap. Vous pouvez essayer " "de recharger la page dans quelques instants." ) debug_msg = str(e) debug_logger.debug("Overpass error: {}".format(str(e))) except Exception as e: error_msg = _("Une erreur non prise en charge s'est produite.") debug_msg = str(e) debug_logger.debug("Unhandled error: {}".format(str(e))) raise e # Logs the request to make statistics. # Doesn't logs if the request comes from an authenticated user, # as it is probably an admin. if not request.user.is_authenticated(): logger = logging.getLogger("statistics") logger.info( "search:{id}:{radius}:{lat}:{lon}".format( id=search_preset.id, radius=radius, # Rounds the stored coordinates for privacy's sake. lat=round(user_latitude), lon=round(user_longitude) ) ) return render(request, "search/light_results.html", { "results": results, "user_coords": user_coords, "user_address": user_address, "search_description": search_description, "permalink": permalink, "error_msg": error_msg })