diff --git a/VERSIONS_HOTLINE/150820 b/VERSIONS_HOTLINE/150820
new file mode 100644
index 0000000000000000000000000000000000000000..eec24b17493f0761d74b56a62f64448aab0e95e1
--- /dev/null
+++ b/VERSIONS_HOTLINE/150820
@@ -0,0 +1 @@
+ - correctif #150820 : [MT] Lettres d'information : Quand un utilisateur s'abonne ou se désabonne d'une lettre d'information, le lien de désabonnement ou d'abonnement est maintenant correctement affiché.
\ No newline at end of file
diff --git a/library/Class/Users.php b/library/Class/Users.php
index 4e576d855440857273f526f25cbb4d603c58a5f7..86e0a39cb12d3762efaf2feeaf0fd2c56fdaa5d5 100644
--- a/library/Class/Users.php
+++ b/library/Class/Users.php
@@ -507,6 +507,7 @@ class Class_Users extends Storm_Model_Abstract {
                                   'is_contact_mail' => 0,
                                   'ordreabon' => 0,
                                   'id_panier_courant' => 0,
+//                                  'disable_newsletter' => 0,
                                   'settings' => '',
                                   'statut' => 0,
                                   'id_int_bib' => null];
diff --git a/library/templates/Intonation/Library/Widget/Carousel/Newsletter/View.php b/library/templates/Intonation/Library/Widget/Carousel/Newsletter/View.php
index 0f8f2a27565aeba35d2c1391ee110e5a9be4928c..aff584ed3a8dc015826e34ce74001f97537feb3e 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/Newsletter/View.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/Newsletter/View.php
@@ -23,6 +23,10 @@
 class Intonation_Library_Widget_Carousel_Newsletter_View
   extends Intonation_Library_Widget_Carousel_View {
 
+  public function shouldCacheContent() {
+    return !Class_Users::hasIdentity();
+  }
+
 
   protected function _findElements() {
     return Class_Newsletter::findAllBy(['draft' => 0,
@@ -42,6 +46,6 @@ class Intonation_Library_Widget_Carousel_Newsletter_View
 
 
   protected function _getWrapper() {
-    return 'Intonation_Library_View_Wrapper_Newsletter';
+    return Intonation_Library_View_Wrapper_Newsletter::class;
   }
 }
diff --git a/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php b/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
index 3f1c0c9e5ff58674fc00f964226e2603b496d632..b7cfb15abd8c59774d79d7ddc060f99f0e59c2e6 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
@@ -32,7 +32,7 @@ abstract class AbstractAbonneControllerNewslettersTestCase extends AbstractContr
     Class_AdminVar::newInstanceWithId('CHAMPS_FICHE_UTILISATEUR',
                                       ['valeur' => 'pseudo;nom;prenom;mail;password']);
 
-    $this->marcus = $this->fixture('Class_Users',
+    $this->marcus = $this->fixture(Class_Users::class,
                                    ['id'=> 10,
                                     'prenom' => 'Marcus',
                                     'nom' => 'Miller',
@@ -60,13 +60,13 @@ abstract class AbonneControllerWithTwoNewslettersTestCase extends AbstractAbonne
   public function setUp() {
     parent::setUp();
 
-    $this->concerts = $this->fixture('Class_Newsletter',
+    $this->concerts = $this->fixture(Class_Newsletter::class,
                                      ['id' => 12,
                                       'titre' =>'Concerts',
                                       'mail_subject' => 'Concerts',
                                       'contenu' => 'Festival jazz']);
 
-    $this->visites = $this->fixture('Class_Newsletter',
+    $this->visites = $this->fixture(Class_Newsletter::class,
                                     ['id' => 14,
                                      'titre' =>'Visites',
                                      'mail_subject' => 'Visites',
@@ -573,7 +573,7 @@ class AbonneControllerNewslettersSubscriptionTest extends AbonneControllerWithTw
 
   public function setUp() {
     parent::setUp();
-    $_SERVER['HTTP_REFERER'] = '/opac/index';
+    $_SERVER['HTTP_REFERER'] = '/opac/widget/render/widget_id/1/profile_id/72';
     $this->dispatch('/opac/abonne/subscribe-newsletter/id/14',true);
 
   }
@@ -587,7 +587,7 @@ class AbonneControllerNewslettersSubscriptionTest extends AbonneControllerWithTw
 
   /** @test **/
   public function subscribeActionShouldRedirectToCurrentPage() {
-    $this->assertRedirectTo('/opac/index');
+    $this->assertRedirectTo('/opac/widget/render/widget_id/1/profile_id/72');
   }
 
 
@@ -689,7 +689,7 @@ class AbonneControllerNewslettersMultipleUnSubscriptionTest extends AbstractCont
 
     $_SERVER['HTTP_REFERER'] = '/opac/index';
 
-    $user = $this->fixture('Class_Users',
+    $user = $this->fixture(Class_Users::class,
                            ['id' => 156,
                             'login' => 'tomato',
                             'password' => 'pwd',
@@ -740,7 +740,7 @@ class AbonneControllerNewslettersMultipleSubscriptionTest extends AbstractContro
     parent::setUp();
     $_SERVER['HTTP_REFERER'] = '/opac/index';
 
-    $user = $this->fixture('Class_Users',
+    $user = $this->fixture(Class_Users::class,
                            ['id' => 156,
                             'login' => 'tomato',
                             'password' => 'pwd',
diff --git a/tests/scenarios/Templates/TemplatesAbonneTest.php b/tests/scenarios/Templates/TemplatesAbonneTest.php
index 666cff2058a0655ad19e3dc609365cc20e657f30..a2e74776abf86ecfdf4e04f66ffe76fb3165f0a9 100644
--- a/tests/scenarios/Templates/TemplatesAbonneTest.php
+++ b/tests/scenarios/Templates/TemplatesAbonneTest.php
@@ -28,7 +28,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
 
   public function setUp() {
     parent::setUp();
-    $item = $this->fixture('Class_Exemplaire',
+    $item = $this->fixture(Class_Exemplaire::class,
                            ['id' => 967,
                             'code_barres' => 123,
                             'id_int_bib' => 1,
@@ -64,7 +64,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
       ->setCodeBarre(124)
       ->getExemplaire()
       ->setTitre('Alice')
-      ->setExemplaireOPAC($this->fixture('Class_Exemplaire',
+      ->setExemplaireOPAC($this->fixture(Class_Exemplaire::class,
                                          ['id' => 918,
                                           'id_origine' => 5678,
                                           'code_barres' => 124,
@@ -103,7 +103,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
                    ]);
 
 
-    $exemplaire_dobby = $this->fixture('Class_Exemplaire',
+    $exemplaire_dobby = $this->fixture(Class_Exemplaire::class,
                                        ['id' => 12089,
                                         'code_barres' => 123,
                                         'id_int_bib' => 1,
@@ -112,7 +112,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
                                                                   ['code' => 'h', 'valeur' => 'Numero 23']]),
                                         'id_notice' => 820]);
 
-    $exemplaire_troy = $this->fixture('Class_Exemplaire',
+    $exemplaire_troy = $this->fixture(Class_Exemplaire::class,
                                       ['id' => 12090,
                                        'code_barres' => 123,
                                        'id_int_bib' => 1,
@@ -150,7 +150,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
       ->setAvailabilityEndDate('2020-06-06')
       ->setWaitingToBePulled();
 
-    $istres = $this->fixture('Class_CodifAnnexe',
+    $istres = $this->fixture(Class_CodifAnnexe::class,
                              ['id' => 15,
                               'libelle' => 'Istres',
                               'id_origine' => 'IST']);
@@ -176,12 +176,12 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
       ->setPseudo('Paul')
       ->beAbonneSIGB();
 
-    $this->fixture('Class_Notice',
+    $this->fixture(Class_Notice::class,
                    ['id' => 10,
                     'titre_principal' => 'Le combat ordinaire',
                     'clef_alpha' => 'COMBAT ORDINAIRE']);
 
-    $this->fixture('Class_Notice',
+    $this->fixture(Class_Notice::class,
                    ['id' => 12,
                     'titre_principal' => 'Blacksad',
                     'clef_alpha' => 'BLACKSAD']);
@@ -190,7 +190,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
                                    ['id' => 1,
                                     'libelle' => 'Libre']);
 
-    $mes_bd = $this->fixture('Class_PanierNotice',
+    $mes_bd = $this->fixture(Class_PanierNotice::class,
                              ['id' => 2,
                               'id_panier' => 1,
                               'libelle' => 'Mes BD',
@@ -204,14 +204,14 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
       ->setParams(['expressionRecherche' => 'Harry Potter',
                    'page' => 2]);
 
-    $this->fixture('Class_User_BookmarkedSearch',
+    $this->fixture(Class_User_BookmarkedSearch::class,
                    ['id' => 5,
                     'id_user' => $current_user->getId(),
                     'label' => 'Potter',
                     'criterias' => serialize($criteres_potter),
                     'creation_date' => '2020-01-17 15:05:57']);
 
-    $this->fixture('Class_AvisNotice',
+    $this->fixture(Class_AvisNotice::class,
                    ['id' => 4,
                     'id_user' => 666,
                     'id_notice' => 20090,
@@ -221,28 +221,63 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
                     'avis' => 'Le Roi des cons sur son throne',
                     'source_author' => null]);
 
-    $this->fixture('Class_Notice',
+    $this->fixture(Class_Notice::class,
                    ['id' => 20090,
                     'url_vignette' => '404.jpg',
                     'clef_oeuvre' => 'PSYKO',
                    ])
          ->setTitrePrincipal('Psykoooo');
 
-    $newsletter = $this->fixture('Class_Newsletter',
+    $newsletter = $this->fixture(Class_Newsletter::class,
                                  ['id' => 45,
                                   'titre' => 'Les nouveautés',
                                   'mail_subject' => 'nouveautés',
                                   'contenu' => 'test de newsletter: http://monurl.newsletter.fr. http://mon-domain.org']);
 
+    $this->fixture(Class_Newsletter::class,
+                   ['id' => 46,
+                    'titre' => 'Les coups de coeur',
+                    'mail_subject' => 'coups de coeurs',
+                    'contenu' => 'On a aimé: http://monurl.newsletter.fr. http://mon-domain.org']);
+
     $current_user->setNewsletters([$newsletter]);
 
+
+    Storm_Cache::setSeed('local');
+    $mock = $this->mock();
+    $mock
+      ->whenCalled('fetchAll')
+      ->with('select user_id as id from user_group_memberships where user_group_id=' . Class_Newsletter::find(46)->getDedicatedGroup()->getId())
+      ->answers([])
+
+      ->whenCalled('fetchAll')
+      ->with('select user_id as id from user_group_memberships where user_group_id=' . Class_Newsletter::find(45)->getDedicatedGroup()->getId())
+      ->answers([['id' => $current_user->getId()]])
+
+      ->whenCalled('fetchAll')
+      ->with("select id_notice, facettes from notices Where (MATCH(titres, auteurs, editeur, collection, matieres, dewey, other_terms) AGAINST('+(HARRY HARRYS ARI) +(POTTER POTTERS POT)' IN BOOLEAN MODE)) and type=1 order by (MATCH(titres) AGAINST(' HARRY POTTER') * 1.5) + (MATCH(auteurs) AGAINST(' HARRY POTTER')) desc",true,false)
+      ->answers([])
+
+      ->whenCalled('fetchAll')
+      ->with("select id_notice, facettes from notices Where (MATCH(titres, auteurs, editeur, collection, matieres, dewey, other_terms) AGAINST(' (HARRY HARRYS ARI)  (POTTER POTTERS POT)')) and type=1 order by (MATCH(titres) AGAINST(' HARRY POTTER') * 1.5) + (MATCH(auteurs) AGAINST(' HARRY POTTER')) desc",true,false)
+      ->answers([])
+
+      ->whenCalled('fetchAll')
+      ->with("select id_notice, facettes from notices Where type=1 limit 10000", true, false)
+      ->answers([])
+
+      ->beStrict();
+
+
+    Zend_Registry::set('sql', $mock);
+
     Class_Loan_Pnb::setTimeSource(new TimeSourceForTest('2017-11-14 10:23:10'));
     Class_AdminVar::set('DILICOM_PNB_ENABLE_HOLDS', 1);
 
     $http = $this->mock()->whenCalled('open_url')->answers(null);
     Class_WebService_BibNumerique_Dilicom_Hub::setDefaultHttpClient($http);
 
-    $pnb_album = $this->fixture('Class_Album',
+    $pnb_album = $this->fixture(Class_Album::class,
                                 ['id' => 543,
                                  'titre' => 'Dr House',
                                  'visible' => 1,
@@ -251,7 +286,7 @@ abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTes
 
     $pnb_album->index();
 
-    $this->fixture('Class_Loan_Pnb',
+    $this->fixture(Class_Loan_Pnb::class,
                    ['id' => 3,
                     'record_origin_id' => 'Dilicom-3663608260879',
                     'subscriber_id' => '',
@@ -297,8 +332,6 @@ class TemplatesDispatchAbonneLoansTest extends TemplatesIntonationAccountTestCas
 
 
 abstract class TemplatesAbonnePaginatedCollectionsTestCase extends TemplatesIntonationAccountTestCase {
-
-
   public function setUp() {
     parent::setUp();
 
@@ -502,7 +535,7 @@ class TemplateAbonnePaginatedCollectionWithNoResultTest extends TemplatesAbonneP
 
 
 
-class TemplatesDispatchAbonneAjaxLoansTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchAjaxLoansTest extends TemplatesIntonationAccountTestCase {
   public function setUp(){
     parent::setUp();
 
@@ -556,7 +589,7 @@ class TemplatesDispatchAbonneAjaxLoansTest extends TemplatesIntonationAccountTes
 
 
 
-abstract class TemplatesDispatchAbonneWithILSChildCardTestCase extends TemplatesIntonationAccountTestCase {
+abstract class TemplatesAbonneDispatchWithILSChildCardTestCase extends TemplatesIntonationAccountTestCase {
   public function setUp() {
     parent::setUp();
     $user =
@@ -614,7 +647,7 @@ abstract class TemplatesDispatchAbonneWithILSChildCardTestCase extends Templates
 
 
 
-class TemplatesDispatchAbonnesWithILSChildCardFailuresTest extends TemplatesDispatchAbonneWithILSChildCardTestCase {
+class TemplatesAbonneDispatchsWithILSChildCardFailuresTest extends TemplatesAbonneDispatchWithILSChildCardTestCase {
   /** @test */
   public function WithOrdreabonn1LoanlistTitleShouldNotContainsBeartEnPublic() {
     Class_Users::find(42)->setOrdreabon(1);
@@ -680,7 +713,7 @@ class TemplatesDispatchAbonnesWithILSChildCardFailuresTest extends TemplatesDisp
 
 
 
-class TemplatesDispatchAbonneAjaxLoansWithILSChildCardTest extends TemplatesDispatchAbonneWithILSChildCardTestCase {
+class TemplatesAbonneDispatchAjaxLoansWithILSChildCardTest extends TemplatesAbonneDispatchWithILSChildCardTestCase {
   public function setUp(){
     parent::setUp();
     $this->dispatch('/opac/abonne/ajax-loans/id_profil/72');
@@ -705,7 +738,7 @@ class TemplatesDispatchAbonneAjaxLoansWithILSChildCardTest extends TemplatesDisp
 
 
 
-class TemplatesDispatchAbonneReservationWithILSChildCardTest extends TemplatesDispatchAbonneWithILSChildCardTestCase {
+class TemplatesAbonneDispatchReservationWithILSChildCardTest extends TemplatesAbonneDispatchWithILSChildCardTestCase {
   public function setUp(){
     parent::setUp();
     $this->dispatch('/opac/abonne/reservations/id_profil/72');
@@ -729,7 +762,7 @@ class TemplatesDispatchAbonneReservationWithILSChildCardTest extends TemplatesDi
 
 
 
-class TemplatesDispatchAbonneMonHistoriqueTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchMonHistoriqueTest extends TemplatesIntonationAccountTestCase {
   public function setUp(){
     parent::setUp();
 
@@ -737,13 +770,13 @@ class TemplatesDispatchAbonneMonHistoriqueTest extends TemplatesIntonationAccoun
     $notice_unimarc = (new Class_NoticeUnimarc_Fluent);
     $notice_unimarc->newZone()->label('200')->addChild('a', 'Pottifar');
 
-    $notice = $this->fixture('Class_Notice',
+    $notice = $this->fixture(Class_Notice::class,
                              ['id' => 890,
                               'clef_alpha' => 'MYSUPERkey',
                               'unimarc' => $notice_unimarc->render(),
                               'facettes' => 'M8897 T1 B3 A18 Lfre']);
 
-    $exemplaire = $this->fixture('Class_Exemplaire',
+    $exemplaire = $this->fixture(Class_Exemplaire::class,
                                  ['id' => 891,
                                   'id_origine' => 1234,
                                   'code_barres' => 456,
@@ -788,7 +821,7 @@ class TemplatesDispatchAbonneMonHistoriqueTest extends TemplatesIntonationAccoun
 
 
 
-class TemplatesDispatchAbonneLoansWithHistoryTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchLoansWithHistoryTest extends TemplatesIntonationAccountTestCase {
   public function setUp(){
     parent::setUp();
 
@@ -796,13 +829,13 @@ class TemplatesDispatchAbonneLoansWithHistoryTest extends TemplatesIntonationAcc
     $notice_unimarc = (new Class_NoticeUnimarc_Fluent);
     $notice_unimarc->newZone()->label('200')->addChild('a', 'Pottifar');
 
-    $notice = $this->fixture('Class_Notice',
+    $notice = $this->fixture(Class_Notice::class,
                              ['id' => 890,
                               'clef_alpha' => 'MYSUPERkey',
                               'unimarc' => $notice_unimarc->render(),
                               'facettes' => 'M8897 T1 B3 A18 Lfre']);
 
-    $exemplaire = $this->fixture('Class_Exemplaire',
+    $exemplaire = $this->fixture(Class_Exemplaire::class,
                                  ['id' => 891,
                                   'id_origine' => 1234,
                                   'code_barres' => 456,
@@ -861,7 +894,7 @@ class TemplatesDispatchAbonneLoansWithHistoryTest extends TemplatesIntonationAcc
 
 
 
-class TemplatesDispatchAbonneHoldsTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchHoldsTest extends TemplatesIntonationAccountTestCase {
   public function setUp(){
     parent::setUp();
 
@@ -909,7 +942,7 @@ class TemplatesDispatchAbonneHoldsTest extends TemplatesIntonationAccountTestCas
 
 
 
-class TemplatesDispatchAbonneLargeNumberOfHoldsTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchLargeNumberOfHoldsTest extends TemplatesIntonationAccountTestCase {
   public function setUp(){
     parent::setUp();
 
@@ -988,7 +1021,7 @@ class TemplatesDispatchAbonneLargeNumberOfHoldsTest extends TemplatesIntonationA
 
 
 
-class TemplatesDispatchAbonneReviewsTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchReviewsTest extends TemplatesIntonationAccountTestCase {
   /** @test */
   public function leRoiDesConsShouldBeDisplay() {
     $this->dispatch('/opac/abonne/mes-avis/id_profil/72');
@@ -1014,7 +1047,7 @@ class TemplatesDispatchAbonneReviewsTest extends TemplatesIntonationAccountTestC
 
 
 
-class TemplatesDispatchAbonneConfigurationsTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchConfigurationsTest extends TemplatesIntonationAccountTestCase {
 
   public function setUp() {
     parent::setUp();
@@ -1036,7 +1069,7 @@ class TemplatesDispatchAbonneConfigurationsTest extends TemplatesIntonationAccou
 
 
 
-class TemplatesDispatchAbonneDonnerDesAvisTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchDonnerDesAvisTest extends TemplatesIntonationAccountTestCase {
   /** @test */
   public function donnerDesAvisShouldBeDisplay() {
     $this->dispatch('/opac/abonne/donner-des-avis/id_profil/72');
@@ -1047,7 +1080,7 @@ class TemplatesDispatchAbonneDonnerDesAvisTest extends TemplatesIntonationAccoun
 
 
 
-class TemplatesDispatchAbonneSuivreUneRechercheTest
+class TemplatesAbonneDispatchSuivreUneRechercheTest
   extends TemplatesIntonationAccountTestCase {
 
 
@@ -1285,10 +1318,11 @@ class TemplatesAbonneAccountEditTest extends TemplatesIntonationAccountTestCase
 
 
 
-class TemplatesIntonationDispatchAccountTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchAccountTest extends TemplatesIntonationAccountTestCase {
   public function setUp() {
     parent::setUp();
     Class_FileManager::setFileSystem(null);
+
     $this->dispatch('/opac/abonne/fiche/id_profil/72');
   }
 
@@ -1375,6 +1409,48 @@ class TemplatesIntonationDispatchAccountTest extends TemplatesIntonationAccountT
   public function paulShouldHaveLinkToEditProfileImage() {
     $this->assertXPath('//div//a[contains(@href, "/abonne/change-image")][contains(@title, "Modifier mon image")]');
   }
+
+
+  /** @test */
+  public function pageNewsletterDisplayShouldContainsNewsLetterLesNouveautes() {
+    $this->assertXPathContentContains('//div[contains(@class, "card_title_Intonation_Library_View_Wrapper_Newsletter")]//a', 'Les nouveautés');
+  }
+
+
+  /** @test */
+  public function pageNewsletterDisplayShouldContainsLinkMeDesinscrire() {
+    $this->assertXPathContentContains('//a[contains(@href,"unsubscribe-newsletter/id/45")]', 'Me désinscrire', $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function pageNewsletterLinkMeDesinscrireShouldContainsTitleMeDesinscrire() {
+    $this->assertXPathContentContains('//a[contains(@href,"unsubscribe-newsletter/id/45")]//@title', 'Me désinscrire à la lettre d\'information Les nouveautés');
+  }
+
+
+  /** @test */
+  public function pageNewsletterDisplayShouldContainsNewsLetterCoupsDeCoeur() {
+    $this->assertXPathContentContains('//div[contains(@class, "card_title_Intonation_Library_View_Wrapper_Newsletter")]//a', 'coups de coeur');
+  }
+
+
+  /** @test */
+  public function pageWithNewsletterInformationLinkToSubscribeShouldContainsLesCoupsDeCoeur() {
+    $this->assertXPathContentContains('//div[contains(@class, "card_title_Intonation_Library_View_Wrapper_Newsletter")]//a[contains(@href,"subscribe-newsletter/id/46")]', 'Les coups de coeur');
+  }
+
+
+  /** @test */
+  public function pageWithNewsletterInformationActionShouldContainsLinkMInscrire() {
+    $this->assertXPathContentContains('//div[contains(@class, "card_action")]//a[contains(@href,"subscribe-newsletter/id/46")]', 'M\'inscrire');
+  }
+
+
+  /** @test */
+  public function pageNewsletterDisplayShouldContainsTitleMinscrireALaLettre() {
+    $this->assertXPathContentContains('//a[contains(@href,"subscribe-newsletter/id/46")]/@title', 'M\'inscrire à la lettre d\'information Les coups de coeur');
+  }
 }
 
 
@@ -1402,7 +1478,7 @@ class TemplatesAbonneInformationsTest extends TemplatesIntonationAccountTestCase
 
 
 
-class TemplatesDispatchAbonneClearHistoryTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchClearHistoryTest extends TemplatesIntonationAccountTestCase {
   /** @test */
   public function shouldRedirect() {
     $this->dispatch('/opac/abonne/clear-history/id_profil/72');
@@ -1413,7 +1489,7 @@ class TemplatesDispatchAbonneClearHistoryTest extends TemplatesIntonationAccount
 
 
 
-class TemplatesDispatchAbonneCardsTest extends TemplatesIntonationAccountTestCase {
+class TemplatesAbonneDispatchCardsTest extends TemplatesIntonationAccountTestCase {
   public function setUp() {
     parent::setUp();
     $this->dispatch('/opac/abonne/cards/id_profil/72');
@@ -1427,7 +1503,7 @@ class TemplatesDispatchAbonneCardsTest extends TemplatesIntonationAccountTestCas
 }
 
 
-class TemplatesDispatchAbonnePagesTest extends AbstractControllerTestCase {
+class TemplatesAbonneDispatchPagesTest extends AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
 
   public function setUp() {
@@ -1476,13 +1552,13 @@ class TemplatesAbonneWithPNBHoldsTest extends AbstractControllerTestCase {
     $this->_buildTemplateProfil(['id' => 90,
                                  'template' => 'CHILI']);
 
-    $group = $this->fixture('Class_UserGroup',
+    $group = $this->fixture(Class_UserGroup::class,
                             ['id' => '20',
                              'libelle' => 'Multimedia',
                              'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]]);
 
     $logged_user =
-      $this->fixture('Class_Users',
+      $this->fixture(Class_Users::class,
                      ['id' => 6,
                       'nom'=>'Pito',
                       'login'=>'Chat',
@@ -1988,7 +2064,6 @@ class TemplatesAbonneCacheSuggestionsTest extends TemplatesAbonneCacheTestCase {
 
 class TemplatesAbonnePaginatedReviewsSearchConsRoiTest extends TemplatesAbonnePaginatedReviewsPage2Test {
 
-
   protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
     $this->dispatch('/opac/index/ajax-paginated-list/page/1/render/ajax/size/3/search/cons+roi/id/' . $helper->getId());
   }
diff --git a/tests/scenarios/Templates/TemplatesNewslettersTest.php b/tests/scenarios/Templates/TemplatesNewslettersTest.php
index 9f80447777aa8b7a21e90f6762760dd988886bb3..9f4a6f5b7d565a3ae946d114097d43e436f077df 100644
--- a/tests/scenarios/Templates/TemplatesNewslettersTest.php
+++ b/tests/scenarios/Templates/TemplatesNewslettersTest.php
@@ -30,7 +30,7 @@ class TemplatesNewslettersWidgetWithDescriptionLengthTest extends AbstractContro
     Class_AdminVar::set('TEMPLATING', 1);
     ZendAfi_Auth::getInstance()->clearIdentity();
 
-    $profile = $this->fixture('Class_Profil',
+    $profile = $this->fixture(Class_Profil::class,
                               ['id' => 34,
                                'template' => 'MUSCLE'
                               ]);
@@ -48,7 +48,7 @@ class TemplatesNewslettersWidgetWithDescriptionLengthTest extends AbstractContro
                    'size' => 1,
                    'description_length' => 4]);
 
-    $this->fixture('Class_Newsletter',
+    $this->fixture(Class_Newsletter::class,
                    ['id' => 3,
                     'titre' => 'Jeunesse',
                     'mail_subject' => 'Jeunesse',
@@ -74,7 +74,8 @@ class TemplatesNewslettersWidgetWithDescriptionLengthTest extends AbstractContro
 
 
 
-class TemplatesNewslettersWidgetWithCatalogueTestCase extends AbstractControllerTestCase {
+class TemplatesNewslettersWidgetWithCatalogueTestCase
+  extends AbstractControllerTestCase {
 
   protected
     $_storm_default_to_volatile = true,
@@ -138,9 +139,8 @@ class TemplatesNewslettersWidgetWithCatalogueTestCase extends AbstractController
 
 
 
-class TemplatesNewslettersWidgetWithCatalogueAndZeroNbRecords extends TemplatesNewslettersWidgetWithCatalogueTestCase {
-
-
+class TemplatesNewslettersWidgetWithCatalogueAndZeroNbRecords
+    extends TemplatesNewslettersWidgetWithCatalogueTestCase {
   protected $_nb_notices = 0;
 
 
@@ -153,6 +153,7 @@ class TemplatesNewslettersWidgetWithCatalogueAndZeroNbRecords extends TemplatesN
 
 
 
+
 class TemplatesNewslettersWidgetWithCatalogueAndOneNbRecords extends TemplatesNewslettersWidgetWithCatalogueTestCase {
 
 
@@ -164,3 +165,121 @@ class TemplatesNewslettersWidgetWithCatalogueAndOneNbRecords extends TemplatesNe
     $this->assertTrue(Class_Notice::methodHasBeenCalled('getNoticesFromPreferences'));
   }
 }
+
+
+
+
+abstract class TemplatesNewslettersIndexWithWidgetTestCase extends AbstractControllerTestCase {
+
+  protected $_storm_default_to_volatile = true;
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $user =
+      $this->fixture(Class_Users::class,
+                     ['id' => 42,
+                      'login' => 'bilbon',
+                      'role_level' => ZendAfi_Acl_AdminControllerRoles::INVITE,
+                      'disable_newsletter' => 0,
+                      'password' => 's3cr3t']);
+
+    $this->_userConnected();
+
+    $profile = $this->_buildTemplateProfil(['id' => 34]);
+
+    $profile_patcher = (new Class_Template_ProfilePatcher(null))
+      ->setProfile($profile);
+
+    $profile_patcher
+      ->addWidget(Intonation_Library_Widget_Carousel_Newsletter_Definition::CODE,
+                  Class_Profil::DIV_MAIN,
+                  ['rendering' => 'card-description',
+                   'layout' => 'list',
+                   'size' => 1,
+                   'description_length' => 4]);
+
+    $prefs = $profile->getModuleAccueilPreferences(1,'NEWS');
+
+    $newsletter =
+      $this->fixture(Class_Newsletter::class,
+                     ['id' => 3,
+                      'titre' => 'Jeunesse',
+                      'mail_subject' => 'Jeunesse',
+                      'contenu' => 'La description s\'arrête ici et pas plus loin.']);
+
+    $user->addNewsletter($newsletter)->save();
+
+    $sql_mock = $this
+      ->mock()
+
+      ->whenCalled('fetchAll')
+      ->with('select user_id as id from user_group_memberships where user_group_id=1')
+      ->answers([['id' => 42]])
+
+      ->beStrict();
+
+    Zend_Registry::set('sql', $sql_mock);
+
+    Storm_Cache::beVolatile();
+
+
+    $key = [1,
+            34,
+            'fr',
+            $prefs];
+
+    (new Storm_Cache)->memoize($key, fn() => 'Cache de la boite newsletter.');
+
+    $this->dispatch('/index');
+  }
+
+
+  /** @test */
+  public function userGroupForNewsletterJeunesseShouldBeCreated() {
+    $this->assertEquals('Groupe manuel pour la lettre "Jeunesse"',
+                        Class_UserGroup::find(1)->getLibelle());
+  }
+
+
+  /** @test */
+  public function bilbonShouldBeInGroupManuelJeunesse() {
+    $this->assertTrue(Class_UserGroup::find(1)->hasUser(Class_Users::find(42)));
+  }
+}
+
+
+
+
+class TemplatesNewslettersIndexWithWidgetAndUserConnectedTest extends TemplatesNewslettersIndexWithWidgetTestCase {
+
+
+  protected function _userConnected() {
+    ZendAfi_Auth::getInstance()->logUser(Class_Users::find(42));
+  }
+
+
+  /** @test */
+  public function linkUnsubscribeShouldBePresent() {
+    $this->assertXPathContentContains('//div[@class="card-footer d-flex flex-row justify-content-between card_footer card_footer_Intonation_Library_View_Wrapper_Newsletter"]//a[@href="/abonne/unsubscribe-newsletter/id/3"]',
+                                      'Me désinscrire');
+  }
+}
+
+
+
+
+class TemplatesNewslettersIndexWithWidgetAndNoUserTest extends TemplatesNewslettersIndexWithWidgetTestCase {
+
+  protected function _userConnected() {
+    ZendAfi_Auth::getInstance()->clearIdentity();
+  }
+
+
+  /** @test */
+  public function bodyShouldContainsHtmlCacheOfNewsletterWidget() {
+    $this->assertXPathContentContains('//body//div[@class="section_content_wrapper"]',
+                                      'Cache de la boite newsletter.');
+  }
+}
\ No newline at end of file