profile: add user full name template definition popup (#74507) #19

Merged
pmarillonnet merged 2 commits from wip/74507-profile-user-full-name-template-field into main 2023-02-28 15:00:06 +01:00
9 changed files with 107 additions and 5 deletions

26
hobo/profile/forms.py Normal file
View File

@ -0,0 +1,26 @@
# hobo - portal to configure and deploy applications
# Copyright (C) 2015-2023 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django import forms
from django.utils.translation import ugettext_lazy as _
class EditFullNameTemplateForm(forms.Form):
user_full_name_template = forms.CharField(
label=_('User full name template (Django)'),
widget=forms.Textarea,
required=False,
)

View File

@ -9,6 +9,7 @@
{% block appbar %}
<h2>{% trans 'User Profile' %}</h2>
<span class="actions">
<a rel="popup" href="{% url 'profile-edit-user-full-name-template' %}">{% trans 'User full name template' %}</a>
<a rel="popup" href="{% url 'profile-add-attribute' %}">{% trans 'New attribute' %}</a>
</span>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends "hobo/base.html" %}
{% load i18n %}
{% block content %}
<form method="post" enctype="multipart/form-data">
<div id="profile-full-name-template-form">
{% csrf_token %}
{{ form.as_p }}
</div>
{% block buttons %}
<div class="buttons">
<button class="submit-button">{% trans 'Save' %}</button>
<a class="cancel" href="{% url 'profile-home' %}">{% trans 'Cancel' %}</a>
</div>
{% endblock %}
</form>
{% endblock %}

View File

@ -23,4 +23,9 @@ urlpatterns = [
re_path(r'(?P<name>[\w-]+)/options', views.options, name='profile-attribute-options'),
path('reorder', views.reorder, name='profile-reorder'),
path('add-attribute', views.add_attribute, name='profile-add-attribute'),
path(
'edit-user-full-name-template',
views.edit_user_full_name_template,
name='profile-edit-user-full-name-template',
),
]

View File

@ -16,10 +16,13 @@
from django.shortcuts import redirect
from django.urls import reverse, reverse_lazy
from django.views.generic import CreateView, ListView, RedirectView, UpdateView
from django.utils.translation import ugettext as _
from django.views.generic import CreateView, ListView, RedirectView, TemplateView, UpdateView
from hobo.deploy.signals import notify_agents
from hobo.environment.forms import VariablesFormMixin
from .forms import EditFullNameTemplateForm
from .models import AttributeDefinition
@ -72,6 +75,16 @@ class OptionsView(UpdateView):
options = OptionsView.as_view()
class EditFullNameTemplateView(VariablesFormMixin, TemplateView):
template_name = 'profile/edit_full_name_template.html'
form_class = EditFullNameTemplateForm
variables = ['user_full_name_template']
success_message = _('User full name template has been updated.')
edit_user_full_name_template = EditFullNameTemplateView.as_view()
def reorder(request):
new_order_list = [int(x) for x in request.GET['new-order'].split(',')]
for attribute in AttributeDefinition.objects.all():

View File

@ -17,7 +17,7 @@ def get_full_name(user):
context = {}
context['user'] = user
template_vars = getattr(settings, 'TEMPLATE_VARS', {})
if 'user_full_name_template' in template_vars:
if template_vars.get('user_full_name_template'):
try:
template = engines['django'].from_string(template_vars['user_full_name_template'])
return template.render(context)

View File

@ -17,7 +17,7 @@
import pytest
from hobo.environment.models import Authentic
from hobo.environment.models import Authentic, Variable
from hobo.environment.utils import get_variable
from hobo.profile import models
from hobo.profile.models import AttributeDefinition
@ -79,13 +79,39 @@ def test_add_attribute(logged_app, admin_user, kind):
assert models.AttributeDefinition.objects.filter(kind=kind).filter(name='test').count() == 1
def test_edit_user_full_name_template(logged_app, admin_user, settings):
app = logged_app
value = '{{ user.first_name }}'
assert not Variable.objects.filter(name='user_full_name_template')
page = app.get('/profile/edit-user-full-name-template', status=200)
page.form['user_full_name_template'] = value
page.form.submit()
assert Variable.objects.get(name='user_full_name_template').value == value
value = '{{ user.last_name }} etc.'
page = app.get('/profile/edit-user-full-name-template', status=200)
page.form['user_full_name_template'] = value
page.form.submit()
assert Variable.objects.get(name='user_full_name_template').value == value
page = app.get('/profile/edit-user-full-name-template', status=200)
page.form['user_full_name_template'] = 'whatever'
page.click('Cancel')
assert Variable.objects.get(name='user_full_name_template').value == value
page = app.get('/profile/edit-user-full-name-template', status=200)
page.form['user_full_name_template'] = ''
page.form.submit()
assert Variable.objects.get(name='user_full_name_template').value == ''
def test_attribute_kind_not_restricted_at_model_level(db):
assert models.AttributeDefinition.objects.create(label='test', kind='somestring')
def test_profile_home_view(logged_app):
resp = logged_app.get('/profile/', status=200)
assert [x['href'] for x in resp.html.findAll('a', {'rel': 'popup'})][1:4] == [
assert [x['href'] for x in resp.html.findAll('a', {'rel': 'popup'})][2:5] == [
'/profile/title/options',
'/profile/first_name/options',
'/profile/last_name/options',
@ -99,7 +125,7 @@ def test_reorder_view(logged_app):
assert resp.location == '/profile/'
assert AttributeDefinition.objects.filter(name='last_name')[0].order == 1
resp = resp.follow()
assert [x['href'] for x in resp.html.findAll('a', {'rel': 'popup'})][1:4] == [
assert [x['href'] for x in resp.html.findAll('a', {'rel': 'popup'})][2:5] == [
'/profile/last_name/options',
'/profile/first_name/options',
'/profile/title/options',

View File

@ -36,9 +36,15 @@ def test_user_get_full_name_from_template(user):
):
assert get_full_name(user) == 'Jane bar'
with override_settings(TEMPLATE_VARS={'user_full_name_template': ''}):
assert get_full_name(user) == 'Jane Doe'
def test_user_get_full_name(user):
with override_settings(
TEMPLATE_VARS={'user_full_name_template': '{{ user.first_name }} {{ user.attributes.foo }}'}
):
assert user.get_full_name() == 'Jane bar'
with override_settings(TEMPLATE_VARS={'user_full_name_template': ''}):
assert user.get_full_name() == 'Jane Doe'

View File

@ -49,6 +49,9 @@ def test_get_full_name_from_template_utils_from_multiple_attrs(db, tenant, setti
):
assert get_full_name(user) == 'Jane Milly Minnie'
with override_settings(TEMPLATE_VARS={'user_full_name_template': ''}):
assert get_full_name(user) == 'Jane Doe'
def test_get_full_name_from_template_accessor_from_multiple_attrs(db, tenant, settings):
with tenant_context(tenant):
@ -90,3 +93,6 @@ def test_get_full_name_from_template_accessor_from_multiple_attrs(db, tenant, se
}
):
assert user.get_full_name() == 'Jane Milly Minnie'
with override_settings(TEMPLATE_VARS={'user_full_name_template': ''}):
assert user.get_full_name() == 'Jane Doe'