/accounts/: compute profile completion ratio (#88287)
gitea/authentic/pipeline/head This commit looks good Details

This commit is contained in:
Paul Marillonnet 2024-03-18 12:08:09 +01:00
parent 2b3d04a6d1
commit ad67e67417
4 changed files with 93 additions and 0 deletions

View File

@ -284,6 +284,9 @@ default_settings = dict(
definition='Set a random password on request to reset the password from the front-office',
),
A2_ACCOUNTS_URL=Setting(default=None, definition='IdP has no account page, redirect to this one.'),
A2_ACCOUNTS_DISPLAY_COMPLETION_RATIO=Setting(
default=False, definition='Display user\'s profile completion ratio.'
),
A2_CACHE_ENABLED=Setting(default=True, definition='Disable all cache decorators for testing purpose.'),
A2_ALLOW_PHONE_AUTHN_MANAGEMENT=Setting(
default=False,

View File

@ -47,6 +47,12 @@
{% endif %}
{% endif %}
<div id="a2-profile" class="a2-profile-block">
{% if completion_ratio is not None %}
<div id="a2-profile-completion-ratio">
{% widthratio completion_ratio 1 100 as completion_percent %}
{% blocktranslate %}You have completed {{ completion_percent }}% of your user profile.{% endblocktranslate %}
</div>
{% endif %}
{% if attributes %}
<dl>
{% for attribute in attributes %}

View File

@ -821,6 +821,29 @@ class ProfileView(HomeURLMixin, cbv.TemplateNamesMixin, TemplateView):
and authenticator.phone_identifier_field.user_editable
and not authenticator.phone_identifier_field.disabled
)
completion_ratio = None
if app_settings.A2_ACCOUNTS_DISPLAY_COMPLETION_RATIO and (
total_attrs := models.Attribute.objects.filter(
disabled=False,
user_visible=True,
user_editable=True,
)
):
total_count = total_attrs.count()
filled_attrs_count = (
models.AttributeValue.objects.filter(
content_type=ContentType.objects.get_for_model(get_user_model()),
object_id=self.request.user.id,
attribute_id__in=total_attrs,
content__isnull=False,
)
.order_by('attribute_id')
.distinct('attribute_id')
.count()
)
completion_ratio = round(filled_attrs_count / total_count, 2)
context.update(
{
'frontends_block': blocks,
@ -835,6 +858,7 @@ class ProfileView(HomeURLMixin, cbv.TemplateNamesMixin, TemplateView):
# TODO: deprecated should be removed when publik-base-theme is updated
'allow_password_change': utils_misc.user_can_change_password(request=request),
'federation_management': federation_management,
'completion_ratio': completion_ratio,
}
)

View File

@ -531,3 +531,63 @@ def test_account_view_boolean(app, simple_user, settings):
simple_user.attributes.accept = False
resp = app.get(reverse('account_management'))
assert 'Vrai' not in resp.text
def test_account_profile_completion_ratio(app, simple_user, settings):
settings.A2_ACCOUNTS_DISPLAY_COMPLETION_RATIO = True
Attribute.objects.all().delete()
for i in range(8):
Attribute.objects.create(
name=f'attr_{i}',
label=f'Attribute {i}',
kind='string',
disabled=False,
multiple=False,
user_visible=True,
user_editable=True,
)
utils.login(app, simple_user)
resp = app.get(reverse('account_management'))
assert (
resp.pyquery('#a2-profile-completion-ratio')[0].text_content().strip()
== 'You have completed 0% of your user profile.'
)
simple_user.attributes.attr_0 = 'foo'
resp = app.get(reverse('account_management'))
assert (
resp.pyquery('#a2-profile-completion-ratio')[0].text_content().strip()
== 'You have completed 12% of your user profile.'
)
simple_user.attributes.attr_1 = 'bar'
resp = app.get(reverse('account_management'))
assert (
resp.pyquery('#a2-profile-completion-ratio')[0].text_content().strip()
== 'You have completed 25% of your user profile.'
)
# test that multiple attribute values don't jinx the stats
attr_2 = Attribute.objects.get(name='attr_2')
attr_2.multiple = True
attr_2.save()
simple_user.attributes.attr_2 = ['b', 'é', 'p', 'o']
resp = app.get(reverse('account_management'))
assert (
resp.pyquery('#a2-profile-completion-ratio')[0].text_content().strip()
== 'You have completed 38% of your user profile.'
)
# remaining attributes up to 100% completion
for i, percent in (('3', 50), ('4', 62), ('5', 75), ('6', 88), ('7', 100)):
setattr(simple_user.attributes, f'attr_{i}', i)
resp = app.get(reverse('account_management'))
assert (
resp.pyquery('#a2-profile-completion-ratio')[0].text_content().strip()
== f'You have completed {percent}% of your user profile.'
)
settings.A2_ACCOUNTS_DISPLAY_COMPLETION_RATIO = False
resp = app.get(reverse('account_management'))
assert not resp.pyquery('#a2-profile-completion-ratio')