diff --git a/VERSIONS_HOTLINE/33614 b/VERSIONS_HOTLINE/33614
new file mode 100644
index 0000000000000000000000000000000000000000..7c76081c99a7ebb7483584489ca786b92e4a90b4
--- /dev/null
+++ b/VERSIONS_HOTLINE/33614
@@ -0,0 +1 @@
+ - ticket #33614 : Gestion sitothèque: Ajout d'un messages d'erreur si l'url n'est pas valide
\ No newline at end of file
diff --git a/library/Class/Sitotheque.php b/library/Class/Sitotheque.php
index 43afaf9e770b8768545f90b244d63885f24d2616..ee1c1e0aeac089991a691660e2a748034f726dde 100644
--- a/library/Class/Sitotheque.php
+++ b/library/Class/Sitotheque.php
@@ -229,17 +229,19 @@ class Class_Sitotheque extends Storm_Model_Abstract {
 
 
   public function validate()  {
+    $this->checkAttribute('titre',
+                          $this->getTitre() && mb_strlen($this->getTitre(),'UTF-8') <= 255,
+                          $this->_('Le champ "Titre" doit être renseigné et inférieur à 255 caractères'));
 
-    $this->checkAttribute('titre', $this->getTitre() && mb_strlen($this->getTitre(),'UTF-8') <= 255,
-                 $this->_("Le champ 'Titre' doit être renseigné et inférieur à 255 caractères"));
+    $this->checkAttribute('url',
+                          $this->getUrl() && mb_strlen($this->getUrl(),'UTF-8') <= 250,
+                          $this->_('Vous devez compléter le champ "Url" et il doit être inférieur à 250 caractères'));
 
-    $this->checkAttribute('url',$this->getUrl() && mb_strlen($this->getUrl(),'UTF-8') <= 250,
-                 $this->_("Vous devez compléter le champ 'Url' et il doit être inférieur à 250 caractères"));
     $url_validator = new ZendAfi_Validate_Url();
     if (!$url_validator->isValid($this->getUrl())) {
       $messages = $url_validator->getMessages();
       foreach($messages as $message)
-        $this->addError($message);
+        $this->addAttributeError('url', $message);
     }
   }
 
diff --git a/library/ZendAfi/Validate/Url.php b/library/ZendAfi/Validate/Url.php
index 5d028388a4b0acdbb0a47de771a2fce7ad64bc27..0f774e85102feaea370f09fd96b161ab2ac15340 100644
--- a/library/ZendAfi/Validate/Url.php
+++ b/library/ZendAfi/Validate/Url.php
@@ -26,8 +26,10 @@ class ZendAfi_Validate_Url extends Zend_Validate_Abstract {
   public function isValid($value) {
     if ('' === $valueString = (string) $value)
       return true;
+
     if (false == strpos($valueString,'://'))
-      $valueString='http:/'.$valueString;
+      $valueString = 'http://' . $valueString;
+
     $this->_setValue($value);
 
     if (!Zend_Uri::check($valueString)) {
diff --git a/tests/application/modules/admin/controllers/SitothequeControllerTest.php b/tests/application/modules/admin/controllers/SitothequeControllerTest.php
index 9695823613604053fe4007eae79baed14d4037fb..0bae467e70e1c332191619f7899e4fbd256547d0 100644
--- a/tests/application/modules/admin/controllers/SitothequeControllerTest.php
+++ b/tests/application/modules/admin/controllers/SitothequeControllerTest.php
@@ -21,34 +21,33 @@
 require_once 'AdminAbstractControllerTestCase.php';
 
 abstract class SitothequeControllerTestCase extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
   protected $_le_monde;
 
   public function setUp() {
     parent::setUp();
     $this->setupCustomFields();
     $this->setupDomaines();
-    Class_Exemplaire::beVolatile();
-    Class_Notice::beVolatile();
-    Class_CodifThesaurus::beVolatile();
-    Storm_Model_Loader::defaultToVolatile();
-    $categorie_informations = $this->fixture('Class_SitothequeCategorie',
-                                             ['id' => 2,
-                                              'libelle' => 'Informations',
-                                              'id_site' => 3,
-                                              'sous_categories' => [],
-                                              'sitotheques' => [
-                                                $this->fixture('Class_Sitotheque',
-                                                               ['id' => 22,
-                                                                'titre' => 'Le Canard',
-                                                                'url' => 'http://www.canard.fr',
-                                                                'description' => 'indépendant',
-                                                                'domaine_ids' => [10]]),
-
-                                                $this->_le_monde = $this->fixture('Class_Sitotheque',
-                                                                                  ['id' => 23,
-                                                                                   'titre' => 'Le Monde',
-                                                                                   'url' => 'http://www.monde.fr'])]
-                                               ]);
+
+    $categorie_informations = $this
+      ->fixture('Class_SitothequeCategorie',
+                ['id' => 2,
+                 'libelle' => 'Informations',
+                 'id_site' => 3,
+                 'sous_categories' => [],
+                 'sitotheques' => [
+                                   $this->fixture('Class_Sitotheque',
+                                                  ['id' => 22,
+                                                   'titre' => 'Le Canard',
+                                                   'url' => 'http://www.canard.fr',
+                                                   'description' => 'indépendant',
+                                                   'domaine_ids' => [10]]),
+
+                                   $this->_le_monde = $this->fixture('Class_Sitotheque',
+                                                                     ['id' => 23,
+                                                                      'titre' => 'Le Monde',
+                                                                      'url' => 'http://www.monde.fr'])]
+                ]);
 
 
     $bib_annecy = $this->fixture('Class_Bib',
@@ -61,7 +60,6 @@ abstract class SitothequeControllerTestCase extends Admin_AbstractControllerTest
 
 
   public function setupCustomFields() {
-    Class_CustomField_Meta::beVolatile();
     $theme = $this->fixture('Class_CustomField',
                             ['id' => 2,
                              'priority' => 3,
@@ -71,17 +69,9 @@ abstract class SitothequeControllerTestCase extends Admin_AbstractControllerTest
                              'model' => 'Sitotheque']);
 
     $theme->getMeta()->setIndexable(true)->save();
-
-  }
-
-
-  public function tearDown() {
-    Storm_Model_Loader::defaultToDb();
-    parent::tearDown();
   }
 
 
-
   public function setupDomaines() {
     $this->fixture('Class_Catalogue', ['id' => 10,
                                        'libelle' => 'Histoire',
@@ -215,7 +205,6 @@ class SitothequeControllerSitoEditTest extends SitothequeControllerTestCase {
   public function customFieldShouldBeDisplayed() {
     $this->assertXPathContentContains('//select[@id="field_2"]//option', 'web links', $this->_response->getBody());
   }
-
 }
 
 
@@ -279,12 +268,10 @@ class SitothequeControllerPostAddActionTest extends SitothequeControllerTestCase
   public function setUp() {
     parent::setUp();
 
-    $this->cache = Storm_Test_ObjectWrapper::mock()
-      ->whenCalled('save')
-      ->answers(true)
+    $this->cache = $this->mock()
+                        ->whenCalled('save')->answers(true)
+                        ->whenCalled('clean')->answers(true);
 
-      ->whenCalled('clean')
-      ->answers(true);
     Storm_Cache::setDefaultZendCache($this->cache);
 
     $this->postDispatch('/admin/sito/add/id_cat/2',
@@ -334,6 +321,7 @@ class SitothequeControllerPostAddActionTest extends SitothequeControllerTestCase
     $this->assertContains('HCFCF0001', Class_Notice::find(1)->getFacettes());
   }
 
+
   /** @test */
   public function cacheShouldHaveBeenCleaned() {
     $this->assertTrue($this->cache->methodHasBeenCalled('clean'));
@@ -362,6 +350,7 @@ class SitothequeControllerNotIndexedPostAddActionTest extends SitothequeControll
                         true);
   }
 
+
   /** @test */
   public function siteShouldNotBeIndexed() {
     $this->assertNull(Class_Sitotheque::findFirstBy(['order'=>'titre desc'])->getNotice());
@@ -372,14 +361,30 @@ class SitothequeControllerNotIndexedPostAddActionTest extends SitothequeControll
 
 
 class SitothequeControllerInvalidPostActionTest extends SitothequeControllerTestCase {
-  public function setUp() {
-    parent::setUp();
-    $this->postDispatch('/admin/sito/add/id_cat/2', [], true);
+  protected function _assertError($message) {
+    $this->assertXPathContentContains('//ul[@class="errors"]/li', $message,
+                                      $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function titleShouldBeRequired() {
+    $this->postDispatch('/admin/sito/add/id_cat/2', []);
+    $this->_assertError('Le champ "Titre" doit être renseigné et inférieur à 255 caractères');
+  }
+
+
+  /** @test */
+  public function urlShouldBeRequired() {
+    $this->postDispatch('/admin/sito/add/id_cat/2', []);
+    $this->_assertError('Vous devez compléter le champ "Url"');
   }
 
+
   /** @test */
-  public function pageShouldContainsErrorValeurRequise() {
-    $this->assertXPathContentContains('//ul[@class="errors"]/li', "Le champ 'Titre' doit être renseigné et inférieur à 255 caractères",$this->_response->getBody());
+  public function urlShouldBeValid() {
+    $this->postDispatch('/admin/sito/add/id_cat/2', ['url' => 'http://|']);
+    $this->_assertError('n\'est pas une URL valide');
   }
 }
 
@@ -389,9 +394,8 @@ class SitothequeControllerInvalidPostActionTest extends SitothequeControllerTest
 class SitothequeControllerSitoPostEditLeMondeTest extends SitothequeControllerTestCase {
   public function setUp() {
     parent::setUp();
-    $this->postDispatch('/admin/sito/edit/id/23',
-                        ['titre' => 'Times'],
-                        true);
+
+    $this->postDispatch('/admin/sito/edit/id/23', ['titre' => 'Times']);
     Class_Sitotheque::clearCache();
     $this->_le_monde = Class_Sitotheque::find(23);
   }
@@ -407,8 +411,6 @@ class SitothequeControllerSitoPostEditLeMondeTest extends SitothequeControllerTe
   public function anwersShouldRedirectToSitoEdit23() {
     $this->assertRedirectTo('/admin/sito/edit/id/23');
   }
-
-
 }
 
 
@@ -439,8 +441,7 @@ class SitothequeControllerSitoDeleteLeMondeTest extends SitothequeControllerTest
 class SitothequeControllerActionErrorsTest extends SitothequeControllerTestCase {
   public function errorUrls() {
     return [['/admin/sito/catdel/id_cat/-1'],
-            ['/admin/sito/catedit/id_cat/-1']
-    ];
+            ['/admin/sito/catedit/id_cat/-1']];
   }
 
 
@@ -482,9 +483,9 @@ class SitothequeControllerEditCategorieInformationsTest extends SitothequeContro
 class SitothequeControllerPostEditCategorieInformationsTest extends SitothequeControllerTestCase {
   public function setUp() {
     parent::setUp();
+
     $this->postDispatch('/admin/sito/catedit/id/2',
-                        ['libelle' => 'News'],
-                        true);
+                        ['libelle' => 'News']);
     Class_SitothequeCategorie::clearCache();
   }
 
@@ -513,7 +514,8 @@ class SitothequeControllerAddCategorieTest extends SitothequeControllerTestCase
 
   /** @test */
   public function selectIdCatMereShouldHaveCategorieInformationsSelected() {
-    $this->assertXPathContentContains('//select/optgroup[@label="Annecy"]/option[@value="2"][@selected="selected"]', 'Informations',
+    $this->assertXPathContentContains('//select/optgroup[@label="Annecy"]/option[@value="2"][@selected="selected"]',
+                                      'Informations',
                                       $this->_response->getBody());
   }
 }
@@ -524,15 +526,14 @@ class SitothequeControllerAddCategorieTest extends SitothequeControllerTestCase
 class SitothequeControllerPostAddEmptyCategorieTest extends SitothequeControllerTestCase {
   public function setUp() {
     parent::setUp();
-    $this->postDispatch('/admin/sito/catadd/id/2',
-                        ['libelle' => ''],
-                        true);
+    $this->postDispatch('/admin/sito/catadd/id/2', ['libelle' => '']);
   }
 
 
   /** @test */
   public function pageShouldDisplayErrorNomVide() {
-    $this->assertXPathContentContains('//span[@class="error"]', 'Vous devez compléter le champ');
+    $this->assertXPathContentContains('//span[@class="error"]',
+                                      'Vous devez compléter le champ');
   }
 }
 
@@ -545,10 +546,7 @@ class SitothequeControllerPostAddCategorieNationalesTest extends SitothequeContr
   public function setUp() {
     parent::setUp();
 
-    $this->postDispatch('/admin/sito/catadd/id/2',
-                        ['libelle' => 'Nationales'],
-                        true);
-
+    $this->postDispatch('/admin/sito/catadd/id/2', ['libelle' => 'Nationales']);
     $this->_new_cat = Class_SitothequeCategorie::find(3);
   }
 
@@ -568,10 +566,7 @@ class SitothequeControllerPostAddCategorieInBibTest extends SitothequeController
   public function setUp() {
     parent::setUp();
 
-    $this->postDispatch('/admin/sito/catadd/id_bib/5',
-                        ['libelle' => 'Dans la bib'],
-                        true);
-
+    $this->postDispatch('/admin/sito/catadd/id_bib/5', ['libelle' => 'Dans la bib']);
     $this->_new_cat = Class_SitothequeCategorie::find(3);
   }
 
@@ -615,6 +610,7 @@ protected
 
   public function setUp() {
     parent::setUp();
+
     Class_WebService_SimpleWebClient::setInstance($this->mock()
                                                   ->whenCalled('open_url')
                                                   ->answers($this->_getContent()));
@@ -739,7 +735,6 @@ class SitothequeControllerImportBnfFromUrlTest
 
   /** @test */
   public function titleShouldBeBnfDotFr() {
-    $this->assertEquals('http://www.bnf.fr',
-                        $this->_album->getTitre());
+    $this->assertEquals('http://www.bnf.fr', $this->_album->getTitre());
   }
 }
\ No newline at end of file