From 229c8ad84d6cce2416c963a4a5ec6f57c6f1e017 Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Tue, 19 Feb 2019 15:15:56 +0100
Subject: [PATCH] dev #64573 record media

---
 .../opac/controllers/NoticeajaxController.php |  22 +++
 library/Class/WebService/Lastfm.php           |  10 +-
 library/Class/Xml.php                         |   7 +-
 .../Intonation/Assets/css/intonation.css      |  19 +++
 .../templates/Intonation/Library/LastFm.php   | 158 ++++++++++++++++++
 .../templates/Intonation/Library/Picture.php  |  23 +++
 .../templates/Intonation/Library/Pictures.php |  70 ++++++++
 .../templates/Intonation/Library/Track.php    |   3 +-
 .../templates/Intonation/Library/Tracks.php   |  42 +++--
 .../templates/Intonation/View/RenderEmbed.php |   1 +
 .../Intonation/View/RenderPictures.php        |  40 +++++
 .../Intonation/View/RenderRecord.php          |  17 +-
 .../Intonation/View/RenderTracks.php          |  64 +++----
 tests/scenarios/Templates/TemplatesTest.php   |  58 +++++--
 14 files changed, 462 insertions(+), 72 deletions(-)
 create mode 100644 library/templates/Intonation/Library/LastFm.php
 create mode 100644 library/templates/Intonation/Library/Picture.php
 create mode 100644 library/templates/Intonation/Library/Pictures.php
 create mode 100644 library/templates/Intonation/View/RenderPictures.php

diff --git a/application/modules/opac/controllers/NoticeajaxController.php b/application/modules/opac/controllers/NoticeajaxController.php
index 414146e6497..7635e9d7ed9 100644
--- a/application/modules/opac/controllers/NoticeajaxController.php
+++ b/application/modules/opac/controllers/NoticeajaxController.php
@@ -505,4 +505,26 @@ class NoticeAjaxController extends ZendAfi_Controller_Action {
 
     $this->_sendResponseWithScripts($this->view->renderEmbed($data['source'], $url));
   }
+
+
+  public function picturesAction() {
+    session_write_close();
+
+    $pictures = (new Intonation_Library_Pictures)
+      ->setModel($this->notice)
+      ->collection();
+
+    $this->_sendResponseWithScripts($this->view->renderPictures($pictures));
+  }
+
+
+  public function tracksAction() {
+    session_write_close();
+
+    $tracks = (new Intonation_Library_Tracks)
+      ->setModel($this->notice)
+      ->collection();
+
+    $this->_sendResponseWithScripts($this->view->renderTracks($tracks));
+  }
 }
\ No newline at end of file
diff --git a/library/Class/WebService/Lastfm.php b/library/Class/WebService/Lastfm.php
index 930427fecb4..625edbd06bb 100644
--- a/library/Class/WebService/Lastfm.php
+++ b/library/Class/WebService/Lastfm.php
@@ -186,6 +186,9 @@ class Class_WebService_Lastfm  extends Class_WebService_Abstract {
 
 
   public function getPhotos($auteur) {
+    if (!$auteur)
+      return [];
+
     if (!$artist_url = $this->_getArtistBaseUrl($auteur))
       return [];
 
@@ -263,9 +266,10 @@ class Class_WebService_Lastfm  extends Class_WebService_Abstract {
     if (!$item = $this->xml->getNode("OPENSEARCH:TOTALRESULTS"))
        return false;
 
+    if (-1 == $item)
+      return false;
+
     $value = $this->xml->get_value($item);
     return $value > 0;
   }
-}
-
-?>
+}
\ No newline at end of file
diff --git a/library/Class/Xml.php b/library/Class/Xml.php
index 75f50922049..c608b68107a 100644
--- a/library/Class/Xml.php
+++ b/library/Class/Xml.php
@@ -85,8 +85,11 @@ class Class_Xml {
 
 
   public function getNode($tag) {
-    $tag=strToUpper($tag);
-    if(isset($this->index[$tag])) return $this->index[$tag][0];
+    $tag = strToUpper($tag);
+
+    if(isset($this->index[$tag]))
+      return $this->index[$tag][0];
+
     return -1;
   }
 
diff --git a/library/templates/Intonation/Assets/css/intonation.css b/library/templates/Intonation/Assets/css/intonation.css
index 68414f04b81..8fff34044b7 100644
--- a/library/templates/Intonation/Assets/css/intonation.css
+++ b/library/templates/Intonation/Assets/css/intonation.css
@@ -15,6 +15,7 @@
     --front-widget-background: #FFF;
     --front-navbar-background: #CCC;
     --front-background-overlay: rgba(0, 0 , 0 ,0.7);
+    --front-background-modale: rgba(0, 0 , 0 ,0.95);
 }
 
 body {
@@ -396,4 +397,22 @@ label[for=note] ~ div label.multi-element-label + br {
 
 .jumbotron .nav-link {
     font-size: 1.5em;
+}
+
+.modal_image {
+    position: fixed;
+    width: 100%;
+    height: 100%;
+    padding: 5%;
+    top: 0;
+    left: 0;
+    background-color: var(--front-background-modale);
+    z-index: 20;
+    text-align: center;
+    flex: 100%;
+    max-width: 100%;
+}
+
+.blockquote-footer {
+    color: inherit;
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/LastFm.php b/library/templates/Intonation/Library/LastFm.php
new file mode 100644
index 00000000000..3fe1b9fa07a
--- /dev/null
+++ b/library/templates/Intonation/Library/LastFm.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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 Intonation_Library_LastFm extends Class_Entity {
+
+  use Trait_Translator;
+
+
+  const
+    IMGS_XPATH = '//ul[@class="image-list"]/li/a/img',
+    TRACKS_XPATH = '//section[@id="tracks-section"]//table//td/a[contains(@class, "chartlist-play-button")]',
+    LAST_FM_IMGS = '/+images/',
+    LAST_FM = 'https://www.last.fm/music/';
+
+
+  public function __construct($attributes = []) {
+    parent::__construct($attributes);
+    $this->setWebClient(Class_WebService_SimpleWebClient::getInstance());
+  }
+
+
+  public function getAlbumPictures() {
+    return $this->_getPictures($this->getModel()->getAuteurPrincipal());
+  }
+
+
+  public function getAlbumTracks() {
+    return $this->_getTracks($this->getModel()->getAuteurPrincipal(), $this->getModel()->getTitrePrincipal());
+  }
+
+
+  protected function _getTracks($author, $album) {
+    if (!$author)
+      return [];
+
+    if (!$album)
+      return [];
+
+    return
+      $this->_withUrlDo(static::LAST_FM . urlencode($author) . '/' . urlencode($album),
+                        function($body)
+                        {
+                          return $this->_extractTracksFrom($body);
+                        });
+  }
+
+
+  protected function _withUrlDo($url, $callback) {
+    if (!$response = $this->getWebClient()->getResponse($url))
+      return [];
+
+    if (!$response->isSuccessful())
+      return [];
+
+    return ($body = $response->getBody())
+      ? $callback($body)
+      : [];
+  }
+
+
+  protected function _getPictures($author) {
+    if (!$author)
+      return [];
+
+    return
+      $this->_withUrlDo(static::LAST_FM . urlencode($author) . static::LAST_FM_IMGS,
+                        function($body)
+                        {
+                          return $this->_extractPicturesFrom($body);
+                        });
+  }
+
+
+  protected function _extractPicturesFrom($html) {
+    return $this->_withHtmlXpathDo($html,
+                                   static::IMGS_XPATH,
+                                   function($element, $elements)
+                                   {
+                                     if (!$url = str_replace('avatar170s',
+                                                             '1024x0',
+                                                             $element->getAttribute('src')))
+                                       return $elements;
+
+                                     $title = $this->_('Illustration du document %s de %s',
+                                                       $this->getModel()->getTitrePrincipal(),
+                                                       $this->getModel()->getAuteurPrincipal(' '));
+
+                                     $elements [] =
+                                       new Intonation_Library_Picture(['Src' => $url,
+                                                                       'Source' => 'Last.fm',
+                                                                       'Title' => $title]);
+
+                                     return $elements;
+                                   });
+  }
+
+
+  protected function _extractTracksFrom($html) {
+    return $this->_withHtmlXpathDo($html,
+                                   static::TRACKS_XPATH,
+                                   function ($element, $elements)
+                                   {
+                                     if (!$url = str_replace('watch?v=', 'embed/', $element->getAttribute('href')))
+                                       return $elements;
+
+                                     if (!$title = $element->getAttribute('data-track-name'))
+                                       return $elements;
+
+                                     $elements [] = new Intonation_Library_Track(['Url' => $url,
+                                                                                  'Source' => 'Youtube - Last.fm',
+                                                                                  'Title' => $title]);
+                                     return $elements;
+                                   });
+  }
+
+
+  protected function _withHtmlXpathDo($html, $xpath, $callback) {
+    $dom = new DOMDocument();
+
+    try {
+      $dom->loadHTML($html);
+    } catch (Exception $e) {
+      return [];
+    }
+
+    if (!$dom_xpath = new DOMXpath($dom))
+      return [];
+
+    if (!$elements = $dom_xpath->query($xpath))
+      return [];
+
+    $collected = [];
+
+    foreach($elements as $element)
+      $collected = $callback($element, $collected);
+
+    return $collected;
+  }
+}
diff --git a/library/templates/Intonation/Library/Picture.php b/library/templates/Intonation/Library/Picture.php
new file mode 100644
index 00000000000..16c734a838e
--- /dev/null
+++ b/library/templates/Intonation/Library/Picture.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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 Intonation_Library_Picture extends Class_Entity {}
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/Pictures.php b/library/templates/Intonation/Library/Pictures.php
new file mode 100644
index 00000000000..60678eeea27
--- /dev/null
+++ b/library/templates/Intonation/Library/Pictures.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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 Intonation_Library_Pictures {
+
+  use Trait_Translator;
+
+  protected $_model;
+
+
+  public function setModel($model) {
+    $this->_model = $model;
+    return $this;
+  }
+
+
+  public function collection() {
+    return new Storm_Collection($this->pictures());
+  }
+
+
+  public function pictures() {
+    $model_title = $this->_model->getTitrePrincipal(' ');
+
+    $pictures = [new Intonation_Library_Picture(['Src' => $this->_model->fetchUrlLocalVignette(),
+                                                 'Source' => 'AFI',
+                                                 'Title' => $this->_('Vignette du document %s',
+                                                                   $model_title)]),
+                 new Intonation_Library_Picture(['Src' => $this->_model->fetchUrlImage(),
+                                                 'Source' => 'AFI',
+                                                 'Title' => $this->_('Image du document %s',
+                                                                   $model_title)])];
+
+    if (!$this->_canGetPicturesFronLastFm())
+      return $pictures;
+
+    if (!$more_pictures = (new Intonation_Library_LastFm)
+        ->setModel($this->_model)
+        ->getAlbumPictures())
+      return $pictures;
+
+    return array_merge($pictures, $more_pictures);
+  }
+
+
+  protected function _canGetPicturesFronLastFm() {
+    return $this->_model->isDisc()
+      || $this->_model->isDVD()
+      || $this->_model->isAudioRecord();
+  }
+}
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/Track.php b/library/templates/Intonation/Library/Track.php
index 19e5f383297..75d591b61cf 100644
--- a/library/templates/Intonation/Library/Track.php
+++ b/library/templates/Intonation/Library/Track.php
@@ -20,5 +20,4 @@
  */
 
 
-class Intonation_Library_Track extends Class_Entity {
-}
+class Intonation_Library_Track extends Class_Entity {}
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/Tracks.php b/library/templates/Intonation/Library/Tracks.php
index ae5835b115d..aaa50f31301 100644
--- a/library/templates/Intonation/Library/Tracks.php
+++ b/library/templates/Intonation/Library/Tracks.php
@@ -40,14 +40,20 @@ class Intonation_Library_Tracks {
     if (!$this->_model->isTypeDocSonore())
       return [];
 
-    if ($this->_model->isGam())
-      return (new Intonation_Library_TracksGam)
+    $tracks = ($this->_model->isGam())
+      ? ((new Intonation_Library_TracksGam)
+         ->setModel($this->_model)
+         ->getTracks())
+      : ((new Intonation_Library_TracksBase)
+         ->setModel($this->_model)
+         ->getTracks());
+
+    if (!$more_tracks = (new Intonation_Library_LastFm)
         ->setModel($this->_model)
-        ->getTracks();
+        ->getAlbumTracks())
+      return $tracks;
 
-    return (new Intonation_Library_TracksBase)
-      ->setModel($this->_model)
-      ->getTracks();
+    return array_merge($tracks, $more_tracks);
   }
 }
 
@@ -84,12 +90,20 @@ class Intonation_Library_TracksBase extends Intonation_Library_TracksAbstract {
 
   protected function _trackFromUnimarc($unimarc, $tracks) {
     $field = $this->_model->get_field($unimarc);
-    $tracks [] = new Intonation_Library_Track(['Title' => $field->gett(),
+
+    if (!$title = $field->gett())
+      return $tracks;
+
+    if (!$url = $field->get3())
+      return $tracks;
+
+    $tracks [] = new Intonation_Library_Track(['Title' => $title,
                                                'Duration' => $field->getd(),
+                                               'Source' => 'CVS',
                                                'Author' => implode(' ', [$field->geta(),
                                                                          $field->getb()]),
                                                'Volume' => $field->getv(),
-                                               'Url' => $field->get3()]);
+                                               'Url' => $url]);
     return $tracks;
   }
 }
@@ -110,8 +124,16 @@ class Intonation_Library_TracksGam extends Intonation_Library_TracksAbstract {
 
   protected function _trackFromUnimarc($unimarc, $tracks) {
     $field = $this->_model->get_field($unimarc);
-    $tracks [] = new Intonation_Library_Track(['Title' => $field->getz(),
-                                               'Url' => $field->getu()]);
+
+    if (!$title = $field->getz())
+      return $tracks;
+
+    if (!$url = $field->getu())
+      return $tracks;
+
+    $tracks [] = new Intonation_Library_Track(['Title' => $title,
+                                               'Source' => 'GAM',
+                                               'Url' => $url]);
     return $tracks;
   }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/View/RenderEmbed.php b/library/templates/Intonation/View/RenderEmbed.php
index 10153419399..0bd45182372 100644
--- a/library/templates/Intonation/View/RenderEmbed.php
+++ b/library/templates/Intonation/View/RenderEmbed.php
@@ -27,6 +27,7 @@ class Intonation_View_RenderEmbed extends ZendAfi_View_Helper_BaseHelper {
                   $this->_tag('iframe',
                               '',
                               ['src' => $url,
+                               'crossorigin' => 1,
                                'allowfullscreen' => 1,
                                'class' => 'embed-responsive-item']))
       . $this->_tag('p',
diff --git a/library/templates/Intonation/View/RenderPictures.php b/library/templates/Intonation/View/RenderPictures.php
new file mode 100644
index 00000000000..3c88b987451
--- /dev/null
+++ b/library/templates/Intonation/View/RenderPictures.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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 Intonation_View_RenderPictures extends ZendAfi_View_Helper_BaseHelper {
+  public function renderPictures($collection) {
+    return $this->view->renderMultipleCarousel($collection, function($picture)
+                                   {
+                                     return $this->_div(['onclick' => '$(this).toggleClass(\'modal_image\');',
+                                                         'class' => 'card'],
+                                                        $this->_div(['class' => 'card-img'],
+                                                                    $this->view->tagImg($picture->getSrc(),
+                                                                                        ['class' => 'img-fluid',
+                                                                                         'title' => $picture->getTitle(),
+                                                                                         'alt' => $picture->getAlt()]))
+                                                        . $this->_div(['class' => 'card-body p-1'],
+                                                                      $this->_tag('p',
+                                                                      $picture->getSource(),
+                                                                                  ['class' => 'm-0 blockquote-footer text-right'])));
+                                   });
+  }
+}
diff --git a/library/templates/Intonation/View/RenderRecord.php b/library/templates/Intonation/View/RenderRecord.php
index 242798ad037..dfa9382e503 100644
--- a/library/templates/Intonation/View/RenderRecord.php
+++ b/library/templates/Intonation/View/RenderRecord.php
@@ -87,19 +87,14 @@ class Intonation_View_RenderRecord extends ZendAfi_View_Helper_BaseHelper {
               ? $this->view->renderAlbum($album)
               : '');
 
-    $trailer = $this->_renderAjaxBloc('trailer');
-    $tracks = (new Intonation_Library_Tracks)
-      ->setModel($this->_record)
-      ->collection();
-
-    $html = $album
-      . $trailer
-      . $this->view->renderTracks($tracks)
-      . $this->_renderAjaxBloc('photos');
+    $html = [$album,
+             $this->_renderAjaxBloc('tracks'),
+             $this->_renderAjaxBloc('pictures'),
+             $this->_renderAjaxBloc('trailer')];
 
     return
       $this->_renderBloc($this->_('Médias'),
-                         $this->_grid($html));
+                         $this->_grid(implode($html)));
   }
 
 
@@ -254,7 +249,7 @@ class Intonation_View_RenderRecord extends ZendAfi_View_Helper_BaseHelper {
                                                                                 'action' => $action,
                                                                                 'id' => $this->_record->getId()])));
     return $this->_div(['id' => $id,
-                        'class' => 'col-12'], '');
+                        'class' => 'col-12 mb-3'], '');
   }
 
 
diff --git a/library/templates/Intonation/View/RenderTracks.php b/library/templates/Intonation/View/RenderTracks.php
index ff8dbaceadf..d27cf648069 100644
--- a/library/templates/Intonation/View/RenderTracks.php
+++ b/library/templates/Intonation/View/RenderTracks.php
@@ -25,33 +25,41 @@ class Intonation_View_RenderTracks extends ZendAfi_View_Helper_BaseHelper {
     if ($tracks->isEmpty())
       return '';
 
-    $html = [];
-
-    /* foreach ($tracks as $track) */
-    /*   if ( ($title = $track->getTitle()) && ($url = $track->getUrl())) */
-    /*     $html [] = $this->_tag('track' */
-
-    /* return $this->view->grid(implode($html)); */
-
-    foreach ($tracks as $track)
-      if ( ($title = $track->getTitle()) && ($url = $track->getUrl()))
-        $html [] = $this->_div(['class' => 'col-lg-5 mb-3'],
-                               $this->_div(['class' => 'card bg-info text-white shadow'],
-                               $this->_div(['class' => 'card-body'],
-                                           $this->_div(['class' => 'card-title'],
-                                                       $this->_tag('h3',
-                                                                   Class_Template::current()->getIco($this->view,
-                                                                                                     'track',
-                                                                                                     'utils')
-                                                                   . $track->getTitle()))
-                                           . $this->_tag('audio',
-                                                         '',
-                                                         ['class' => 'd-block',
-                                                          'src' => $url,
-                                                          'preload' => 'auto',
-                                                          'onplaying' => "$('audio').not($(this)).trigger('pause');",
-                                                          'controls' => 'true']))));
-
-    return $this->view->grid(implode($html), [], ['class' => 'justify-content-between']);
+    return $this->view->renderCarousel($tracks, function($track)
+                                   {
+                                     return
+                                         $this->_div(['class' => 'card bg-info text-white shadow'],
+                                                     $this->_div(['class' => 'card-body'],
+                                                                 $this->_div(['class' => 'card-title'],
+                                                                             $this->_tag('h3',
+                                                                                         Class_Template::current()->getIco($this->view,
+                                                                                                                           'track',
+                                                                                                                           'utils')
+                                                                                         . $track->getTitle()))
+                                                                 . $this->_div(['class' => 'text-center'],
+                                                                               $this->_getPlayer($track))));
+
+                                     return '';
+                                   });
+  }
+
+
+  protected function _getPlayer($track) {
+    $url = $track->getUrl();
+    return false === strpos($url, 'youtube')
+
+      ? ($this->_tag('audio',
+                '',
+                ['class' => '',
+                 'src' => $url,
+                 'preload' => 'auto',
+                 'onplaying' => "$('audio, video').not($(this)).trigger('pause');",
+                 'controls' => 'true'])
+
+         . $this->_tag('p',
+                       $track->getSource(),
+                       ['class' => 'blockquote-footer text-right']))
+
+      : $this->view->renderEmbed($track->getSource(), $url);
   }
 }
diff --git a/tests/scenarios/Templates/TemplatesTest.php b/tests/scenarios/Templates/TemplatesTest.php
index 4613002ce58..fc117429c20 100644
--- a/tests/scenarios/Templates/TemplatesTest.php
+++ b/tests/scenarios/Templates/TemplatesTest.php
@@ -2092,6 +2092,7 @@ class TemplatesRecordMediaDispatchTest extends TemplatesIntonationTestCase {
                               'unimarc' => $unimarc->render(),
                               'type_doc' => 8,
                               'clef_oeuvre' => 'PSYKO',
+                              'url_vignette' => 'big_picture_300x300.jpg',
                               'facettes' => 'G13 M12']);
 
     $this->dispatch('/opac/record/media/id/456/id_profil/72');
@@ -2106,7 +2107,7 @@ class TemplatesRecordMediaDispatchTest extends TemplatesIntonationTestCase {
 
   /** @test */
   public function shouldContainsTracks() {
-    $this->assertXPath('//div//track[contains(@href, "big_picture_300x300.jpg")]');
+    $this->assertXPath('//div//audio');
   }
 
 
@@ -2155,11 +2156,27 @@ class TemplatesDispatchNoticeAjaxTrailerTest extends TemplatesIntonationTestCase
 
 
 
-class TemplatesGamRecordMediaDispatchTest extends TemplatesIntonationTestCase {
-  public function setUp() {
-    parent::setUp();
+class TemplatesDispatchNoticeAjaxPicturesTest extends TemplatesIntonationTestCase {
 
-    $this->fixture('Class_TypeDoc',
+  /** @test */
+  public function shouldDisplayTrailer() {
+    $this->fixture('Class_Notice',
+                   ['id' => 34,
+                    'titre_principal' => 'Psycho',
+                   ]);
+
+    $this->dispatch('/noticeajax/pictures/id/34/id_profil/72');
+    $this->assertXPath('//div//img');
+  }
+}
+
+
+
+class TemplatesDispatchNoticeAjaxTracksTest extends TemplatesIntonationTestCase {
+
+  /** @test */
+  public function shouldDisplayAudio() {
+        $this->fixture('Class_TypeDoc',
                    ['id' => 8,
                     'label' => 'mp3',
                     'famille_id' => Class_CodifTypeDoc::SONORE
@@ -2167,27 +2184,36 @@ class TemplatesGamRecordMediaDispatchTest extends TemplatesIntonationTestCase {
 
     $unimarc = (new Class_NoticeUnimarc_Fluent)
       ->zoneWithContent('001', '12345')
+
+      ->zoneWithChildren('200', ['f' => 'Iron Maiden'])
+
+      ->zoneWithChildren('461', ['t' => 'The book of souls'])
+
       ->zoneWithChildren('801', ['b' => 'GAM'])
-      ->zoneWithChildren('464', ['t' => 'Lotus out of water'])
+      ->zoneWithChildren('464', ['t' => 'If eternity should fail'])
       ->zoneWithChildren('856', ['u' => 'https://my-super-sound/1.mp3',
-                                 'z' => 'Lotus out of water'])
-      ->zoneWithChildren('464', ['t' => 'Milking song',
+                                 'z' => 'If eternity should fail'])
+      ->zoneWithChildren('464', ['t' => 'Speed of light',
                                  '3' => 'https://my-super-sound/2.mp3']);
 
     $record = $this->fixture('Class_Notice',
                              ['id' => 456,
-                              'titre_principal' => 'Psycho',
                               'unimarc' => $unimarc->render(),
                               'type_doc' => 8,
-                              'clef_oeuvre' => 'PSYKO',
+                              'clef_oeuvre' => 'THE BOOK OF SOULS',
                               'facettes' => 'G13 M12']);
 
-    $this->dispatch('/opac/record/media/id/456/id_profil/72');
-  }
+    $web_client = $this
+      ->mock()->beStrict()
 
+      ->whenCalled('getResponse')
+      ->with('https://www.last.fm/music/Iron+Maiden/The+book+of+souls')
+      ->answers(new Class_Testing_HttpResponse)
+      ;
 
-  /** @test */
-  public function shouldGamTracks() {
-    $this->assertXPath('//div//track');
+    Class_WebService_SimpleWebClient::setInstance($web_client);
+
+    $this->dispatch('/noticeajax/tracks/id/456/id_profil/72');
+    $this->assertXPath('//div//audio');
   }
-}
\ No newline at end of file
+}
-- 
GitLab