diff --git a/project/services/user.py b/project/services/user.py index 801ec12..69beef7 100644 --- a/project/services/user.py +++ b/project/services/user.py @@ -1,5 +1,4 @@ from flask_security import hash_password -from sqlalchemy.orm import joinedload from project import user_datastore from project.models import Role, User @@ -57,6 +56,4 @@ def get_user(id): def find_all_users_with_role(role_name: str) -> list: - return ( - User.query.options(joinedload(User.roles)).filter(Role.name == role_name).all() - ) + return User.query.filter(User.roles.any(Role.name == role_name)).all() diff --git a/project/views/utils.py b/project/views/utils.py index a1dbab1..a835819 100644 --- a/project/views/utils.py +++ b/project/views/utils.py @@ -124,11 +124,19 @@ def send_mails(recipients, subject, template, **context): if len(recipients) == 0: # pragma: no cover return - msg = Message(subject) - msg.recipients = recipients - msg.body = render_template("email/%s.txt" % template, **context) - msg.html = render_template("email/%s.html" % template, **context) - send_mail_message(msg) + body = render_template("email/%s.txt" % template, **context) + html = render_template("email/%s.html" % template, **context) + send_mails_with_body(recipients, subject, body, html) + + +def send_mails_with_body(recipients, subject, body, html): + # Send single mails, otherwise recipients will see each other + for recipient in recipients: + msg = Message(subject) + msg.recipients = [recipient] + msg.body = body + msg.html = html + send_mail_message(msg) def send_mail_message(msg): diff --git a/requirements.txt b/requirements.txt index 9f17dc2..9064203 100644 --- a/requirements.txt +++ b/requirements.txt @@ -71,7 +71,7 @@ packaging==20.8 passlib==1.7.4 pathspec==0.8.1 pilkit==2.0 -Pillow==8.3.1 +Pillow==8.3.2 pluggy==0.13.1 pre-commit==2.9.3 psycopg2-binary==2.8.6 diff --git a/tests/api/test_event.py b/tests/api/test_event.py index 51a2933..1afb1c7 100644 --- a/tests/api/test_event.py +++ b/tests/api/test_event.py @@ -534,6 +534,7 @@ def test_report_mail(client, seeder, utils, app, mocker): user_id, admin_unit_id = seeder.setup_base(admin=False, log_in=False) event_id = seeder.create_event(admin_unit_id) seeder.create_user(email="admin@test.de", admin=True) + seeder.create_user(email="normal@test.de", admin=False) mail_mock = utils.mock_send_mails(mocker) url = utils.get_url("api_v1_event_reports", id=event_id) diff --git a/tests/services/test_user.py b/tests/services/test_user.py new file mode 100644 index 0000000..525785d --- /dev/null +++ b/tests/services/test_user.py @@ -0,0 +1,15 @@ +def test_update_event_dates_with_recurrence_rule(client, seeder, utils, app): + user_id, admin_unit_id = seeder.setup_base(admin=False, log_in=False) + seeder.create_event(admin_unit_id) + admin_id = seeder.create_user(email="admin@test.de", admin=True) + seeder.create_user(email="normal@test.de", admin=False) + + with app.app_context(): + from project.services.user import find_all_users_with_role + + admins = find_all_users_with_role("admin") + assert len(admins) == 1 + + admin = admins[0] + assert admin.id == admin_id + assert admin.email == "admin@test.de" diff --git a/tests/utils.py b/tests/utils.py index d717ac3..283d280 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -175,28 +175,32 @@ class UtilActions(object): ) def mock_send_mails(self, mocker): - return mocker.patch("project.views.utils.send_mail_message") + return mocker.patch("project.views.utils.send_mails_with_body") - def assert_send_mail_called(self, mock, recipients, contents=None): + def assert_send_mail_called( + self, mock, expected_recipients, expected_contents=None + ): mock.assert_called_once() args, kwargs = mock.call_args - message = args[0] + send_recipients, subject, body, html = args - if not isinstance(recipients, list): - recipients = [recipients] + if not isinstance(expected_recipients, list): + expected_recipients = [expected_recipients] - for recipient in recipients: - assert recipient in message.recipients, f"{recipient} not in recipients" + assert len(send_recipients) == len(expected_recipients) - if contents: - if not isinstance(contents, list): - contents = [contents] + for expected_recipient in expected_recipients[:]: + assert ( + expected_recipient in send_recipients + ), f"{expected_recipient} not in recipients" - for content in contents: - assert content in message.body, f"{content} not in body" - assert content in message.html, f"{content} not in html" + if expected_contents: + if not isinstance(expected_contents, list): + expected_contents = [expected_contents] - return message + for content in expected_contents: + assert content in body, f"{content} not in body" + assert content in html, f"{content} not in html" def mock_now(self, mocker, year, month, day): from project.dateutils import create_berlin_date