mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Thanks
synced 2024-12-18 17:30:31 +00:00
e483b844c9
I've moved all API classes into a separate folder, as I felt like grouping modules improves readability. APIs themselves had storage logic which I extracted and put in another folder. I was originally going with an interface to the storage to allow for other storage methods than log entries, but the code was too tightly coupled with it, so I've left that for another day. Added dependency injection for all services and used ServiceOptions for config vars. Bug: T337002 Change-Id: Ie8a1f435d635e1d0e1286f673bfe96cc4fdfe4fe
238 lines
6.5 KiB
PHP
238 lines
6.5 KiB
PHP
<?php
|
|
|
|
use Flow\Model\AbstractRevision;
|
|
use Flow\Model\PostRevision;
|
|
use Flow\Model\UUID;
|
|
use Flow\Model\Workflow;
|
|
|
|
/**
|
|
* Integration tests for the Thanks Flow api module
|
|
*
|
|
* @covers \MediaWiki\Extension\Thanks\Api\ApiFlowThank
|
|
*
|
|
* @group Thanks
|
|
* @group Database
|
|
* @group medium
|
|
* @group API
|
|
* @group Flow
|
|
*
|
|
* @author Benjamin Chen
|
|
*/
|
|
class ApiFlowThankIntegrationTest extends ApiTestCase {
|
|
|
|
/** @var PostRevision */
|
|
public $topic;
|
|
|
|
/** @var User */
|
|
public $meUser;
|
|
|
|
/** @var User */
|
|
public $otherUser;
|
|
|
|
/** @var PostRevision */
|
|
public $postByOtherUser;
|
|
|
|
/** @var PostRevision */
|
|
public $postByMe;
|
|
|
|
public function setUp(): void {
|
|
parent::setUp();
|
|
|
|
if ( !ExtensionRegistry::getInstance()->isLoaded( 'Flow' ) ) {
|
|
$this->markTestSkipped( 'Flow is not installed' );
|
|
}
|
|
|
|
// mock topic and post
|
|
if ( method_exists( $this, 'getTestUser' ) ) {
|
|
$this->meUser = $this->getMutableTestUser()->getUser();
|
|
$this->otherUser = $this->getMutableTestUser()->getUser();
|
|
} else {
|
|
$this->meUser = self::$users[ 'sysop' ]->getUser();
|
|
$this->otherUser = self::$users[ 'uploader' ]->getUser();
|
|
}
|
|
$this->topic = $this->generateObject();
|
|
$this->postByOtherUser = $this->generateObject( [
|
|
'tree_orig_user_id' => $this->otherUser->getId(),
|
|
'tree_parent_id' => $this->topic->getPostId()->getBinary(),
|
|
], [], 1 );
|
|
$this->postByMe = $this->generateObject( [
|
|
'tree_orig_user_id' => $this->meUser->getId(),
|
|
'tree_parent_id' => $this->topic->getPostId()->getBinary(),
|
|
], [], 1 );
|
|
|
|
// Set up mock classes in Container.
|
|
$mockLoader = $this->createMock( \Flow\Repository\RootPostLoader::class );
|
|
$mockLoader->expects( $this->any() )
|
|
->method( 'getWithRoot' )
|
|
->willReturnCallback(
|
|
function ( $postId ) {
|
|
switch ( $postId ) {
|
|
case $this->postByOtherUser->getPostId():
|
|
return [
|
|
'post' => $this->postByOtherUser,
|
|
'root' => $this->topic
|
|
];
|
|
|
|
case $this->postByMe->getPostId():
|
|
return [
|
|
'post' => $this->postByMe,
|
|
'root' => $this->topic
|
|
];
|
|
|
|
default:
|
|
return [ 'post' => null ];
|
|
}
|
|
}
|
|
);
|
|
|
|
$mockWorkflow = $this->createMock( Workflow::class );
|
|
$mockWorkflow->expects( $this->any() )
|
|
->method( 'getOwnerTitle' )
|
|
->willReturn( $this->createMock( Title::class ) );
|
|
$mockWorkflow->expects( $this->any() )
|
|
->method( 'getArticleTitle' )
|
|
->willReturn( $this->createMock( Title::class ) );
|
|
|
|
$mockStorage = $this->createMock( \Flow\Data\ManagerGroup::class );
|
|
|
|
$mockStorage->expects( $this->any() )
|
|
->method( 'get' )
|
|
->willReturn( $mockWorkflow );
|
|
|
|
$mockTemplating = $this->createMock( \Flow\Templating::class );
|
|
|
|
$mockTemplating->expects( $this->any() )
|
|
->method( 'getContent' )
|
|
->willReturn( 'test content' );
|
|
|
|
Flow\Container::reset();
|
|
$container = Flow\Container::getContainer();
|
|
$container[ 'loader.root_post' ] = $mockLoader;
|
|
$container[ 'storage' ] = $mockStorage;
|
|
$container[ 'templating' ] = $mockTemplating;
|
|
|
|
\DeferredUpdates::clearPendingUpdates();
|
|
}
|
|
|
|
public function testRequestWithoutToken() {
|
|
$this->expectApiErrorCode( 'missingparam' );
|
|
$this->doApiRequest( [
|
|
'action' => 'flowthank',
|
|
'postid' => UUID::create( '42' )->getAlphadecimal(),
|
|
] );
|
|
}
|
|
|
|
public function testInvalidRequest() {
|
|
$this->expectApiErrorCode( 'missingparam' );
|
|
$this->doApiRequestWithToken( [ 'action' => 'flowthank' ] );
|
|
}
|
|
|
|
public function testValidRequest() {
|
|
list( $result,, ) = $this->doApiRequestWithToken( [
|
|
'action' => 'flowthank',
|
|
'postid' => $this->postByOtherUser->getPostId()->getAlphadecimal(),
|
|
] );
|
|
$this->assertSuccess( $result );
|
|
}
|
|
|
|
public function testRequestWithInvalidId() {
|
|
$this->expectApiErrorCode( 'invalidpostid' );
|
|
$this->doApiRequestWithToken( [
|
|
'action' => 'flowthank',
|
|
'postid' => UUID::create( '42' )->getAlphadecimal(),
|
|
] );
|
|
}
|
|
|
|
public function testRequestWithOwnId() {
|
|
$this->expectApiErrorCode( 'invalidrecipient' );
|
|
$this->doApiRequestWithToken( [
|
|
'action' => 'flowthank',
|
|
'postid' => $this->postByMe->getPostId()->getAlphadecimal(),
|
|
], null, $this->meUser );
|
|
}
|
|
|
|
protected function assertSuccess( $result ) {
|
|
$this->assertSame( 1, $result[ 'result' ][ 'success' ] );
|
|
}
|
|
|
|
/**
|
|
* This method is obtained from Flow/tests/PostRevisionTestCase.php
|
|
*
|
|
* Returns an array, representing flow_revision & flow_tree_revision db
|
|
* columns.
|
|
*
|
|
* You can pass in arguments to override default data.
|
|
* With no arguments tossed in, default data (resembling a newly-created
|
|
* topic title) will be returned.
|
|
*
|
|
* @param array $row DB row data (only specify override columns)
|
|
* @return array
|
|
*/
|
|
protected function generateRow( array $row = [] ) {
|
|
$uuidPost = UUID::create();
|
|
$uuidRevision = UUID::create();
|
|
|
|
$user = $this->meUser;
|
|
$userId = $user->getId();
|
|
$userIp = null;
|
|
|
|
return $row + [
|
|
// flow_revision
|
|
'rev_id' => $uuidRevision->getBinary(),
|
|
'rev_type' => 'post',
|
|
'rev_user_id' => $userId,
|
|
'rev_user_ip' => $userIp,
|
|
'rev_user_wiki' => WikiMap::getCurrentWikiId(),
|
|
'rev_parent_id' => null,
|
|
'rev_flags' => 'html',
|
|
'rev_content' => 'test content',
|
|
'rev_change_type' => 'new-post',
|
|
'rev_mod_state' => AbstractRevision::MODERATED_NONE,
|
|
'rev_mod_user_id' => null,
|
|
'rev_mod_user_ip' => null,
|
|
'rev_mod_user_wiki' => null,
|
|
'rev_mod_timestamp' => null,
|
|
'rev_mod_reason' => null,
|
|
'rev_last_edit_id' => null,
|
|
'rev_edit_user_id' => null,
|
|
'rev_edit_user_ip' => null,
|
|
'rev_edit_user_wiki' => null,
|
|
|
|
// flow_tree_revision
|
|
'tree_rev_descendant_id' => $uuidPost->getBinary(),
|
|
'rev_type_id' => $uuidPost->getBinary(),
|
|
'tree_rev_id' => $uuidRevision->getBinary(),
|
|
'tree_orig_create_time' => wfTimestampNow(),
|
|
'tree_orig_user_id' => $userId,
|
|
'tree_orig_user_ip' => $userIp,
|
|
'tree_orig_user_wiki' => WikiMap::getCurrentWikiId(),
|
|
'tree_parent_id' => null,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* This method is obtained from Flow/tests/PostRevisionTestCase.php
|
|
*
|
|
* Returns a PostRevision object.
|
|
*
|
|
* You can pass in arguments to override default data.
|
|
* With no arguments tossed in, a default revision (resembling a newly-
|
|
* created topic title) will be returned.
|
|
*
|
|
* @param array $row DB row data (only specify override columns)
|
|
* @param array $children Array of child PostRevision objects
|
|
* @param int $depth Depth of the PostRevision object
|
|
* @return PostRevision
|
|
*/
|
|
protected function generateObject( array $row = [], $children = [], $depth = 0 ) {
|
|
$row = $this->generateRow( $row );
|
|
|
|
$revision = PostRevision::fromStorageRow( $row );
|
|
$revision->setChildren( $children );
|
|
$revision->setDepth( $depth );
|
|
|
|
return $revision;
|
|
}
|
|
|
|
}
|