Skip to content

Commit

Permalink
Merge pull request #516 from HEPData/resending-email-invitations
Browse files Browse the repository at this point in the history
Resending email invitations implementation
  • Loading branch information
GraemeWatt authored Sep 11, 2024
2 parents 6ca863a + 3a71a89 commit 4120cbb
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ $(document).ready(function() {
$.ajax({
dataType: "json",
url: '/permissions/manage/' + window.recid + '/' + window.data_person_type + '/' + window.action + '/' + window.userid,
type: 'POST',
data: {
review_message: $("#review-message").val()
},
success: function (data) {
if (data.success) {
process_reviews(data['recid']);
Expand Down Expand Up @@ -147,6 +151,8 @@ $(document).ready(function() {
html_block += '<div class="trigger-actions">';
if (additional_class == 'reserve') {
html_block += '<button data-toggle="tooltip" data-placement="top" title="Remove user from submission" class="btn btn-xs btn-danger mail-trigger" data-action="remove" data-person-type="' + action_type + '" data-recid="' + data["recid"] + '" data-userid="' + array[val_idx]['id'] + '"><span class="fa fa-trash-o"></span> </button>';
} else {
html_block += '<button data-toggle="tooltip" data-placement="top" title="Send a reminder to this user" class="btn btn-xs btn-primary mail-trigger" data-action="email" data-person-type="' + action_type + '" data-recid="' + data["recid"] + '" data-userid="' + array[val_idx]['id'] + '"><span class="fa fa-envelope-o"></span> </button>';
}
html_block += '<button data-toggle="tooltip" data-placement="top" title="' + alt_text + '" class="btn btn-xs btn-' + arrow_box_class + ' ' + downgrade_show + ' mail-trigger" data-action="' + action + '" data-person-type="' + action_type + '" data-recid="' + data["recid"] + '" data-userid="' + array[val_idx]['id'] + '"><span class="fa ' + arrow_box_icon + '"></span> </button>' +
'</div>';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ <h4>Reviewers <span id="add_reviewer" class="pull-right add-new-uprev" data-acti
<br/>
<div id="confirmation_message"></div>
<br/>
<div id="review-message-container">
<form id="review-message-form">
<label for="review-message">Would you like to leave a message for the recipient? (Optional):</label>
<textarea id="review-message" class="form-control" name="review_message" placeholder="Message here!"></textarea>
</form>
</div>
<br>
<button class="btn btn-danger reject-move-action">Cancel</button>
<button class="btn btn-success confirm-move-action">Confirm</button>
</div>
Expand Down
14 changes: 12 additions & 2 deletions hepdata/modules/email/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,17 @@ def notify_subscribers(hepsubmission, record):


def send_cookie_email(submission_participant,
record_information, message=None, version=1):

record_information, message=None, version=1, reminder=False):
"""
Sends an email to either an uploader, or reviewer containing their invitation cookie/token
and any custom messaging.
:param submission_participant: A SubmissionParticipant object, to receive the email reminder
:param record_information: Record object containing record information
:param version: The record version (Default is 1)
:param message: Any specific message text input into the form (Default is None)
:param reminder: Whether the reminder should be sent or not
"""
hepsubmission = get_latest_hepsubmission(
publication_recid=record_information['recid']
)
Expand All @@ -295,6 +304,7 @@ def send_cookie_email(submission_participant,
invite_token=submission_participant.invitation_cookie,
status=submission_participant.status,
recid=submission_participant.publication_recid,
reminder=reminder,
version=version,
email=submission_participant.email,
coordinator_email=coordinator.email,
Expand Down
66 changes: 41 additions & 25 deletions hepdata/modules/permissions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,47 +54,63 @@


@blueprint.route(
'/manage/<int:recid>/<string:action>/<string:status_action>/<int:participant_id>')
'/manage/<int:recid>/<string:action>/<string:status_action>/<int:participant_id>', methods=['POST', 'GET'])
@login_required
def manage_participant_status(recid, action, status_action,
participant_id):
def manage_participant_status(recid, action, status_action, participant_id):
"""
Can promote or demote a participant to/from primary reviewer/uploader, or
remove the participant from the record.
:param recid: record id that the user will be promoted or demoted for
:param action: upload or review
:param status_action: demote, promote or remove
:param participant_id: id of user from the SubmissionParticipant table.
Handles actions received from the "Manage Submission" widget window buttons.
Manages user promotion/demotion for uploader and reviewer roles,
removal of reserve users, and email reminders to primary uploaders/reviewers
Request can contain a message for reminder email.
status_action possibilities are:
promote: Promote a reserve uploader/reviewer to primary position
demote: Demote a reserve uploader/reviewer from primary position
email: Send reminder email to primary uploader/reviewer
remove: Remove a reserve uploader/reviewer from the submission
:param recid: ID of target record to manage
:param action: (Unused) Target of the action ('upload', OR 'review')
:param status_action: The status of which action button was clicked.
:param participant_id: ID of target participant to update
:return:
"""
try:
participant = SubmissionParticipant.query.filter_by(
id=participant_id).one()

if status_action == 'remove':
db.session.delete(participant)
else:
status = 'reserve'
if status_action == 'promote':
status = 'primary'
if status_action != 'email':
if status_action == 'remove':
db.session.delete(participant)
else:
status = 'reserve'
if status_action == 'promote':
status = 'primary'

participant.status = status
db.session.add(participant)
participant.status = status
db.session.add(participant)

db.session.commit()
db.session.commit()

record = get_record_by_id(recid)

# now send the email telling the user of their new status!
hepsubmission = get_latest_hepsubmission(publication_recid=recid)
if status_action == 'promote':
send_cookie_email(participant, record, version=hepsubmission.version)
elif status_action == 'demote':
send_reserve_email(participant, record)
if status_action != 'email':
if status_action == 'promote':
send_cookie_email(participant, record, version=hepsubmission.version)
elif status_action == 'demote':
send_reserve_email(participant, record)
admin_idx = AdminIndexer()
admin_idx.index_submission(hepsubmission)
else:
send_cookie_email(participant,
record,
version=hepsubmission.version,
message=request.form['review_message'],
reminder=True)


admin_idx = AdminIndexer()
admin_idx.index_submission(hepsubmission)

return json.dumps({"success": True, "recid": recid})
except Exception as e:
Expand Down
7 changes: 7 additions & 0 deletions hepdata/modules/theme/assets/scss/dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -977,4 +977,11 @@ body, html {
height: 100vh;
}

#review-message-container {
text-align: left;
}

#review-message-container label {
display: block;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{% extends 'hepdata_theme/email/email_container.html' %}
{% block email_type %}
{% if reminder %}
Reminder:
{% endif %}
Invite to be a{% if role == 'uploader' %}n{% endif %} {{ role | capitalize }} of HEPData record {{ recid }}
{% endblock %}

Expand Down
14 changes: 13 additions & 1 deletion tests/e2e/test_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,19 @@ def test_dashboard(live_server, logged_in_browser):
manage_widget = WebDriverWait(browser, 10).until(
EC.visibility_of_element_located((By.ID, 'manageWidget'))
)
assert manage_widget.find_element(By.CLASS_NAME, 'modal-title').text == 'Manage Submission'

assert manage_widget.find_element(By.CLASS_NAME,'modal-title').text == 'Manage Submission'

# Check reminder email button works
reminder_button = manage_widget.find_element(By.CSS_SELECTOR, '.trigger-actions .btn-primary')
assert reminder_button.get_attribute('data-action') == 'email'
reminder_button.click()
confirmation_message = manage_widget.find_element(By.ID, 'confirmation_message').text
assert confirmation_message == 'Are you sure you want to email this uploader?'
confirmation_button = manage_widget.find_element(By.CSS_SELECTOR, '.confirm-move-action')
confirmation_button.click()
assert not manage_widget.find_element(By.ID, 'confirmation').is_displayed()

# Close modal
manage_widget.find_element(By.CSS_SELECTOR, '.modal-footer .btn-default').click()
WebDriverWait(browser, 10).until(
Expand Down
88 changes: 88 additions & 0 deletions tests/email_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#
# This file is part of HEPData.
# Copyright (C) 2016 CERN.
#
# HEPData is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# HEPData 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with HEPData; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""
HEPData email module test cases.
Used to specifically test email sending call functions.
"""

import os

from invenio_db import db
from unittest.mock import patch

from hepdata.modules.email.api import send_cookie_email
from hepdata.modules.permissions.models import SubmissionParticipant
from tests.conftest import create_test_record


def test_send_cookie_email(app):
"""
Basic testing of the send_cookie_email method.
Tests expected output (argument calls) of the create_send_email_task function.
"""

# Set up the submission used for testing purposes
# Create test participant
test_participant = SubmissionParticipant(
user_account=1, publication_recid=2,
email="[email protected]", role='primary')
db.session.add(test_participant)
db.session.commit()

# Correctly set up the test_submission folder path
base_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
test_directory = os.path.join(base_directory, 'tests', 'test_data', 'test_submission')

# Create and upload the submission
# and set the coordinator
test_submission = create_test_record(test_directory, "todo")
test_submission.coordinator = 1
db.session.add(test_participant)
db.session.commit()

record_information = {
"recid": test_submission.publication_recid,
"title": "Test Title"
}
message = "TestMessage"

# Set up the patch for call access then run
with patch("hepdata.modules.email.api.create_send_email_task", side_effect=None) as task_patch:
# Execute the test function
send_cookie_email(test_participant, record_information, message=message)
# Check to see if the email function was properly called
task_patch.assert_called_once()

# Get the arguments used from the function call
called_args = task_patch.call_args.args
called_kwargs = task_patch.call_args.kwargs

# Check email was used in task call, and as recipient email
assert called_args[0] == test_participant.email
assert called_kwargs["reply_to_address"] == test_participant.email

# TODO - Expand to further check email contents
# Confirm existence of message sent in email
assert message in called_args[2]

0 comments on commit 4120cbb

Please sign in to comment.