diff --git a/VERSIONS_HOTLINE/141990 b/VERSIONS_HOTLINE/141990
new file mode 100644
index 0000000000000000000000000000000000000000..d2082148003caebc74efa65c356107f51a596595
--- /dev/null
+++ b/VERSIONS_HOTLINE/141990
@@ -0,0 +1 @@
+ - ticket #141990 : DiMusic : Ajout du script scripts/dimusic_first_harvest.php permettant de lancer le premier moissonage de cette ressource.
\ No newline at end of file
diff --git a/library/Class/DigitalResource.php b/library/Class/DigitalResource.php
index c4e26c3c7096c6109bf2849867aff6c8f334cdda..6832c9e2fc51e7ae0faf056f8677ccf613b221a1 100644
--- a/library/Class/DigitalResource.php
+++ b/library/Class/DigitalResource.php
@@ -148,6 +148,24 @@ class Class_DigitalResource extends Class_Entity {
   }
 
 
+  public function getImporters() {
+    return $this->pluginsByName(function($config)
+                                {
+                                  if($importer = $config->getImporter())
+                                    return $this->build($importer, $config);
+                                });
+  }
+
+
+  public function getHarvesters() {
+    return $this->pluginsByName(function($config)
+                                {
+                                  if($harvester = $config->getHarvester())
+                                    return $this->build($harvester, $config);
+                                });
+  }
+
+
   public function hasRightAccessPlugin($plugin, $user) {
     if (!$this->isPluginDocType($plugin))
       return false;
diff --git a/library/Class/DigitalResource/Config.php b/library/Class/DigitalResource/Config.php
index e2f92262271a4ea29ea46c83ecedaf173ce86126..400946039522a5e2d34251c8b8aa4fae933bc3fa 100644
--- a/library/Class/DigitalResource/Config.php
+++ b/library/Class/DigitalResource/Config.php
@@ -110,6 +110,32 @@ class Class_DigitalResource_Config extends Class_Entity {
   }
 
 
+  public function isFirstHarvestAware() {
+    return  $this->getHarvester()
+      && $this->getImporter();
+  }
+
+
+  public function isFirstHarvestDone() {
+    return $this->getHarvesterInstance()->isDone();
+  }
+
+
+  public function isFirstImportDone() {
+    return $this->getImporterInstance()->isDone();
+  }
+
+
+  public function isFirstHarvestRunning() {
+    return $this->getHarvesterInstance()->isRunning();
+  }
+
+
+  public function isFirstImportRunning() {
+    return $this->getImporterInstance()->isRunning();
+  }
+
+
   public function getDashboardUrl() {
     return Class_Url::absolute(['module' => $this->getModuleName()],
                                null,
@@ -118,7 +144,33 @@ class Class_DigitalResource_Config extends Class_Entity {
 
 
   public function getBatchInstance() {
-    return $this->getDigitalResource()->getBatches()[$this->getBatch()];
+    return $this->_getObjectInstance($this->getDigitalResource()->getBatches(),
+                                     $this->getBatch());
+  }
+
+
+  public function getImporterInstance() {
+    return $this->_getObjectInstance($this->getDigitalResource()->getImporters());
+  }
+
+
+  public function getHarvesterInstance() {
+    return $this->_getObjectInstance($this->getDigitalResource()->getHarvesters());
+  }
+
+
+  protected function _getObjectInstance($instances, $key = '') {
+    if ( ! $instances )
+      return null;
+
+    $key =
+      ( $key
+       ? $key
+       : $this->getName() );
+
+    return isset($instances[$key])
+      ? $instances[$key]
+      : null;
   }
 
 
diff --git a/library/Class/DigitalResource/Harvester/OAI.php b/library/Class/DigitalResource/Harvester/OAI.php
new file mode 100644
index 0000000000000000000000000000000000000000..37022f93ad30e2adda53df1ba37a86da65654303
--- /dev/null
+++ b/library/Class/DigitalResource/Harvester/OAI.php
@@ -0,0 +1,103 @@
+<?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_DigitalResource_Harvester_OAI extends Class_DigitalResource_OAI_AbstractInitJob {
+
+  public function __construct() {
+    parent::__construct();
+    $this->_job = $this->_('moissonnage de l\'OAI');
+  }
+
+
+  protected function _clean() {
+    return $this
+      ->_cleanHarvestLogs()
+      ->_cleanXML();
+  }
+
+
+  protected function _cleanHarvestLogs() {
+    $this->_log($this->_('Suppression des précédents journaux de moissonnage de %s.',
+                                     $this->_name));
+
+    Class_WebService_HarvestLog::deleteBy([ 'type_doc' => $this->_doc_type ]);
+    $this->_cleanMemory();
+
+    return $this;
+  }
+
+
+  protected function _cleanXML() {
+    $this->_log($this->_('Suppression des fichiers XML existants dans %s', $this->_oai_xml_directory_path));
+
+    Class_FileManager::deleteFiles($this->_oai_xml_directory_path);
+
+    return $this;
+  }
+
+
+  protected function _work() {
+    $this->_log($this->_('Début du moissonnage.'));
+    $this->_oai_ws->setLogger($this->getLogger());
+
+    Class_FileManager::create($this->_oai_xml_directory_name,
+                              Class_FileManager::find(USERFILES));
+
+    $page = 0;
+    while($this->_oai_ws->hasRecordsToHarvest())
+      $this->_writeXML($page ++);
+
+    Class_WebService_HarvestLog::newInstance(['end_date' => $this->getCurrentDate(),
+                                              'type_doc' => $this->_doc_type])
+      ->save();
+
+    $this->_log($this->_('%s fichiers sauvegardés.', ((int) $page ) -1));
+    return $this;
+  }
+
+
+  protected function _writeXML($page) {
+    if ( ! $xml = $this->_getXML($page))
+      return;
+
+    $this->_oai_ws->parseResumptionToken($xml);
+    Class_FileManager::createFile($this->_oai_xml_directory_path . '/' . $page . '.xml', $xml);
+  }
+
+
+  protected function _getXML($page) {
+    return $page == 1
+      ? $this->_oai_ws->getXML()
+      : $this->_oai_ws->getNextXML();
+  }
+
+
+  public function isDone() {
+    return Class_WebService_HarvestLog::findFirstBy(['type_doc' => $this->_doc_type]);
+  }
+
+
+  public function isRunning() {
+    return ( ! $this->isDone())
+      && Class_FileManager::hasFilesIn($this->_oai_xml_directory_path);
+  }
+}
diff --git a/library/Class/DigitalResource/Importer/OAI.php b/library/Class/DigitalResource/Importer/OAI.php
new file mode 100644
index 0000000000000000000000000000000000000000..547fa1c1ccdf825404fa2bf32d70ccd5f487eaea
--- /dev/null
+++ b/library/Class/DigitalResource/Importer/OAI.php
@@ -0,0 +1,121 @@
+<?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_DigitalResource_Importer_OAI extends Class_DigitalResource_OAI_AbstractInitJob {
+
+  public function __construct() {
+    parent::__construct();
+    $this->_job = $this->_('import des albums');
+  }
+
+
+  protected function _clean() {
+    if (Class_FileManager::files($this->_oai_xml_done_directory_path))
+      return $this;
+
+    $this->_log($this->_('%s : suppression des albums existants',
+                                     $this->_name));
+
+    $count_all_dimusic_albums = Class_Album::countBy(['type_doc_id' => $this->_doc_type]);
+
+    $deleted_albums = 0;
+
+    while ( $albums = Class_Album::findAllBy(['type_doc_id' => $this->_doc_type,
+                                              'limit' => 100])) {
+      $deleted_albums += $this->_deleteAlbums($albums);
+      $this->_log(sprintf('%s/%s',
+                                      $deleted_albums,
+                                      $count_all_dimusic_albums));
+
+      $this->_cleanMemory();
+    }
+
+    return $this;
+  }
+
+
+  protected function _deleteAlbums($albums) {
+    $deleted_albums = 0;
+    foreach($albums as $album) {
+      $album->delete();
+      $deleted_albums ++;
+    }
+
+    return $deleted_albums;
+  }
+
+
+  protected function _work() {
+    $this->_log($this->_('%s : création des albums.',
+                                     $this->_name));
+
+    Class_FileManager::create(static::DONE_DIRECTORY,
+                              Class_FileManager::find($this->_oai_xml_directory_path));
+
+    $files = Class_FileManager::files($this->_oai_xml_directory_path);
+    $total = count($files);
+    $count = 1;
+
+    foreach ( $files as $xml_file ) {
+      $this->_log($this->_('Traitement du fichier : %s. %s/%s',
+                                       $xml_file->getPath(),
+                                       $count,
+                                       $total));
+      $this->_workWithFile($xml_file);
+      $count ++;
+    }
+
+    return $this;
+  }
+
+
+  protected function _workWithFile($xml_file) {
+    $xml = $xml_file->getContent();
+    if ($this->_service->importFrom($xml))
+      Class_FileManager::moveItemInto($xml_file,
+                                      $this->_oai_xml_done_directory_path
+                                      . '/'
+                                      . $xml_file->getName());
+
+    return $this;
+  }
+
+
+  public function isDone() {
+    return (0 < $this->_config->countAlbums())
+      && $this->_config->getHarvesterInstance()->isDone();
+  }
+
+
+  public function isRunning() {
+    return ( ! $this->isDone())
+      && Class_FileManager::hasFilesIn($this->_oai_xml_directory_path);
+  }
+
+
+  public function getUserfilesFolderToDelete() {
+    return (Class_FileManager::find($this->_oai_xml_done_directory_path)
+            && $this->isDone())
+      ? $this->_oai_xml_directory_path
+      : '';
+  }
+}
diff --git a/library/Class/DigitalResource/OAI/AbstractInitJob.php b/library/Class/DigitalResource/OAI/AbstractInitJob.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b9df3508153f60de2dff02ab67db2eb53c00eac
--- /dev/null
+++ b/library/Class/DigitalResource/OAI/AbstractInitJob.php
@@ -0,0 +1,109 @@
+<?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
+ */
+
+
+abstract class Class_DigitalResource_OAI_AbstractInitJob {
+  use
+    Trait_TimeSource,
+    Trait_Translator,
+    Trait_MemoryCleaner,
+    Trait_Logger;
+
+  const DONE_DIRECTORY = 'done';
+
+
+  protected
+    $_job,
+    $_config,
+    $_service,
+    $_doc_type,
+    $_oai_xml_directory_name,
+    $_oai_xml_directory_path;
+
+
+  public function __construct() {
+    $this->_config = Class_DigitalResource_Config::getInstanceFor(static::class);
+    $this->_name = $this->_config->getName();
+    $this->_doc_type = $this->_config->getDocType();
+    $this->_service = $this->_config->getServiceInstance();
+    $this->_oai_ws = $this->_config->newOAIClient();
+
+    $this->_oai_xml_directory_name = sprintf('%s_oai_xml_responses',
+                                             strtolower($this->_name));
+
+    $this->_oai_xml_directory_path = USERFILES . '/' . $this->_oai_xml_directory_name;
+
+    $this->_oai_xml_done_directory_path =
+      $this->_oai_xml_directory_path
+      . '/'
+      . static::DONE_DIRECTORY;
+
+    Class_FileManager::disableCache();
+    Class_FileManager::beOpenBar();
+    Class_FileManager_FileSystem::beUnlimited();
+  }
+
+
+  protected function _log($message) {
+    return $this->getLogger()->log("\n" . $message);
+  }
+
+
+  public function run() {
+    if ( ! $this->_config->isEnabled() ) {
+      $this->_log($this->_('%s n\'est pas activé. Le script est arrété.',
+                                       $this->_name));
+      return $this;;
+    }
+
+    return $this
+      ->_intro()
+      ->_clean()
+      ->_work()
+      ->_stop();
+  }
+
+  protected function _intro() {
+    $this->_log($this->_('%s : Début premier %s à %s.',
+                                     $this->_name,
+                                     $this->_job,
+                                     $this->getCurrentDateTime()));
+    return $this;
+  }
+
+
+  protected function _stop() {
+    Class_FileManager::reset();
+    $this->_oai_ws->reset();
+
+    $this->_log($this->_('%s : Fin du premier %s à %s.',
+                                     $this->_name,
+                                     $this->_job,
+                                     $this->getCurrentDateTime()));
+    return $this;
+  }
+
+
+  abstract protected function _clean();
+  abstract protected function _work();
+  abstract public function isDone();
+  abstract public function isRunning();
+}
\ No newline at end of file
diff --git a/library/Class/FileManager.php b/library/Class/FileManager.php
index b81ed12c86ea10f770538bbe66f65aac16a776c1..084c7b5643bd2b6cca2b3e68ca2a94d8c8ea29d6 100644
--- a/library/Class/FileManager.php
+++ b/library/Class/FileManager.php
@@ -67,6 +67,11 @@ class Class_FileManager extends Class_Entity {
   }
 
 
+  public static function disableCache() {
+    return static::getFileSystem()->disableCache();
+  }
+
+
   public static function getDiskSpaceInfo() {
     return static::getFileSystem()->diskSpaceInfo();
   }
@@ -276,6 +281,17 @@ class Class_FileManager extends Class_Entity {
   }
 
 
+  public static function deleteFiles ($path) {
+    foreach (Class_FileManager::files($path) as $file)
+      Class_FileManager::delete($file);
+  }
+
+
+  public static function hasFilesIn($path) {
+    return 0 < static::getFileSystem()->countFilesIn($path);
+  }
+
+
   public static function search($term, $path) {
     if (!static::userHasRightOnPath($path))
       return [];
@@ -363,6 +379,11 @@ class Class_FileManager extends Class_Entity {
 
 
   public static function createImage($path, $content) {
+    return static::createFile($path, $content);
+  }
+
+
+  public static function createFile($path, $content) {
     return static::getFileSystem()->createImage($path, $content);
   }
 
diff --git a/library/Class/FileManager/FileSystem.php b/library/Class/FileManager/FileSystem.php
index d98f26518820aa6910ca3ccd0688ce5a1b12a2ee..ca500fc6280d89113a3fba181450c70d5e5cf866 100644
--- a/library/Class/FileManager/FileSystem.php
+++ b/library/Class/FileManager/FileSystem.php
@@ -26,7 +26,9 @@ class Class_FileManager_FileSystem {
   const
     LISTING_LIMIT = 200;
 
-  protected static $_limited = true;
+  protected static
+    $_limited = true,
+    $_cache_status = true;
 
   protected
     $_cached_paths = [],
@@ -40,6 +42,7 @@ class Class_FileManager_FileSystem {
 
   public static function reset() {
     static::$_limited = true;
+    static::$_cache_status = true;
   }
 
 
@@ -53,8 +56,13 @@ class Class_FileManager_FileSystem {
   }
 
 
+  public function countFilesIn($path) {
+    return count($this->_glob($path, false));
+  }
+
+
   protected function _filterEntriesAt($path, $callback = null) {
-    $items = $this->_glob($path, true);
+    $items = $this->_glob($path, static::$_cache_status);
 
     if (static::$_limited && Class_FileManager_FileSystem::LISTING_LIMIT < count($items)) {
       $this->_oversized[] = $path;
@@ -334,16 +342,17 @@ class Class_FileManager_FileSystem {
   protected function _glob($path, $cache = true) {
     $this->_cached_paths[] = $path;
 
-    $closure = function() use ($path) {
-      $paths = glob($path . '/{,.}[!.,!..]*', GLOB_BRACE);
-      $paths = array_filter($paths,
-                            function($path)
-    {
-      return Class_FileManager::userHasRightOnPath($path);
-    });
-      sort($paths, SORT_NATURAL);
-      return $paths;
-    };
+    $closure = function() use ($path)
+      {
+        $paths = glob($path . '/{,.}[!.,!..]*', GLOB_BRACE);
+        $paths = (array_filter($paths,
+                               function($path)
+                               {
+                                 return Class_FileManager::userHasRightOnPath($path);
+                               }));
+        sort($paths, SORT_NATURAL);
+        return $paths;
+      };
 
     if($cache)
       return (new Storm_Cache())
@@ -398,4 +407,9 @@ class Class_FileManager_FileSystem {
     ob_end_clean();
     return readfile($path);
   }
+
+
+  public function disableCache() {
+    static::$_cache_status = false;
+  }
 }
\ No newline at end of file
diff --git a/library/Class/WebService/BibNumerique/AbstractOAI.php b/library/Class/WebService/BibNumerique/AbstractOAI.php
index 96723336ba7f8b9b858c3a40251b4de7c81bf74f..aa9c8c14bd9ea27c816cd9d40722f4a1d8d47e0e 100644
--- a/library/Class/WebService/BibNumerique/AbstractOAI.php
+++ b/library/Class/WebService/BibNumerique/AbstractOAI.php
@@ -38,6 +38,11 @@ abstract class Class_WebService_BibNumerique_AbstractOAI extends Class_WebServic
   }
 
 
+  public function importFrom($xml) {
+    return $this->_importRessources($this->getOaiWS()->parseXML($xml));
+  }
+
+
   protected function _logRun() {
     Class_WebService_HarvestLog::newInstance(['end_date' => $this->getCurrentDate(),
                                               'type_doc' => $this->getDocType()])->save();
@@ -97,7 +102,7 @@ abstract class Class_WebService_BibNumerique_AbstractOAI extends Class_WebServic
 
 
   protected function getOaiWS() {
-    return $this->_oaiws;
+    return $this->_oaiws->setLogger($this->getLogger());
   }
 
 
diff --git a/library/Class/WebService/BibNumerique/ArteVOD/Config.php b/library/Class/WebService/BibNumerique/ArteVOD/Config.php
index 2cbbd9b390bc04fa195a8140f25b439249daf988..d3c359e42da839b3257120eb53a7c79586d3bf85 100644
--- a/library/Class/WebService/BibNumerique/ArteVOD/Config.php
+++ b/library/Class/WebService/BibNumerique/ArteVOD/Config.php
@@ -201,4 +201,9 @@ class Class_WebService_BibNumerique_ArteVOD_Config extends Class_Entity {
   public function renderTrySsoUrlOn($view, $params=[]) {
     return $view->url(array_merge($params, ['action' => 'artevod-try-sso']));
   }
+
+
+  public function isFirstHarvestAware() {
+    return false;
+  }
 }
diff --git a/library/Class/WebService/OAI.php b/library/Class/WebService/OAI.php
index 6a7a8c37579eb81678cc621b429aab69d5c3d803..a299a152e529b58ba6e43d5894e61f8e4aea4387 100644
--- a/library/Class/WebService/OAI.php
+++ b/library/Class/WebService/OAI.php
@@ -31,6 +31,9 @@
  */
 
 class Class_WebService_OAI extends Class_WebService_Abstract {
+  use Trait_Translator;
+
+
   const
     Verb = 'verb',
     MetadataPrefix = 'metadataPrefix',
@@ -52,6 +55,14 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
     $_logger;
 
 
+  /** @override Trait_SimpleWebClient::getWebClient() */
+  public static function getWebClient() {
+    return isset(static::$_web_client)
+      ? static::$_web_client
+      : new Class_WebService_WaitingSimpleWebClient();
+  }
+
+
   public static function baseURL() {
     return Class_Url::absolute(['module' => 'opac',
                                 'controller' => 'oai',
@@ -154,8 +165,19 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
 
   public function oaiAsks($verb, $parameters) {
     $url = $this->_askUrlFor($verb, $parameters);
+    $this->_log($this->_('Url : %s', $url));
+
     $response = $this->getContent($url);
-    $this->_log($url, $response);
+    200 < strlen($response)
+      ? ($this
+         ->_log($this->_('Réponse :'))
+         ->_log(substr($response, 0, 200))
+         ->_log('[…]')
+         ->_log(substr($response, -200)))
+      : $response;
+
+    if ( ! $response )
+      $this->setListRecordsResumptionToken(null);
 
     return $response;
   }
@@ -173,10 +195,12 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
   }
 
 
-  protected function _log($url, $response) {
+  protected function _log($message) {
     if (!$this->_logger)
-      return;
-    $this->_logger->log($url, $response);
+      return $this;
+
+    $this->_logger->log($message);
+    return $this;
   }
 
 
@@ -235,11 +259,9 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
     if (!$this->isFirstPage())
       return $this->getNextNumericResources();
 
-    $params = array_filter(array_merge([static::MetadataPrefix => $this->_metadata_prefix,
-                                        static::Set => $this->_default_set],
-                                       $params));
     $this->_first_page = false;
-    $xml_data = $this->oaiAsks(static::ListRecords, $params);
+
+    $xml_data = $this->getXML($params);
 
     return $this->parseListRecordsRessourcesNumeriqueXML($xml_data);
   }
@@ -258,7 +280,8 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
 
 
   public function getRecords($params = []) {
-    $params = array_merge([static::MetadataPrefix => $this->_metadata_prefix], $params);
+    $params = array_merge([static::MetadataPrefix => $this->_metadata_prefix],
+                          $params);
     $xml_data = $this->oaiAsks(static::ListRecords, $params);
 
     return $this->parseListRecordsXML($xml_data);
@@ -304,14 +327,39 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
 
 
   protected function _withNextPageDo($method) {
-    if (!$this->hasNextRecords())
-      return [];
+    return ($xml_data = $this->getNextXML())
+      ? $this->$method($xml_data)
+      : [];
+  }
 
-    $xml_data = $this
-      ->oaiAsks(static::ListRecords,
-                [static::ResumptionToken => $this->getListRecordsResumptionToken()->getToken()]);
 
-    return $this->$method($xml_data);
+  public function getXML($params = []) {
+    $params = array_filter(array_merge([static::MetadataPrefix => $this->_metadata_prefix,
+                                        static::Set => $this->_default_set],
+                                       $params));
+    return $this->oaiAsks(static::ListRecords, $params);
+  }
+
+
+  public function getNextXML() {
+    return $this->hasNextRecords()
+      ? $this->getXML([static::MetadataPrefix => null,
+                       static::Set => null,
+                       static::ResumptionToken =>
+                       $this->getListRecordsResumptionToken()->getToken()])
+      : '';
+  }
+
+
+  public function parseResumptionToken($xml) {
+    $this->parser->parse($xml);
+
+    return ($token = $this->parser->getResumptionToken())
+      ? ($this
+         ->setListRecordsResumptionToken($token)
+         ->beNextPage())
+      : ($this
+         ->setListRecordsResumptionToken(null));
   }
 
 
@@ -356,6 +404,19 @@ class Class_WebService_OAI extends Class_WebService_Abstract {
   }
 
 
+  public function beNextPage() {
+    $this->_first_page = false;
+    return $this;
+  }
+
+
+  public function parseXML($xml) {
+    $this->parser->acceptVisitor($this);
+    $this->parser->parse($xml);
+    return $this->parser->getRecordsRessourceNumeriques();
+  }
+
+
   public function reset() {
     return $this->setListRecordsResumptionToken(null)
                 ->beFirstPage();
diff --git a/library/ZendAfi/View/Helper/BaseHelper.php b/library/ZendAfi/View/Helper/BaseHelper.php
index e6d92f6709cc906fa17fc73fbc1bf345cc5d471d..cf4db9a25b04f749c334e52268778df18d22fbde 100644
--- a/library/ZendAfi/View/Helper/BaseHelper.php
+++ b/library/ZendAfi/View/Helper/BaseHelper.php
@@ -71,6 +71,11 @@ class ZendAfi_View_Helper_BaseHelper extends Zend_View_Helper_HtmlElement {
   }
 
 
+  protected function _tagSuccess($message) {
+    return call_user_func_array([$this->view, 'tagSuccess'], func_get_args());
+  }
+
+
   protected function _tagWarning($message) {
     return call_user_func_array([$this->view, 'tagWarning'], func_get_args());
   }
diff --git a/library/ZendAfi/View/Helper/DigitalResource/Dashboard/Harvest.php b/library/ZendAfi/View/Helper/DigitalResource/Dashboard/Harvest.php
index bb3ed791f9e472cddca788d09e6e47fd21d136b5..39e5d08723acaca1d51958d9794dd26475eb9c0f 100644
--- a/library/ZendAfi/View/Helper/DigitalResource/Dashboard/Harvest.php
+++ b/library/ZendAfi/View/Helper/DigitalResource/Dashboard/Harvest.php
@@ -33,6 +33,9 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard_Harvest extends ZendAfi_View
   protected function _render($config) {
     $html = [$this->_tag('h3', $this->_('Diagnostic moissonnage'))];
 
+    if ($config->isFirstHarvestAware())
+      $html = $this->_addFirstHarvestAware($html, $config);
+
     if (!$config->getBatch()) {
       $html [] = $this->_tagNotice($this->_('Cette ressource ne prend pas en charge le moissonnage')) ;
       return implode($html);
@@ -51,7 +54,7 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard_Harvest extends ZendAfi_View
 
   protected function _getTypedocImage($config){
     return $this->_tag('h4',
-                      $this->_('Image du type de document: ')
+                       $this->_('Image du type de document: ')
                        . $config->getTypeDocImage($this->view));
   }
 
@@ -106,7 +109,7 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard_Harvest extends ZendAfi_View
                  'condition' => function($model) {
                     return Class_Users::isCurrentUserSuperAdmin()
                     && $model->isActive();
-                  },
+                 },
                  'anchorOptions' => ['data-popup' => 'true']],
 
                 ['url' => '/admin/batch/run/id/%s',
@@ -200,4 +203,52 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard_Harvest extends ZendAfi_View
                                 $this->_('Nombre de notices présentes dans Bokeh : %d', $count)),
                     $records_link]);
   }
+
+
+  protected function _addFirstHarvestAware($html, $config) {
+    if ( $harvest_done = $config->isFirstHarvestDone())
+      $html [] = $this->_tagSuccess($this->_('Le premier moissonnage a été effectué.'));
+
+    if ( $import_done = $config->isFirstImportDone())
+      $html [] = $this->_tagSuccess($this->_('Le premier import d\'albums a été effectué.'));
+
+    if ( $harvest_done && $import_done)
+      return $html = $this->_allowDeletionOfFiles($html, $config);
+
+    $html [] = $this->_tagError($this->_('Cette ressource nécessite un premier moissonnage manuel et un premier import manuel.'));
+
+    $html [] = $this->_tagError($this->_('Vous devez contacter votre hébergeur pour réaliser ces actions.'));
+
+    if ( $harvest_running = $config->isFirstHarvestRunning() )
+      $html [] = $this->_tagWarning($this->_('Le premier moissonnage d\'albums est en cours.'));
+
+    if ( $import_running = $config->isFirstImportRunning() )
+      $html [] = $this->_tagWarning($this->_('Le premier import d\'albums est en cours.'));
+
+    $html [] = $this->_tagError($this->_('En attendant le batch %s ne doit ni être lancé ni être plannifié.',
+                                         $config->getBatchInstance()->getLabel()));
+
+    return $html;
+  }
+
+
+  protected function _allowDeletionOfFiles($html, $config) {
+    $importer = $config->getImporterInstance();
+
+    if ($userfiles_folder = $importer->getUserfilesFolderToDelete()) {
+      $delete_folder_anchor =
+        $this->view->tagAnchor($this->_url(['module' => 'admin',
+                                            'controller' => 'file-manager',
+                                            'action' => 'delete',
+                                            'item' => $userfiles_folder],
+                                           null, true),
+                               $this->_('Supprimer'));
+
+      $html [] = $this->_tagNotice($this->_('Vous pouvez supprimer le dossier %s dans l\'explorateur de fichier : %s',
+                                            $userfiles_folder,
+                                            $delete_folder_anchor));
+    }
+
+    return $html;
+  }
 }
\ No newline at end of file
diff --git a/library/digital_resources/DiMusic/Config.php b/library/digital_resources/DiMusic/Config.php
index bf5750388727ee271f39c939dfd8811af4bafcfa..5e2e95fb00dd69b8cad7ebb8ad6eeb09aa006e43 100644
--- a/library/digital_resources/DiMusic/Config.php
+++ b/library/digital_resources/DiMusic/Config.php
@@ -38,6 +38,9 @@ class DiMusic_Config extends Class_DigitalResource_Config {
             'Service' => $this->withNameSpace('Service'),
             'Batch' => $this->withNameSpace('Batch'),
 
+            'Importer' => $this->withNameSpace('Importer'),
+            'Harvester' => $this->withNameSpace('Harvester'),
+
             'DocTypeLabel' => $this->_('Ressource diMusic'),
             'PhoneLabel' => $this->_('Accéder à l\'album'),
 
diff --git a/library/digital_resources/DiMusic/Harvester.php b/library/digital_resources/DiMusic/Harvester.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1e75f1141153e5939c1a548e846668f217b9eab
--- /dev/null
+++ b/library/digital_resources/DiMusic/Harvester.php
@@ -0,0 +1,23 @@
+<?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 DiMusic_Harvester extends Class_DigitalResource_Harvester_OAI {}
\ No newline at end of file
diff --git a/library/digital_resources/DiMusic/Importer.php b/library/digital_resources/DiMusic/Importer.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3d6fb666ec27b760cc115a1d1834628b605dd0e
--- /dev/null
+++ b/library/digital_resources/DiMusic/Importer.php
@@ -0,0 +1,23 @@
+<?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 DiMusic_Importer extends Class_DigitalResource_Importer_OAI{}
diff --git a/library/digital_resources/DiMusic/tests/DiMusicTest.php b/library/digital_resources/DiMusic/tests/DiMusicTest.php
index 9beb08b88a23e0109f6a910a9897158f1cce3768..e3501f96f24d0cebd5c01c29e532678684f79c1a 100644
--- a/library/digital_resources/DiMusic/tests/DiMusicTest.php
+++ b/library/digital_resources/DiMusic/tests/DiMusicTest.php
@@ -44,6 +44,11 @@ abstract class DiMusicActivatedTestCase extends AbstractControllerTestCase {
                    ['id' => 1,
                     'code' => 'DiMusic'])
          ->permitTo($group,  new Class_Entity());
+
+    $now = new TimeSourceForTest('2021-11-18 14:21:00');
+
+    DiMusic_Harvester::setTimeSource($now);
+    DiMusic_Importer::setTimeSource($now);
   }
 }
 
@@ -108,7 +113,7 @@ class DiMusicDashboardUnactivatedTest extends Admin_AbstractControllerTestCase {
 
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/DiMusic_Plugin', true);
+    $this->dispatch('/DiMusic_Plugin');
   }
 
 
@@ -128,8 +133,6 @@ class DiMusicDashboardUnactivatedTest extends Admin_AbstractControllerTestCase {
 
 
 class DiMusicDashboardActivatedTest extends DiMusicActivatedTestCase {
-  protected $_storm_default_to_volatile = true;
-
 
   public function setUp() {
     parent::setUp();
@@ -154,7 +157,7 @@ class DiMusicDashboardActivatedTest extends DiMusicActivatedTestCase {
                                 'password' => 'admin',
                                 'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]));
 
-    $this->dispatch('/DiMusic_Plugin', true);
+    $this->dispatch('/DiMusic_Plugin');
   }
 
 
@@ -199,9 +202,22 @@ class DiMusicDashboardActivatedTest extends DiMusicActivatedTestCase {
   public function doctypeImageUrlShouldBePresent() {
     $this->assertXPath('//h4/img[contains(@src, "/digital-resource/typedoc-icon/id/DiMusic")]');
   }
-}
 
 
+  /** @test */
+  public function firstHarvestErrorMessageShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="error"]',
+                                      'Cette ressource nécessite un premier moissonnage manuel et un premier import manuel.');
+  }
+
+
+  /** @test */
+  public function contextShouldExpectation() {
+    $this->assertXPathContentContains('//p[@class="error"]',
+                                      'Vous devez contacter votre hébergeur pour réaliser ces actions.');
+  }
+}
+
 
 
 
@@ -657,4 +673,444 @@ class DiMusicNoticeAjaxControllerTest extends AbstractControllerTestCase {
   public function onloadUtilShouldBeLoaded() {
     $this->assertXPath('//script[contains(@src, "onload_util")]');
   }
+}
+
+
+
+
+abstract class DiMusicOAIFirstHarvestTestCase extends DiMusicActivatedTestCase {
+    protected
+      $_logger,
+      $_log = [],
+      $_web_client,
+      $_file_system,
+      $_userfiles,
+      $_page1,
+      $_page2,
+      $_page1_xml,
+      $_page2_xml;
+
+
+  public function setUp() {
+    parent::setUp();
+
+    Class_AdminVar::set('DiMusic_Harvest_Url','https://music.divercities.eu/oai');
+
+    $this->_page1_xml = file_get_contents(__DIR__ . '/oai_page1.xml');
+    $this->_page2_xml = file_get_contents(__DIR__ . '/oai_page2.xml');
+
+    $this->_page1 = $this
+      ->mock()
+      ->whenCalled('getModels')
+      ->answers(1);
+
+    $this->_page2 = $this
+      ->mock()
+      ->whenCalled('getModels')
+      ->answers(1);
+
+    $this->_userfiles = $this
+      ->mock()
+
+      ->whenCalled('isWritable')->answers(true)
+
+      ->whenCalled('isDir')->answers(true)
+
+      ->whenCalled('getId')->answers('userfiles')
+
+      ->beStrict();
+
+    $this->_file_system = $this
+      ->mock()
+
+      ->whenCalled('disableCache')
+      ->answers(true)
+
+      ->beStrict();
+
+    $this->_web_client = $this
+      ->mock()
+      ->beStrict();
+
+    Class_FileManager::setFileSystem($this->_file_system);
+    Class_WebService_OAI::setWebClient($this->_web_client);
+  }
+}
+
+
+
+
+class DiMusicHarvesterTest extends DiMusicOAIFirstHarvestTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->_file_system
+      ->whenCalled('filesAt')->with('userfiles/dimusic_oai_xml_responses')
+      ->answers([$this->_page1, $this->_page2])
+
+      ->whenCalled('directoryAt')->with('userfiles')
+      ->answers($this->_userfiles)
+
+      ->whenCalled('create')->with('userfiles/dimusic_oai_xml_responses')
+      ->answers(true)
+
+      ->whenCalled('createImage')->with('userfiles/dimusic_oai_xml_responses/1.xml',
+                                        $this->_page1_xml)
+      ->answers(true)
+
+      ->whenCalled('createImage')->with('userfiles/dimusic_oai_xml_responses/2.xml',
+                                        $this->_page2_xml)
+      ->answers(true);
+
+    $this->_web_client
+      ->whenCalled('open_url')->with('https://music.divercities.eu/oai?verb=ListRecords&metadataPrefix=oai1dtouch_dc')
+      ->answers($this->_page1_xml)
+
+      ->whenCalled('open_url')
+      ->with('https://music.divercities.eu/oai?verb=ListRecords&resumptionToken=oai1dtouch_dc.f%282015-02-09T08%3A46%3A09Z%29.u%282015-02-09T08%3A47%3A27Z%29%3A133')
+      ->answers($this->_page2_xml);
+
+    $this->_logger = new Class_Cata_LogVolatile;
+    $harvester = (new DiMusic_Harvester)
+      ->setLogger($this->_logger);
+    $harvester->run();
+    $this->_log = $this->_logger->getLines();
+  }
+
+
+  /** @test */
+  public function diMusicHarvestShouldCollectOAI() {
+    $page1_start = substr($this->_page1_xml, 0, 200);
+    $page1_end = substr($this->_page1_xml, -200);
+
+    $page2_start = substr($this->_page2_xml, 0, 200);
+    $page2_end = substr($this->_page2_xml, -200);
+
+    $this->assertEquals(["\nDiMusic : Début premier moissonnage de l'OAI à 2021-11-18 14:21:00.",
+                         "\nSuppression des précédents journaux de moissonnage de DiMusic.",
+                         "\nSuppression des fichiers XML existants dans userfiles/dimusic_oai_xml_responses",
+                         "\nDébut du moissonnage.",
+                         "Url : https://music.divercities.eu/oai?verb=ListRecords&metadataPrefix=oai1dtouch_dc",
+                         "Réponse :",
+                         $page1_start,
+                         "[…]",
+                         $page1_end,
+                         "Url : https://music.divercities.eu/oai?verb=ListRecords&resumptionToken=oai1dtouch_dc.f%282015-02-09T08%3A46%3A09Z%29.u%282015-02-09T08%3A47%3A27Z%29%3A133",
+                         "Réponse :",
+                         $page2_start,
+                         "[…]",
+                         $page2_end,
+                         "\n2 fichiers sauvegardés.",
+                         "\nDiMusic : Fin du premier moissonnage de l'OAI à 2021-11-18 14:21:00."],
+                        $this->_log);
+  }
+
+
+  /** @test */
+  public function harvestLogShouldHaveBeenCreated() {
+    $this->assertNotNull(Class_WebService_HarvestLog::find(1));
+  }
+}
+
+
+
+
+class DiMusicImporterTest extends DiMusicOAIFirstHarvestTestCase {
+
+
+  public function setUp() {
+    parent::setUp();
+
+
+    $this->fixture(Class_Album::class,
+                   ['id' => 1,
+                    'titre' => 'old_album',
+                    'type_doc_id' => 'DiMusic']);
+
+    $this->_page1
+      ->whenCalled('getContent')
+      ->answers($this->_page1_xml)
+
+      ->whenCalled('getPath')
+      ->answers('userfiles/dimusic_oai_xml_responses/1.xml')
+
+      ->whenCalled('isWritable')
+      ->answers(true)
+
+      ->whenCalled('isDir')
+      ->answers(false)
+
+      ->whenCalled('getId')
+      ->answers('userfiles/dimusic_oai_xml_responses/1.xml')
+
+      ->whenCalled('getName')
+      ->answers('1.xml');
+
+    $this->_page2
+      ->whenCalled('getContent')
+      ->answers($this->_page2_xml)
+
+      ->whenCalled('getPath')
+      ->answers('userfiles/dimusic_oai_xml_responses/2.xml')
+
+      ->whenCalled('isWritable')
+      ->answers(true)
+
+      ->whenCalled('isDir')
+      ->answers(false)
+
+      ->whenCalled('getName')
+      ->answers('2.xml')
+
+      ->whenCalled('getId')
+      ->answers('userfiles/dimusic_oai_xml_responses/2.xml');
+
+    $dimusic_oai_xml_responses = $this
+      ->mock()
+      ->whenCalled('isWritable')
+      ->answers(true)
+
+      ->whenCalled('isDir')
+      ->answers(true)
+
+      ->whenCalled('getId')
+      ->answers('dimusic_oai_xml_responses');
+
+    $this->_file_system
+      ->whenCalled('directoryAt')->with('userfiles/dimusic_oai_xml_responses')
+      ->answers($dimusic_oai_xml_responses)
+
+      ->whenCalled('filesAt')->with('userfiles/dimusic_oai_xml_responses/done')
+      ->answers([])
+
+      ->whenCalled('create')->with('dimusic_oai_xml_responses/done')
+      ->answers(true)
+
+      ->whenCalled('filesAt')->with('userfiles/dimusic_oai_xml_responses')
+      ->answers([$this->_page1, $this->_page2])
+
+      ->whenCalled('rename')->with('userfiles/dimusic_oai_xml_responses/1.xml',
+                                   'userfiles/dimusic_oai_xml_responses/done/1.xml')
+      ->answers(true)
+
+      ->whenCalled('rename')->with('userfiles/dimusic_oai_xml_responses/2.xml',
+                                   'userfiles/dimusic_oai_xml_responses/done/2.xml')
+      ->answers(true);
+
+    $this->_logger = new Class_Cata_LogVolatile;
+    (new DiMusic_Importer)
+      ->setLogger($this->_logger)
+      ->run();
+
+    $this->_log = $this->_logger->getLines();
+  }
+
+
+  /** @test */
+  public function diMusicImporterShouldCreateFourAlbums() {
+    $this->assertEquals(4, Class_Album::countBy(['type_doc_id' => DiMusic_Config::getInstance()->getDocType()]));
+  }
+
+
+  /** @test */
+  public function diMusicImportLogShouldBeHasExpected() {
+    $this->assertEquals(["\nDiMusic : Début premier import des albums à 2021-11-18 14:21:00.",
+                         "\nDiMusic : suppression des albums existants",
+                         "\n1/1",
+                         "\nDiMusic : création des albums.",
+                         "\nTraitement du fichier : userfiles/dimusic_oai_xml_responses/1.xml. 1/2",
+                         "\nTraitement du fichier : userfiles/dimusic_oai_xml_responses/2.xml. 2/2",
+                         "\nDiMusic : Fin du premier import des albums à 2021-11-18 14:21:00."],
+                        $this->_log);
+  }
+}
+
+
+
+
+class DiMusicOAIFirstHarvestLoadingTest extends DiMusicActivatedTestCase {
+  /** @test */
+  public function diMusicHarvesterShouldExists() {
+    $this->assertEquals(['DiMusic' => (new DiMusic_Harvester)], Class_DigitalResource::getInstance()->getHarvesters());
+  }
+
+
+  /** @test */
+  public function diMusicImporterShouldExists() {
+    $this->assertEquals(['DiMusic' => (new DiMusic_Importer)], Class_DigitalResource::getInstance()->getImporters());
+  }
+}
+
+
+
+
+class DiMusicDashboardActivatedAndFirstRunDoneTest extends DiMusicActivatedTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $album = $this->fixture('Class_Album',
+                            ['id' => 20,
+                             'titre' => '10 moutons',
+                             'type_doc_id' => 'DiMusic',
+                            ]);
+
+    $album->addPosterURI('https://assest.server.eu/cargo/1.jpg')
+          ->assertSave();
+
+    Class_WebService_BibNumerique_Vignette::setHttpClient($this->mock()
+                                                          ->whenCalled('getResponse')
+                                                          ->answers(new Class_Testing_HttpResponse(['Body' => true])));
+
+    ZendAfi_Auth::getInstance()
+      ->logUser($this->fixture('Class_Users',
+                               ['id' => 2,
+                                'login' => 'admin',
+                                'password' => 'admin',
+                                'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]));
+
+    $this->fixture(Class_WebService_HarvestLog::class,
+                   ['id' => 1,
+                   'type_doc' => 'DiMusic']);
+
+    $file_system = $this
+      ->mock()
+
+      ->whenCalled('disableCache')
+      ->answers(true)
+
+      ->whenCalled('directoryAt')->with('userfiles/dimusic_oai_xml_responses/done')
+      ->answers(true)
+
+      ->beStrict();
+
+    Class_FileManager::setFileSystem($file_system);
+
+    $this->dispatch('/DiMusic_Plugin');
+  }
+
+
+  public function tearDown() {
+    Class_WebService_BibNumerique_Vignette::setHttpClient(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function shouldDisplayActivated() {
+    $this->assertXPathContentContains('//button', 'Activé');
+  }
+
+
+  /** @test */
+  public function firstImportSuccessMessageShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="success"]',
+                                      'Le premier import d\'albums a été effectué.');
+  }
+
+
+  /** @test */
+  public function firstHarvestSuccessMessageShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="success"]',
+                                      'Le premier moissonnage a été effectué.');
+  }
+
+
+  /** @test */
+  public function removeDiMusicFilesMessageShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="notice"]',
+                                      'Vous pouvez supprimer le dossier userfiles/dimusic_oai_xml_responses dans l\'explorateur de fichier :');
+  }
+
+
+  /** @test */
+  public function removeDiMusicLinkShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="notice"]//a[@href =  "/admin/file-manager/delete/item/userfiles%2Fdimusic_oai_xml_responses"]',
+                                      'Supprimer');
+  }
+}
+
+
+
+class DiMusicDashboardActivatedAndFirstRunRunningTest extends DiMusicActivatedTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $album = $this->fixture('Class_Album',
+                            ['id' => 20,
+                             'titre' => '10 moutons',
+                             'type_doc_id' => 'DiMusic',
+                            ]);
+
+    $album->addPosterURI('https://assest.server.eu/cargo/1.jpg')
+          ->assertSave();
+
+    Class_WebService_BibNumerique_Vignette::setHttpClient($this->mock()
+                                                          ->whenCalled('getResponse')
+                                                          ->answers(new Class_Testing_HttpResponse(['Body' => true])));
+
+    ZendAfi_Auth::getInstance()
+      ->logUser($this->fixture('Class_Users',
+                               ['id' => 2,
+                                'login' => 'admin',
+                                'password' => 'admin',
+                                'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]));
+
+    $file_system = $this
+      ->mock()
+
+      ->whenCalled('disableCache')
+      ->answers(true)
+
+      ->whenCalled('directoryAt')->with('userfiles/dimusic_oai_xml_responses/done')
+      ->answers(true)
+
+      ->whenCalled('directoryAt')->with('userfiles/dimusic_oai_xml_responses')
+      ->answers(true)
+
+      ->whenCalled('countFilesIn')->with('userfiles/dimusic_oai_xml_responses')
+      ->answers(3)
+
+      ->beStrict();
+
+    Class_FileManager::setFileSystem($file_system);
+
+    $this->dispatch('/DiMusic_Plugin');
+  }
+
+
+  public function tearDown() {
+    Class_WebService_BibNumerique_Vignette::setHttpClient(null);
+    Class_FileManager::reset();
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function shouldDisplayActivated() {
+    $this->assertXPathContentContains('//button', 'Activé');
+  }
+
+
+  /** @test */
+  public function firstImportSuccessMessageShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="warning"]',
+                                      'Le premier import d\'albums est en cours.');
+  }
+
+
+  /** @test */
+  public function firstHarvestSuccessMessageShouldBeDisplay() {
+    $this->assertXPathContentContains('//p[@class="warning"]',
+                                      'Le premier moissonnage d\'albums est en cours.');
+  }
+
+
+  /** @test */
+  public function removeDiMusicLinkShouldBeDisplay() {
+    $this->assertNotXPathContentContains('//p[@class="notice"]//a',
+                                         'Supprimer');
+  }
 }
\ No newline at end of file
diff --git a/library/digital_resources/DiMusic/tests/oai_page1.xml b/library/digital_resources/DiMusic/tests/oai_page1.xml
index 5e92ceb4c116b36df9feaa36311ceb24948d6ad3..c4fb631a08080d1dc0e70840a0183d66867c2c82 100644
--- a/library/digital_resources/DiMusic/tests/oai_page1.xml
+++ b/library/digital_resources/DiMusic/tests/oai_page1.xml
@@ -7,639 +7,637 @@
   <ListRecords>
     <record>
       <header status="deleted">
-	<identifier>oai:oai1dtouch.com/album2</identifier>
-	<datestamp>2017-02-22T12:46:19Z</datestamp>
-	<setSpec>music</setSpec>
+      <identifier>oai:oai1dtouch.com/album2</identifier>
+      <datestamp>2017-02-22T12:46:19Z</datestamp>
+      <setSpec>music</setSpec>
       </header>
     </record>
     <record>
       <header>
-	<identifier>oai:oai1dtouch.com:124
-	</identifier>
-	<datestamp>2015-02-09T08:47:27Z
-	</datestamp>
+      <identifier>oai:oai1dtouch.com:124
+      </identifier>
+      <datestamp>2015-02-09T08:47:27Z
+      </datestamp>
       </header>
       <metadata>
-	<oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
-	  <id>124
-	  </id>
-	  <icpn>3610159181474
-	  </icpn>
-	  <title>WOLFEP0241</title>
-	  <description>A Dance House music album</description>
-	  <date>2014-11-03T00:00:00Z
-	  </date>
-	  <label>Wolf Music Recordings
-	  </label>
-	  <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159181474.jpg
-	  </cover_url>
-	  <url>http://music.1dtouch.com/albums/124
-	  </url>
-	  <artists>
-	    <artist>Ishmael
-	    </artist>
-	  </artists>
-	  <styles>
-	    <style>Dance
-	    </style>
-	    <style>House
-	    </style>
-	    <style>Deep
-	    </style>
-	  </styles>
-	  <tracks>
-	    <track>
-	      <id>1789AEYU89
-	      </id>
-	      <isrc>GB2SA1200088
-	      </isrc>
-	      <position>1
-	      </position>
-	      <title>Dejong
-	      </title>
-	      <length>PT0H7M20S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200088_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GB2SA1200089
-	      </isrc>
-	      <position>2
-	      </position>
-	      <title>Takoma
-	      </title>
-	      <length>PT0H5M30S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200089_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GB2SA1200090
-	      </isrc>
-	      <position>3
-	      </position>
-	      <title>Ashbury Roll
-	      </title>
-	      <length>PT0H5M26S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200090_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GB2SA1200091
-	      </isrc>
-	      <position>4
-	      </position>
-	      <title>Takoma
-	      </title>
-	      <length>PT0H7M13S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200091_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	  </tracks>
-	</oai1dtouch_dc>
+      <oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
+        <id>124
+        </id>
+        <icpn>3610159181474
+        </icpn>
+        <title>WOLFEP0241</title>
+        <description>A Dance House music album</description>
+        <date>2014-11-03T00:00:00Z
+        </date>
+        <label>Wolf Music Recordings
+        </label>
+        <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159181474.jpg
+        </cover_url>
+        <url>http://music.1dtouch.com/albums/124
+        </url>
+        <artists>
+          <artist>Ishmael
+          </artist>
+        </artists>
+        <styles>
+          <style>Dance
+          </style>
+          <style>House
+          </style>
+          <style>Deep
+          </style>
+        </styles>
+        <tracks>
+          <track>
+            <id>1789AEYU89
+            </id>
+            <isrc>GB2SA1200088
+            </isrc>
+            <position>1
+            </position>
+            <title>Dejong
+            </title>
+            <length>PT0H7M20S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200088_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GB2SA1200089
+            </isrc>
+            <position>2
+            </position>
+            <title>Takoma
+            </title>
+            <length>PT0H5M30S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200089_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GB2SA1200090
+            </isrc>
+            <position>3
+            </position>
+            <title>Ashbury Roll
+            </title>
+            <length>PT0H5M26S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200090_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GB2SA1200091
+            </isrc>
+            <position>4
+            </position>
+            <title>Takoma
+            </title>
+            <length>PT0H7M13S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200091_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+        </tracks>
+      </oai1dtouch_dc>
       </metadata>
     </record>
     <record>
       <header>
-	<identifier>oai:oai1dtouch.com:125
-	</identifier>
-	<datestamp>2015-02-09T08:47:27Z
-	</datestamp>
+      <identifier>oai:oai1dtouch.com:125
+      </identifier>
+      <datestamp>2015-02-09T08:47:27Z
+      </datestamp>
       </header>
       <metadata>
-	<oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
-	  <id>125
-	  </id>
-	  <icpn>3610159181993
-	  </icpn>
-	  <title>Ataché
-	  </title>
-	  <date>2014-11-06T00:00:00Z
-	  </date>
-	  <label>Altino's Music / Couleurs Music Publishing
-	  </label>
-	  <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159181993.jpg
-	  </cover_url>
-	  <url>http://music.1dtouch.com/albums/125
-	  </url>
-	  <artists>
-	    <artist>T-Micky
-	    </artist>
-	  </artists>
-	  <styles>
-	    <style>World
-	    </style>
-	  </styles>
-	  <tracks>
-	    <track>
-	      <isrc>GBGYQ1400032
-	      </isrc>
-	      <position>1
-	      </position>
-	      <title>Pa kite
-	      </title>
-	      <length>PT0H4M54S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400032_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR6V82527830
-	      </isrc>
-	      <position>2
-	      </position>
-	      <title>Nou pare
-	      </title>
-	      <length>PT0H3M50S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr6v82527830_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400033
-	      </isrc>
-	      <position>3
-	      </position>
-	      <title>Manvi kwazé L
-	      </title>
-	      <length>PT0H3M27S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400033_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400034
-	      </isrc>
-	      <position>4
-	      </position>
-	      <title>Kite L ale
-	      </title>
-	      <length>PT0H4M38S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400034_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400035
-	      </isrc>
-	      <position>5
-	      </position>
-	      <title>Pale yo
-	      </title>
-	      <length>PT0H3M39S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400035_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400036
-	      </isrc>
-	      <position>6
-	      </position>
-	      <title>Love Me
-	      </title>
-	      <length>PT0H4M14S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400036_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1200019
-	      </isrc>
-	      <position>7
-	      </position>
-	      <title>N'oublies pas
-	      </title>
-	      <length>PT0H3M50S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1200019_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400037
-	      </isrc>
-	      <position>8
-	      </position>
-	      <title>Mèt bliye M
-	      </title>
-	      <length>PT0H3M43S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400037_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400038
-	      </isrc>
-	      <position>9
-	      </position>
-	      <title>Mesi manman
-	      </title>
-	      <length>PT0H4M35S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400038_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400039
-	      </isrc>
-	      <position>10
-	      </position>
-	      <title>San ou
-	      </title>
-	      <length>PT0H4M14S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400039_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400040
-	      </isrc>
-	      <position>11
-	      </position>
-	      <title>Sere mwen
-	      </title>
-	      <length>PT0H4M20S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400040_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400041
-	      </isrc>
-	      <position>12
-	      </position>
-	      <title>Nouvèl la gaye
-	      </title>
-	      <length>PT0H3M44S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400041_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GBGYQ1400042
-	      </isrc>
-	      <position>13
-	      </position>
-	      <title>Yo met pale
-	      </title>
-	      <length>PT0H4M6S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400042_320k.mp3
-	      </url>
-	      <artists>
-		<artist>T-Micky
-		</artist>
-	      </artists>
-	    </track>
-	  </tracks>
-	</oai1dtouch_dc>
+      <oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
+        <id>125
+        </id>
+        <icpn>3610159181993
+        </icpn>
+        <title>Ataché
+        </title>
+        <date>2014-11-06T00:00:00Z
+        </date>
+        <label>Altino's Music / Couleurs Music Publishing
+        </label>
+        <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159181993.jpg
+        </cover_url>
+        <url>http://music.1dtouch.com/albums/125
+        </url>
+        <artists>
+          <artist>T-Micky
+          </artist>
+        </artists>
+        <styles>
+          <style>World
+          </style>
+        </styles>
+        <tracks>
+          <track>
+            <isrc>GBGYQ1400032
+            </isrc>
+            <position>1
+            </position>
+            <title>Pa kite
+            </title>
+            <length>PT0H4M54S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400032_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR6V82527830
+            </isrc>
+            <position>2
+            </position>
+            <title>Nou pare
+            </title>
+            <length>PT0H3M50S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr6v82527830_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400033
+            </isrc>
+            <position>3
+            </position>
+            <title>Manvi kwazé L
+            </title>
+            <length>PT0H3M27S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400033_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400034
+            </isrc>
+            <position>4
+            </position>
+            <title>Kite L ale
+            </title>
+            <length>PT0H4M38S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400034_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400035
+            </isrc>
+            <position>5
+            </position>
+            <title>Pale yo
+            </title>
+            <length>PT0H3M39S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400035_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400036
+            </isrc>
+            <position>6
+            </position>
+            <title>Love Me
+            </title>
+            <length>PT0H4M14S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400036_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1200019
+            </isrc>
+            <position>7
+            </position>
+            <title>N'oublies pas
+            </title>
+            <length>PT0H3M50S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1200019_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400037
+            </isrc>
+            <position>8
+            </position>
+            <title>Mèt bliye M
+            </title>
+            <length>PT0H3M43S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400037_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400038
+            </isrc>
+            <position>9
+            </position>
+            <title>Mesi manman
+            </title>
+            <length>PT0H4M35S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400038_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400039
+            </isrc>
+            <position>10
+            </position>
+            <title>San ou
+            </title>
+            <length>PT0H4M14S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400039_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400040
+            </isrc>
+            <position>11
+            </position>
+            <title>Sere mwen
+            </title>
+            <length>PT0H4M20S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400040_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400041
+            </isrc>
+            <position>12
+            </position>
+            <title>Nouvèl la gaye
+            </title>
+            <length>PT0H3M44S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400041_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GBGYQ1400042
+            </isrc>
+            <position>13
+            </position>
+            <title>Yo met pale
+            </title>
+            <length>PT0H4M6S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gbgyq1400042_320k.mp3
+            </url>
+            <artists>
+            <artist>T-Micky
+            </artist>
+            </artists>
+          </track>
+        </tracks>
+      </oai1dtouch_dc>
       </metadata>
     </record>
     <record>
       <header>
-	<identifier>oai:oai1dtouch.com:126
-	</identifier>
-	<datestamp>2015-02-09T08:47:27Z
-	</datestamp>
+      <identifier>oai:oai1dtouch.com:126
+      </identifier>
+      <datestamp>2015-02-09T08:47:27Z
+      </datestamp>
       </header>
       <metadata>
-	<oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
-	  <id>126
-	  </id>
-	  <icpn>3610159198724
-	  </icpn>
-	  <title>Impact
-	  </title>
-	  <date>2015-01-12T00:00:00Z
-	  </date>
-	  <label>Karlito
-	  </label>
-	  <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159198724.jpg
-	  </cover_url>
-	  <url>http://music.1dtouch.com/albums/126
-	  </url>
-	  <artists>
-	    <artist>Karlito
-	    </artist>
-	  </artists>
-	  <styles>
-	    <style>Hip Hop
-	    </style>
-	    <style>French Hip Hop
-	    </style>
-	  </styles>
-	  <tracks>
-	    <track>
-	      <isrc>FR10S1493172
-	      </isrc>
-	      <position>1
-	      </position>
-	      <title>Undercover
-	      </title>
-	      <length>PT0H3M22S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493172_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493173
-	      </isrc>
-	      <position>2
-	      </position>
-	      <title>Le zoo
-	      </title>
-	      <length>PT0H3M10S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493173_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493174
-	      </isrc>
-	      <position>3
-	      </position>
-	      <title>Continue
-	      </title>
-	      <length>PT0H4M17S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493174_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493175
-	      </isrc>
-	      <position>4
-	      </position>
-	      <title>A la kiss
-	      </title>
-	      <length>PT0H3M6S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493175_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493176
-	      </isrc>
-	      <position>5
-	      </position>
-	      <title>Banga
-	      </title>
-	      <length>PT0H1M41S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493176_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493177
-	      </isrc>
-	      <position>6
-	      </position>
-	      <title>Ego
-	      </title>
-	      <length>PT0H3M37S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493177_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493178
-	      </isrc>
-	      <position>7
-	      </position>
-	      <title>O.Dog Psycho
-	      </title>
-	      <length>PT0H3M17S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493178_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493179
-	      </isrc>
-	      <position>8
-	      </position>
-	      <title>Affranchis
-	      </title>
-	      <length>PT0H3M12S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493179_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493180
-	      </isrc>
-	      <position>9
-	      </position>
-	      <title>Biz Biz
-	      </title>
-	      <length>PT0H1M22S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493180_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493181
-	      </isrc>
-	      <position>10
-	      </position>
-	      <title>Ghetto Youth
-	      </title>
-	      <length>PT0H3M42S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493181_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493182
-	      </isrc>
-	      <position>11
-	      </position>
-	      <title>Défoncer
-	      </title>
-	      <length>PT0H3M5S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493182_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493183
-	      </isrc>
-	      <position>12
-	      </position>
-	      <title>Illimité
-	      </title>
-	      <length>PT0H4M22S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493183_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493184
-	      </isrc>
-	      <position>13
-	      </position>
-	      <title>No Drama
-	      </title>
-	      <length>PT0H3M35S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493184_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493185
-	      </isrc>
-	      <position>14
-	      </position>
-	      <title>La folie
-	      </title>
-	      <length>PT0H3M48S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493185_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>FR10S1493186
-	      </isrc>
-	      <position>15
-	      </position>
-	      <title>Victoria
-	      </title>
-	      <length>PT0H4M46S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493186_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Karlito
-		</artist>
-	      </artists>
-	    </track>
-	  </tracks>
-	</oai1dtouch_dc>
+      <oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
+        <id>126
+        </id>
+        <icpn>3610159198724
+        </icpn>
+        <title>Impact
+        </title>
+        <date>2015-01-12T00:00:00Z
+        </date>
+        <label>Karlito
+        </label>
+        <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159198724.jpg
+        </cover_url>
+        <url>http://music.1dtouch.com/albums/126
+        </url>
+        <artists>
+          <artist>Karlito
+          </artist>
+        </artists>
+        <styles>
+          <style>Hip Hop
+          </style>
+          <style>French Hip Hop
+          </style>
+        </styles>
+        <tracks>
+          <track>
+            <isrc>FR10S1493172
+            </isrc>
+            <position>1
+            </position>
+            <title>Undercover
+            </title>
+            <length>PT0H3M22S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493172_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493173
+            </isrc>
+            <position>2
+            </position>
+            <title>Le zoo
+            </title>
+            <length>PT0H3M10S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493173_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493174
+            </isrc>
+            <position>3
+            </position>
+            <title>Continue
+            </title>
+            <length>PT0H4M17S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493174_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493175
+            </isrc>
+            <position>4
+            </position>
+            <title>A la kiss
+            </title>
+            <length>PT0H3M6S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493175_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493176
+            </isrc>
+            <position>5
+            </position>
+            <title>Banga
+            </title>
+            <length>PT0H1M41S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493176_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493177
+            </isrc>
+            <position>6
+            </position>
+            <title>Ego
+            </title>
+            <length>PT0H3M37S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493177_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493178
+            </isrc>
+            <position>7
+            </position>
+            <title>O.Dog Psycho
+            </title>
+            <length>PT0H3M17S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493178_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493179
+            </isrc>
+            <position>8
+            </position>
+            <title>Affranchis
+            </title>
+            <length>PT0H3M12S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493179_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493180
+            </isrc>
+            <position>9
+            </position>
+            <title>Biz Biz
+            </title>
+            <length>PT0H1M22S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493180_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493181
+            </isrc>
+            <position>10
+            </position>
+            <title>Ghetto Youth
+            </title>
+            <length>PT0H3M42S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493181_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493182
+            </isrc>
+            <position>11
+            </position>
+            <title>Défoncer
+            </title>
+            <length>PT0H3M5S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493182_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493183
+            </isrc>
+            <position>12
+            </position>
+            <title>Illimité
+            </title>
+            <length>PT0H4M22S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493183_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493184
+            </isrc>
+            <position>13
+            </position>
+            <title>No Drama
+            </title>
+            <length>PT0H3M35S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493184_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493185
+            </isrc>
+            <position>14
+            </position>
+            <title>La folie
+            </title>
+            <length>PT0H3M48S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493185_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>FR10S1493186
+            </isrc>
+            <position>15
+            </position>
+            <title>Victoria
+            </title>
+            <length>PT0H4M46S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/fr10s1493186_320k.mp3
+            </url>
+            <artists>
+            <artist>Karlito
+            </artist>
+            </artists>
+          </track>
+        </tracks>
+      </oai1dtouch_dc>
       </metadata>
     </record>
-   
-
-<resumptionToken>oai1dtouch_dc.f(2015-02-09T08:46:09Z).u(2015-02-09T08:47:27Z):133</resumptionToken></ListRecords></OAI-PMH>
+    <resumptionToken>oai1dtouch_dc.f(2015-02-09T08:46:09Z).u(2015-02-09T08:47:27Z):133</resumptionToken></ListRecords></OAI-PMH>
diff --git a/library/digital_resources/DiMusic/tests/oai_page2.xml b/library/digital_resources/DiMusic/tests/oai_page2.xml
index bfa106a4d517a166463d0273dcf2a9036177630d..ffd514a10980087d4dd4bedb193b34fad3c0527a 100644
--- a/library/digital_resources/DiMusic/tests/oai_page2.xml
+++ b/library/digital_resources/DiMusic/tests/oai_page2.xml
@@ -7,107 +7,107 @@
   <ListRecords>
     <record>
       <header>
-	<identifier>oai:oai1dtouch.com:128
-	</identifier>
-	<datestamp>2015-02-09T08:47:27Z
-	</datestamp>
+      <identifier>oai:oai1dtouch.com:128
+      </identifier>
+      <datestamp>2015-02-09T08:47:27Z
+      </datestamp>
       </header>
       <metadata>
-	<oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
-	  <id>128
-	  </id>
-	  <icpn>3610159181474
-	  </icpn>
-	  <title>WOLFEP026
-	  </title>
-	  <date>2014-11-03T00:00:00Z
-	  </date>
-	  <label>Wolf Music Recordings
-	  </label>
-	  <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159181474.jpg
-	  </cover_url>
-	  <url>http://music.1dtouch.com/albums/124
-	  </url>
-	  <artists>
-	    <artist>Ishmael
-	    </artist>
-	  </artists>
-	  <styles>
-	    <style>Dance
-	    </style>
-	    <style>House
-	    </style>
-	    <style>Deep
-	    </style>
-	  </styles>
-	  <tracks>
-	    <track>
-	      <isrc>GB2SA1200088
-	      </isrc>
-	      <position>1
-	      </position>
-	      <title>Dejong
-	      </title>
-	      <length>PT0H7M20S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200088_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GB2SA1200089
-	      </isrc>
-	      <position>2
-	      </position>
-	      <title>Takoma
-	      </title>
-	      <length>PT0H5M30S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200089_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GB2SA1200090
-	      </isrc>
-	      <position>3
-	      </position>
-	      <title>Ashbury Roll
-	      </title>
-	      <length>PT0H5M26S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200090_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	    <track>
-	      <isrc>GB2SA1200091
-	      </isrc>
-	      <position>4
-	      </position>
-	      <title>Takoma
-	      </title>
-	      <length>PT0H7M13S
-	      </length>
-	      <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200091_320k.mp3
-	      </url>
-	      <artists>
-		<artist>Ishmael
-		</artist>
-	      </artists>
-	    </track>
-	  </tracks>
-	</oai1dtouch_dc>
+      <oai1dtouch_dc xmlns="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc/ http://dev.1dtouch.com/OAI/2.0/oai1dtouch_dc.xsd">
+        <id>128
+        </id>
+        <icpn>3610159181474
+        </icpn>
+        <title>WOLFEP026
+        </title>
+        <date>2014-11-03T00:00:00Z
+        </date>
+        <label>Wolf Music Recordings
+        </label>
+        <cover_url>https://commondatastorage.googleapis.com/music-staging/cargo/medium_3610159181474.jpg
+        </cover_url>
+        <url>http://music.1dtouch.com/albums/124
+        </url>
+        <artists>
+          <artist>Ishmael
+          </artist>
+        </artists>
+        <styles>
+          <style>Dance
+          </style>
+          <style>House
+          </style>
+          <style>Deep
+          </style>
+        </styles>
+        <tracks>
+          <track>
+            <isrc>GB2SA1200088
+            </isrc>
+            <position>1
+            </position>
+            <title>Dejong
+            </title>
+            <length>PT0H7M20S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200088_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GB2SA1200089
+            </isrc>
+            <position>2
+            </position>
+            <title>Takoma
+            </title>
+            <length>PT0H5M30S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200089_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GB2SA1200090
+            </isrc>
+            <position>3
+            </position>
+            <title>Ashbury Roll
+            </title>
+            <length>PT0H5M26S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200090_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+          <track>
+            <isrc>GB2SA1200091
+            </isrc>
+            <position>4
+            </position>
+            <title>Takoma
+            </title>
+            <length>PT0H7M13S
+            </length>
+            <url>https://commondatastorage.googleapis.com/music-staging/cargo/gb2sa1200091_320k.mp3
+            </url>
+            <artists>
+            <artist>Ishmael
+            </artist>
+            </artists>
+          </track>
+        </tracks>
+      </oai1dtouch_dc>
       </metadata>
     </record>
-<resumptionToken></resumptionToken>   
+    <resumptionToken></resumptionToken>   
 </ListRecords></OAI-PMH>
diff --git a/scripts/dimusic_first_harvest.php b/scripts/dimusic_first_harvest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d613ec5506b259236f7c08644da8463f7dbe8e17
--- /dev/null
+++ b/scripts/dimusic_first_harvest.php
@@ -0,0 +1,25 @@
+<?php
+require('console.php');
+
+class Write_Log_In_Temp {
+  protected $_path = './temp/dimusic_harvest_log.txt';
+
+  public function __construct() {
+    file_put_contents($this->_path,
+                      '');
+  }
+
+
+  public function log($message) {
+    file_put_contents($this->_path,
+                      $message . "\n",
+                      FILE_APPEND);
+  }
+}
+
+Class_DigitalResource::getInstance()->getHarvesters();
+
+(new Dimusic_Harvester)
+  ->setLogger(new Write_Log_In_Temp)
+  ->run();
+?>
\ No newline at end of file
diff --git a/scripts/dimusic_first_import.php b/scripts/dimusic_first_import.php
new file mode 100644
index 0000000000000000000000000000000000000000..1bbcf67d5615290196a3e93d29ed22b36914acb9
--- /dev/null
+++ b/scripts/dimusic_first_import.php
@@ -0,0 +1,25 @@
+<?php
+require('console.php');
+
+class Write_Log_In_Temp {
+  protected $_path = './temp/dimusic_import_log.txt';
+
+  public function __construct() {
+    file_put_contents($this->_path,
+                      '');
+  }
+
+
+  public function log($message) {
+    file_put_contents($this->_path,
+                      $message . "\n",
+                      FILE_APPEND);
+  }
+}
+
+Class_DigitalResource::getInstance()->getImporters();
+
+(new Dimusic_Importer)
+  ->setLogger(new Write_Log_In_Temp)
+  ->run();
+?>
\ No newline at end of file
diff --git a/tests/TearDown.php b/tests/TearDown.php
new file mode 100644
index 0000000000000000000000000000000000000000..19532ce8e10cc964df0ae24c58638ac109e2511b
--- /dev/null
+++ b/tests/TearDown.php
@@ -0,0 +1,110 @@
+<?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 TearDown {
+
+  public function __construct($volatile_status, $sql = null, $cfg = null) {
+    $this->_reset($volatile_status,
+                  $sql,
+                  $cfg);
+  }
+
+
+  protected function _reset($volatile_status, $sql, $cfg) {
+    if ($volatile_status) {
+      Storm_Model_Loader::defaultToDb();
+      Class_Versions::defaultToFile();
+    }
+
+    if ($sql)
+      Zend_Registry::set('sql', $sql);
+
+    if ($cfg)
+      Zend_Registry::set('cfg', $cfg);
+
+    Bokeh_Engine::reset();
+
+    Class_Album::setFileSystem(null);
+
+    Class_Codification::reset();
+    Class_Codification::resetInstance();
+    Class_CommSigb::setInstance(null);
+    Class_Cosmogramme_LandingDirectory::reset();
+    Class_Cosmogramme_Generator_KindsTask::setDbAdapter(null);
+    Class_Crypt::setPhpCommand(null);
+
+    Class_DigitalResource::resetInstance();
+
+    Class_I18n::reset();
+
+    Class_FederationReview::resetInstance();
+    Class_FileManager::reset();
+
+    Class_Log::resetInstance();
+
+    Class_MoteurRecherche::resetInstance();
+    Class_MoteurRecherche::setTimeSource(null);
+    Class_MoteurRecherche_FacetsByCount::reset();
+    Class_MoteurRecherche_Facettes::reset();
+
+    Class_Notice_Thumbnail_ResizeImage::reset();
+    Class_Notice_Xsl::reset();
+    Class_Notice::setTimeSource(null);
+    Class_Notice_Facette::reset();
+
+    Class_Profil::getCurrentProfil()->clearInstanceCache();
+    Class_Profil::clearCache();
+
+    Class_ScriptLoader::resetInstance();
+
+    Class_Systeme_Report_Portal::setIp(null);
+    Class_Systeme_ModulesMenu::reset();
+    Class_Systeme_Widget_Abstract::reset();
+    Class_Systeme_ModulesAccueil::reset();
+
+    Class_Template::reset();
+
+    Class_User_Settings::clearCache();
+
+    Class_Url::setBaseUrl(null);
+    Class_Url::setPhpMode(null);
+
+    Class_WebService_Abstract::resetHttpClient();
+    Class_WebService_Afi::setHttpClient(null);
+    Class_WebService_Afi::setKey(null);
+    Class_WebService_AllServices::setHttpClient(null);
+    Class_WebService_BibNumerique_Vignette::resetInstance();
+    Class_WebService_BibNumerique_Vignette::resetHttpClient();
+    Class_WebService_SIGB_Nanook::reset();
+    Class_WebService_SIGB_Nanook_PatronPasswordNotSecure::resetInstance();
+    Class_WebService_SIGB_AbstractService::setLogger(null);
+    Class_WebService_SIGB_AbstractRESTService::shouldThrowError(false);
+
+    Intonation_Library_Record::reset();
+
+    Storm_Model_Abstract::unsetLoaders();
+
+    ZendAfi_Form_Element_Captcha::reset();
+    ZendAfi_Acl_AdminControllerGroup::setAcl(null);
+    ZendAfi_Acl_AdminControllerRoles::reset();
+  }
+}
diff --git a/tests/application/modules/AbstractControllerTestCase.php b/tests/application/modules/AbstractControllerTestCase.php
index b1f1e9e17521eff60c089d52eb6a29ec8d829d47..48ae2d067ecd3906722a44bdc934fe4423be4966 100644
--- a/tests/application/modules/AbstractControllerTestCase.php
+++ b/tests/application/modules/AbstractControllerTestCase.php
@@ -164,58 +164,9 @@ abstract class AbstractControllerTestCase extends Zend_Test_PHPUnit_ControllerTe
 
 
   public function tearDown() {
-    if ($this->_storm_default_to_volatile) {
-      Storm_Model_Loader::defaultToDb();
-      Class_Versions::defaultToFile();
-    }
-
-    Storm_Model_Abstract::unsetLoaders();
-    Zend_Registry::set('sql', $this->_registry_sql);
-    Zend_Registry::set('cfg', $this->_registry_cfg);
-    Class_ScriptLoader::resetInstance();
-    Class_Codification::resetInstance();
-    Class_MoteurRecherche::resetInstance();
-    Class_MoteurRecherche::setTimeSource(null);
-    Class_WebService_Abstract::resetHttpClient();
-    Class_WebService_AllServices::setHttpClient(null);
-    Class_WebService_Afi::setHttpClient(null);
-    Class_WebService_Afi::setKey(null);
-    Class_I18n::reset();
-    ZendAfi_Form_Element_Captcha::reset();
-    Class_Url::setBaseUrl(null);
-    Class_Url::setPhpMode(null);
-    Class_Log::resetInstance();
-    Class_WebService_BibNumerique_Vignette::resetInstance();
-    Class_WebService_BibNumerique_Vignette::resetHttpClient();
-    Class_Notice_Thumbnail_ResizeImage::reset();
-    Class_FileManager::reset();
-    Class_Notice_Xsl::reset();
-    Class_Notice::setTimeSource(null);
-    Class_CommSigb::setInstance(null);
-    ZendAfi_Acl_AdminControllerGroup::setAcl(null);
-    Class_Systeme_ModulesAccueil::reset();
-    Class_Album::setFileSystem(null);
-    Class_Crypt::setPhpCommand(null);
-    Class_User_Settings::clearCache();
-    Class_Profil::getCurrentProfil()->clearInstanceCache();
-    Class_Profil::clearCache();
-    Class_DigitalResource::resetInstance();
-    Class_Systeme_ModulesMenu::reset();
-    Class_WebService_SIGB_Nanook::reset();
-    Class_WebService_SIGB_Nanook_PatronPasswordNotSecure::resetInstance();
-    Class_WebService_SIGB_AbstractService::setLogger(null);
-    Class_FederationReview::resetInstance();
-    Class_Template::reset();
-    Class_Systeme_Report_Portal::setIp(null);
-    Class_Systeme_ModulesMenu::reset();
-    Class_MoteurRecherche_FacetsByCount::reset();
-    Class_MoteurRecherche_Facettes::reset();
-    Class_Notice_Facette::reset();
-    Class_Systeme_Widget_Abstract::reset();
-    Class_Codification::reset();
-    ZendAfi_Acl_AdminControllerRoles::reset();
-    Intonation_Library_Record::reset();
-    Class_WebService_SIGB_AbstractRESTService::shouldThrowError(false);
+    new TearDown($this->_storm_default_to_volatile,
+                 $this->_registry_sql,
+                 $this->_registry_cfg);
   }
 
 
diff --git a/tests/library/Class/ModelTestCase.php b/tests/library/Class/ModelTestCase.php
index 25bb6a495bbfe5e157b6fa95ac539ca2033237d1..703002c6ce3ef4b2441840040eaa27357170b9b9 100644
--- a/tests/library/Class/ModelTestCase.php
+++ b/tests/library/Class/ModelTestCase.php
@@ -99,28 +99,9 @@ abstract class ModelTestCase extends Storm_Test_ModelTestCase {
 
 
   protected function tearDown() {
-    Bokeh_Engine::reset();
-    Class_Url::setPhpMode(null);
-    Class_Notice_Thumbnail_ResizeImage::reset();
-    Class_Album::setFileSystem(null);
-    Class_FileManager::reset();
-    Class_MoteurRecherche::resetInstance();
-    Class_Crypt::setPhpCommand(null);
-    Class_Cosmogramme_LandingDirectory::reset();
-    Class_Cosmogramme_Generator_KindsTask::setDbAdapter(null);
-
-    if($this->_storm_default_to_volatile) {
-      Storm_Model_Loader::defaultToDb();
-      Class_Versions::defaultToFile();
-    }
-
-    Storm_Model_Abstract::unsetLoaders();
-    Class_Systeme_ModulesAccueil::reset();
-    if ($this->_registry_sql)
-      Zend_Registry::set('sql', $this->_registry_sql);
-
-    Class_Systeme_Report_Portal::setIp(null);
-    parent::tearDown();
+    new TearDown($this->_storm_default_to_volatile,
+                 $this->_registry_sql);
+    return parent::tearDown();
   }
 
 
diff --git a/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php b/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php
index bf1b5fa72ff9fce28d8931d0a047b256518ffa66..251e3321af706384c35899b282bb13a515da0b12 100644
--- a/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php
+++ b/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php
@@ -63,7 +63,6 @@ class CiteDeLaMusiqueFixtures {
     $user->beAbonneSIGB()
          ->assertSave();
 
-
     $test->fixture('Class_Profil',
                    ['id' => 5,
                     'browser' => 'opac',
@@ -133,6 +132,9 @@ class CiteDeLaMusiqueDisabledAdminTest extends Admin_AbstractControllerTestCase
 
 
 class CiteDeLaMusiqueModulesControllerTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+
   public function setUp() {
     parent::setUp();
     CiteDeLaMusiqueFixtures::prepare($this);
@@ -172,6 +174,10 @@ class CiteDeLaMusiqueModulesControllerTest extends AbstractControllerTestCase {
 
 
 class CiteDeLaMusiqueRenderAlbumTest extends ViewHelperTestCase {
+
+  protected $_storm_default_to_volatile = true;
+
+
   public function setUp() {
     parent::setUp();
     CiteDeLaMusiqueFixtures::prepare($this);
@@ -470,7 +476,14 @@ class CiteDeLaMusiqueOAIHarvestTest extends ModelTestCase {
       ->answers(CiteDeLaMusiqueFixtures::getFixtureContent('cite_de_la_musique_oai.xml'))
 
       ->whenCalled('open_url')
-      ->answers('');
+      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&resumptionToken=%21%21videos-concerts-docu-entiers%21100%211061%21Ermes')
+      ->answers('')
+
+      ->whenCalled('open_url')
+      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=ermes&set=audios-concerts-entiers&from=2017-10-11')
+      ->answers('')
+
+      ->beStrict();
 
     Class_WebService_BibNumerique_CiteDeLaMusique::setDefaultHttpClient($http_client);