diff --git a/library/ZendAfi/View/Helper/MonocleReaderServerSide.php b/library/ZendAfi/View/Helper/MonocleReaderServerSide.php
index c80c9421d9f8fbe6520f6b6be780ede2464c7ccf..8a710caa8a796f11f2f3fdffdeeb67fbfda6f73a 100644
--- a/library/ZendAfi/View/Helper/MonocleReaderServerSide.php
+++ b/library/ZendAfi/View/Helper/MonocleReaderServerSide.php
@@ -108,7 +108,8 @@ class ZendAfi_View_Helper_MonocleReaderServerSide extends Zend_View_Helper_HtmlE
                                          'controller' => 'bib-numerique',
                                          'action' => 'full-screen',
                                          'id' => $ressource->getId()],
-                                        '<img src="'.URL_ADMIN_IMG.'picto/show.gif" title="'.$this->view->_('Plein écran').'">',
+                                        $this->view->tagImg(URL_ADMIN_IMG . 'picto/show.gif',
+                                                            ['alt' => $this->view->_('Plein écran')]),
                                         ['data-ajax' => 'false']
           );
       }
diff --git a/library/storm b/library/storm
index 580af71e233e87517e38d9fab12df9d3b7bcee29..57fb2c7f9ae96f2cb825484e4576619ffa2d91e7 160000
--- a/library/storm
+++ b/library/storm
@@ -1 +1 @@
-Subproject commit 580af71e233e87517e38d9fab12df9d3b7bcee29
+Subproject commit 57fb2c7f9ae96f2cb825484e4576619ffa2d91e7
diff --git a/public/opac/java/slider_navigation/tests/agenda_slider_test.js b/public/opac/java/slider_navigation/tests/agenda_slider_test.js
index dc6cbeeef1be6ef741df1d8ea7a24e803b09d51c..b9327a596ce7e24217f4b573f94492b3c4da2c43 100644
--- a/public/opac/java/slider_navigation/tests/agenda_slider_test.js
+++ b/public/opac/java/slider_navigation/tests/agenda_slider_test.js
@@ -103,21 +103,21 @@ test('window height should be 80px', function() {
 });
 
 
-QUnit.asyncTest('cycle should trigger click and move articles', function( assert ) {
+QUnit.asyncTest('cycle should not trigger click and not move articles', function( assert ) {
   expect( 1 );
- 
+  fixture.trigger('click');
   setTimeout(function() {
-     deepEqual(fixture.find('div.news_row').css('margin-left'), '-110px', fixture.html());
+    deepEqual(fixture.find('div.news_row').css('margin-left'), '0px', fixture.html());
     QUnit.start();
-  }, 1000);
+  }, 1500);
 });
 
 
-QUnit.asyncTest('cycle should not trigger click and not move articles', function( assert ) {
+QUnit.asyncTest('cycle should trigger click and move articles', function( assert ) {
   expect( 1 );
-  fixture.trigger('click');
+ 
   setTimeout(function() {
-     deepEqual(fixture.find('div.news_row').css('margin-left'), '0px', fixture.html());
+     deepEqual(fixture.find('div.news_row').css('margin-left'), '-110px', fixture.html());
     QUnit.start();
-  }, 1500);
+  }, 1000);
 });
diff --git a/tests/application/modules/AbstractControllerTestCase.php b/tests/application/modules/AbstractControllerTestCase.php
index 95323ebfef9ba8aabcee8765edb101d4b89eb563..b6a06e301855c2ab6c7f0cc681dfb4c67d0efde0 100644
--- a/tests/application/modules/AbstractControllerTestCase.php
+++ b/tests/application/modules/AbstractControllerTestCase.php
@@ -181,7 +181,7 @@ abstract class AbstractControllerTestCase extends Zend_Test_PHPUnit_ControllerTe
 
 
   protected function _generateLoaderFor($model, $methods) {
-    $loader = $this->getMock('Mock'.$model, $methods);
+    $loader = $this->createMock('Mock'.$model, $methods);
     Storm_Model_Abstract::setLoaderFor($model, $loader);
     return $loader;
   }
diff --git a/tests/application/modules/admin/controllers/AmberControllerTest.php b/tests/application/modules/admin/controllers/AmberControllerTest.php
index 808e8977df622e6be8f8d61787082a8a41339866..75bd96150b556f9b0549aff50c6d3bcaa5f56fec 100644
--- a/tests/application/modules/admin/controllers/AmberControllerTest.php
+++ b/tests/application/modules/admin/controllers/AmberControllerTest.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 require_once 'AdminAbstractControllerTestCase.php';
 require_once 'application/modules/admin/controllers/AmberController.php';
@@ -33,8 +33,7 @@ class AmberControllerTest extends Admin_AbstractControllerTestCase {
     parent::setUp();
 
     $this->assertInstanceOf('Class_FileWriter', Admin_AmberController::getFileWriter());
-
-    $this->mock_filewriter = $this->getMock('Class_FileWriter', array('putContents'));
+    $this->mock_filewriter = $this->createMock('Class_FileWriter', array('putContents'));
     Admin_AmberController::setFileWriter($this->mock_filewriter);
 
     $this->_old_cfg = Zend_Registry::get('cfg');
@@ -48,7 +47,7 @@ class AmberControllerTest extends Admin_AbstractControllerTestCase {
 
   public function tearDown() {
     Zend_Registry::set('cfg', $this->_old_cfg);
-    
+
     parent::tearDown();
   }
 
@@ -70,7 +69,7 @@ class AmberControllerTest extends Admin_AbstractControllerTestCase {
       ->expects($this->once())
       ->method('putContents')
       ->with('./amber/src/js/Kernel.js', 'somejs');
-    
+
     $this->putDispatch('/admin/amber/commitJs/Kernel.js', 'somejs');
   }
 
@@ -82,7 +81,7 @@ class AmberControllerTest extends Admin_AbstractControllerTestCase {
       ->expects($this->once())
       ->method('putContents')
       ->with('./amber/afi/js/AFI-Core.js', 'somejs');
-    
+
     $this->putDispatch('/admin/amber/commitJs/AFI-Core.js', 'somejs');
   }
 
@@ -95,7 +94,7 @@ class AmberControllerTest extends Admin_AbstractControllerTestCase {
       ->expects($this->once())
       ->method('putContents')
       ->with('./amber/src/st/Kernel.st', 'some smalltalk');
-    
+
     $this->putDispatch('/admin/amber/commitSt/Kernel.st', 'some smalltalk');
   }
 
@@ -108,7 +107,7 @@ class AmberControllerTest extends Admin_AbstractControllerTestCase {
       ->mock_filewriter
       ->expects($this->never())
       ->method('putContents');
-    
+
     $this->putDispatch('/admin/amber/commitJs/Kernel.js', 'somejs');
   }
 }
diff --git a/tests/application/modules/admin/controllers/NewsletterControllerTest.php b/tests/application/modules/admin/controllers/NewsletterControllerTest.php
index 44b5a7511761730bb0a84d0fe93fd707689504bb..eeda907295e05d8dbea7b9c4abc5d1b5665f5572 100644
--- a/tests/application/modules/admin/controllers/NewsletterControllerTest.php
+++ b/tests/application/modules/admin/controllers/NewsletterControllerTest.php
@@ -424,6 +424,7 @@ class Admin_NewsletterControllerValidationsTest extends Admin_NewsletterControll
 
 
 
+
 class Admin_NewsletterControllerDeleteActionTest extends Admin_AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
 
diff --git a/tests/application/modules/admin/controllers/UsersControllerTest.php b/tests/application/modules/admin/controllers/UsersControllerTest.php
index 9062378084801fd1c9b21a0123980eb58df41749..ebe8a4becd432c2aef16aee924ae773bb9cf4d11 100644
--- a/tests/application/modules/admin/controllers/UsersControllerTest.php
+++ b/tests/application/modules/admin/controllers/UsersControllerTest.php
@@ -590,7 +590,7 @@ class UsersControllerPostValidDataWithCommOpsysTest extends UsersControllerWithM
   public function setUp() {
     parent::setUp();
 
-    $this->opsys_service = $this->getMock('MockOpsysService', ['saveEmprunteur']);
+    $this->opsys_service = $this->createMock('MockOpsysService', ['saveEmprunteur']);
     $this->emprunteur = new Class_WebService_SIGB_Emprunteur('2341', 'Marcus');
     $this->emprunteur->setService($this->opsys_service);
 
diff --git a/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php b/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
index d22e3ed68756624696a567ac9aff581f114774d8..6e8916235efac1b809b927e5076dc15ab6f265ee 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
@@ -385,7 +385,7 @@ class AbonneControllerNewslettersOpsysCommunicationTest extends AbonneController
   public function setUp() {
     parent::setUp();
 
-    $this->opsys_service = $this->getMock('MockOpsysService', array('saveEmprunteur'));
+    $this->opsys_service = $this->createMock('MockOpsysService', array('saveEmprunteur'));
     $this->emprunteur = new Class_WebService_SIGB_Emprunteur('00123', 'Marcus');
     $this->emprunteur->setService($this->opsys_service);
 
diff --git a/tests/application/modules/telephone/controllers/BibNumeriqueControllerTest.php b/tests/application/modules/telephone/controllers/BibNumeriqueControllerTest.php
index bb3b1c787d9392d5426332b79bab9666ef6c9afb..f7d09f827d82eb46687adbdb94ddcaea6b9e88e6 100644
--- a/tests/application/modules/telephone/controllers/BibNumeriqueControllerTest.php
+++ b/tests/application/modules/telephone/controllers/BibNumeriqueControllerTest.php
@@ -87,6 +87,7 @@ class BibNumeriqueControllerTelephoneViewAlbumMonumentsTest extends BibNumerique
     $this->assertXPath('//ul[@data-role="listview"]//li[@data-role="list-divider"]//a[contains(@href, "media/versailles.epub")]//img[contains(@src, "epub.png")]');
   }
 
+
   /** @test */
   public function pageShouldBeHTML5Valid() {
     $this->assertHTML5();
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index d2f3af4053c92dd09af1e2eb41de2d587f00fe1f..4e026a7b8f0af06d5e9396827b668ef844ef51c2 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -86,6 +86,7 @@ $translate->setLocale('fr');
 require_once 'tests/library/ZendAfi/View/Helper/ViewHelperTestCase.php';
 require_once 'tests/application/modules/admin/controllers/AdminAbstractControllerTestCase.php';
 require_once 'tests/fixtures/RessourcesNumeriquesFixtures.php';
+require_once 'tests/fixtures/MockedClasses.php';
 
 register_shutdown_function(function(){
   TestSpeedTrap::printSpeedTrappedTests();
diff --git a/tests/fixtures/MockedClasses.php b/tests/fixtures/MockedClasses.php
new file mode 100644
index 0000000000000000000000000000000000000000..bee98e902b6518ef9e4234332bd3595b55f892ff
--- /dev/null
+++ b/tests/fixtures/MockedClasses.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, 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
+ */
+
+
+abstract class BokehBaseMockClass {
+  public function select() {}
+  public function fetchall() {}
+  public function find() {}
+  public function findAllBy() {}
+  public function saveEmprunteur() {}
+  public function setOAIHandler(){}
+  public function getRecordsFromSet(){}
+  public function getListRecordsResumptionToken(){}
+  public function setListRecordsResumptionToken(){}
+  public function translate(){}
+  public function open_url(){}
+  public function getGUID(){}
+  public function OuvrirSession(){}
+  public function FermerSession(){}
+  public function getEmpruntsOf(){}
+  public function getReservationsOf(){}
+  public function getAvisFromPreferences(){}
+}
+
+
+class MockLoader extends BokehBaseMockClass {}
+class MockOpsysService extends BokehBaseMockClass {}
+class Mock_OpsysService extends BokehBaseMockClass {}
+class OpsysFactory extends BokehBaseMockClass {}
+class Class_WebServiceOAI extends BokehBaseMockClass {}
+class MockTranslator extends BokehBaseMockClass {}
+class Class_XMLMock extends BokehBaseMockClass {}
+class OuvreSessionResponseMock extends BokehBaseMockClass{}
+class MappedSoapClientMock extends BokehBaseMockClass{}
+class Storm_Model_TableClass_Article extends BokehBaseMockClass {}
+class Storm_Model_TableClass_AvisNotice extends BokehBaseMockClass {}
+class Storm_Model_TableClass_PanierNotice extends BokehBaseMockClass {}
+class Storm_Model_TableClass_NewsletterSubscription extends BokehBaseMockClass {}
+class Storm_Model_TableClass_Newsletter extends BokehBaseMockClass {}
+class Storm_Model_TableClass_Users extends BokehBaseMockClass {}
+class Storm_Model_TableClass_Notice extends BokehBaseMockClass {}
+class MockClass_Users extends BokehBaseMockClass {}
+class MockClass_AvisNotice extends BokehBaseMockClass {}
\ No newline at end of file
diff --git a/tests/library/Class/ModelTestCase.php b/tests/library/Class/ModelTestCase.php
index b454d8e0a335301c188986a00f1f5d2ae9f9c261..44eb3778cf616fdb7b6ac34d1585aeeb6d972618 100644
--- a/tests/library/Class/ModelTestCase.php
+++ b/tests/library/Class/ModelTestCase.php
@@ -45,7 +45,7 @@ abstract class ModelTestCase extends Storm_Test_ModelTestCase {
 
 
   protected function _buildTableMock($model, $methods) {
-    $table = $this->getMock('Storm_Model_Table'.$model,$methods);
+    $table = $this->createMock('Storm_Model_Table'.$model,$methods);
     $loader = call_user_func([$model, 'getLoader']);
     $loader->setTable($table);
     return $table;
@@ -107,7 +107,7 @@ abstract class ModelTestCase extends Storm_Test_ModelTestCase {
 
 
   protected function _generateLoaderFor($model, $methods) {
-    $loader = $this->getMock('Mock'.$model, $methods);
+    $loader = $this->createMock('Mock'.$model, $methods);
     Storm_Model_Abstract::setLoaderFor($model, $loader);
     return $loader;
   }
diff --git a/tests/library/Class/NewsletterSubscriptionTest.php b/tests/library/Class/NewsletterSubscriptionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf29ad107a918bce079901ee18d2be923462b92d
--- /dev/null
+++ b/tests/library/Class/NewsletterSubscriptionTest.php
@@ -0,0 +1,399 @@
+<?php
+/**
+ * Copyright (c) 2012, 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
+ */
+require_once 'Class/Newsletter.php';
+require_once 'Class/NewsletterSubscription.php';
+require_once 'Class/Users.php';
+
+class UserSubscriptionsFixtures {
+  public static function miles() {
+    return array('ID_USER' => 1,
+                 'LOGIN' => 'mdavis',
+                 'ROLE' => 'invite',
+                 'ROLE_LEVEL' => 0,
+                 'PASSWORD' => 'nifnif',
+                 'ID_SITE' => 1,
+                 'NOM' => 'Davis',
+                 'PRENOM' => 'Miles');
+  }
+
+  public static function truffaz() {
+    return array('ID_USER' => 34,
+                 'LOGIN' => 'etruffaz',
+                 'ROLE' => 'invite',
+                 'ROLE_LEVEL' => 0,
+                 'PASSWORD' => 'nafnaf',
+                 'ID_SITE' => 1,
+                 'NOM' => 'Truffaz',
+                 'PRENOM' => 'Erik');
+  }
+
+  public static function marcus() {
+    return array('ID_USER' => 18,
+                 'LOGIN' => 'mmiller',
+                 'ROLE' => 'invite',
+                 'ROLE_LEVEL' => 0,
+                 'PASSWORD' => 'noufnouf',
+                 'ID_SITE' => 1,
+                 'NOM' => 'Miller',
+                 'PRENOM' => 'Marcus');
+  }
+
+  public static function marcus_instance() {
+    return Class_Users::getLoader()->newFromRow(UserSubscriptionsFixtures::marcus());
+  }
+
+
+  public static function concerts() {
+    return array('id' => 26,
+                 'titre' => 'Concerts',
+                 'contenu' => 'Du festival de Jazz');
+  }
+
+  public static function concerts_instance() {
+    return Class_Newsletter::getLoader()->newFromRow(UserSubscriptionsFixtures::concerts());
+  }
+
+  public static function animations() {
+    return array('id' => 32,
+                 'titre' => 'Animations',
+                 'contenu' => 'Des noctibules');
+  }
+
+  public static function animations_instance() {
+    return Class_Newsletter::getLoader()->newFromRow(UserSubscriptionsFixtures::animations());
+  }
+
+  public static function marcus_subscriptions() {
+    return array('id' => 12,
+                 'user_id' => 18,
+                 'newsletter_id' => 26);
+  }
+
+  public static function marcus_subscriptions_instance() {
+    return Class_Newsletter::getLoader()->newFromRow(UserSubscriptionsFixtures::marcus_subscriptions());
+  }
+}
+
+
+class NewSubscriptionTest extends ModelTestCase {
+  public function setUp() {
+    $this->subscription = new Class_NewsletterSubscription();
+  }
+
+  public function testUserReturnsNull() {
+    $this->assertEquals(null, $this->subscription->getUser());
+  }
+
+  public function testNewsletterReturnsNull() {
+    $this->assertEquals(null, $this->subscription->getNewsletter());
+  }
+}
+
+
+class MarcusSubscriptionTest extends ModelTestCase {
+  public function setUp() {
+    $this->_setFindExpectation('Class_NewsletterSubscription',
+                               UserSubscriptionsFixtures::marcus_subscriptions(),
+                               12);
+
+    $this->marcus_newsletter = Class_NewsletterSubscription::getLoader()->find(12);
+  }
+
+  public function testSubscriptionUserIdIs18() {
+    $this->assertEquals(18, $this->marcus_newsletter->getUserId());
+  }
+
+
+  public function testUserReturnsMarcus() {
+    $this->_setFindExpectation('Class_Users', UserSubscriptionsFixtures::marcus(), 18);
+
+    $marcus = $this->marcus_newsletter->getUser();
+    $this->assertEquals('Miller', $marcus->getNom());
+  }
+
+
+  public function testNewsletterReturnsConcerts() {
+    $this->_setFindExpectation('Class_Newsletter', UserSubscriptionsFixtures::concerts(), 26);
+
+    $nl = $this->marcus_newsletter->getNewsletter();
+    $this->assertEquals('Concerts', $nl->getTitre());
+  }
+}
+
+
+abstract class AbstractFindAllByTestCase extends ModelTestCase {
+  public function setUp() {
+    $this->select = new Zend_Db_Table_Select(new Storm_Model_Table(array('name' => 'newsletters_users')));
+    $rs_subscriptions = $this->_buildRowset(array(UserSubscriptionsFixtures::marcus_subscriptions()));
+
+    $tbl_nls_users = $this->_buildTableMock('Class_NewsletterSubscription', array('fetchAll', 'select'));
+
+    $tbl_nls_users
+      ->expects($this->once())
+      ->method('select')
+      ->will($this->returnValue($this->select));
+
+    $tbl_nls_users
+      ->expects($this->once())
+      ->method('fetchAll')
+      //->with($this->select)
+      ->will($this->returnValue($rs_subscriptions));
+  }
+
+  public function testExpectedSubscriptionInstance() {
+    $this->assertEquals(18, $this->subscriptions[0]->getUserId());
+    $this->assertEquals(26, $this->subscriptions[0]->getNewsletterId());
+  }
+
+  public function testOneSubscriptionReturned() {
+    $this->assertEquals(1, count($this->subscriptions));
+  }
+}
+
+
+class FindAllByNewsletterTest extends AbstractFindAllByTestCase {
+  public function setUp() {
+    parent::setUp();
+    $concerts = Class_Newsletter::getLoader()->newFromRow(UserSubscriptionsFixtures::concerts());
+    $this->subscriptions = Class_NewsletterSubscription::getLoader()
+      ->findAllBy(array('role' => 'newsletter',
+                        'model' => $concerts));
+  }
+
+  public function testExpectedSQLQuery() {
+    $this->assertEquals('SELECT `newsletters_users`.* FROM `newsletters_users` WHERE (newsletter_id=26)',
+                        $this->select->assemble());
+  }
+}
+
+
+class FindAllByUserTest extends AbstractFindAllByTestCase {
+  public function setUp() {
+    parent::setUp();
+    $marcus = Class_Users::getLoader()->newFromRow(UserSubscriptionsFixtures::marcus());
+
+    $this->subscriptions = Class_NewsletterSubscription::getLoader()
+      ->findAllBy(array('role' => 'user',
+                        'model' => $marcus));
+  }
+
+  public function testExpectedSQLQuery() {
+    $this->assertEquals('SELECT `newsletters_users`.* FROM `newsletters_users` WHERE (user_id=18)',
+                        $this->select->assemble());
+  }
+}
+
+
+
+class UserWithOneSubscriptionTest extends Storm_Test_ModelTestCase {
+  public function setUp() {
+    $this->concerts = UserSubscriptionsFixtures::concerts_instance();
+    $this->marcus = UserSubscriptionsFixtures::marcus_instance();
+    $this->marcus_subscription = Class_NewsletterSubscription::newInstanceWithId(2,
+                                                                                 ['user' => $this->marcus,
+                                                                                  'newsletter' => $this->concerts]);
+    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_NewsletterSubscription')
+      ->whenCalled('save')->answers(true)
+      ->whenCalled('delete')->answers(true);
+
+
+    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Users')
+            ->whenCalled('delete')
+            ->answers(true)
+            ->whenCalled('save')
+            ->answers(true);
+  }
+
+
+  protected function _setLoaderFindAllReturnsSubscriptionFor($params) {
+    Class_NewsletterSubscription::whenCalled('findAllBy')
+      ->with($params)
+      ->answers([$this->marcus_subscription]);
+  }
+
+
+  public function testMarcusSubscriptions() {
+    $this->_setLoaderFindAllReturnsSubscriptionFor(array('role' => 'user',
+                                                         'model' => $this->marcus));
+
+    $subscriptions = $this->marcus->getSubscriptions();
+    $this->assertEquals(array($this->marcus_subscription), $subscriptions);
+  }
+
+
+  public function testConcertsNewsletterSubscriptions() {
+    $this->_setLoaderFindAllReturnsSubscriptionFor(array('role' => 'newsletter',
+                                                         'model' => $this->concerts));
+    $subscriptions = $this->concerts->getSubscriptions();
+
+    $this->assertEquals(array($this->marcus_subscription), $subscriptions);
+  }
+
+
+  public function testDeleteMarcusDeletesSubscriptions() {
+    $this->_setLoaderFindAllReturnsSubscriptionFor(array('role' => 'user',
+                                                         'model' => $this->marcus));
+
+    $this->marcus->delete();
+    $this->assertTrue(Class_NewsletterSubscription::methodHasBeenCalled('delete'));
+  }
+
+
+  public function testSavingMarcusWithSubscriptionsRemovedDeleteThem() {
+    $this->_setLoaderFindAllReturnsSubscriptionFor(array('role' => 'user',
+                                                         'model' => $this->marcus));
+
+    $this->marcus->setSubscriptions(array());
+
+    $this->marcus->save();
+
+    $this->assertTrue(Class_Users::methodHasBeenCalled('save'));
+  }
+
+
+  public function testSavingMarcusWithNewslettersRemovedDeleteSubscription() {
+    Class_NewsletterSubscription::whenCalled('findAllBy')->answers([$this->marcus_subscription]);
+
+    $this->marcus->removeNewsletter($this->concerts);
+
+    $this->marcus->save();
+    $this->assertTrue(Class_NewsletterSubscription::methodHasBeenCalled('delete'));
+  }
+
+
+  public function testSavingMarcusWithNewslettersSetSubscription() {
+    Class_NewsletterSubscription::whenCalled('findAllBy')->answers([$this->marcus_subscription]);
+
+    $animations = UserSubscriptionsFixtures::animations_instance();
+
+    $this->marcus->setNewsletters(array($animations));
+    $this->marcus->save();
+
+    $subscriptions = $this->marcus->getSubscriptions();
+    $this->assertEquals($animations, $subscriptions[0]->getNewsletter());
+    $this->assertTrue(Class_NewsletterSubscription::methodHasBeenCalled('save'));
+  }
+
+
+  public function testSavingMarcusWithNewslettersAddedAddSubscription() {
+    Class_NewsletterSubscription::whenCalled('findAllBy')->answers([$this->marcus_subscription]);
+
+    $animations = UserSubscriptionsFixtures::animations_instance();
+
+    $this->marcus->addNewsletter($animations);
+
+    $this->marcus->save();
+
+    $this->marcus->removeNewsletter($this->concerts);
+
+    $subscriptions = $this->marcus->getSubscriptions();
+    $this->assertEquals($animations, $subscriptions[0]->getNewsletter());
+    $this->assertTrue(Class_NewsletterSubscription::methodHasBeenCalled('save'));
+  }
+
+
+  /** @test **/
+  public function createUserMarcusWithAutoSubscribeCheckedOnConcertShouldAddMarcusToSubscriber() {
+
+    Class_NewsletterSubscription::beVolatile();
+
+    $news = $this->fixture('Class_Newsletter',
+                           ['id' => 1,
+                            'titre' => 'News']);
+    $news->setAutoSubscribe(true)->save();
+
+    $marcus = $this->fixture('Class_Users',
+                             ['id' => null,
+                              'login' => 'Marcus',
+                              'password' => 'pwd',
+                              'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
+
+    $this->assertContains($news, $marcus->getNewsletters());
+
+  }
+
+
+    /** @test **/
+  public function createUserMarcusWithAutoSubscribeNotCheckedOnConcertShouldNotAddMarcusToSubscriber() {
+
+    $this->concerts->setAutoSubscribe(false);
+
+    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Newsletter');
+    Class_Newsletter::whenCalled('findAllBy')
+      ->with(['auto_subscribe'=>true])
+      ->answers([]);
+
+    $marcus = Class_Users::newInstance(['login'=>'Marcus',
+                                         'password'=>'vue']);
+    $marcus->save();
+    $this->assertNotContains($this->concerts, $marcus->getNewsletters());
+
+  }
+
+
+      /** @test **/
+  public function oldUserMarcusWithAutoSubscribeCheckedOnConcertShouldNotAddMarcusToSubscriber() {
+
+    $this->concerts->setAutoSubscribe(true);
+
+    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Newsletter');
+    Class_Newsletter::whenCalled('findAllBy')
+      ->with(['auto_subscribe'=>true])
+      ->never();
+
+    $marcus = Class_Users::newInstanceWithId(2,['login'=>'Marcus',
+                                         'password'=>'vue']);
+    $marcus->save();
+    $this->assertNotContains($this->concerts, $marcus->getNewsletters());
+
+  }
+
+
+  public function testSavingMarcusWithNewSubscriptionsAddThem() {
+    $this->_setLoaderFindAllReturnsSubscriptionFor(array('role' => 'user',
+                                                         'model' => $this->marcus));
+
+    $new_subscription = $this->createMock('NewsletterSubscription',
+                                       array('save', '_set'));
+
+    $new_subscription
+      ->expects($this->atLeastOnce())
+      ->method('_set')
+      ->with('user', $this->equalTo($this->marcus));
+
+    $this->marcus->addSubscription($new_subscription);
+  }
+
+
+
+  public function testDeleteConcertsDeletesSubscriptions() {
+    $this->_setLoaderFindAllReturnsSubscriptionFor(array('role' => 'newsletter',
+                                                         'model' => $this->concerts));
+
+    $this->concerts->delete();
+    $this->assertTrue(Class_NewsletterSubscription::methodHasBeenCalled('delete'));
+  }
+}
+
+
+
+
+?>
diff --git a/tests/library/Class/NoticeOAITest.php b/tests/library/Class/NoticeOAITest.php
index f1241a541eb801d872d8cfc7d5ece8ae1356f306..76d765ccb3ffb8c97e668bc1f309eb47ab01e8c5 100644
--- a/tests/library/Class/NoticeOAITest.php
+++ b/tests/library/Class/NoticeOAITest.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 require_once 'Class/NoticeOAI.php';
 require_once 'Class/WebService/OAI.php';
@@ -56,9 +56,9 @@ class OAINoticeTestHarverstWithOneRecord extends PHPUnit_Framework_TestCase {
                     'editeur' => 'T. Du Bray (Paris)',
                     'description' => '');
 
-    $oai_service = $this->getMock('Class_WebServiceOAI', 
-                                  array('getRecordsFromSet', 
-                                        'setOAIHandler', 
+    $oai_service = $this->createMock('Class_WebServiceOAI',
+                                  array('getRecordsFromSet',
+                                        'setOAIHandler',
                                         'getNextRecords',
                                         'getListRecordsResumptionToken'));
 
@@ -96,13 +96,13 @@ class OAINoticeTestHarverstWithOneRecord extends PHPUnit_Framework_TestCase {
   }
 
   public function testDateIs1608() {
-    $this->assertEquals('1608', 
+    $this->assertEquals('1608',
                         $this->inserted_data_in_db['date']);
 
   }
 
   public function testIdOaiIsGallica() {
-    $this->assertEquals('http://gallica.bnf.fr/ark:/12148/bpt6k701371', 
+    $this->assertEquals('http://gallica.bnf.fr/ark:/12148/bpt6k701371',
                         $this->inserted_data_in_db['id_oai']);
   }
 
@@ -135,9 +135,9 @@ class OAINoticeTestResume extends PHPUnit_Framework_TestCase {
       ->setLibelle('BNF gallica')
       ->setHandler('http://oai.bnf.fr/oai2/OAIHandler');
 
-    $this->oai_service = $this->getMock('Class_WebServiceOAI', 
-                                        array('getRecordsFromSet', 
-                                              'setOAIHandler', 
+    $this->oai_service = $this->createMock('Class_WebServiceOAI',
+                                        array('getRecordsFromSet',
+                                              'setOAIHandler',
                                               'hasNextRecords',
                                               'getNextRecords',
                                               'getListRecordsResumptionToken',
diff --git a/tests/library/Class/ProfilI18nStringExtractorTest.php b/tests/library/Class/ProfilI18nStringExtractorTest.php
index 2acf4aaa69fa6025d801583730d4cf6892eb3ffc..c8f45687864a24ad1b47ec46f3289866af6d9618 100644
--- a/tests/library/Class/ProfilI18nStringExtractorTest.php
+++ b/tests/library/Class/ProfilI18nStringExtractorTest.php
@@ -133,7 +133,7 @@ class ChatenayMenusI18nStringExtractorTest extends I18nStringExtractorTestCase {
 
   /** @test */
   public function withAnotherTranslatorExtractShouldGetOriginalText() {
-    $englishTranslator = $this->getMock('MockTranslator', array('translate'));
+    $englishTranslator = $this->createMock('MockTranslator', array('translate'));
     $englishTranslator
       ->expects($this->never())
       ->method('translate');
diff --git a/tests/library/Class/UploadTest.php b/tests/library/Class/UploadTest.php
index 1836cae8257cdc372cdb2262271d452dd2c1b0f3..352a6bee2cf632ffa6ee7784c2552e92725caff7 100644
--- a/tests/library/Class/UploadTest.php
+++ b/tests/library/Class/UploadTest.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 class UploadFichierTest extends PHPUnit_Framework_TestCase {
@@ -29,7 +29,7 @@ class UploadFichierTest extends PHPUnit_Framework_TestCase {
 
   protected function setUp() {
     parent::setUp();
-    $this->_folderManager = $this->getMock('Class_Folder_Manager');
+    $this->_folderManager = $this->createMock('Class_Folder_Manager');
     $this->_upload = Class_Upload::newInstanceFor('fichier')
       ->setFolderManager($this->_folderManager);
   }
diff --git a/tests/library/Class/WebService/BabelioTest.php b/tests/library/Class/WebService/BabelioTest.php
index 4cb34ee7a810c965822e7268c763a2d687ddcfbf..543c1fdeea9779deedd1503b6451182ffa92bf1e 100644
--- a/tests/library/Class/WebService/BabelioTest.php
+++ b/tests/library/Class/WebService/BabelioTest.php
@@ -16,12 +16,12 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class Class_WebService_BabelioTest extends PHPUnit_Framework_TestCase {
   /** @test */
   public function clientShouldBeCalledWithAuthAndTimestamp() {
-    $mock = $this->getMock('Zend_Http_Client');
+    $mock = $this->createMock('Zend_Http_Client');
     $mock
       ->expects($this->once())
       ->method('setUri')
@@ -30,11 +30,11 @@ class Class_WebService_BabelioTest extends PHPUnit_Framework_TestCase {
 
     $service = new Class_WebService_Babelio();
     $service->setHttpClient($mock);
-    
+
     $service
       ->setVolatileTime(1311003574)
       ->requete('999');
-    
+
   }
-  
+
 }
\ No newline at end of file
diff --git a/tests/library/Class/WebService/OAITest.php b/tests/library/Class/WebService/OAITest.php
index 1ec7e9d79f0b919017ce1e1d587c4d670a375c1f..6e4346ca8f00c6166cd8ed8afd00c051766d2db8 100644
--- a/tests/library/Class/WebService/OAITest.php
+++ b/tests/library/Class/WebService/OAITest.php
@@ -22,7 +22,7 @@ require_once 'Class/WebService/OAI.php';
 
 class OAITestGetSets extends PHPUnit_Framework_TestCase {
   public function setUp() {
-    $xml_mock = $this->getMock('Class_XMLMock',
+    $xml_mock = $this->createMock('Class_XMLMock',
                                     array('open_url'));
     $xml_mock
       ->expects($this->any())
@@ -63,7 +63,7 @@ class OAITestGetRecordsOfSetGallica extends PHPUnit_Framework_TestCase {
   protected $oai_service;
 
   public function setUp() {
-    $xml_mock = $this->getMock('Class_XMLMock',
+    $xml_mock = $this->createMock('Class_XMLMock',
                                array('open_url'));
     $xml_mock
       ->expects($this->any())
@@ -119,7 +119,7 @@ class OAITestGetRecordsOfSetGallica extends PHPUnit_Framework_TestCase {
 
 
   public function testNextRecordsUseResumptionTokenAndFetchNextRecords() {
-    $xml_mock = $this->getMock('Class_XMLMock',
+    $xml_mock = $this->createMock('Class_XMLMock',
                                array('open_url'));
     $this->oai_service->setWebClient($xml_mock);
     $xml_mock
diff --git a/tests/library/Class/WebService/SIGB/OpsysServiceTest.php b/tests/library/Class/WebService/SIGB/OpsysServiceTest.php
index 8a56bf9b70daa88c20203a87488022009d9d8638..a7a85ac98f7e034802d126bbbc5d88aa37611b1f 100644
--- a/tests/library/Class/WebService/SIGB/OpsysServiceTest.php
+++ b/tests/library/Class/WebService/SIGB/OpsysServiceTest.php
@@ -132,7 +132,7 @@ class OpsysServiceTestAutoConnect extends Storm_Test_ModelTestCase {
   private $client;
 
   public function setUp(){
-    $this->ouvre_session_res = $this->getMock(
+    $this->ouvre_session_res = $this->createMock(
                                               'OuvreSessionResponseMock',
                                               array('getGUID'));
     $this->ouvre_session_res
@@ -140,7 +140,7 @@ class OpsysServiceTestAutoConnect extends Storm_Test_ModelTestCase {
       ->method('getGUID')
       ->will($this->returnValue("12345"));
 
-    $this->ouvre_session_error = $this->getMock(
+    $this->ouvre_session_error = $this->createMock(
                                     'OuvreSessionResponseMock',
                                     array('getGUID'));
     $this->ouvre_session_error
@@ -148,7 +148,7 @@ class OpsysServiceTestAutoConnect extends Storm_Test_ModelTestCase {
       ->method('getGUID')
       ->will($this->returnValue(""));
 
-    $this->search_client = $this->getMock(
+    $this->search_client = $this->createMock(
                                    'MappedSoapClientMock',
                                    array('OuvrirSession', 'FermerSession'));
   }
@@ -211,9 +211,9 @@ class Class_WebService_SIGB_OpsysServiceTestProxy extends Storm_Test_ModelTestCa
   private $mock_opsys_service;
 
   public function setUp(){
-    $this->factory = $this->getMock('OpsysFactory', array('createOpsysService'));
+    $this->factory = $this->createMock('OpsysFactory', array('createOpsysService'));
 
-    $this->mock_opsys_service = $this->getMock(
+    $this->mock_opsys_service = $this->createMock(
                                          'Class_WebService_SIGB_Opsys',
                                          array('newOpsysServiceFactory'));
 
@@ -716,7 +716,7 @@ class OpsysServiceGetExemplaireFromCacheTestDisponibilite extends OpsysServiceWi
       $notice_potter->addExemplaire($ex);
     }
 
-    $recuperer_notice_res = $this->getMock('RecupererNoticeResponse',
+    $recuperer_notice_res = $this->createMock('RecupererNoticeResponse',
                                            array('createNotice'));
     $recuperer_notice_res
       ->expects($this->once())
@@ -1203,7 +1203,7 @@ class OpsysServiceEmprReserverResponseTest extends Storm_Test_ModelTestCase {
 
 class OpsysServiceEmprunteurAttributesTest extends Storm_Test_ModelTestCase {
   public function setUp(){
-    $this->opsys_service = $this->getMock('Mock_OpsysService',
+    $this->opsys_service = $this->createMock('Mock_OpsysService',
                                           array('getEmpruntsOf',
                                                 'getReservationsOf'));
 
@@ -1443,7 +1443,7 @@ class OpsysServiceEmpruntRetardAttributesTest extends Storm_Test_ModelTestCase {
 
 class OpsysServiceEmpruntTestSort extends Storm_Test_ModelTestCase {
   public function setUp() {
-    $this->opsys_service = $this->getMock('Mock_OpsysService',
+    $this->opsys_service = $this->createMock('Mock_OpsysService',
                                           array('getEmpruntsOf', 'getReservationsOf'));
     $this->opsys_service
       ->expects($this->any())
diff --git a/tests/library/Class/WebService/SIGB/VSmartAuthenticateTest.php b/tests/library/Class/WebService/SIGB/VSmartAuthenticateTest.php
index 41ba510079cee5646cec19ca75433d50411d17b9..debc3a46391d977e83ae742f141bb50c599cc94c 100644
--- a/tests/library/Class/WebService/SIGB/VSmartAuthenticateTest.php
+++ b/tests/library/Class/WebService/SIGB/VSmartAuthenticateTest.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 include_once('VSmartFixtures.php');
 
@@ -182,8 +182,8 @@ class VSmartAuthenticateServiceTest extends PHPUnit_Framework_TestCase {
 
                           Class_Exemplaire::getLoader()
                           ->newInstanceWithId(234)
-                          ->setIdOrigine('2/01234'), 
-                          
+                          ->setIdOrigine('2/01234'),
+
                           ''));
   }
 
@@ -202,7 +202,7 @@ class VSmartAuthenticateServiceTest extends PHPUnit_Framework_TestCase {
 
                           Class_Exemplaire::getLoader()
                           ->newInstanceWithId(234)
-                          ->setIdOrigine('2/01234'), 
+                          ->setIdOrigine('2/01234'),
 
                           ''));
   }
@@ -233,7 +233,7 @@ class VSmartAuthenticateServiceTest extends PHPUnit_Framework_TestCase {
     $expected_url = sprintf('http://%s/LoginWebSso.csp?Token=ABCD&Function=UserActivities&Module=ADM',
                             Class_WebService_SIGB_VSmart_Service::MOULINS_POPUP_SERVER);
 
-    $mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
+    $mock_web_client = $this->createMock('Class_WebService_SimpleWebClient');
     $mock_web_client
       ->expects($this->once())
       ->method('open_url')
diff --git a/tests/library/ZendAfi/View/Helper/Accueil/CacheTest.php b/tests/library/ZendAfi/View/Helper/Accueil/CacheTest.php
index b82e82750784b1fff504d012edad95e26ca8d16b..9aeb2296104953c9b0cf3a1d3c79b41701a7e7d1 100644
--- a/tests/library/ZendAfi/View/Helper/Accueil/CacheTest.php
+++ b/tests/library/ZendAfi/View/Helper/Accueil/CacheTest.php
@@ -36,7 +36,7 @@ class CacheWithCritiquesTest extends ViewHelperTestCase {
                                  'display_order' => 'Random',
                                  'only_img' => true]];
 
-    $this->avis_loader = $this->getMock('MockLoader', ['getAvisFromPreferences']);
+    $this->avis_loader = $this->createMock('MockLoader', ['getAvisFromPreferences']);
     Storm_Model_Abstract::setLoaderFor('Class_AvisNotice', $this->avis_loader);
 
     $this->critiques_helper = new ZendAfi_View_Helper_Accueil_Critiques(2, $params);
diff --git a/tests/library/ZendAfi/View/Helper/TagBanniereTest.php b/tests/library/ZendAfi/View/Helper/TagBanniereTest.php
index 9305baea4fc2ca4d05fba1075f3f56d5e28d2782..2034d0b007ed3e777ca69b018b56c608efcfc14a 100644
--- a/tests/library/ZendAfi/View/Helper/TagBanniereTest.php
+++ b/tests/library/ZendAfi/View/Helper/TagBanniereTest.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 class ZendAfi_View_Helper_TagBanniereCycleTest extends ViewHelperTestCase {
@@ -30,9 +30,9 @@ class ZendAfi_View_Helper_TagBanniereCycleTest extends ViewHelperTestCase {
     parent::setUp();
 
     defineConstant("PATH_SKIN","");
-  
 
-    $this->file_system=$this->getMock('Class_Testing_FileSystem',['readdir',
+
+    $this->file_system=$this->createMock('Class_Testing_FileSystem',['readdir',
                                                                   'opendir',
                                                                   'file_exists',
                                                                   'mkdir',
@@ -47,9 +47,9 @@ class ZendAfi_View_Helper_TagBanniereCycleTest extends ViewHelperTestCase {
     $this->file_system->expects($this->any())->method('closedir')->will($this->returnValue(null));
 
     Class_Profil::setFileSystem($this->file_system);
-    $this->profil = $this->fixture('Class_Profil', 
+    $this->profil = $this->fixture('Class_Profil',
                                    ['id' => 999, 'header_img_cycle' => true]);
-  
+
     $this->_helper = new ZendAfi_View_Helper_TagBanniere();
     $this->_helper->setView(new ZendAfi_Controller_Action_Helper_View());
     $this->_helper->view->profil = Class_Profil::getLoader()
@@ -74,7 +74,7 @@ class ZendAfi_View_Helper_TagBanniereCycleTest extends ViewHelperTestCase {
   /** @test */
   function ban2ShouldBeVisible() {
     $this->assertXPath($this->_html, "//img[@src='".USERFILESURL."bannieres/ban2.jpg']",$this->_html);
-  } 
+  }
 }
 
 ?>
\ No newline at end of file