Very lite "My Profile" page to allow changing username

This commit is contained in:
Yohan Boniface 2023-08-21 15:09:30 +02:00
parent fb6b0f4d9b
commit 2b471be171
8 changed files with 108 additions and 2 deletions

View file

@ -89,3 +89,10 @@ class MapSettingsForm(forms.ModelForm):
class Meta:
fields = ('settings', 'name', 'center', 'slug')
model = Map
class UserProfileForm(forms.ModelForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name')

View file

@ -129,6 +129,8 @@ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
FROM_EMAIL = None
# https://docs.djangoproject.com/en/4.2/releases/4.1/#forms
FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
# =============================================================================
# Calculation of directories relative to the project module location

View file

@ -133,6 +133,13 @@ h2.section {
text-align: center;
padding-top: 28px;
}
h2.tabs a {
font-weight: normal;
color: #666;
}
h2.tabs a:hover {
text-decoration: underline;
}
.showcase-map .map_fragment {
height: 400px;
}

View file

@ -0,0 +1,23 @@
{% extends "umap/content.html" %}
{% load i18n %}
{% block maincontent %}
<div class="col wide">
<h2 class="section tabs">
<a href="{% url 'user_dashboard' %}">{% trans "My dashboard" %}</a> | {% trans "My profile" %}
</h2>
</div>
<div class="wrapper">
<div class="row">
{% if form.non_field_errors %}
<ul class="form-errors">
{% for error in form.non_field_errors %}<li>{{ error }}</li>{% endfor %}
</ul>
{% endif %}
<form id="user_form" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="{% trans 'Save' %}" />
</form>
</div>
</div>
{% endblock maincontent %}

View file

@ -6,7 +6,9 @@
{% block maincontent %}
{% trans "Search my maps" as placeholder %}
<div class="col wide">
<h2 class="section">{% trans "My dashboard" %}</h2>
<h2 class="section tabs">
{% trans "My dashboard" %} | <a href="{% url 'user_profile' %}">{% trans "My profile" %}</a>
</h2>
{% include "umap/search_bar.html" with action=request.get_full_path placeholder=placeholder %}
</div>
<div class="wrapper">

View file

@ -11,6 +11,8 @@ from django.test import RequestFactory
from umap import VERSION
from umap.views import validate_url
User = get_user_model()
def get(target="http://osm.org/georss.xml", verb="get", **kwargs):
defaults = {
@ -141,7 +143,6 @@ def test_login_contains_form_if_enabled(client, settings):
@pytest.mark.django_db
def test_can_login_with_username_and_password_if_enabled(client, settings):
settings.ENABLE_ACCOUNT_LOGIN = True
User = get_user_model()
user = User.objects.create(username="test")
user.set_password("test")
user.save()
@ -279,3 +280,49 @@ def test_logout_should_return_redirect(client, user, settings):
response = client.get(reverse("logout"))
assert response.status_code == 302
assert response["Location"] == "/"
@pytest.mark.django_db
def test_user_profile_is_restricted_to_logged_in(client):
response = client.get(reverse("user_profile"))
assert response.status_code == 302
assert response["Location"] == "/en/login/?next=/en/me/profile"
@pytest.mark.django_db
def test_user_profile_allows_to_edit_username(client, map):
client.login(username=map.owner.username, password="123123")
new_name = "newname"
response = client.post(
reverse("user_profile"), data={"username": new_name}, follow=True
)
assert response.status_code == 200
user = User.objects.get(pk=map.owner.pk)
assert user.username == new_name
@pytest.mark.django_db
def test_user_profile_cannot_set_to_existing_username(client, map, user2):
client.login(username=map.owner.username, password="123123")
response = client.post(
reverse("user_profile"), data={"username": user2.username}, follow=True
)
assert response.status_code == 200
user = User.objects.get(pk=map.owner.pk)
assert user.username == map.owner.username
assert user.username != user2.username
@pytest.mark.django_db
def test_user_profile_does_not_allow_to_edit_other_fields(client, map):
client.login(username=map.owner.username, password="123123")
new_email = "foo@bar.com"
response = client.post(
reverse("user_profile"),
data={"username": new_email, "is_superuser": True},
follow=True,
)
assert response.status_code == 200
user = User.objects.get(pk=map.owner.pk)
assert user.email != new_email
assert user.is_superuser is False

View file

@ -103,6 +103,11 @@ i18n_urls += decorated_patterns(
views.user_dashboard,
name="user_dashboard",
),
re_path(
r"^me/profile$",
views.user_profile,
name="user_profile",
),
)
map_urls = [
re_path(

View file

@ -50,6 +50,7 @@ from .forms import (
MapSettingsForm,
SendLinkForm,
UpdateMapPermissionsForm,
UserProfileForm,
)
from .models import DataLayer, Licence, Map, Pictogram, Star, TileLayer
from .utils import get_uri_template, gzip_file, is_ajax
@ -164,6 +165,18 @@ class About(Home):
about = About.as_view()
class UserProfile(UpdateView):
model = User
form_class = UserProfileForm
success_url = reverse_lazy('user_profile')
def get_object(self):
return self.get_queryset().get(pk=self.request.user.pk)
user_profile = UserProfile.as_view()
class UserMaps(PaginatorMixin, DetailView):
model = User
slug_url_kwarg = "identifier"