DAT-3199 unit tests fixed

This commit is contained in:
idradm 2015-09-23 15:51:41 +02:00
parent 859a0ee81b
commit dbef0b9915
5 changed files with 217 additions and 84 deletions

View file

@ -48,6 +48,7 @@ $wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag' ] = $
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper' ] = $dir . 'services/Helpers/PortableInfoboxRenderServiceHelper.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxClassification' ] = $dir . 'services/Helpers/PortableInfoboxClassification.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper' ] = $dir . 'services/Helpers/PortableInfoboxTemplatesHelper.php';
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PagePropsProxy' ] = $dir . 'services/Helpers/PagePropsProxy.php';
// controller classes
$wgAutoloadClasses[ 'PortableInfoboxParserTagController' ] = $dir . 'controllers/PortableInfoboxParserTagController.class.php';

View file

@ -0,0 +1,15 @@
<?php
namespace Wikia\PortableInfobox\Helpers;
class PagePropsProxy {
public function get( $id, $property ) {
return \Wikia::getProps( $id, $property );
}
public function set( $id, $data ) {
\Wikia::setProps( $id, $data );
}
}

View file

@ -16,7 +16,7 @@ class PortableInfoboxTemplatesHelper {
*
* @param $title \Title
*
* @return mixed
* @return mixed false when no infoboxes found, Array with infoboxes on success
*/
public function parseInfoboxes( $title ) {
// for templates we need to check for include tags
@ -42,7 +42,8 @@ class PortableInfoboxTemplatesHelper {
}
}
return $parser->getOutput()->getProperty( \PortableInfoboxDataService::INFOBOXES_PROPERTY_NAME );
return json_decode( $parser->getOutput()
->getProperty( \PortableInfoboxDataService::INFOBOXES_PROPERTY_NAME ), true );
}
}

View file

@ -1,5 +1,6 @@
<?php
use Wikia\PortableInfobox\Helpers\PagePropsProxy;
use Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper;
use Wikia\PortableInfobox\Parser\Nodes\NodeInfobox;
@ -8,34 +9,47 @@ class PortableInfoboxDataService {
const IMAGE_FIELD_TYPE = 'image';
const INFOBOXES_PROPERTY_NAME = 'infoboxes';
/**
* @var Title $title
*/
protected $title;
protected $templateHelper;
protected $propsProxy;
protected $cache;
protected $cachekey;
/**
* @param $title Title
* @param $helper
*
* @internal param $helper
*/
protected function __construct( $title, $helper ) {
$this->title = $title;
$this->templateHelper = $helper ? $helper : new PortableInfoboxTemplatesHelper();
$this->cachekey = wfMemcKey( $title->getArticleID(), self::INFOBOXES_PROPERTY_NAME );
protected function __construct( $title ) {
$this->title = $title !== null ? $title : new Title();
$this->templateHelper = new PortableInfoboxTemplatesHelper();
$this->propsProxy = new PagePropsProxy();
$this->cachekey = wfMemcKey( $this->title->getArticleID(), self::INFOBOXES_PROPERTY_NAME );
}
public static function newFromTitle( $title, $helper = null ) {
return new PortableInfoboxDataService( $title, $helper );
public static function newFromTitle( $title ) {
return new PortableInfoboxDataService( $title );
}
public static function newFromPageID( $pageid, $helper = null ) {
return new PortableInfoboxDataService( Title::newFromID( $pageid ), $helper );
public static function newFromPageID( $pageid ) {
return new PortableInfoboxDataService( Title::newFromID( $pageid ) );
}
// set internal helpers methods
public function setTemplatesHelper( $helper ) {
$this->templateHelper = $helper;
return $this;
}
public function setPagePropsProxy( $proxy ) {
$this->propsProxy = $proxy;
return $this;
}
/**
* Returns infobox data
* Returns infobox data, terminal method
*
* @return array in format [ 'data' => [], 'sources' => [] ] or [] will be returned
*/
@ -44,15 +58,16 @@ class PortableInfoboxDataService {
$hidden = $this->templateHelper->parseInfoboxes( $this->title );
if ( $hidden ) {
$this->delete();
$this->set( json_decode( $hidden, true ) );
$this->set( $hidden );
};
}
$result = $this->get();
return $this->get();
return $result !== null ? $result : [ ];
}
/**
* Get image list from infobox data
* Get image list from infobox data, terminal method
*
* @return array
*/
@ -79,6 +94,8 @@ class PortableInfoboxDataService {
* Save infobox data, permanently
*
* @param NodeInfobox $raw infobox parser output
*
* @return $this
*/
public function save( NodeInfobox $raw ) {
if ( $raw ) {
@ -86,6 +103,8 @@ class PortableInfoboxDataService {
$stored[] = [ 'data' => $raw->getRenderData(), 'sources' => $raw->getSource() ];
$this->set( $stored );
}
return $this;
}
/**
@ -94,6 +113,8 @@ class PortableInfoboxDataService {
public function delete() {
$this->clear();
unset( $this->cache );
return $this;
}
/**
@ -104,6 +125,8 @@ class PortableInfoboxDataService {
global $wgMemc;
$wgMemc->delete( $this->cachekey );
unset( $this->cache );
return $this;
}
// soft cache handlers
@ -128,7 +151,7 @@ class PortableInfoboxDataService {
// first try memcache, then go to props
$data = $wgMemc->get( $this->cachekey );
if ( $data === false ) {
$data = json_decode( Wikia::getProps( $id, self::INFOBOXES_PROPERTY_NAME ), true );
$data = json_decode( $this->propsProxy->get( $id, self::INFOBOXES_PROPERTY_NAME ), true );
$wgMemc->set( $this->cachekey, $data, WikiaResponse::CACHE_STANDARD );
}
@ -143,7 +166,7 @@ class PortableInfoboxDataService {
if ( $id ) {
global $wgMemc;
$wgMemc->set( $this->cachekey, $data, WikiaResponse::CACHE_STANDARD );
Wikia::setProps( $id, [ self::INFOBOXES_PROPERTY_NAME => json_encode( $data ) ] );
$this->propsProxy->set( $id, [ self::INFOBOXES_PROPERTY_NAME => json_encode( $data ) ] );
}
}
@ -152,7 +175,7 @@ class PortableInfoboxDataService {
if ( $id ) {
global $wgMemc;
$wgMemc->set( $this->cachekey, '', WikiaResponse::CACHE_STANDARD );
Wikia::setProps( $id, [ self::INFOBOXES_PROPERTY_NAME => '' ] );
$this->propsProxy->set( $id, [ self::INFOBOXES_PROPERTY_NAME => '' ] );
}
}
}

View file

@ -1,5 +1,7 @@
<?php
use Wikia\PortableInfobox\Parser\Nodes\NodeFactory;
class PortableInfoboxDataServiceTest extends PHPUnit_Framework_TestCase {
protected function setUp() {
@ -7,74 +9,110 @@ class PortableInfoboxDataServiceTest extends PHPUnit_Framework_TestCase {
parent::setUp();
}
protected function getInfoboxData() {
$data =
[
[ // INFOBOX 1
'data' => [
[
"type" => "data",
"data" => [
"value" => "AAAA",
"label" => "BBBB"
]
],
[
"type" => "image",
"data" => [
"key" => "Test.jpg",
"alt" => null,
"caption" => null,
]
],
[
"type" => "image",
"data" => [
"key" => "Test2.jpg",
"alt" => null,
"caption" => null
]
]
]
],
[ // INFOBOX 2
'data' => [
[
"type" => "image",
"data" => [
"key" => "Test2.jpg",
"alt" => null,
"caption" => null
]
]
]
]
];
/**
* @param $id
* @param int $ns
*
* @return Title
*/
protected function prepareTitle( $id = 0, $ns = NS_MAIN ) {
$title = new Title();
$title->mArticleID = $id;
$title->mNamespace = $ns;
return $data;
return $title;
}
public function testEmptyData() {
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle() )
// empty page props
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) )
->getData();
$this->assertEquals( [ ], $result );
}
public function testLoadFromProps() {
$data = '[{"data": [], "sources": []}]';
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
// purge memc so we can rerun tests
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => $data ] ) )
->getData();
$this->assertEquals( json_decode( $data, true ), $result );
}
public function testSave() {
$markup = '<infobox><data source="test"><default>{{{test2}}}</default></data></infobox>';
$infoboxNode = NodeFactory::newFromXML( $markup, [ 'test' => 1 ] );
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) )
->save( $infoboxNode )
->getData();
$this->assertEquals( [ [ 'data' => [ [ 'type' => 'data', 'data' => [ 'label' => null, 'value' => 1 ] ] ],
'sources' => [ 'test', 'test2' ] ] ], $result );
}
public function testTemplate() {
$data = [ [ 'data' => [ ], 'sources' => [ ] ] ];
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1, NS_TEMPLATE ) )
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) )
->setTemplatesHelper( new TemplateHelperDummy( $data ) )
->getData();
$this->assertEquals( $data, $result );
}
public function testDelete() {
$data = '[{"data": [], "sources": []}]';
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
// purge memc so we can rerun tests
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => $data ] ) )
->delete()
->getData();
$this->assertEquals( '', $result );
}
public function testPurge() {
$data = '[{"data": [], "sources": []}]';
$service = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
// purge memc so we can rerun tests
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => $data ] ) );
// this should load data from props to memc
$result = $service->getData();
$service->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) );
$purged = $service->getData();
$this->assertEquals( [ json_decode( $data, true ), [ ] ], [ $result, $purged ] );
}
public function testImageListRemoveDuplicates() {
$mock = $this->getMockBuilder( 'PortableInfoboxDataService' )
->disableOriginalConstructor()
->setMethods( [ 'getData' ] )
->getMock();
$mock->expects( $this->any() )->method( 'getData' )->will( $this->returnValue( $this->getInfoboxData() ) );
$images = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => json_encode( $this->getInfoboxData() ) ] ) )
->getImages();
$images = $mock->getImages();
$this->assertTrue( count( $images ) === 2 );
$this->assertEquals( count( $images ), 2 );
}
public function testImageListFetchImages() {
$mock = $this->getMockBuilder( 'PortableInfoboxDataService' )
->disableOriginalConstructor()
->setMethods( [ 'getData' ] )
->getMock();
$mock->expects( $this->any() )->method( 'getData' )->will( $this->returnValue( $this->getInfoboxData() ) );
$images = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
->purge()
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => json_encode( $this->getInfoboxData() ) ] ) )
->getImages();
$images = $mock->getImages();
$this->assertTrue( in_array( "Test.jpg", $images ), "Test.jpg should be in images array" );
$this->assertTrue( in_array( "Test2.jpg", $images ), "Test2.jpg should be in images array" );
$this->assertEquals( [ 'Test.jpg', 'Test2.jpg' ], $images );
}
public function testTitleNullConstructor() {
@ -89,4 +127,59 @@ class PortableInfoboxDataServiceTest extends PHPUnit_Framework_TestCase {
$this->assertEquals( [ ], $result );
}
protected function getInfoboxData() {
return [ [ 'data' => [ [ "type" => "data",
"data" => [
"value" => "AAAA",
"label" => "BBBB"
]
], [ "type" => "image",
"data" => [
"key" => "Test.jpg",
"alt" => null,
"caption" => null,
]
], [ "type" => "image",
"data" => [
"key" => "Test2.jpg",
"alt" => null,
"caption" => null
] ] ] ],
[ 'data' => [ [ "type" => "image",
"data" => [
"key" => "Test2.jpg",
"alt" => null,
"caption" => null
] ] ] ] ];
}
}
class TemplateHelperDummy {
public function __construct( $hidden = false ) {
$this->hidden = $hidden;
}
public function parseInfoboxes( $title ) {
return $this->hidden;
}
}
class PagePropsProxyDummy {
public function __construct( $data ) {
$this->data = $data;
}
public function get( $id, $property ) {
$prop = $this->data[ $id . $property ];
return $prop !== null ? $prop : '';
}
public function set( $id, $data ) {
foreach ( $data as $property => $value ) {
$this->data[ $id . $property ] = $value;
}
}
}