Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add cancel link #177

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions member_database/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ def send_registration_mail(registration):
token = ts.dumps(
(person.id, registration.id),
)
if registration.status_name == 'pending':

edit = registration.status_name != 'pending'
if not edit:
subject = 'Bestätige deine Anmeldung zu '
else:
subject = 'Bearbeite deine Anmeldung zu '
Expand All @@ -228,11 +230,46 @@ def send_registration_mail(registration):
name=person.name,
event=event.name,
confirmation_link=ext_url_for('events.confirmation', token=token),
submit_url=url_for('events.registration', event_id=event.id)
submit_url=url_for('events.registration', event_id=event.id),
cancel_link=ext_url_for("events.cancel", token=token),
edit=edit
)
)


@events.route('/cancel/<token>/', methods=['GET', 'POST'])
def cancel(token):
ts = URLSafeSerializer(
current_app.config["SECRET_KEY"],
salt='registration-key',
)
try:
person_id, registration_id = ts.loads(token)
except BadData as e:
print(e)
abort(404)

person = Person.query.get(person_id)
registration = EventRegistration.query.get_or_404(registration_id)

class CancelForm(FlaskForm):
submit = SubmitField(f'{person.name} ({person.email}) von {registration.event.name} abmelden.')

form = CancelForm()
if form.validate_on_submit():
if not registration.event.registration_open:
flash('Abmelden nicht möglich. Veranstaltung schon vorbei.', category='danger')
return redirect(url_for('events.index'))

# Delete registration
db.session.delete(registration)
db.session.commit()
flash('Von Veranstaltung abgemeldet.', category='success')
return redirect(url_for('events.index'))
else:
return render_template('events/cancel.html', form=form)


@events.route('/resend_email/', methods=['POST'])
def resend_email():
registration_id = request.form['registration_id']
Expand Down Expand Up @@ -388,7 +425,8 @@ def confirmation(token):
abort(404)

person = Person.query.get(person_id)
registration = EventRegistration.query.get(registration_id)
registration = EventRegistration.query.get_or_404(registration_id)

event = registration.event
n_participants = EventRegistration.query.filter_by(event_id=event.id, status_name='confirmed').count()
booked_out = event.max_participants and n_participants >= event.max_participants
Expand Down Expand Up @@ -420,6 +458,7 @@ def confirmation(token):
name=person.name,
event=registration.event.name,
edit_link=ext_url_for('events.confirmation', token=token),
cancel_link=ext_url_for('events.cancel', token=token)
)
)
if event.notify_email:
Expand Down
9 changes: 9 additions & 0 deletions member_database/events/templates/events/cancel.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% extends "base.html" %}
{% block main %}

<h1>Von Veranstaltung abmelden</h1>

{% from 'bootstrap/form.html' import render_form %}
{{ render_form(form, method='POST') }}

{% endblock %}
4 changes: 4 additions & 0 deletions member_database/events/templates/events/confirmation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ Um deine Anmeldung für die Veranstaltung „{{ event }}” abzuschließen,
bestätige sie bitte durch klicken auf den folgenden Link:

{{ confirmation_link }}
{% if edit %}

Möchtest du dich von der Veranstaltung abmelden klicke auf folgenden Link:
{{ cancel_link }}
{% endif %}
Mit freundlichen Grüßen

{% include "mail/signature.txt" %}
4 changes: 4 additions & 0 deletions member_database/events/templates/events/confirmed.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Wenn du deine Anmeldung ändern möchtest, kannst du dies unter
{{ edit_link }}
tun.

Wenn du dich von der Veranstaltung abmelden möchtest, kannst du das unter
{{ cancel_link }}
tun.

Mit freundlichen Grüßen

{% include "mail/signature.txt" %}
2 changes: 1 addition & 1 deletion member_database/events/templates/events/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h1>PeP et al. Veranstaltungsanmeldungen</h1>

{% if full_events or events %}
<p> Falls du dich bereits für eine Veranstaltung angemeldet hast,
aber keine Email bekommen hast, kannst du sie <a href="{{ url_for('events.resend_emails') }}">
aber keine Email bekommen hast, sie nicht mehr findest oder den Abmeldungsllink suchst, kannst du sie <a href="{{ url_for('events.resend_emails') }}">
hier erneut anfordern</a>.
{% endif %}

Expand Down
22 changes: 20 additions & 2 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def test_event(client):

mails = 'test1', 'test2'
expected_state = 'confirmed', 'waitinglist'
cancel_link = ""
for i, (email, state) in enumerate(zip(mails, expected_state), start=1):
# test registering
with mail.record_messages() as outbox:
Expand All @@ -58,8 +59,15 @@ def test_event(client):
link = m.group(0)

# test confirmation
ret = client.get(link)
assert ret.status_code == 200
with mail.record_messages() as outbox:
ret = client.get(link)
assert ret.status_code == 200
assert len(outbox) == 1
m = re.search(r'http(s)?:\/\/.*events\/cancel\/.*', outbox[0].body)
assert m
if i == 1:
cancel_link = m.group(0)

soup = BeautifulSoup(ret.data.decode('utf-8'), 'html.parser')
if state == 'waitinglist':
assert soup.find('div', {'class': 'alert alert-warning'})
Expand All @@ -74,3 +82,13 @@ def test_event(client):
alert = s.find('div', {'class': 'alert alert-warning'})
assert alert
assert 'Warteliste' in alert.text

# test event cancel
r = client.post(cancel_link, data={'submit': True}, follow_redirects=True)
assert r.status_code == 200
# event should not be full anymore
r = client.get('/events/1/registration/')
s = BeautifulSoup(r.data.decode('utf-8'), 'html.parser')
alert = s.find('div', {'class': 'alert alert-success'})
assert alert
assert 'verfügbar' in alert.text