Property type: record (formally page).
Property ID: '___USEREDITCNT'. Property structure: * '___USEREDITCNT_NS': _num (namespace number), * '___USEREDITCNTNS_CNT': _num (user's edit count in this namespace). Property domain: User namespace. Property uniqueness: one value per namespace provided user has made edits in it. Property annotator class: UserEditCountPropertyAnnotator. Property annotator test class: UserEditCountPerNsPropertyAnnotatorTest. {{#ask:}} query examples: Edit count rating per user per namespace: {{#ask:[[-User edit count per namesoace::+]] | mainlabel = - | ?-User edit count per namespace | ?Namespace | ?Edit count | sort = Edit count | order = DESC }} Certain user's edits in the main namespace: {{#ask:[[-User edit count per namespace::User:Alex Mashin]] [[Namespace::0]] | ?Edit count = | mainlabel = - }} Made in reference to #169.
这个提交包含在:
父节点
ddc5d96b41
当前提交
944ba5048c
|
@ -141,6 +141,25 @@
|
|||
"alias": "sesp-property-user-edit-count",
|
||||
"label": "User edit count"
|
||||
},
|
||||
"_USEREDITCNTNS": {
|
||||
"id": "___USEREDITCNTNS",
|
||||
"type": "_wpg",
|
||||
"show": false,
|
||||
"alias": "sesp-property-user-edit-count-per-ns",
|
||||
"label": "User edit count per namespace"
|
||||
},
|
||||
"_USEREDITCNTNS_NS": {
|
||||
"id": "___USEREDITCNTNS_NS",
|
||||
"type": "_num",
|
||||
"alias": "sesp-property-user-edit-count-ns",
|
||||
"label": "User edit count per namespace:Namespace"
|
||||
},
|
||||
"_USEREDITCNTNS_CNT": {
|
||||
"id": "___USEREDITCNTNS_CNT",
|
||||
"type": "_num",
|
||||
"alias": "sesp-property-user-edit-count-cnt",
|
||||
"label": "User edit count per namespace:Edit count"
|
||||
},
|
||||
"_USERBLOCK": {
|
||||
"id": "___USERBLOCK",
|
||||
"type": "_txt",
|
||||
|
|
|
@ -32,6 +32,7 @@ Property labels differ according to the language the wiki was set up. An easy wa
|
|||
- `_SUBP` adds a property called "Subpage" which records all subpages to a page
|
||||
- `_USERREG` adds a property called "User registration date" to user pages which records the user's registration date
|
||||
- `_USEREDITCNT` adds a property called "User edit count" to user pages which records the user's edit count
|
||||
- `_USEREDITCNTNS` adds a property called "User edit count per namespace" to user pages, which records the user's edit counts in all namespaces
|
||||
- `_USERBLOCK` adds a property called "User block" to user pages which records the user's block status
|
||||
- `_USERRIGHT` adds a property called "User right" to user pages which records the user's assigned rights
|
||||
- `_USERGROUP` adds a property called "User group" to user pages which records the user's assigned groups
|
||||
|
|
|
@ -47,6 +47,12 @@
|
|||
"sesp-property-user-registration-date-desc": "\"$1\" records the user's registration date. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
|
||||
"sesp-property-user-edit-count": "User edit count",
|
||||
"sesp-property-user-edit-count-desc": "\"$1\" records the user's edit count. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
|
||||
"sesp-property-user-edit-count-per-ns": "User edit count per namespace",
|
||||
"sesp-property-user-edit-count-per-ns-desc": "\"$1\" records the user's edit count in certain namespace. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
|
||||
"sesp-property-user-edit-count-ns": "Namespace",
|
||||
"sesp-property-user-edit-count-ns-desc": "\"$1\" records the namespace number in the user's edit count record. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
|
||||
"sesp-property-user-edit-count-cnt": "Edit count",
|
||||
"sesp-property-user-edit-count-cnt-desc": "\"$1\" records the edit count in the user's edit count record. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
|
||||
"sesp-property-user-block": "User block",
|
||||
"sesp-property-user-block-desc": "\"$1\" records a list of blocks applied to a user. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
|
||||
"sesp-property-user-right": "User right",
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
"sesp-property-user-registration-date-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
|
||||
"sesp-property-user-edit-count": "{{Doc-smw-sp|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-per-ns": "{{Doc-smw-sp|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-per-ns-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-ns": "{{Doc-smw-sp|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-ns-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-cnt": "{{Doc-smw-sp|extension=SESP}}",
|
||||
"sesp-property-user-edit-count-cnt-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
|
||||
"sesp-property-user-block": "This is the name of a special property.",
|
||||
"sesp-property-user-block-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
|
||||
"sesp-property-user-right": "This is the name of a special property.",
|
||||
|
|
|
@ -43,6 +43,12 @@
|
|||
"sesp-property-approved-status-desc": "«$1» определяет статус одобрения страницы. Предоставляется расширением [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties].",
|
||||
"sesp-property-user-registration-date": "Дата регистрации пользователя",
|
||||
"sesp-property-user-edit-count": "Число правок участника",
|
||||
"sesp-property-user-edit-count-per-ns": "Число правок участника в пространстве имён",
|
||||
"sesp-property-user-edit-count-per-ns-desc": "\"$1\" содержит число правок участника в определённом пространстве имён. Предоставляется расширением [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties].",
|
||||
"sesp-property-user-edit-count-ns": "Пространство имён",
|
||||
"sesp-property-user-edit-count-ns-desc": "\"$1\" содержит номер пространства имён в записи о числе правок в пространстве имён. Предоставляется расширением [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties].",
|
||||
"sesp-property-user-edit-count-cnt": "Число правок",
|
||||
"sesp-property-user-edit-count-cnt-desc": "\"$1\" содержит число правок в записи о пространстве имён. Предоставляется расширением [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties].",
|
||||
"sesp-property-user-block": "Блокировка участника",
|
||||
"sesp-property-user-block-desc": "«$1» предоставляет список блоков, применяемых к пользователю. Предоставляется расширением [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties]",
|
||||
"sesp-property-user-right": "Право участника",
|
||||
|
|
|
@ -87,7 +87,7 @@ class HookRegistry {
|
|||
|
||||
$exemptionlist = [
|
||||
'___EUSER', '___CUSER', '___SUBP', '___REVID', '___VIEWS',
|
||||
'___NREV', '___NTREV', '___USEREDITCNT', '___EXIFDATA', '___NSID', '___NSNAME'
|
||||
'___NREV', '___NTREV', '___USEREDITCNT', '___EXIFDATA', '___NSID', '___NSNAME', '___NAMESPACE'
|
||||
];
|
||||
|
||||
// Exclude listed properties from indexing
|
||||
|
|
|
@ -143,6 +143,10 @@ class DispatchingPropertyAnnotator implements PropertyAnnotator {
|
|||
return new UserEditCountPropertyAnnotator( $appFactory );
|
||||
},
|
||||
|
||||
UserEditCountPerNsPropertyAnnotator::PROP_ID => function( $appFactory ) {
|
||||
return new UserEditCountPerNsPropertyAnnotator( $appFactory );
|
||||
},
|
||||
|
||||
UserBlockPropertyAnnotator::PROP_ID => function( $appFactory ) {
|
||||
return new UserBlockPropertyAnnotator( $appFactory );
|
||||
},
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
namespace SESP\PropertyAnnotators;
|
||||
|
||||
use SESP\PropertyAnnotator;
|
||||
use SESP\AppFactory;
|
||||
use SMW\DIProperty;
|
||||
use SMW\DIWikiPage;
|
||||
use SMW\SemanticData;
|
||||
use SMWContainerSemanticData as ContainerSemanticData;
|
||||
use SMWDataItem as DataItem;
|
||||
use SMWDIContainer as DIContainer;
|
||||
use SMWDINumber as DINumber;
|
||||
use User;
|
||||
use Wikimedia\IPUtils;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @ingroup SESP
|
||||
*
|
||||
* @license GNU GPL v2+
|
||||
*
|
||||
* @author Alexander Mashin
|
||||
*/
|
||||
class UserEditCountPerNsPropertyAnnotator implements PropertyAnnotator {
|
||||
/**
|
||||
* Predefined property IDs
|
||||
*/
|
||||
/** @const string PROP_ID ID for the whole record. */
|
||||
public const PROP_ID = '___USEREDITCNTNS';
|
||||
/** @const string PROP_NS_ID ID for the NS number in the record. */
|
||||
private const PROP_NS_ID = '___USEREDITCNTNS_NS';
|
||||
/** @const string PROP_CNT_ID ID for the edit count in the record. */
|
||||
private const PROP_CNT_ID = '___USEREDITCNTNS_CNT';
|
||||
|
||||
/** @var DIProperty $nsProperty DIProperty object for namespace number. */
|
||||
private static $nsProperty;
|
||||
/** @var DIProperty $editsProperty DIProperty object for number if edits in NS. */
|
||||
private static $editsProperty;
|
||||
|
||||
/** @var AppFactory $appFactory */
|
||||
private $appFactory;
|
||||
|
||||
/**
|
||||
* @param AppFactory $appFactory
|
||||
*/
|
||||
public function __construct( AppFactory $appFactory ) {
|
||||
$this->appFactory = $appFactory;
|
||||
self::$nsProperty = self::$nsProperty ?: new DIProperty( self::PROP_NS_ID );
|
||||
self::$editsProperty = self::$editsProperty ?: new DIProperty( self::PROP_CNT_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isAnnotatorFor( DIProperty $property ) {
|
||||
return $property->getKey() === self::PROP_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addAnnotation( DIProperty $property, SemanticData $semanticData ) {
|
||||
|
||||
$subject = $semanticData->getSubject();
|
||||
$title = $subject->getTitle();
|
||||
|
||||
if ( !$title->inNamespace( NS_USER ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $this->appFactory->newUserFromTitle( $title );
|
||||
|
||||
$id = null;
|
||||
$ip = null;
|
||||
if ( $user instanceof User && ( $count = $user->getEditCount() ) && is_int( $count ) ) {
|
||||
$id = $user->getID();
|
||||
} elseif ( IPUtils::isIPAddress( $title->getText() ) ) {
|
||||
$ip = $title->getText();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
$stats = $this->getEditsPerNs( $id, $ip );
|
||||
foreach ( $stats as $ns => $edits ) {
|
||||
$dataItem = self::container( $subject, $ns, $edits );
|
||||
if ( $dataItem instanceof DataItem ) {
|
||||
$semanticData->addPropertyObjectValue( $property, $dataItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form a DIContainer holding namespace and number of edits.
|
||||
*
|
||||
* @param DIWikiPage $subject User page
|
||||
* @param int $ns Namespace
|
||||
* @param int $edits Number of edits
|
||||
* @return DIContainer
|
||||
*/
|
||||
public static function container( DIWikiPage $subject, $ns, $edits ): DIContainer {
|
||||
$container = new ContainerSemanticData( new DIWikiPage(
|
||||
$subject->getDBkey(),
|
||||
$subject->getNamespace(),
|
||||
$subject->getInterwiki(),
|
||||
'_USEREDITCNTNS' . (string)$ns
|
||||
), false );
|
||||
$container->addPropertyObjectValue( self::$nsProperty, new DINumber( $ns ) );
|
||||
$container->addPropertyObjectValue( self::$editsProperty, new DINumber( $edits ) );
|
||||
return new DIContainer( $container );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $id User ID (0 for anonymous users)
|
||||
* @param string|null $ip Anonymous user's IP address
|
||||
* @return int[] An associative array NS number => revision count
|
||||
*/
|
||||
private function getEditsPerNs( $id, $ip ): array {
|
||||
$db = $this->appFactory->getConnection();
|
||||
$result = $db->select(
|
||||
[ 'revision', 'revision_actor_temp', 'actor', 'page' ], // FROM.
|
||||
[ 'ns' => 'page.page_namespace', 'edits' => 'COUNT(revision.rev_id)' ], // SELECT.
|
||||
$id === null ? [ 'actor.actor_name' => $ip ] : [ 'actor.actor_user' => $id ], // WHERE.
|
||||
__METHOD__,
|
||||
[ 'GROUP BY' => [ 'page.page_namespace' ] ], // GROUP BY.
|
||||
[ // JOIN conditions.
|
||||
'page' => [ 'INNER JOIN', ['page.page_id=revision.rev_page'] ],
|
||||
'revision_actor_temp' => [ 'INNER JOIN', ['revision_actor_temp.revactor_rev=revision.rev_id'] ],
|
||||
'actor' => [ 'INNER JOIN', ['actor.actor_id=revision_actor_temp.revactor_actor'] ]
|
||||
]
|
||||
);
|
||||
$records = [];
|
||||
foreach ( $result as $row ) {
|
||||
$records[$row->ns] = $row->edits;
|
||||
}
|
||||
return $records;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ use SESP\PropertyAnnotators\PageViewsPropertyAnnotator;
|
|||
use SESP\PropertyAnnotators\LocalPropertyAnnotator;
|
||||
use SESP\PropertyAnnotators\UserRegistrationDatePropertyAnnotator;
|
||||
use SESP\PropertyAnnotators\UserEditCountPropertyAnnotator;
|
||||
use SESP\PropertyAnnotators\UserEditCountPerNsPropertyAnnotator;
|
||||
use SESP\PropertyAnnotators\UserBlockPropertyAnnotator;
|
||||
use SESP\PropertyAnnotators\UserRightPropertyAnnotator;
|
||||
use SESP\PropertyAnnotators\UserGroupPropertyAnnotator;
|
||||
|
@ -163,6 +164,11 @@ class DispatchingPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase {
|
|||
UserEditCountPropertyAnnotator::class
|
||||
];
|
||||
|
||||
$provider[] = [
|
||||
UserEditCountPerNsPropertyAnnotator::PROP_ID,
|
||||
UserEditCountPerNsPropertyAnnotator::class
|
||||
];
|
||||
|
||||
$provider[] = [
|
||||
UserBlockPropertyAnnotator::PROP_ID,
|
||||
UserBlockPropertyAnnotator::class
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
<?php
|
||||
|
||||
namespace SESP\Tests\PropertyAnnotators;
|
||||
|
||||
use SESP\AppFactory;
|
||||
use SESP\PropertyAnnotators\UserEditCountPerNsPropertyAnnotator;
|
||||
use SMWDIContainer;
|
||||
use SMW\DIProperty;
|
||||
use SMW\DIWikiPage;
|
||||
use SMW\SemanticData;
|
||||
use User;
|
||||
use Wikimedia\Rdbms\Database;
|
||||
use Wikimedia\Rdbms\FakeResultWrapper;
|
||||
|
||||
/**
|
||||
* @covers \SESP\PropertyAnnotators\UserEditCountPerNsPropertyAnnotator
|
||||
* @group semantic-extra-special-properties
|
||||
* @group Databasa
|
||||
*
|
||||
* @license GNU GPL v2+
|
||||
*
|
||||
* @author Alexander Mashin
|
||||
*/
|
||||
class UserEditCountPerNsPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
/** @var DIProperty $property */
|
||||
private $property;
|
||||
/** @var AppFactory $appFactory */
|
||||
private $appFactory;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->appFactory = $this->getMockBuilder( AppFactory::class )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->property = new DIProperty( '___USEREDITCNTNS' );
|
||||
}
|
||||
|
||||
public function testIsAnnotatorFor() {
|
||||
$instance = new UserEditCountPerNsPropertyAnnotator( $this->appFactory );
|
||||
$this->assertTrue(
|
||||
$instance->isAnnotatorFor( $this->property )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getEditsPerNsProvider
|
||||
* @param int $id User ID.
|
||||
* @param string $ip Anonymous user's IP address.
|
||||
* @param array $expected Expected result.
|
||||
*/
|
||||
public function testGetEditsPerNs( $id, $ip, array $expected ) {
|
||||
// Mock the database.
|
||||
$db = $this->getMockBuilder( Database::class )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$fake = [];
|
||||
foreach ( $expected as $ns => $edits ) {
|
||||
$fake[] = [ 'ns' => $ns, 'edits' => $edits ];
|
||||
}
|
||||
$db->method( 'select' )
|
||||
->willReturn( new FakeResultWrapper( $fake ) );
|
||||
|
||||
// Mock the application factory (only for the mock database).
|
||||
$factory = $this->appFactory;
|
||||
$factory->method( 'getConnection' )
|
||||
->willReturn( $db );
|
||||
|
||||
$annotator = new UserEditCountPerNsPropertyAnnotator( $factory );
|
||||
// Expose the private method getEditsPerNs().
|
||||
$reflector = new \ReflectionObject( $annotator );
|
||||
$method = $reflector->getMethod( 'getEditsPerNs' );
|
||||
$method->setAccessible ( true );
|
||||
|
||||
// Call the tested method.
|
||||
$stats = $method->invokeArgs( $annotator, [ $id, $ip ] );
|
||||
|
||||
$this->assertEquals( $expected, $stats );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getEditsPerNsProvider(): array {
|
||||
$user = $this->getMockBuilder( User::class )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$id = $user->getId();
|
||||
|
||||
$provider = [];
|
||||
|
||||
// Registered user.
|
||||
$provider[] = [ $id, '', [ 0 => 42, 1 => 21 ] ];
|
||||
// Anonymous user.
|
||||
$provider[] = [ 0, '127.0.0.1', [ 0 => 84, 1 => 42 ] ];
|
||||
|
||||
return $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider containerProvider
|
||||
* @param int $ns Namespace
|
||||
* @param int $edits Number of edits
|
||||
* @param $expected
|
||||
*/
|
||||
public function testContainer( $ns, $edits ) {
|
||||
$subject = new DIWikiPage ( 'Test', NS_USER );
|
||||
|
||||
$annotator = new UserEditCountPerNsPropertyAnnotator( $this->appFactory );
|
||||
// Expose the private method container().
|
||||
$reflector = new \ReflectionObject( $annotator );
|
||||
$method = $reflector->getMethod( 'container' );
|
||||
$method->setAccessible ( true );
|
||||
$container = $method->invokeArgs( $annotator, [ $subject, $ns, $edits ] );
|
||||
|
||||
$this->assertInstanceOf( SMWDIContainer::class, $container, 'Container is not an instance of SMWDIContainer' );
|
||||
|
||||
$data = $container->getSemanticData();
|
||||
$properties = $data->getProperties();
|
||||
|
||||
$this->assertArrayHasKey( '___USEREDITCNTNS_NS', $properties, 'No namespace number in the container' );
|
||||
$nsValue = $data->getPropertyValues(new DIProperty( '___USEREDITCNTNS_NS' ) )[0]->getNumber();
|
||||
$this->assertEquals( $ns, $nsValue, 'Wrong namespace number' );
|
||||
|
||||
$this->assertArrayHasKey( '___USEREDITCNTNS_CNT', $properties, 'No edit cont in the container' );
|
||||
$editsValue = $data->getPropertyValues(new DIProperty( '___USEREDITCNTNS_CNT' ) )[0]->getNumber();
|
||||
$this->assertEquals( $edits, $editsValue, 'Wrong edit count' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function containerProvider (): array {
|
||||
return [
|
||||
[ 0, 42 ],
|
||||
[ 1, 21 ]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider addAnnotationProvider
|
||||
* @param string|null $name User name
|
||||
* @param string|null $ip Anonymous iser's I address
|
||||
* @param array $stats
|
||||
*/
|
||||
public function testAddAnnotation( $name, $ip, array $stats ) {
|
||||
$subject = new DIWikiPage ( $name ?: $ip, NS_USER );
|
||||
$semanticData = new SemanticData( $subject );
|
||||
|
||||
// Mock the database.
|
||||
$db = $this->getMockBuilder( Database::class )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$fake = [];
|
||||
foreach ( $stats as $ns => $edits ) {
|
||||
$fake[] = [ 'ns' => $ns, 'edits' => $edits ];
|
||||
}
|
||||
$db->method( 'select' )
|
||||
->willReturn( new FakeResultWrapper( $fake ), new FakeResultWrapper( $fake ) );
|
||||
|
||||
// Mock the application factory; only for the database.
|
||||
$factory = $this->appFactory;
|
||||
$factory->method( 'getConnection' )
|
||||
->willReturn( $db );
|
||||
|
||||
$user = $this->getMockBuilder( User::class )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$user->method( 'getId' )
|
||||
->willReturn( 1 );
|
||||
$user->expects( $this->once() )
|
||||
->method( 'getEditCount' )
|
||||
->willReturn( array_sum( $stats ) );
|
||||
|
||||
$factory = $this->appFactory;
|
||||
|
||||
$this->appFactory->expects( $this->once() )
|
||||
->method( 'newUserFromTitle' )
|
||||
->willReturn( $user );
|
||||
|
||||
$annotator = new UserEditCountPerNsPropertyAnnotator( $factory );
|
||||
|
||||
$annotator->addAnnotation( $this->property, $semanticData );
|
||||
|
||||
$properties = $semanticData->getProperties();
|
||||
|
||||
if ( count( $stats ) > 0 ) {
|
||||
$this->assertArrayHasKey( '___USEREDITCNTNS', $properties, 'No edit count record for the page' );
|
||||
|
||||
$records = $semanticData->getPropertyValues( new DIProperty( '___USEREDITCNTNS' ) );
|
||||
foreach ( $records as $record ) {
|
||||
$this->assertInstanceOf( DIWikiPage::class, $record );
|
||||
}
|
||||
$actual = [];
|
||||
foreach ( $semanticData->getSubSemanticData() as $subSemanticDatum ) {
|
||||
$properties = $subSemanticDatum->getProperties();
|
||||
$this->assertArrayHasKey( '___USEREDITCNTNS_NS', $properties, 'No namespace number for the record' );
|
||||
$ns = $subSemanticDatum->getPropertyValues( $properties['___USEREDITCNTNS_NS'] )[0]->getNumber();
|
||||
$this->assertArrayHasKey( '___USEREDITCNTNS_CNT', $properties, 'No edit count for the record' );
|
||||
$edits = $subSemanticDatum->getPropertyValues( $properties['___USEREDITCNTNS_CNT'] )[0]->getNumber();
|
||||
$actual[$ns] = $edits;
|
||||
}
|
||||
$this->assertEquals( $stats, $actual, 'Edit count arrays mismatch' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function addAnnotationProvider(): array {
|
||||
$provider = [];
|
||||
$provider[] = [ 'Test user', null, [ 0 => 42, 1 => 2, 8 => 7 ] ];
|
||||
$provider[] = [ null, '127.0.0.1', [ 0 => 84, 8 => 21 ] ];
|
||||
$provider[] = [ null, '127.0.0.1', [] ];
|
||||
return $provider;
|
||||
}
|
||||
}
|
||||
|
正在加载...
在新工单中引用