Skip to content

Commit

Permalink
add more constraints on profile descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
Changaco committed Sep 18, 2023
1 parent c23ca66 commit 8b061d6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
33 changes: 23 additions & 10 deletions tests/py/test_profile_edit.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,48 @@
from liberapay.testing import Harness


LOREM_IPSUM = (
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "
"incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis "
"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore "
"eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt "
"in culpa qui officia deserunt mollit anim id est laborum."
)


class Tests(Harness):

def edit_statement(self, lang, statement, auth_as='alice', action='publish'):
def edit_statement(self, lang, statement, auth_as='alice', action='publish', summary=''):
alice = self.make_participant('alice')
return self.client.POST(
"/alice/edit/statement",
{'lang': lang, 'statement': statement, 'action': action},
{'lang': lang, 'statement': statement, 'summary': summary, 'action': action},
auth_as=alice if auth_as == 'alice' else auth_as,
raise_immediately=False
)

def test_anonymous_gets_403(self):
r = self.edit_statement('en', 'Some statement', auth_as=None)
r = self.edit_statement('en', LOREM_IPSUM, auth_as=None)
assert r.code == 403

def test_participant_can_change_their_statement(self):
r = self.edit_statement('en', 'Lorem ipsum')
r = self.edit_statement('en', LOREM_IPSUM)
assert r.code == 302
r = self.client.GET('/alice/')
assert '<p>Lorem ipsum</p>' in r.text, r.text
assert LOREM_IPSUM in r.text, r.text

def test_participant_can_preview_their_statement(self):
r = self.edit_statement('en', 'Lorem ipsum', action='preview')
r = self.edit_statement('en', LOREM_IPSUM, action='preview')
assert r.code == 200
assert '<p>Lorem ipsum</p>' in r.text, r.text
assert LOREM_IPSUM in r.text, r.text

def test_participant_can_switch_language(self):
alice = self.make_participant('alice')
r = self.client.PxST(
"/alice/edit/statement",
{'lang': 'en', 'switch_lang': 'fr', 'statement': '', 'action': 'switch'},
{'lang': 'en', 'switch_lang': 'fr', 'statement': '', 'summary': '',
'action': 'switch'},
auth_as=alice
)
assert r.code == 302
Expand All @@ -41,14 +52,16 @@ def test_participant_is_warned_of_unsaved_changes_when_switching_language(self):
alice = self.make_participant('alice')
r = self.client.POST(
"/alice/edit/statement",
{'lang': 'en', 'switch_lang': 'fr', 'statement': 'foo', 'action': 'switch'},
{'lang': 'en', 'switch_lang': 'fr', 'statement': 'foo', 'summary': '',
'action': 'switch'},
auth_as=alice
)
assert r.code == 200
assert " are you sure you want to discard them?" in r.text, r.text
r = self.client.PxST(
"/alice/edit/statement",
{'lang': 'en', 'switch_lang': 'fr', 'statement': 'foo', 'action': 'switch', 'discard': 'yes'},
{'lang': 'en', 'switch_lang': 'fr', 'statement': 'foo', 'summary': '',
'action': 'switch', 'discard': 'yes'},
auth_as=alice
)
assert r.code == 302
59 changes: 38 additions & 21 deletions www/%username/edit/statement.spt
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,47 @@ from liberapay.utils import excerpt_intro, form_post_success, get_participant, m
[---]
participant = get_participant(state, restrict=True, allow_member=True)

errors = []

if request.method == 'POST':
lang = request.body['lang']
switch_lang = request.body.get('switch_lang')
summary = request.body.get('summary') or ''
statement = request.body['statement']

action = request.body.get('action')
if action is None:
# Temporary fallback
if request.body.get('save') == 'true':
action = 'publish'
elif request.body.get('preview') == 'true':
action = 'preview'
else:
action = 'edit'
summary = request.body['summary'].strip()
statement = request.body['statement'].strip()
action = request.body.get_choice('action', ('edit', 'preview', 'publish', 'switch'))

if lang not in ACCEPTED_LANGUAGES:
raise response.invalid_input(lang, 'lang', 'body')
if switch_lang and switch_lang not in ACCEPTED_LANGUAGES:
raise response.invalid_input(lang, 'switch_lang', 'body')

if len(summary) > constants.SUMMARY_MAX_SIZE:
raise response.error(400, _(
"The submitted summary is too long ({0} > {1}).",
len(summary), constants.SUMMARY_MAX_SIZE)
)
if action != 'switch':
if len(summary) > constants.SUMMARY_MAX_SIZE:
errors.append(ngettext(
"",
"The summary can't be more than {n} characters long.",
constants.SUMMARY_MAX_SIZE
))
if len(statement) < 100:
errors.append(ngettext(
"",
"The full description must be at least {n} characters long.",
n=100
))
elif len(statement) > 50_000:
errors.append(ngettext(
"",
"The full description can't be more than {n} characters long.",
n=50_000
))
if statement and statement == summary:
errors.append(_("The full description can't be identical to the summary."))
if summary in (participant.username, participant.public_name):
errors.append(_("The summary can't be only your name."))
if statement in (participant.username, participant.public_name):
errors.append(_("The description can't be only your name."))
if errors:
action = 'edit'

if action == 'publish':
participant.upsert_statement(lang, summary, 'summary')
Expand Down Expand Up @@ -83,16 +98,16 @@ subhead = _("Descriptions")
<form action="" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
<input type="hidden" name="lang" value="{{ lang }}" />
<h3>{{ _("Statement") }}</h3>
<input type="hidden" name="summary" value="{{ summary }}" />
<textarea class="hidden" name="statement">{{ statement }}</textarea>
<h3>{{ _("Description") }}</h3>
<section class="profile-statement" lang="{{ lang }}">{{ rendered_stmt }}</section>
<hr>
<h4>{{ _("Excerpt that will be used in social media:") }}</h4>
<blockquote lang="{{ lang }}">{{ excerpt_intro(rendered_stmt) }}</blockquote>
<hr>
% if summary
<h3>{{ _("Preview of the short description") }}</h3>
<input type="hidden" name="summary" value="{{ summary }}" lang="{{ lang }}" />
{{ profile_box_embedded(participant, summary) }}
<hr>
% if participant.username in summary
Expand Down Expand Up @@ -120,9 +135,7 @@ subhead = _("Descriptions")
<input type="hidden" name="lang" value="{{ lang }}" />
<input type="hidden" name="switch_lang" value="{{ switch_lang }}" />
<input type="hidden" name="discard" value="yes" />
% if summary
<input type="hidden" name="summary" value="{{ summary }}" />
% endif
<textarea class="hidden" name="statement">{{ statement }}</textarea>
<div class="buttons">
<button class="btn btn-danger btn-lg" name="action" value="switch">{{ _("Discard") }}</button>
Expand All @@ -133,6 +146,10 @@ subhead = _("Descriptions")

% else

% for error in errors
<p class="alert alert-danger">{{ error }}</p>
% endfor

<p>{{ _(
"Describe your work, why you're asking for donations, etc. The short "
"summary will be used when showcasing your profile alongside others, "
Expand Down

0 comments on commit 8b061d6

Please sign in to comment.