From 2d17f25770a4cd7be65518912693112989c56cce Mon Sep 17 00:00:00 2001 From: Patrick Barroca <pbarroca@afi-sa.fr> Date: Wed, 29 Sep 2021 11:14:07 +0200 Subject: [PATCH] dev #141922 : enhance activities registration mails * add ical attachment * add details in b * add details in body * subject and body are now admin vars --- VERSIONS_WIP/141922 | 1 + library/Class/Activity/AbstractMail.php | 20 ++- library/Class/Activity/RegistrationMail.php | 71 ++++++++- library/Class/AdminVar.php | 13 +- library/Class/ICal/SessionActivity.php | 74 ++++++++++ library/Class/SessionActivity.php | 18 ++- library/ZendAfi/Mail.php | 5 + .../ZendAfi/View/Helper/Admin/AdminVar.php | 9 ++ .../AbonneControllerActivitiesTest.php | 137 +++++++++++++----- .../ActivitiesWithQueueAdminTest.php | 30 +++- .../scenarios/Activities/ActivityIcalTest.php | 126 ++++++++++++++++ 11 files changed, 451 insertions(+), 53 deletions(-) create mode 100644 VERSIONS_WIP/141922 create mode 100644 library/Class/ICal/SessionActivity.php rename tests/{application/modules/opac/controllers => scenarios/Activities}/AbonneControllerActivitiesTest.php (90%) create mode 100644 tests/scenarios/Activities/ActivityIcalTest.php diff --git a/VERSIONS_WIP/141922 b/VERSIONS_WIP/141922 new file mode 100644 index 00000000000..20ef5ad5092 --- /dev/null +++ b/VERSIONS_WIP/141922 @@ -0,0 +1 @@ + - ticket #141922 : Activités : Améliorations des courriels de confirmation d'inscription \ No newline at end of file diff --git a/library/Class/Activity/AbstractMail.php b/library/Class/Activity/AbstractMail.php index f52950e0516..8c8f11cceb6 100644 --- a/library/Class/Activity/AbstractMail.php +++ b/library/Class/Activity/AbstractMail.php @@ -69,7 +69,8 @@ abstract class Class_Activity_AbstractMail { protected function _sendMail($recipients, $subject, $body) { if (!$recipients = array_filter($recipients)) return $this; - $mail = new ZendAfi_Mail(); + + $mail = new ZendAfi_Mail; foreach($recipients as $recipient) $mail->addTo($recipient); @@ -77,13 +78,25 @@ abstract class Class_Activity_AbstractMail { $mail ->setFrom('no-reply@' . Class_AdminVar::getNomDomaine()) ->setSubject($subject) - ->setBodyHtml($body) - ->send(); + ->setBodyHtml($body); + + if ($ical = $this->_ical()) { + $attachment = $mail->createAttachment($ical, Class_ICal_SessionActivity::MIME_TYPE); + $attachment->filename = 'calendar.ics'; + } + + $mail->send(); return $this; } + protected function _ical() { + return (new Class_ICal_SessionActivity($this->_training_session)) + ->renderCalendar(Class_Profil::getCurrentProfil()); + } + + protected function _sendMailToSubscriber() { return $this->_sendMail([$this->_subscriber->getMail()], $this->_getSubscriberSubject(), @@ -114,4 +127,3 @@ abstract class Class_Activity_AbstractMail { abstract protected function _getTeachersBody(); } -?> \ No newline at end of file diff --git a/library/Class/Activity/RegistrationMail.php b/library/Class/Activity/RegistrationMail.php index 4d3fdcbe082..9d35bdcfd2c 100644 --- a/library/Class/Activity/RegistrationMail.php +++ b/library/Class/Activity/RegistrationMail.php @@ -22,15 +22,20 @@ class Class_Activity_RegistrationMail extends Class_Activity_AbstractMail { protected function _getSubscriberSubject() { - return $this->_('Confirmation d\'inscription à l\'activité "%s"', - $this->_training_session->getLibelleActivity()); + return $this->_fusion('ACTIVITY_REGISTRATION_SUBJECT'); } protected function _getSubscriberBody() { - return $this->_('Bonjour,<br><br>nous vous confirmons votre inscription à l\'activité <a href="%s">"%s"</a>', - $this->_getSessionUrl(), - $this->_training_session->getLibelleActivity()); + return $this->_fusion('ACTIVITY_REGISTRATION_BODY'); + } + + + protected function _fusion($var_key) { + return (new Class_ModeleFusion) + ->setContenu(Class_AdminVar::getValueOrDefault($var_key)) + ->setDataSource(['session' => new Class_Activity_RegistrationMail_SessionActivity($this->_training_session, $this->_getSessionUrl())]) + ->getContenuFusionne(); } @@ -48,6 +53,60 @@ class Class_Activity_RegistrationMail extends Class_Activity_AbstractMail { $this->_getSessionUrl(), $this->_training_session->getLibelleActivity()); } +} + + + + +class Class_Activity_RegistrationMail_SessionActivity { + use Trait_GetterByAttributeName, Trait_Translator; + + protected + $_training_session, + $_url; + + public function __construct($session, $url) { + $this->_training_session = $session; + $this->_url = $url; + } + + + public function getUrl() { + return $this->_url; + } + + + public function getLibelleActivity() { + return $this->_training_session->getLibelleActivity(); + } + + + public function getStartLabel() { + $start_timestamp = $this->_training_session->getStartTimestamp(); + $date_start = strftime($this->_('le %d %B %Y'), $start_timestamp); + if ('0000' === strftime('%H%M', $start_timestamp)) + return $date_start; + + return $this->_('%s à %s', + $date_start, + strftime($this->_('%Hh%M'), $start_timestamp)); + } + + public function getLocationLabel() { + return ($location = $this->_training_session->getLieu()) + ? $this->_(' à %s', $location->getLibelle()) + : ''; + } + + + public function getLocationDetails() { + return (new ZendAfi_Controller_Action_Helper_View) + ->renderLieu($this->_training_session->getLieu()); + } + + + public function getContentOrActivityDescription() { + return $this->_training_session->getContentOrActivityDescription(); + } } -?> \ No newline at end of file diff --git a/library/Class/AdminVar.php b/library/Class/AdminVar.php index b371cf2c957..372c917288b 100644 --- a/library/Class/AdminVar.php +++ b/library/Class/AdminVar.php @@ -609,7 +609,13 @@ Pour vous désabonner de la lettre d\'information, merci de cliquer sur le lien 'ACTIVITY_NOTIFICATION_DELAY' => Class_AdminVar_Meta::newDefault($this->_('Délai d\'envoi des rappels pour les activités (en jours)'), ['value' => '0']), 'ACTIVITY_NOTIFICATION_SUBJECT' => Class_AdminVar_Meta::newDefault($this->_('Sujet de l\'email de rappel pour les activités'), ['value'=> 'Rappel : {session.libelle_activity}']), 'ACTIVITY_NOTIFICATION_BODY' => Class_AdminVar_Meta::newEditor($this->_('Contenu de l\'email de rappel pour les activités'), ['value' => '<p>Bonjour {stagiaire.nom_complet},</p><p>L\'activité {session.libelle_activity} à laquelle vous êtes inscrit, commencera le {session.date_debut_texte}.</p><p>Cordialement</p>']), - 'ACTIVITY_NOTIFICATION_IN_QUEUE' => Class_AdminVar_Meta::newDefault($this->_('Message de notification lors de la validation en liste d\'attente'), ['value' => 'Attention: vous avez été placé en liste d\'attente, si des places se libèrent, vous serez averti par Email']) + 'ACTIVITY_NOTIFICATION_IN_QUEUE' => Class_AdminVar_Meta::newDefault($this->_('Message de notification lors de la validation en liste d\'attente'), ['value' => 'Attention: vous avez été placé en liste d\'attente, si des places se libèrent, vous serez averti par Email']), + 'ACTIVITY_REGISTRATION_SUBJECT' => Class_AdminVar_Meta::newDefault($this->_('Sujet de l\'email de confirmation d\'inscription'), ['value'=> 'Confirmation d\'inscription à l\'activité "{session.libelle_activity}"']), + 'ACTIVITY_REGISTRATION_BODY' => Class_AdminVar_Meta::newEditor($this->_('Contenu du mail de confirmation d\'inscription'), + ['value' => 'Bonjour,<br><br>nous vous confirmons votre inscription à l\'activité <a href="{session.url}">"{session.libelle_activity}"</a>.' + . '<p>Elle débutera {session.start_label}{session.location_label}.</p>' + . '<h2>Lieu</h2> {session.location_details}' + . '<h2>Contenu de la session</h2> {session.content_or_activity_description}']), ]; } @@ -1299,6 +1305,11 @@ class Class_AdminVar extends Storm_Model_Abstract { } + public function isEditor() { + return $this->getMeta()->isEditor(); + } + + public function validate() { $this->getMeta()->validate($this); } diff --git a/library/Class/ICal/SessionActivity.php b/library/Class/ICal/SessionActivity.php new file mode 100644 index 00000000000..e8139a554f6 --- /dev/null +++ b/library/Class/ICal/SessionActivity.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright (c) 2012-2021, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Class_ICal_SessionActivity extends Class_ICal_Abstract { + const PREFIX_ID = '//session-activity:'; + + public function renderCalendar($profil) { + Class_ICal_Autoloader::getInstance()->ensureAutoload(); + + if (!$this->_model + || !$profil + || (!$event = $this->_event($profil))) + return ''; + + $calendar = $this->_calendar(); + $calendar->addComponent($event); + + return $calendar->render(); + } + + + protected function _calendar() { + return new \Eluceo\iCal\Component\Calendar(static::PRODUCT_ID); + } + + + protected function _event($profil) { + $dt_start = (new DateTime())->setTimestamp($this->_model->getStartTimestamp()); + + $unique_id_on_universe = Class_Url::absolute([], null, true) + . static::PREFIX_ID + . $this->_model->getId(); + $event = (new \Eluceo\iCal\Component\Event($unique_id_on_universe)) + ->setUseTimezone(true) + ->setDtStart($dt_start) + ->setSummary($this->_model->getLibelleActivity()) + ->setUrl(Class_Url::absolute(['controller' => 'abonne', + 'action' => Class_Template::current()->isLegacy() + ? 'activities-registered' + : 'agenda', + 'id_profil' => $profil->getId()], + null, true)); + + if (!$location = $this->_model->getLieu()) + return $event; + + $event->setLocation($location->getLibelle()); + $latitude = (string)$location->getLatitude(); + $longitude = (string)$location->getLongitude(); + if (strlen($latitude) > 0 && strlen($longitude) > 0) + $event->setGeoLocation(new \Eluceo\iCal\Property\Event\Geo($latitude, $longitude)); + + return $event; + } +} diff --git a/library/Class/SessionActivity.php b/library/Class/SessionActivity.php index d2feca5ea31..a4565470d1b 100644 --- a/library/Class/SessionActivity.php +++ b/library/Class/SessionActivity.php @@ -168,6 +168,13 @@ class Class_SessionActivity extends Storm_Model_Abstract { } + public function getContentOrActivityDescription() { + return ($content = $this->getContenu()) + ? $content + : $this->getActivityDescription(); + } + + public function beforeSave() { if (!$this->getDateLimiteFin()) $this->setDatelimiteFin($this->getDateDebut()); @@ -320,6 +327,11 @@ class Class_SessionActivity extends Storm_Model_Abstract { } + public function getStartTimestamp() { + return strtotime(parent::_get('date_debut')); + } + + public function getDateFin() { return $this->_rangeDateFormat(parent::_get('date_fin')); } @@ -741,11 +753,7 @@ class Class_SessionActivity_Article protected function _contentFrom($model) { - $content = ($content = $model->getContenu()) - ? $content - : $model->getActivityDescription(); - - return $content + return $model->getContentOrActivityDescription() . $this->_getInformations($model) . $this->_getRegisterLink($model); } diff --git a/library/ZendAfi/Mail.php b/library/ZendAfi/Mail.php index 8aec63b477f..7ec8adf3860 100644 --- a/library/ZendAfi/Mail.php +++ b/library/ZendAfi/Mail.php @@ -77,4 +77,9 @@ class ZendAfi_Mail extends Zend_Mail { public function getDecodedSubject() { return iconv_mime_decode($this->getSubject()); } + + + public function getParts() { + return $this->_parts; + } } diff --git a/library/ZendAfi/View/Helper/Admin/AdminVar.php b/library/ZendAfi/View/Helper/Admin/AdminVar.php index c6a1a4eabcb..1161a155f92 100644 --- a/library/ZendAfi/View/Helper/Admin/AdminVar.php +++ b/library/ZendAfi/View/Helper/Admin/AdminVar.php @@ -28,6 +28,9 @@ class ZendAfi_View_Helper_Admin_AdminVar extends ZendAfi_View_Helper_BaseHelper if ($var->isMultiInput()) return $this->renderMultiInput($var); + if ($var->isEditor()) + return $this->renderEditor($var); + return $this->renderSimple($var); } @@ -62,6 +65,12 @@ class ZendAfi_View_Helper_Admin_AdminVar extends ZendAfi_View_Helper_BaseHelper } + protected function renderEditor($var) { + return $this->_tag('div', $this->view->escape($var->getValeur()), + ['style' => 'width:20em;']); + } + + protected function renderSimple($var) { return wordwrap($this->cleanValue($var), 35, '<br />', true); } diff --git a/tests/application/modules/opac/controllers/AbonneControllerActivitiesTest.php b/tests/scenarios/Activities/AbonneControllerActivitiesTest.php similarity index 90% rename from tests/application/modules/opac/controllers/AbonneControllerActivitiesTest.php rename to tests/scenarios/Activities/AbonneControllerActivitiesTest.php index 5a1f4b939e6..8bfa201fb84 100644 --- a/tests/application/modules/opac/controllers/AbonneControllerActivitiesTest.php +++ b/tests/scenarios/Activities/AbonneControllerActivitiesTest.php @@ -1,6 +1,6 @@ <?php /** - * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved. + * Copyright (c) 2021, Agence Française Informatique (AFI). All rights reserved. * * BOKEH is free software; you can redistribute it and/or modify * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by @@ -35,7 +35,7 @@ abstract class AbstractAbonneControllerActivitiesTestCase $_session_java_fevrier, $_session_java_septembre, $_session_python_juillet, - $_gallice_cafe, + $_galice_cafe, $_bib_romains, $_bonlieu, $_mail_transport; @@ -57,7 +57,7 @@ abstract class AbstractAbonneControllerActivitiesTestCase $this->_mail_transport = new MockMailTransport(); Zend_Mail::setDefaultTransport($this->_mail_transport); - $this->_amadou = $this->fixture('Class_Users', + $this->_amadou = $this->fixture(Class_Users::class, ['id' => 435, 'nom' => 'Dou', 'prenom' => 'Ama', @@ -75,17 +75,17 @@ abstract class AbstractAbonneControllerActivitiesTestCase ZendAfi_Auth::getInstance()->logUser($this->_amadou); - $this->_gallice_cafe = $this->fixture('Class_Lieu', + $this->_galice_cafe = $this->fixture(Class_Lieu::class, ['id' => 98, 'libelle' => 'Galice']); - $this->_bib_romains = $this->fixture('Class_Lieu', + $this->_bib_romains = $this->fixture(Class_Lieu::class, ['id' => '99', 'libelle' => 'Bibliothèque des romains']); - $this->_bonlieu = $this->fixture('Class_Lieu', + $this->_bonlieu = $this->fixture(Class_Lieu::class, ['id' => 100, 'libelle' => 'Bonlieu', 'adresse' => "1, rue Jean-Jaures\nBP 294", @@ -95,29 +95,29 @@ abstract class AbstractAbonneControllerActivitiesTestCase 'longitude' => '6.128715']); $this->_learn_smalltalk = $this - ->fixture('Class_Activity', + ->fixture(Class_Activity::class, ['id' => 1, 'libelle' => 'Learn Smalltalk']); $this->_session_smalltalk_janvier = $this - ->fixture('Class_SessionActivity', + ->fixture(Class_SessionActivity::class, ['id' => 11, 'activity' => $this->_learn_smalltalk, 'effectif_min' => 1, 'effectif_max' => 10, - 'lieu' => $this->_gallice_cafe, + 'lieu' => $this->_galice_cafe, 'date_debut' => '2015-01-10', 'date_fin' => '2015-01-10', 'date_limite_fin' => '2015-01-10', 'stagiaires' => []]); $this->_session_smalltalk_juillet = $this - ->fixture('Class_SessionActivity', + ->fixture(Class_SessionActivity::class, ['id' => 12, 'activity' => $this->_learn_smalltalk, 'effectif_min' => 1, 'effectif_max' => 10, - 'lieu' => $this->_gallice_cafe, + 'lieu' => $this->_galice_cafe, 'stagiaires' => [], 'date_debut' => '2014-07-11', 'date_fin' => '2014-07-15', @@ -129,13 +129,13 @@ abstract class AbstractAbonneControllerActivitiesTestCase ->assertSave(); - $this->_learn_java = $this->fixture('Class_Activity', + $this->_learn_java = $this->fixture(Class_Activity::class, ['id' => 3, 'libelle' => 'Learn Java', 'description' => 'whaaat ?']); - $this->_session_java_fevrier = $this->fixture('Class_SessionActivity', + $this->_session_java_fevrier = $this->fixture(Class_SessionActivity::class, ['id' => 31, 'activity' => $this->_learn_java, 'effectif_min' => 2, @@ -146,7 +146,7 @@ abstract class AbstractAbonneControllerActivitiesTestCase 'stagiaires' => [], 'date_limite_fin' => '2015-01-20']); - $this->_session_java_fevrier->setArticle($this->fixture('Class_Article', + $this->_session_java_fevrier->setArticle($this->fixture(Class_Article::class, ['id' => 10, 'titre' => 'Java est mort, vive python !', 'contenu' => 'Java has been']) @@ -156,17 +156,18 @@ abstract class AbstractAbonneControllerActivitiesTestCase ->save(); - $this->_session_java_mars = $this->fixture('Class_SessionActivity', + $this->_session_java_mars = $this->fixture(Class_SessionActivity::class, ['id' => 32, 'activity' => $this->_learn_java, 'effectif_min' => 2, 'effectif_max' => 5, - 'lieu' => $this->_gallice_cafe, - 'date_debut' => '2015-03-01', + 'lieu' => $this->_galice_cafe, + 'date_debut' => '2015-03-01 10:00:00', 'stagiaires' => [], + 'contenu' => 'Comment sortir d\'un environnement toxique', 'date_limite_fin' => '2015-03-01']); - $this->_session_java_septembre = $this->fixture('Class_SessionActivity', + $this->_session_java_septembre = $this->fixture(Class_SessionActivity::class, ['id' => 30, 'activity' => $this->_learn_java, 'effectif_min' => 2, @@ -174,7 +175,7 @@ abstract class AbstractAbonneControllerActivitiesTestCase 'date_debut' => '2014-09-10', 'date_fin' => '2014-09-10', 'stagiaires' => [], - 'lieu' => $this->_gallice_cafe, + 'lieu' => $this->_galice_cafe, 'date_limite_fin' => '2014-09-10']); $this->_session_java_septembre->beAnnule(); @@ -185,12 +186,12 @@ abstract class AbstractAbonneControllerActivitiesTestCase ->assertSave(); - $this->_learn_python = $this->fixture('Class_Activity', + $this->_learn_python = $this->fixture(Class_Activity::class, ['id' => 12, 'libelle' => 'Learn Python']); $this->_session_python_juillet = $this - ->fixture('Class_SessionActivity', + ->fixture(Class_SessionActivity::class, ['id' => 121, 'activity' => $this->_learn_python, 'date_debut' => '2014-07-10', @@ -204,7 +205,7 @@ abstract class AbstractAbonneControllerActivitiesTestCase 'horaires' => '8h-12h, 14h-18h', 'lieu' => $this->_bib_romains, 'stagiaires' => [$this->_amadou], - 'intervenants' => [$this->fixture('Class_Users', + 'intervenants' => [$this->fixture(Class_Users::class, ['id' =>76, 'login' => 'jpp', 'password' => 'pwd', @@ -563,7 +564,7 @@ class AbonneControllerActivitiesFicheAbonneWithRightRegisterTest ['id' => 7987, 'rights' => [Class_UserGroup::RIGHT_REGISTER_ACTIVITY]]); - $redacteur = $this->fixture('Class_Users', + $redacteur = $this->fixture(Class_Users::class, ['id' => 1654, 'login' => 'redacteur', 'password' => 'redacteur', @@ -757,6 +758,36 @@ class AbonneControllerActivitiesAmadouInscritSessionMarsJavaClosedTest +class AbonneControllerActivitiesAmadouInscritSessionMarsJavaOpenedTest extends AbstractAbonneControllerActivitiesTestCase { + protected $_first_mail_body; + + public function setUp() { + parent::setUp(); + $this->dispatch('/opac/abonne/inscrire-session/id/32'); + $this->_first_mail_body = quoted_printable_decode($this + ->_mail_transport + ->getSentMails()[0] + ->getBodyHtml(true)); + } + + + /** @test */ + public function firstMailBodyShouldContainsElleDebuteraLe01Mars2015A10h00() { + $this->assertContains('Elle débutera le 01 mars 2015 à 10h00 à Galice', + $this->_first_mail_body); + } + + + /** @test */ + public function firstMailBodyShouldContainsCommentSortirDunEnvironnementToxique() { + $this->assertContains('Comment sortir d\'un environnement toxique', + $this->_first_mail_body); + } +} + + + + class AbonneControllerActivitiesAmadouInscritSessionMarsJavaNotOpenTest extends AbstractAbonneControllerActivitiesTestCase { @@ -793,9 +824,13 @@ class AbonneControllerActivitiesAmadouInscritSessionMarsJavaNotOpenTest -class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest extends AbstractAbonneControllerActivitiesTestCase { +class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest + extends AbstractAbonneControllerActivitiesTestCase { + protected - $_mails; + $_mails, + $_first_mail_body; + public function setUp() { parent::setUp(); @@ -804,12 +839,13 @@ class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest extends ->setIntervenants($this->_session_python_juillet ->getIntervenants())->save(); - $this->dispatch('/opac/abonne/inscrire-session/id/31', true); + $this->dispatch('/opac/abonne/inscrire-session/id/31'); Class_SessionActivity::clearCache(); Class_Article::clearCache(); $this->_mails = $this->_mail_transport->getSentMails(); + $this->_first_mail_body = quoted_printable_decode($this->_mails[0]->getBodyHtml(true)); } @@ -829,7 +865,7 @@ class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest extends /** @test */ - function answerShouldRedirectToActivityList() { + public function answerShouldRedirectToActivityList() { $this->assertRedirectTo('/activities'); } @@ -843,7 +879,7 @@ class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest extends /** @test */ - function aNewInscriptionShouldHaveBeenCreated() { + public function aNewInscriptionShouldHaveBeenCreated() { $this->assertCount(1, Class_SessionActivityInscription::findAllBy(['stagiaire_id' => 435, 'session_activity_id' => 31])); } @@ -862,7 +898,7 @@ class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest extends /** @test */ - public function firtMailFromShouldBeNoReplyAtBokeh() { + public function firstMailFromShouldBeNoReplyAtBokeh() { $this->assertEquals('no-reply@bokeh.fr', $this->_mails[0]->getFrom()); } @@ -876,16 +912,49 @@ class AbonneControllerActivitiesAmadouInscritSessionFebruaryJavaOpenTest extends /** @test */ - public function firstMailBodyShouldBeWeConfirm() { + public function firstMailBodyShouldContainsNousVousConfirmons() { $this->assertContains('nous vous confirmons', - $this->_mails[0]->getBodyHtml(true)); + $this->_first_mail_body); } /** @test */ public function firstMailBodyShouldContainsUrlToDetailSession() { $this->assertContains('http://localhost' . BASE_URL . '/activities/detail-session/id/31"', - $this->_mails[0]->getBodyHtml(true)); + $this->_first_mail_body); + } + + + /** @test */ + public function firstMailBodyShouldContainsElleDebuteraLe10fevrier2015() { + $this->assertContains('Elle débutera le 10 février 2015 à Bonlieu', + $this->_first_mail_body); + } + + + /** @test */ + public function firstMailBodyShouldContainsMapForBonlieu() { + $this->assertContains('1, rue Jean-Jaures<br />', + $this->_first_mail_body); + } + + + /** @test */ + public function firstMailBodyShouldContainsActivityDescriptionWhaaat() { + $this->assertContains('whaaat ?', $this->_first_mail_body); + } + + + /** @test */ + public function firstMailShouldHaveIcalAttachment() { + $this->assertEquals(1, count($parts = $this->_mails[0]->getParts())); + $part = $parts[0]; + $this->assertEquals(['text/calendar;charset=utf-8', + 'base64', + 'attachment'], + [$part->type, + $part->encoding, + $part->disposition]); } @@ -927,14 +996,14 @@ class AbonneControllerActivitiesAmadouWithoutMailInscritSessionFebruaryJavaOpenT parent::setUp(); $this->_session_java_fevrier - ->addIntervenant($this->fixture('Class_Users', + ->addIntervenant($this->fixture(Class_Users::class, ['id' =>78, 'login' => 'pat', 'password' => 'bator', 'nom' => 'Bator', 'prenom' => 'Pat', 'mail' => 'pat@bat.org'])) - ->addIntervenant($this->fixture('Class_Users', + ->addIntervenant($this->fixture(Class_Users::class, ['id' =>79, 'login' => 'captain', 'password' => 'flam', diff --git a/tests/scenarios/Activities/ActivitiesWithQueueAdminTest.php b/tests/scenarios/Activities/ActivitiesWithQueueAdminTest.php index 00a05fb5a21..f96f667c0b5 100644 --- a/tests/scenarios/Activities/ActivitiesWithQueueAdminTest.php +++ b/tests/scenarios/Activities/ActivitiesWithQueueAdminTest.php @@ -404,9 +404,33 @@ class ActivitiesWithQueueAdminEditQuotasOnSessionTest /** @test */ - public function mailShouldBeSentToChichiro() { - $mail = $this->_mail_transport->getSentMails()[0]; - $this->assertContains('nous vous confirmons votre inscription', $mail->getBodyHtml(true)); + public function shouldHaveSent2Mails() { + $this->assertEquals(2, count($this->_mail_transport->getSentMails())); + } + + /** @test */ + public function firstMailShouldContainsNousVousConfirmonsVotreInscription() { + $this->assertContains('nous vous confirmons votre inscription', + $this->_mail_transport->getSentMails()[0]->getBodyHtml(true)); + } + + + public function mailRecipients() { + return [['chichi@ro.org'], + ['po@nyo.org']]; + } + + + /** + * @test + * @dataProvider mailRecipients + */ + public function mailShouldBeSentToRecipient($recipient) { + $recipients = []; + foreach($this->_mail_transport->getSentMails() as $mail) + $recipients = array_merge($recipients, $mail->getRecipients()); + + $this->assertContains($recipient, $recipients, json_encode($recipients, JSON_PRETTY_PRINT)); } } diff --git a/tests/scenarios/Activities/ActivityIcalTest.php b/tests/scenarios/Activities/ActivityIcalTest.php new file mode 100644 index 00000000000..6cbb002e41e --- /dev/null +++ b/tests/scenarios/Activities/ActivityIcalTest.php @@ -0,0 +1,126 @@ +<?php +/** + * Copyright (c) 2012-2021, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ActivityIcalTest extends ModelTestCase { + protected $_ical; + + public function setUp() { + parent::setUp(); + + $this->fixture(Class_Profil::class, ['id' => 22]) + ->beCurrentProfil(); + + $activity = $this->fixture(Class_Activity::class, + ['id' => 333, + 'libelle' => 'Festival animation']); + + $session_activity = $this + ->fixture(Class_SessionActivity::class, + ['id' => 444, + 'activity' => $activity, + 'date_debut' => '2012-03-27 13:00:00', + 'date_fin' => '2012-03-27 18:00:00', + 'intervenants' => [], + 'lieu' => $this->fixture(Class_Lieu::class, + ['id' => 3, + 'libelle' => 'Annecy', + 'latitude' => '45.916', + 'longitude' => '6.133']), + ]); + + $activity + ->setSessions([$session_activity]) + ->assertSave(); + + $this->_ical = (new Class_ICal_SessionActivity($session_activity)) + ->renderCalendar(Class_Profil::getCurrentProfil()); + } + + + /** @test */ + public function uidShouldBeSessionActivity444() { + $this->assertRegExp('/^UID:.*session-activity:444/m', $this->_ical); + } + + + /** @test */ + public function summaryShouldBeFestivalAnimation() { + $this->assertRegExp('/^SUMMARY:Festival animation/m', $this->_ical); + } + + + /** @test */ + public function dtstartShouldBe20120327T000000InTimeZoneParis() { + $this->assertRegExp('/^DTSTART;TZID=Europe\/Paris:20120327T130000/m', $this->_ical); + } + + + /** @test */ + public function urlShouldBeAbonneActivitiesRegistered() { + $this->assertRegExp('#^URL:.*/abonne/activities-registered/id_profil/22#m', $this->_ical); + } + + + /** @test */ + public function locationShouldBeAnnecy() { + $this->assertRegExp('/^LOCATION:Annecy/m', $this->_ical); + } + + + /** @test */ + public function geoShouldBeLat45Long6() { + $this->assertRegExp('/^GEO:45.916000;6.133000/m', $this->_ical); + } + + + + protected function _renderICalWithLatitudeAndLongitude($lat, $long) { + $session = Class_SessionActivity::find(444); + $session->getLieu() + ->setLatitude($lat) + ->setLongitude($long); + + return (new Class_ICal_SessionActivity($session)) + ->renderCalendar(Class_Profil::getCurrentProfil()); + } + + + /** @test */ + public function withLongitudeAndLatitudeZeroICalGE0ShouldBeZeroAndZero() { + $this->assertRegExp('/^GEO:0.000000;0.000000/m', + $this->_renderICalWithLatitudeAndLongitude('0', '0')); + } + + + /** @test */ + public function withLongitudeAndLatitudeEmptyICalShouldNotContainsGEO() { + $this->assertNotContains('GEO', + $this->_renderICalWithLatitudeAndLongitude('', '')); + } + + + /** @test */ + public function withLongitudeAndLatitudeNullICalShouldNotContainsGEO() { + $this->assertNotContains('GEO', + $this->_renderICalWithLatitudeAndLongitude(null, null)); + } +} -- GitLab