wiki.techinc.nl/tests/phpunit/unit/includes/PingbackTest.php
Amir Sarabadani 8c6c387046 Pingback: Switch to use ICP instead of LB
Bug: T330641
Change-Id: Ia300c13947d7fec67d5bf19614744ae661cc89ad
2023-05-05 13:33:11 +02:00

169 lines
5.1 KiB
PHP

<?php
use MediaWiki\Http\HttpRequestFactory;
use MediaWiki\MainConfigNames;
use Psr\Log\NullLogger;
use Wikimedia\Rdbms\DBConnRef;
use Wikimedia\Rdbms\IConnectionProvider;
use Wikimedia\Rdbms\SelectQueryBuilder;
use Wikimedia\Timestamp\ConvertibleTimestamp;
/**
* @covers Pingback
*/
class PingbackTest extends MediaWikiUnitTestCase {
protected function setUp(): void {
parent::setUp();
ConvertibleTimestamp::setFakeTime( '20110401090000' );
}
/**
* @param DBConnRef $database
* @param HttpRequestFactory $httpRequestFactory
* @param bool $enablePingback
* @param BagOStuff|null $cache
*/
private function testRun(
DBConnRef $database,
$httpRequestFactory,
bool $enablePingback = true,
$cache = null
) {
$dbProvider = $this->createNoOpMock( IConnectionProvider::class, [ 'getPrimaryDatabase', 'getReplicaDatabase' ] );
$dbProvider->method( 'getPrimaryDatabase' )->willReturn( $database );
$dbProvider->method( 'getReplicaDatabase' )->willReturn( $database );
$pingback = new MockPingback(
new HashConfig( [ MainConfigNames::Pingback => $enablePingback ] ),
$dbProvider,
$cache ?? new HashBagOStuff(),
$httpRequestFactory,
new NullLogger()
);
// All of the assertions are in the expectations
$pingback->run();
}
public function testDisabled() {
// Scenario: Disabled
// Expect:
// - no db calls (no select, lock, or upsert)
// - no HTTP request
$this->testRun(
$this->createNoOpMock( DBConnRef::class ),
$this->createNoOpMock( HttpRequestFactory::class ),
false /* $enablePingback */
);
}
public function testCacheBusy() {
// Scenario:
// - enabled
// - table is empty
// - cache lock is unavailable
// Expect:
// - no db lock
// - no HTTP request
// - no db upsert for timestamp
$database = $this->createNoOpMock( DBConnRef::class, [ 'selectField', 'newSelectQueryBuilder' ] );
$database->expects( $this->once() )->method( 'selectField' )->willReturn( false );
$database->method( 'newSelectQueryBuilder' )->willReturnCallback( fn() => new SelectQueryBuilder( $database ) );
$cache = $this->createMock( BagOStuff::class );
$cache->method( 'add' )->willReturn( false );
$this->testRun(
$database,
$this->createNoOpMock( HttpRequestFactory::class ),
true, /* $enablePingback */
$cache
);
}
public function testDbBusy() {
// Scenario:
// - enabled
// - table is empty
// - cache lock is available
// - db lock is unavailable
// Expect:
// - no HTTP request
// - no db upsert for timestamp
$database = $this->createNoOpMock( DBConnRef::class, [ 'selectField', 'lock', 'newSelectQueryBuilder' ] );
$database->expects( $this->once() )->method( 'selectField' )->willReturn( false );
$database->expects( $this->once() )->method( 'lock' )->willReturn( false );
$database->method( 'newSelectQueryBuilder' )->willReturnCallback( fn() => new SelectQueryBuilder( $database ) );
$this->testRun(
$database,
$this->createNoOpMock( HttpRequestFactory::class )
);
}
/**
* @dataProvider provideMakePing
*/
public function testMakePing( $priorPing ) {
// Scenario:
// - enabled
// - table is either
// - empty ($priorPing is false)
// - has a ping from over a month ago ($piorPing)
// - cache lock and db lock are available
// Expect:
// - db lock acquired
// - HTTP POST request
// - db upsert for timestamp
$database = $this->createNoOpMock( DBConnRef::class, [ 'selectField', 'lock', 'upsert', 'newSelectQueryBuilder' ] );
$httpRequestFactory = $this->createNoOpMock( HttpRequestFactory::class, [ 'post' ] );
$database->expects( $this->once() )->method( 'selectField' )->willReturn( $priorPing );
$database->expects( $this->once() )->method( 'lock' )->willReturn( true );
$httpRequestFactory->expects( $this->once() )
->method( 'post' )
->with( 'https://www.mediawiki.org/beacon/event?%7B%22some%22%3A%22stuff%22%7D;' )
->willReturn( true );
$database->expects( $this->once() )->method( 'upsert' );
$database->method( 'newSelectQueryBuilder' )->willReturnCallback( fn() => new SelectQueryBuilder( $database ) );
$this->testRun(
$database,
$httpRequestFactory
);
}
public static function provideMakePing() {
yield 'No prior ping' => [ false ];
yield 'Prior ping from over a month ago' => [
ConvertibleTimestamp::convert( TS_UNIX, '20110301080000' )
];
}
public function testAfterRecentPing() {
// Scenario:
// - enabled
// - table contains a ping from one hour ago
// - cache lock and db lock are available
// Expect:
// - no db lock
// - no HTTP request
// - no db upsert for timestamp
$database = $this->createNoOpMock( DBConnRef::class, [ 'selectField', 'newSelectQueryBuilder' ] );
$database->expects( $this->once() )->method( 'selectField' )->willReturn(
ConvertibleTimestamp::convert( TS_UNIX, '20110401080000' )
);
$database->method( 'newSelectQueryBuilder' )->willReturnCallback( fn() => new SelectQueryBuilder( $database ) );
$this->testRun(
$database,
$this->createNoOpMock( HttpRequestFactory::class )
);
}
}
class MockPingback extends Pingback {
protected function getData(): array {
return [ 'some' => 'stuff' ];
}
}