# -*- coding: utf-8 -*- from __future__ import unicode_literals import datetime import re from django.apps import apps from django.test import TestCase from django.urls import reverse from django.utils.translation import gettext from dav_base.tests.generic import EmailTestMixin from ..models.oneclickaction import OneClickAction from .generic import RoleMixin, EventMixin TEST_EVENT_DATA = { 'title': 'Täst', 'description': 'Teßt', 'mode': 'joint', 'sport': 'W', 'level': 'beginner', 'first_day': datetime.date(2019, 3, 1), 'country': 'DE', 'trainer_firstname': 'Übungsleiter', 'trainer_familyname': 'Weißalles', 'trainer_email': 'trainer@localhost', } class ActionTestCase(EmailTestMixin, RoleMixin, EventMixin, TestCase): def _get_oneclick_url_from_mail(self, mail): uuid_pattern = '[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}' pseudo_uuid = 'abcdef12-1234-abcd-1234-abcdef123456' pseudo_url_path = reverse('dav_events:action_run', kwargs={'pk': pseudo_uuid}) url_path_pattern = pseudo_url_path.replace(pseudo_uuid, uuid_pattern) url_pattern = r'{}({})'.format(self.email_base_url, url_path_pattern) match = re.search(url_pattern, mail.body) if match: url = match.groups()[0] else: # pragma: no cover url = None return url def _get_uuid_from_url(self, url): uuid_pattern = r'([a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})' match = re.search(uuid_pattern, url) if match: uuid = match.groups()[0] else: # pragma: no cover uuid = None return uuid def _test_status_update(self, status_code, user): event = self.create_event_by_model(TEST_EVENT_DATA) self.submit_event(event) if status_code in ('publishing_web', 'publishing_facebook'): self.accept_event(event, user) mails = self.get_mail_for_user(user) self.assertEqual(len(mails), 1) mail = mails[0] action_url = self._get_oneclick_url_from_mail(mail) self.assertNotEqual(action_url, None) uuid = self._get_uuid_from_url(action_url) self.assertNotEqual(uuid, None) action = OneClickAction.objects.get(id=uuid) action_command = 'EVENT_STATUS_UPDATE' action_parameters = [str(event.id), status_code, str(user.id)] self._assertAction(action, command=action_command, parameters=action_parameters, url=action_url) response = self.client.get(action_url) self.assertEqual(response.status_code, 200) content = response.content.decode('utf-8') status_label = self.get_status_label(status_code) message = gettext('Der Status wurde auf \'%(status)s\' gesetzt.') % {'status': status_label} html = message.replace('\'', ''') self.assertInHTML(html, content) self.assertRegex(content, r'alert-success') self.assertTrue(event.workflow.has_reached_status(status_code)) action.refresh_from_db() self.assertTrue(action.done) def _assertAction(self, action, command=None, parameters=None, url=None): if command: self.assertEqual(action.command, command) if parameters: if isinstance(parameters, list): parameters = ','.join(parameters) self.assertEqual(action.parameters, parameters) if url: self.assertEqual(action.get_absolute_url(), url) def _assertRepeated(self, response): self.assertEqual(response.status_code, 200) content = response.content.decode('utf-8') html = gettext('Diese Aktion hast du bereits ausgeführt.') self.assertInHTML(html, content) self.assertRegex(content, r'alert-warning') def _assertAlready(self, response, status_code, user): self.assertEqual(response.status_code, 200) content = response.content.decode('utf-8') status_label = self.get_status_label(status_code) message = (gettext('Der Status wurde bereits' ' am %(date)s' ' von %(user)s' ' auf \'%(status)s\' gesetzt.') % { 'status': status_label, # 'date': datetime.datetime.now().strftime('%d.%m.%Y %H:%M:%S'), 'date': r'\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}', 'user': user.get_full_name(), }) html = message.replace('\'', ''') self.assertRegex(content, html) self.assertRegex(content, r'alert-success') def setUp(self): super(ActionTestCase, self).setUp() app_config = apps.get_containing_app_config(__package__) app_config.settings.enable_email_on_status_update = True self.manager_super = self.create_user_for_role('manager_super', 'password', 'Touren', 'Referent') self.manager_w = self.create_user_for_role('manager_w', 'password', 'Bereichsleiter', 'Wandern') self.publisher_web = self.create_user_for_role('publisher_web', 'password', 'Joomla', 'Redakteur') self.publisher_facebook = self.create_user_for_role('publisher_facebook', 'password', 'Facebook', 'Redakteur') def test_accept_by_manager_super(self): self._test_status_update('accepted', self.manager_super) def test_accept_by_manager_sub(self): self._test_status_update('accepted', self.manager_w) def test_accept_repeated(self): event = self.create_event_by_model(TEST_EVENT_DATA) self.submit_event(event) action_parameters = '{},accepted,{}'.format(event.id, self.manager_super.id) action = OneClickAction.objects.get(command='EVENT_STATUS_UPDATE', parameters=action_parameters) action_url = action.get_absolute_url() self.client.get(action_url) response = self.client.get(action_url) self._assertRepeated(response) def test_accepted_already(self): event = self.create_event_by_model(TEST_EVENT_DATA) self.submit_event(event) action_parameters = '{},accepted,{}'.format(event.id, self.manager_super.id) action = OneClickAction.objects.get(command='EVENT_STATUS_UPDATE', parameters=action_parameters) action_url = action.get_absolute_url() self.client.get(action_url) action_parameters = '{},accepted,{}'.format(event.id, self.manager_w.id) action = OneClickAction.objects.get(command='EVENT_STATUS_UPDATE', parameters=action_parameters) action_url = action.get_absolute_url() response = self.client.get(action_url) self._assertAlready(response, 'accepted', self.manager_super) def test_publishing_by_publisher_web(self): self._test_status_update('publishing_web', self.publisher_web) def test_publishing_by_publisher_facebook(self): self._test_status_update('publishing_facebook', self.publisher_facebook)