Merge branch 'pi-render-service-refactor' into XW-2444

This commit is contained in:
Mateusz Rybarski 2016-12-28 11:29:36 +01:00
commit 3ad591cec6
10 changed files with 924 additions and 448 deletions

View file

@ -18,6 +18,7 @@ $wgExtensionCredits[ 'parserhook' ][] = [
$wgAutoloadClasses[ 'PortableInfoboxQueryService' ] = $dir . 'services/PortableInfoboxQueryService.class.php';
$wgAutoloadClasses[ 'PortableInfoboxRenderService' ] = $dir . 'services/PortableInfoboxRenderService.class.php';
$wgAutoloadClasses[ 'MobileInfoboxRenderService' ] = $dir . 'services/MobileInfoboxRenderService.class.php';
$wgAutoloadClasses[ 'PortableInfoboxErrorRenderService' ] = $dir . 'services/PortableInfoboxErrorRenderService.class.php';
// parser
@ -45,6 +46,7 @@ foreach ( $wgInfoboxParserNodes as $parserNode ) {
// helpers
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\InfoboxParamsValidator' ] = $dir . 'services/Helpers/InfoboxParamsValidator.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag' ] = $dir . 'services/Helpers/PortableInfoboxDataBag.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxMustacheEngine' ] = $dir . 'services/Helpers/PortableInfoboxMustacheEngine.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper' ] = $dir . 'services/Helpers/PortableInfoboxRenderServiceHelper.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper' ] = $dir . 'services/Helpers/PortableInfoboxTemplatesHelper.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PagePropsProxy' ] = $dir . 'services/Helpers/PagePropsProxy.php';

View file

@ -91,7 +91,11 @@ class PortableInfoboxParserTagController extends WikiaController {
$accentColor = $this->getColor( 'accent-color', $params, $frame );
$accentColorText = $this->getColor( 'accent-color-text', $params, $frame );
return ( new PortableInfoboxRenderService() )->renderInfobox( $data, $theme, $layout, $accentColor, $accentColorText );
//TODO: pass colors to render service
$renderSerivce = \F::app()->checkSkin( 'wikiamobile' ) ?
new MobileInfoboxRenderService() : new PortableInfoboxRenderService();
return $renderSerivce->renderInfobox( $data, $theme, $layout );
}
/**
@ -133,7 +137,7 @@ class PortableInfoboxParserTagController extends WikiaController {
*/
public function moveFirstMarkerToTop( &$text ) {
if ( !empty( $this->markers ) ) {
$firstMarker = array_keys( $this->markers )[0];
$firstMarker = array_keys( $this->markers )[ 0 ];
// Skip if the first marker is already at the top
if ( strpos( $text, $firstMarker ) !== 0 ) {

View file

@ -0,0 +1,63 @@
<?php
namespace Wikia\PortableInfobox\Helpers;
use Wikia\Logger\WikiaLogger;
use Wikia\Template\MustacheEngine;
class PortableInfoboxMustacheEngine {
const TYPE_NOT_SUPPORTED_MESSAGE = 'portable-infobox-render-not-supported-type';
protected static $templates = [
'wrapper' => 'PortableInfoboxWrapper.mustache',
'title' => 'PortableInfoboxItemTitle.mustache',
'header' => 'PortableInfoboxItemHeader.mustache',
'image' => 'PortableInfoboxItemImage.mustache',
'image-mobile' => 'PortableInfoboxItemImageMobile.mustache',
'image-mobile-wikiamobile' => 'PortableInfoboxItemImageMobileWikiaMobile.mustache',
'data' => 'PortableInfoboxItemData.mustache',
'group' => 'PortableInfoboxItemGroup.mustache',
'horizontal-group-content' => 'PortableInfoboxHorizontalGroupContent.mustache',
'navigation' => 'PortableInfoboxItemNavigation.mustache',
'hero-mobile' => 'PortableInfoboxItemHeroMobile.mustache',
'hero-mobile-wikiamobile' => 'PortableInfoboxItemHeroMobileWikiaMobile.mustache',
'image-collection' => 'PortableInfoboxItemImageCollection.mustache',
'image-collection-mobile' => 'PortableInfoboxItemImageCollectionMobile.mustache',
'image-collection-mobile-wikiamobile' => 'PortableInfoboxItemImageCollectionMobileWikiaMobile.mustache'
];
protected $templateEngine;
public function __construct() {
$this->templateEngine = ( new MustacheEngine )
->setPrefix( self::getTemplatesDir() );
}
public static function getTemplatesDir() {
return dirname( __FILE__ ) . '/../../templates';
}
public static function getTemplates() {
return self::$templates;
}
public function render( $type, array $data ) {
return $this->templateEngine->clearData()
->setData( $data )
->render( self::getTemplates()[ $type ] );
}
/**
* check if item type is supported and logs unsupported types
*
* @param string $type - template type
*
* @return bool
*/
public static function isSupportedType( $type ) {
$result = isset( static::$templates[ $type ] );
if ( !$result ) {
WikiaLogger::instance()->info( self::TYPE_NOT_SUPPORTED_MESSAGE, [ 'type' => $type ] );
}
return $result;
}
}

View file

@ -148,14 +148,6 @@ class PortableInfoboxRenderServiceHelper {
return false;
}
/**
* required for testing mobile template rendering
* @return bool
*/
public function isMobile() {
return \F::app()->checkSkin( 'wikiamobile' );
}
/**
* @return bool
*/
@ -165,28 +157,6 @@ class PortableInfoboxRenderServiceHelper {
return !empty( $wgArticleAsJson );
}
/**
* check if item type is supported and logs unsupported types
*
* @param string $type - template type
* @param array $templates - array of supported templates
*
* @return bool
*/
public function isTypeSupportedInTemplates( $type, $templates ) {
$isValid = true;
if ( !isset( $templates[ $type ] ) ) {
WikiaLogger::instance()->info( self::LOGGER_LABEL, [
'type' => $type
] );
$isValid = false;
}
return $isValid;
}
/**
* Checks if europa theme is enabled and used
* @return bool

View file

@ -0,0 +1,130 @@
<?php
use Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper;
class MobileInfoboxRenderService extends PortableInfoboxRenderService {
const MEDIA_CONTEXT_INFOBOX_HERO_IMAGE = 'infobox-hero-image';
const MEDIA_CONTEXT_INFOBOX = 'infobox';
protected $imagesWidth = PortableInfoboxRenderServiceHelper::MOBILE_THUMBNAIL_WIDTH;
/**
* renders infobox
*
* @param array $infoboxdata
*
* @param $theme
* @param $layout
* @return string - infobox HTML
*/
public function renderInfobox( array $infoboxdata, $theme, $layout ) {
wfProfileIn( __METHOD__ );
$helper = new PortableInfoboxRenderServiceHelper();
$infoboxHtmlContent = '';
$heroData = [ ];
foreach ( $infoboxdata as $item ) {
$data = $item[ 'data' ];
$type = $item[ 'type' ];
if ( $helper->isValidHeroDataItem( $item, $heroData ) ) {
$heroData[ $type ] = $data;
continue;
} elseif ( $this->templateEngine->isSupportedType( $type ) ) {
$infoboxHtmlContent .= $this->renderItem( $type, $data );
}
}
if ( !empty( $heroData ) ) {
$infoboxHtmlContent = $this->renderInfoboxHero( $heroData ) . $infoboxHtmlContent;
}
if ( !empty( $infoboxHtmlContent ) ) {
$output = $this->renderItem( 'wrapper', [ 'content' => $infoboxHtmlContent ] );
} else {
$output = '';
}
\Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag::getInstance()->setFirstInfoboxAlredyRendered( true );
wfProfileOut( __METHOD__ );
return $output;
}
protected function renderImage( $data ) {
$images = [ ];
$helper = new PortableInfoboxRenderServiceHelper();
for ( $i = 0; $i < count( $data ); $i++ ) {
$data[ $i ][ 'context' ] = self::MEDIA_CONTEXT_INFOBOX;
$data[ $i ] = $helper->extendImageData( $data[ $i ], $this->imagesWidth );
if ( !!$data[ $i ] ) {
$images[] = $data[ $i ];
}
}
if ( count( $images ) === 0 ) {
return '';
}
// use different template for wikiamobile
if ( !$helper->isMercury() ) {
// always display only the first image on WikiaMobile
$data = $images[ 0 ];
$templateName = 'image-mobile-wikiamobile';
} else {
if ( count( $images ) === 1 ) {
$data = $images[ 0 ];
$templateName = 'image-mobile';
} else {
// more than one image means image collection
$data = $helper->extendImageCollectionData( $images );
$templateName = 'image-collection-mobile';
}
}
$data = SanitizerBuilder::createFromType( 'image' )->sanitize( $data );
return parent::render( $templateName, $data );
}
protected function render( $type, array $data ) {
$data = SanitizerBuilder::createFromType( $type )->sanitize( $data );
return parent::render( $type, $data );
}
/**
* renders infobox hero component
*
* @param array $data - infobox hero component data
*
* @return string
*/
private function renderInfoboxHero( $data ) {
$helper = new PortableInfoboxRenderServiceHelper();
// In Mercury SPA content of the first infobox's hero module has been moved to the article header.
$firstInfoboxAlredyRendered = \Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag::getInstance()
->isFirstInfoboxAlredyRendered();
if ( array_key_exists( 'image', $data ) ) {
$image = $data[ 'image' ][ 0 ];
$image[ 'context' ] = self::MEDIA_CONTEXT_INFOBOX_HERO_IMAGE;
$image = $helper->extendImageData( $image, PortableInfoboxRenderServiceHelper::MOBILE_THUMBNAIL_WIDTH );
$data[ 'image' ] = $image;
if ( !$helper->isMercury() ) {
return $this->renderItem( 'hero-mobile-wikiamobile', $data );
} elseif ( $firstInfoboxAlredyRendered ) {
return $this->renderItem( 'hero-mobile', $data );
}
} elseif ( !$helper->isMercury() || $firstInfoboxAlredyRendered ) {
return $this->renderItem( 'title', $data[ 'title' ] );
}
return '';
}
}

View file

@ -1,44 +1,15 @@
<?php
use Wikia\PortableInfobox\Helpers\PortableInfoboxMustacheEngine;
use Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper;
class PortableInfoboxRenderService extends WikiaService {
const MOBILE_TEMPLATE_POSTFIX = '-mobile';
const MEDIA_CONTEXT_INFOBOX_HERO_IMAGE = 'infobox-hero-image';
const MEDIA_CONTEXT_INFOBOX = 'infobox';
private static $templates = [
'wrapper' => 'PortableInfoboxWrapper.mustache',
'title' => 'PortableInfoboxItemTitle.mustache',
'header' => 'PortableInfoboxItemHeader.mustache',
'image' => 'PortableInfoboxItemImage.mustache',
'image-mobile' => 'PortableInfoboxItemImageMobile.mustache',
'image-mobile-wikiamobile' => 'PortableInfoboxItemImageMobileWikiaMobile.mustache',
'data' => 'PortableInfoboxItemData.mustache',
'group' => 'PortableInfoboxItemGroup.mustache',
'horizontal-group-content' => 'PortableInfoboxHorizontalGroupContent.mustache',
'navigation' => 'PortableInfoboxItemNavigation.mustache',
'hero-mobile' => 'PortableInfoboxItemHeroMobile.mustache',
'hero-mobile-wikiamobile' => 'PortableInfoboxItemHeroMobileWikiaMobile.mustache',
'image-collection' => 'PortableInfoboxItemImageCollection.mustache',
'image-collection-mobile' => 'PortableInfoboxItemImageCollectionMobile.mustache',
'image-collection-mobile-wikiamobile' => 'PortableInfoboxItemImageCollectionMobileWikiaMobile.mustache'
];
private $templateEngine;
private $imagesWidth;
protected $templateEngine;
protected $imagesWidth;
function __construct() {
$this->templateEngine = ( new Wikia\Template\MustacheEngine )
->setPrefix( self::getTemplatesDir() );
$this->imagesWidth = PortableInfoboxRenderServiceHelper::DEFAULT_DESKTOP_THUMBNAIL_WIDTH;
}
public static function getTemplatesDir() {
return dirname( __FILE__ ) . '/../templates';
}
public static function getTemplates() {
return self::$templates;
parent::__construct();
$this->templateEngine = new PortableInfoboxMustacheEngine();
}
/**
@ -55,14 +26,10 @@ class PortableInfoboxRenderService extends WikiaService {
$helper = new PortableInfoboxRenderServiceHelper();
$infoboxHtmlContent = '';
$heroData = [ ];
// decide on image width
$this->imagesWidth = $helper->isMobile() ?
PortableInfoboxRenderServiceHelper::MOBILE_THUMBNAIL_WIDTH :
// if europa go with bigger images! else default size
$helper->isEuropaTheme() ? PortableInfoboxRenderServiceHelper::EUROPA_THUMBNAIL_WIDTH :
PortableInfoboxRenderServiceHelper::DEFAULT_DESKTOP_THUMBNAIL_WIDTH;
// decide on image width, if europa go with bigger images! else default size
$this->imagesWidth = $helper->isEuropaTheme() ? PortableInfoboxRenderServiceHelper::EUROPA_THUMBNAIL_WIDTH :
PortableInfoboxRenderServiceHelper::DEFAULT_DESKTOP_THUMBNAIL_WIDTH;
$colors = [
'hasAccentColor' => !empty( $accentColor ),
@ -72,37 +39,13 @@ class PortableInfoboxRenderService extends WikiaService {
];
foreach ( $infoboxdata as $item ) {
$data = $item[ 'data' ];
$type = $item[ 'type' ];
switch ( $type ) {
case 'group':
$infoboxHtmlContent .= $this->renderGroup( $data, $colors );
break;
case 'navigation':
$infoboxHtmlContent .= $this->renderItem( 'navigation', $data );
break;
case 'title':
if ( !$helper->isMobile() ) {
$data = array_merge( $data, $colors );
}
// intentionally missing break statement
default:
if ( $helper->isMobile() && $helper->isValidHeroDataItem( $item, $heroData ) ) {
$heroData[ $type ] = $data;
continue;
}
if ( $helper->isTypeSupportedInTemplates( $type, self::getTemplates() ) ) {
$infoboxHtmlContent .= $this->renderItem( $type, $data );
};
if ( $this->templateEngine->isSupportedType( $type ) ) {
$infoboxHtmlContent .= $this->renderItem( $type, $item[ 'data' ] );
}
}
if ( !empty( $heroData ) ) {
$infoboxHtmlContent = $this->renderInfoboxHero( $heroData ) . $infoboxHtmlContent;
}
if ( !empty( $infoboxHtmlContent ) ) {
$output = $this->renderItem( 'wrapper', [
'content' => $infoboxHtmlContent,
@ -114,13 +57,41 @@ class PortableInfoboxRenderService extends WikiaService {
$output = '';
}
\Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag::getInstance()->setFirstInfoboxAlredyRendered( true );
wfProfileOut( __METHOD__ );
return $output;
}
/**
* Produces HTML output for item type and data
*
* @param $type
* @param array $data
* @return string
*/
protected function render( $type, array $data ) {
return $this->templateEngine->render( $type, $data );
}
/**
* renders part of infobox
*
* @param string $type
* @param array $data
*
* @return string - HTML
*/
protected function renderItem( $type, array $data ) {
if ( $type === 'group' ) {
return $this->renderGroup( $data );
}
if ( $type === 'image' ) {
return $this->renderImage( $data );
}
return $this->render( $type, $data );
}
/**
* renders group infobox component
*
@ -128,7 +99,7 @@ class PortableInfoboxRenderService extends WikiaService {
*
* @return string - group HTML markup
*/
private function renderGroup( $groupData, $colors) {
protected function renderGroup( $groupData ) {
$cssClasses = [ ];
$helper = new PortableInfoboxRenderServiceHelper();
$groupHTMLContent = '';
@ -145,11 +116,7 @@ class PortableInfoboxRenderService extends WikiaService {
foreach ( $dataItems as $item ) {
$type = $item[ 'type' ];
if ( ($type === 'header' || $type === 'title') && !$helper->isMobile() ) {
$item[ 'data' ] = array_merge( $item[ 'data' ], $colors );
}
if ( $helper->isTypeSupportedInTemplates( $type, self::getTemplates() ) ) {
if ( $this->templateEngine->isSupportedType( $type ) ) {
$groupHTMLContent .= $this->renderItem( $type, $item[ 'data' ] );
}
}
@ -160,105 +127,43 @@ class PortableInfoboxRenderService extends WikiaService {
$cssClasses[] = 'pi-collapse-' . $collapse;
}
return $this->renderItem( 'group', [
return $this->render( 'group', [
'content' => $groupHTMLContent,
'cssClasses' => implode( ' ', $cssClasses )
] );
}
/**
* renders infobox hero component
*
* @param array $data - infobox hero component data
*
* @return string
*/
private function renderInfoboxHero( $data ) {
$helper = new PortableInfoboxRenderServiceHelper();
// In Mercury SPA content of the first infobox's hero module has been moved to the article header.
$firstInfoboxAlredyRendered = \Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag::getInstance()
->isFirstInfoboxAlredyRendered();
if ( array_key_exists( 'image', $data ) ) {
$image = $data[ 'image' ][ 0 ];
$image[ 'context' ] = self::MEDIA_CONTEXT_INFOBOX_HERO_IMAGE;
$image = $helper->extendImageData( $image, PortableInfoboxRenderServiceHelper::MOBILE_THUMBNAIL_WIDTH );
$data[ 'image' ] = $image;
if ( !$helper->isMercury() ) {
return $this->renderItem( 'hero-mobile-wikiamobile', $data );
} elseif ( $firstInfoboxAlredyRendered ) {
return $this->renderItem( 'hero-mobile', $data );
}
} elseif ( !$helper->isMercury() || $firstInfoboxAlredyRendered ) {
return $this->renderItem( 'title', $data[ 'title' ] );
}
return '';
}
/**
* renders part of infobox
* If image element has invalid thumbnail, doesn't render this element at all.
*
* @param string $type
* @param array $data
*
* @return bool|string - HTML
* @param $data
* @return string
*/
private function renderItem( $type, array $data ) {
protected function renderImage( $data ) {
$helper = new PortableInfoboxRenderServiceHelper();
$images = [ ];
if ( $type === 'image' ) {
$images = [ ];
for ( $i = 0; $i < count( $data ); $i++ ) {
$data[ $i ] = $helper->extendImageData( $data[ $i ], $this->imagesWidth );
for ( $i = 0; $i < count( $data ); $i++ ) {
$data[ $i ][ 'context' ] = self::MEDIA_CONTEXT_INFOBOX;
$data[ $i ] = $helper->extendImageData( $data[ $i ], $this->imagesWidth );
if ( !!$data[ $i ] ) {
$images[] = $data[ $i ];
}
if ( !!$data[ $i ] ) {
$images[] = $data[ $i ];
}
}
if ( count( $images ) === 0 ) {
return false;
} else if ( count( $images ) === 1 ) {
$data = $images[ 0 ];
$templateName = $type;
} else {
// More than one image means image collection
if ( $helper->isMobile() && !$helper->isMercury() ) {
// Display only the first image on WikiaMobile
$data = $images[ 0 ];
} else {
$data = $helper->extendImageCollectionData( $images );
}
if ( count( $images ) === 0 ) {
return '';
}
$templateName = 'image-collection';
}
if ( $helper->isMobile() ) {
if ( !$helper->isMercury() ) {
$templateName = $templateName . self::MOBILE_TEMPLATE_POSTFIX . '-wikiamobile';
} else {
$templateName = $templateName . self::MOBILE_TEMPLATE_POSTFIX;
}
}
if ( count( $images ) === 1 ) {
$data = $images[ 0 ];
$templateName = 'image';
} else {
$templateName = $type;
// More than one image means image collection
$data = $helper->extendImageCollectionData( $images );
$templateName = 'image-collection';
}
/**
* Currently, based on business decision, sanitization happens ONLY on Mercury
*/
if ( $helper->isMobile() ) {
$data = SanitizerBuilder::createFromType( $type )->sanitize( $data );
}
return $this->templateEngine->clearData()
->setData( $data )
->render( self::getTemplates()[ $templateName ] );
return $this->render( $templateName, $data );
}
}

View file

@ -0,0 +1,621 @@
<?php
class MobileInfoboxRenderServiceTest extends WikiaBaseTest {
//todo: https://wikia-inc.atlassian.net/browse/DAT-3076
//todo: we are testing a lot of functionality and have issues with mocking
//todo: we should move all render service test to API tests
protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp();
}
/**
* @param $input to check presence of some additional config fields. Possible fields:
* 'isInvalidImage' - bool - if getThumbnail should return false
* 'isMercury' - bool - if we want to test Mercury skin
* 'isMercuryExperimentalMarkupEnabled' - bool
* 'smallImageDimensions' - integer - size of small image (both width and height)
*
* @return PHPUnit_Framework_MockObject_MockObject
*/
private function mockInfoboxRenderServiceHelper( $input ) {
$isValidHeroDataItem = isset( $input[ 'isValidHeroDataItem' ] ) && $input[ 'isValidHeroDataItem' ];
$isMercury = isset( $input[ 'isMercury' ] ) && $input[ 'isMercury' ];
$createHorizontalGroupData = isset( $input[ 'createHorizontalGroupData' ] ) ?
$input[ 'createHorizontalGroupData' ] : null;
$extendImageData = isset( $input[ 'extendImageData' ] ) ? $input[ 'extendImageData' ] : null;
$mock = $this->getMockBuilder( 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper' )
->setMethods( [ 'isValidHeroDataItem', 'validateType', 'isMercury',
'isMercuryExperimentalMarkupEnabled', 'createHorizontalGroupData', 'extendImageData' ] )
->getMock();
$mock->expects( $this->any() )
->method( 'isValidHeroDataItem' )
->will( $this->returnValue( $isValidHeroDataItem ) );
$mock->expects( $this->any() )
->method( 'validateType' )
->will( $this->returnValue( true ) );
$mock->expects( $this->any() )
->method( 'isMercury' )
->will( $this->returnValue( $isMercury ) );
$mock->expects( $this->any() )
->method( 'createHorizontalGroupData' )
->will( $this->returnValue( $createHorizontalGroupData ) );
$mock->expects( $this->any() )
->method( 'extendImageData' )
->will( $this->returnValue( $extendImageData ) );
$this->mockClass( 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper', $mock );
}
/**
* @param $html
* @return string
*/
private function normalizeHTML( $html ) {
$DOM = new DOMDocument( '1.0' );
$DOM->formatOutput = true;
$DOM->preserveWhiteSpace = false;
$DOM->loadXML( $html );
return $DOM->saveXML();
}
/**
* @param $input
* @param $expectedOutput
* @param $description
* @param $mockParams
* @dataProvider testRenderInfoboxDataProvider
*/
public function testRenderInfobox( $input, $expectedOutput, $description, $mockParams ) {
$this->mockInfoboxRenderServiceHelper( $mockParams );
$infoboxRenderService = new MobileInfoboxRenderService();
$actualOutput = $infoboxRenderService->renderInfobox( $input, '', '' );
$expectedHtml = $this->normalizeHTML( $expectedOutput );
$actualHtml = $this->normalizeHTML( $actualOutput );
$this->assertEquals( $expectedHtml, $actualHtml, $description );
}
public function testRenderInfoboxDataProvider() {
return [
[
'input' => [ ],
'output' => '',
'description' => 'Empty data should yield no infobox markup'
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test Title'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<h2 class="pi-item pi-item-spacing pi-title">Test Title</h2>
</aside>',
'description' => 'Only title'
],
[
'input' => [
[
'type' => 'navigation',
'data' => [
'value' => 'navigation value',
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<nav class="pi-navigation pi-item-spacing pi-secondary-background pi-secondary-font">navigation value</nav>
</aside>',
'description' => 'navigation only'
],
[
'input' => [
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-data pi-item-spacing pi-border-color">
<h3 class="pi-data-label pi-secondary-font">test label</h3>
<div class="pi-data-value pi-font">test value</div>
</div>
</aside>',
'description' => 'Only pair'
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test Title'
]
],
[
'type' => 'image',
'data' => [
[
'alt' => 'image alt',
'url' => 'http://image.jpg',
'name' => 'image',
'key' => 'image',
'isVideo' => false
]
]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<h2 class="pi-item pi-item-spacing pi-title">Test Title</h2>
<div class="pi-item pi-image">
<img src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D" data-src="http://image.jpg" class="pi-image-thumbnail lazy media article-media" alt="image alt" data-image-key="test1" data-image-name="test1" data-ref="1" data-params="[{&quot;name&quot;:&quot;test1&quot;, &quot;full&quot;:&quot;http://image.jpg&quot;}]"/>
</div>
<div class="pi-item pi-data pi-item-spacing pi-border-color">
<h3 class="pi-data-label pi-secondary-font">test label</h3>
<div class="pi-data-value pi-font">test value</div>
</div>
</aside>',
'description' => 'Simple infobox with title, image and key-value pair',
'mockParams' => [
'extendImageData' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 1,
'width' => '400',
'height' => '200',
'thumbnail' => 'http://image.jpg',
'thumbnail2x' => 'http://image2x.jpg',
'media-type' => 'image',
'isVideo' => false
]
]
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test Title'
]
],
[
'type' => 'image',
'data' => [ ]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<h2 class="pi-item pi-item-spacing pi-title">Test Title</h2>
<div class="pi-item pi-data pi-item-spacing pi-border-color">
<h3 class="pi-data-label pi-secondary-font">test label</h3>
<div class="pi-data-value pi-font">test value</div>
</div>
</aside>',
'description' => 'Simple infobox with title, INVALID image and key-value pair'
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test Title'
]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<h2 class="pi-item pi-item-spacing pi-title">Test Title</h2>
<div class="pi-item pi-data pi-item-spacing pi-border-color">
<h3 class="pi-data-label pi-secondary-font">test label</h3>
<div class="pi-data-value pi-font">test value</div>
</div>
</aside>',
'description' => 'Simple infobox with title, empty image and key-value pair'
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test Title'
]
],
[
'type' => 'group',
'data' => [
'value' => [
[
'type' => 'header',
'data' => [
'value' => 'Test Header'
]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
]
]
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<h2 class="pi-item pi-item-spacing pi-title">Test Title</h2>
<section class="pi-item pi-group pi-border-color">
<h2 class="pi-item pi-header pi-secondary-font pi-item-spacing pi-secondary-background">Test Header</h2>
<div class="pi-item pi-data pi-item-spacing pi-border-color">
<h3 class="pi-data-label pi-secondary-font">test label</h3>
<div class="pi-data-value pi-font">test value</div>
</div>
<div class="pi-item pi-data pi-item-spacing pi-border-color">
<h3 class="pi-data-label pi-secondary-font">test label</h3>
<div class="pi-data-value pi-font">test value</div>
</div>
</section>
</aside>',
'description' => 'Infobox with title, group with header and two key-value pairs'
],
[
'input' => [
[
'type' => 'group',
'data' => [
'value' => [
[
'type' => 'header',
'data' => [
'value' => 'Test header'
]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
],
[
'type' => 'data',
'data' => [
'label' => 'test label',
'value' => 'test value'
]
]
],
'layout' => 'horizontal'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<section class="pi-item pi-group pi-border-color">
<table class="pi-horizontal-group">
<caption
class="pi-header pi-secondary-font pi-secondary-background pi-item-spacing">Test header</caption>
<thead>
<tr>
<th
class="pi-horizontal-group-item pi-data-label pi-secondary-font pi-border-color pi-item-spacing">test label</th>
<th
class="pi-horizontal-group-item pi-data-label pi-secondary-font pi-border-color pi-item-spacing">test label</th>
</tr>
</thead>
<tbody>
<tr>
<td
class="pi-horizontal-group-item pi-data-value pi-font pi-border-color pi-item-spacing">test value</td>
<td
class="pi-horizontal-group-item pi-data-value pi-font pi-border-color pi-item-spacing">test value</td>
</tr>
</tbody>
</table>
</section>
</aside>',
'description' => 'Infobox with horizontal group',
'mockParams' => [
'createHorizontalGroupData' => [
'header' => 'Test header',
'labels' => [ 'test label', 'test label' ],
'values' => [ 'test value', 'test value' ],
'renderLabels' => true
]
]
],
[
'input' => [
[
'type' => 'group',
'data' => [
'value' => [
[
'type' => 'data',
'data' => [
'label' => '',
'value' => 'test value'
]
],
[
'type' => 'data',
'data' => [
'label' => '',
'value' => 'test value'
]
]
],
'layout' => 'horizontal'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<section class="pi-item pi-group pi-border-color">
<table class="pi-horizontal-group pi-horizontal-group-no-labels">
<tbody>
<tr>
<td
class="pi-horizontal-group-item pi-data-value pi-font pi-border-color pi-item-spacing">test value</td>
<td
class="pi-horizontal-group-item pi-data-value pi-font pi-border-color pi-item-spacing">test value</td>
</tr>
</tbody>
</table>
</section>
</aside>',
'description' => 'Infobox with horizontal group without header and labels',
'mockParams' => [
'createHorizontalGroupData' => [
'labels' => [ '', '' ],
'values' => [ 'test value', 'test value' ],
'renderLabels' => false
]
]
],
[
'input' => [
[
'type' => 'navigation',
'data' => [
'value' => '<p>Links</p>'
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<nav class="pi-navigation pi-item-spacing pi-secondary-background pi-secondary-font">
<p>Links</p>
</nav>
</aside>',
'description' => 'Infobox with navigation'
],
[
'input' => [
[
'type' => 'image',
'data' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'ref' => 1,
'name' => 'test1',
'key' => 'test1',
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D" data-src="http://image.jpg" class="pi-image-thumbnail lazy media article-media" alt="image alt" data-image-key="test1" data-image-name="test1" data-ref="1" data-params=\'[{"name":"test1", "full":"http://image.jpg"}]\' />
</div>
</aside>',
'description' => 'WikiaMobile: Only image. Image is not small- should render hero.',
'mockParams' => [
'isMercury' => false,
'isValidHeroDataItem' => true,
'extendImageData' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 1,
'width' => '400',
'height' => '200',
'thumbnail' => 'http://image.jpg',
'thumbnail2x' => 'http://image2x.jpg',
'media-type' => 'image',
'isVideo' => false
]
]
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test <img /><a href="example.com">Title</a>'
]
],
[
'type' => 'image',
'data' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<hgroup class="pi-hero-title-wrapper pi-item-spacing">
<h2 class="pi-hero-title">Test <a href="example.com">Title</a></h2>
</hgroup>
<img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D" data-src="thumbnail.jpg" class="pi-image-thumbnail lazy media article-media" alt="" data-image-key="test1" data-image-name="test1" data-ref="44" data-params=\'[{"name":"test1", "full":"http://image.jpg"}]\'/>
</div>
</aside>',
'description' => 'WikiaMobile: Infobox with full hero module with title with HTML tags',
'mockParams' => [
'isValidHeroDataItem' => true,
'isMercury' => false,
'extendImageData' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'width' => '400',
'height' => '200',
'thumbnail' => 'thumbnail.jpg',
'thumbnail2x' => 'thumbnail2x.jpg',
'isVideo' => false,
'media-type' => 'image'
]
]
],
[
'input' => [
[
'type' => 'image',
'data' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'ref' => 1,
'name' => 'test1',
'key' => 'test1',
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<figure data-component="portable-infobox-hero-image" data-attrs="{&quot;itemContext&quot;:&quot;portable-infobox&quot;,&quot;ref&quot;:1}">
<a href="http://image.jpg">
<img class="article-media-placeholder" src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D\'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg\' viewBox%3D\'0 0 400 200\'%2F%3E" alt="" width="400" height="200"/>
<noscript>
<img src="http://image.jpg" alt="image alt" width="400" height="200"/>
</noscript>
</a>
</figure>
</div>
</aside>',
'description' => 'Mercury: Only image. Image is not small- should render hero.',
'mockParams' => [
'isMercury' => true,
'isMercuryExperimentalMarkupEnabled' => true,
'isValidHeroDataItem' => true,
'extendImageData' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 1,
'width' => '400',
'height' => '200',
'thumbnail' => 'http://image.jpg',
'thumbnail2x' => 'http://image2x.jpg',
'media-type' => 'image',
'isVideo' => false,
'mercuryComponentAttrs' => json_encode( [
'itemContext' => 'portable-infobox',
'ref' => 1
] )
]
]
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test <img /><a href="example.com">Title</a>'
]
],
[
'type' => 'image',
'data' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<hgroup class="pi-hero-title-wrapper pi-item-spacing">
<h2 class="pi-hero-title">Test <a href="example.com">Title</a></h2>
</hgroup>
<figure data-component="portable-infobox-hero-image" data-attrs="{&quot;itemContext&quot;:&quot;portable-infobox&quot;,&quot;ref&quot;:44}">
<a href="http://image.jpg">
<img class="article-media-placeholder" src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D\'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg\' viewBox%3D\'0 0 400 200\'%2F%3E" alt="" width="400" height="200"/>
<noscript>
<img src="http://image.jpg" alt="" width="400" height="200"/>
</noscript>
</a>
</figure>
</div>
</aside>',
'description' => 'Mercury: Infobox with full hero module with title with HTML tags',
'mockParams' => [
'isValidHeroDataItem' => true,
'isMercury' => true,
'isMercuryExperimentalMarkupEnabled' => true,
'extendImageData' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'width' => '400',
'height' => '200',
'thumbnail' => 'thumbnail.jpg',
'thumbnail2x' => 'thumbnail2x.jpg',
'isVideo' => false,
'media-type' => 'image',
'mercuryComponentAttrs' => json_encode( [
'itemContext' => 'portable-infobox',
'ref' => 44
] )
]
]
]
];
}
}

View file

@ -0,0 +1,39 @@
<?php
use Wikia\PortableInfobox\Helpers\PortableInfoboxMustacheEngine;
class PortableInfoboxMustacheEngineTest extends WikiaBaseTest {
protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp();
}
/**
* @dataProvider testIsTypeSupportedInTemplatesDataProvider
*/
public function testIsTypeSupportedInTemplates( $type, $result, $description ) {
$this->assertEquals(
$result,
PortableInfoboxMustacheEngine::isSupportedType( $type ),
$description
);
}
public function testIsTypeSupportedInTemplatesDataProvider() {
return [
[
'type' => 'title',
'result' => true,
'description' => 'valid data type'
],
[
'type' => 'invalidTestType',
'result' => false,
'description' => 'invalid data type'
]
];
}
}

View file

@ -37,23 +37,6 @@ class PortableInfoboxRenderServiceHelperTest extends WikiaBaseTest {
return $fileMock;
}
private function getThumbnailMock( $thumbnailSizes ) {
$thumbnailWidth = isset( $thumbnailSizes[ 'width' ] ) ? $thumbnailSizes[ 'width' ] : null;
$thumbnailHeight = isset( $thumbnailSizes[ 'height' ] ) ? $thumbnailSizes[ 'height' ] : null;
$thumbnailMock = $this->getMockBuilder( 'ThumbnailImage' )
->setMethods( [ 'getWidth', 'getHeight' ] )
->getMock();
$thumbnailMock->expects( $this->any() )
->method( 'getWidth' )
->will( $this->returnValue( $thumbnailWidth ) );
$thumbnailMock->expects( $this->any() )
->method( 'getHeight' )
->will( $this->returnValue( $thumbnailHeight ) );
return $thumbnailMock;
}
/**
* @param array $input
* @param array $expectedOutput
@ -262,39 +245,6 @@ class PortableInfoboxRenderServiceHelperTest extends WikiaBaseTest {
];
}
/**
* @param string $type
* @param boolean $result
* @param string $description
* @dataProvider testIsTypeSupportedInTemplatesDataProvider
*/
public function testIsTypeSupportedInTemplates( $type, $result, $description ) {
$templates = [
'testType' => 'testType.mustache'
];
$this->assertEquals(
$result,
$this->helper->isTypeSupportedInTemplates( $type, $templates ),
$description
);
}
public function testIsTypeSupportedInTemplatesDataProvider() {
return [
[
'type' => 'testType',
'result' => true,
'description' => 'valid data type'
],
[
'type' => 'invalidTestType',
'result' => false,
'description' => 'invalid data type'
]
];
}
/**
* @param $width
* @param $max

View file

@ -13,25 +13,19 @@ class PortableInfoboxRenderServiceTest extends WikiaBaseTest {
/**
* @param $input to check presence of some additional config fields. Possible fields:
* 'isInvalidImage' - bool - if getThumbnail should return false
* 'isMobile' - bool - if we want to test mobile env
* 'isMercury' - bool - if we want to test Mercury skin
* 'isMercuryExperimentalMarkupEnabled' - bool
* 'smallImageDimensions' - integer - size of small image (both width and height)
*
* @return PHPUnit_Framework_MockObject_MockObject
*/
private function mockInfoboxRenderServiceHelper( $input ) {
$isValidHeroDataItem = isset( $input[ 'isValidHeroDataItem' ] ) && $input[ 'isValidHeroDataItem' ];
$isMobile = isset( $input[ 'isMobile' ] ) && $input[ 'isMobile' ];
$isMercury = isset( $input[ 'isMercury' ] ) && $input[ 'isMercury' ];
$createHorizontalGroupData = isset( $input[ 'createHorizontalGroupData' ] ) ?
$input[ 'createHorizontalGroupData' ] : null;
$extendImageData = isset( $input[ 'extendImageData' ] ) ? $input[ 'extendImageData' ] : null;
$mock = $this->getMockBuilder( 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper' )
->setMethods( [ 'isValidHeroDataItem', 'validateType', 'isMobile', 'isMercury',
'isMercuryExperimentalMarkupEnabled', 'createHorizontalGroupData', 'extendImageData' ] )
->setMethods( [ 'isValidHeroDataItem', 'validateType', 'createHorizontalGroupData', 'extendImageData' ] )
->getMock();
$mock->expects( $this->any() )
->method( 'isValidHeroDataItem' )
@ -39,12 +33,6 @@ class PortableInfoboxRenderServiceTest extends WikiaBaseTest {
$mock->expects( $this->any() )
->method( 'validateType' )
->will( $this->returnValue( true ) );
$mock->expects( $this->any() )
->method( 'isMobile' )
->will( $this->returnValue( $isMobile ) );
$mock->expects( $this->any() )
->method( 'isMercury' )
->will( $this->returnValue( $isMercury ) );
$mock->expects( $this->any() )
->method( 'createHorizontalGroupData' )
->will( $this->returnValue( $createHorizontalGroupData ) );
@ -537,202 +525,6 @@ class PortableInfoboxRenderServiceTest extends WikiaBaseTest {
</nav>
</aside>',
'description' => 'Infobox with navigation'
],
[
'input' => [
[
'type' => 'image',
'data' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'ref' => 1,
'name' => 'test1',
'key' => 'test1',
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D" data-src="http://image.jpg" class="pi-image-thumbnail lazy media article-media" alt="image alt" data-image-key="test1" data-image-name="test1" data-ref="1" data-params=\'[{"name":"test1", "full":"http://image.jpg"}]\' />
</div>
</aside>',
'description' => 'WikiaMobile: Only image. Image is not small- should render hero.',
'mockParams' => [
'isMobile' => true,
'isMercury' => false,
'isValidHeroDataItem' => true,
'extendImageData' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 1,
'width' => '400',
'height' => '200',
'thumbnail' => 'http://image.jpg',
'thumbnail2x' => 'http://image2x.jpg',
'media-type' => 'image',
'isVideo' => false
]
]
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test <img /><a href="example.com">Title</a>'
]
],
[
'type' => 'image',
'data' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<hgroup class="pi-hero-title-wrapper pi-item-spacing">
<h2 class="pi-hero-title">Test <a href="example.com">Title</a></h2>
</hgroup>
<img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D" data-src="thumbnail.jpg" class="pi-image-thumbnail lazy media article-media" alt="" data-image-key="test1" data-image-name="test1" data-ref="44" data-params=\'[{"name":"test1", "full":"http://image.jpg"}]\'/>
</div>
</aside>',
'description' => 'WikiaMobile: Infobox with full hero module with title with HTML tags',
'mockParams' => [
'isValidHeroDataItem' => true,
'isMobile' => true,
'isMercury' => false,
'extendImageData' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'width' => '400',
'height' => '200',
'thumbnail' => 'thumbnail.jpg',
'thumbnail2x' => 'thumbnail2x.jpg',
'isVideo' => false,
'media-type' => 'image'
]
]
],
[
'input' => [
[
'type' => 'image',
'data' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'ref' => 1,
'name' => 'test1',
'key' => 'test1',
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<figure data-component="portable-infobox-hero-image" data-attrs="{&quot;itemContext&quot;:&quot;portable-infobox&quot;,&quot;ref&quot;:1}">
<a href="http://image.jpg">
<img class="article-media-placeholder" src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D\'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg\' viewBox%3D\'0 0 400 200\'%2F%3E" alt="" width="400" height="200"/>
<noscript>
<img src="http://image.jpg" alt="image alt" width="400" height="200"/>
</noscript>
</a>
</figure>
</div>
</aside>',
'description' => 'Mercury: Only image. Image is not small- should render hero.',
'mockParams' => [
'isMobile' => true,
'isMercury' => true,
'isMercuryExperimentalMarkupEnabled' => true,
'isValidHeroDataItem' => true,
'extendImageData' => [
'alt' => 'image alt',
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 1,
'width' => '400',
'height' => '200',
'thumbnail' => 'http://image.jpg',
'thumbnail2x' => 'http://image2x.jpg',
'media-type' => 'image',
'isVideo' => false,
'mercuryComponentAttrs' => json_encode( [
'itemContext' => 'portable-infobox',
'ref' => 1
] )
]
]
],
[
'input' => [
[
'type' => 'title',
'data' => [
'value' => 'Test <img /><a href="example.com">Title</a>'
]
],
[
'type' => 'image',
'data' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'isVideo' => false
]
]
],
'output' => '<aside class="portable-infobox pi-background">
<div class="pi-item pi-hero">
<hgroup class="pi-hero-title-wrapper pi-item-spacing">
<h2 class="pi-hero-title">Test <a href="example.com">Title</a></h2>
</hgroup>
<figure data-component="portable-infobox-hero-image" data-attrs="{&quot;itemContext&quot;:&quot;portable-infobox&quot;,&quot;ref&quot;:44}">
<a href="http://image.jpg">
<img class="article-media-placeholder" src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D\'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg\' viewBox%3D\'0 0 400 200\'%2F%3E" alt="" width="400" height="200"/>
<noscript>
<img src="http://image.jpg" alt="" width="400" height="200"/>
</noscript>
</a>
</figure>
</div>
</aside>',
'description' => 'Mercury: Infobox with full hero module with title with HTML tags',
'mockParams' => [
'isValidHeroDataItem' => true,
'isMobile' => true,
'isMercury' => true,
'isMercuryExperimentalMarkupEnabled' => true,
'extendImageData' => [
'url' => 'http://image.jpg',
'name' => 'test1',
'key' => 'test1',
'ref' => 44,
'width' => '400',
'height' => '200',
'thumbnail' => 'thumbnail.jpg',
'thumbnail2x' => 'thumbnail2x.jpg',
'isVideo' => false,
'media-type' => 'image',
'mercuryComponentAttrs' => json_encode( [
'itemContext' => 'portable-infobox',
'ref' => 44
] )
]
]
]
];
}