Localisation updates from https://translatewiki.net.
[mediawiki.git] / tests / phpunit / maintenance / CategoryChangesAsRdfTest.php
blob818b8fe5fe28817cf5f56789bda1a61b137aaefb
1 <?php
3 use MediaWiki\MainConfigNames;
4 use MediaWiki\Title\Title;
5 use MediaWiki\Utils\MWTimestamp;
6 use Wikimedia\Rdbms\IDatabase;
7 use Wikimedia\Timestamp\ConvertibleTimestamp;
9 /**
10 * Tests for CategoryChangesAsRdf recent changes exporter.
11 * @covers \CategoryChangesAsRdf
12 * @group Database
14 class CategoryChangesAsRdfTest extends MediaWikiLangTestCase {
16 protected function setUp(): void {
17 parent::setUp();
18 $this->overrideConfigValues( [
19 MainConfigNames::Server => 'http://acme.test',
20 MainConfigNames::CanonicalServer => 'http://acme.test',
21 ] );
24 public static function provideCategoryData() {
25 return [
26 'delete category' => [
27 __DIR__ . "/../data/categoriesrdf/delete.sparql",
28 'getDeletedCatsIterator',
29 'handleDeletes',
31 (object)[ 'rc_title' => 'Test', 'rc_cur_id' => 1, '_processed' => 1 ],
32 (object)[ 'rc_title' => 'Test 2', 'rc_cur_id' => 2, '_processed' => 2 ],
35 'move category' => [
36 __DIR__ . "/../data/categoriesrdf/move.sparql",
37 'getMovedCatsIterator',
38 'handleMoves',
40 (object)[
41 'rc_title' => 'Test',
42 'rc_cur_id' => 4,
43 'page_title' => 'MovedTo',
44 'page_namespace' => NS_CATEGORY,
45 '_processed' => 4,
46 'pp_propname' => null,
47 'cat_pages' => 10,
48 'cat_subcats' => 2,
49 'cat_files' => 1,
51 (object)[
52 'rc_title' => 'MovedTo',
53 'rc_cur_id' => 4,
54 'page_title' => 'MovedAgain',
55 'page_namespace' => NS_CATEGORY,
56 'pp_propname' => 'hiddencat',
57 'cat_pages' => 10,
58 'cat_subcats' => 2,
59 'cat_files' => 1,
61 (object)[
62 'rc_title' => 'Test 2',
63 'rc_cur_id' => 5,
64 'page_title' => 'AlsoMoved',
65 'page_namespace' => NS_CATEGORY,
66 '_processed' => 5,
67 'pp_propname' => null,
68 'cat_pages' => 10,
69 'cat_subcats' => 2,
70 'cat_files' => 1,
72 (object)[
73 'rc_title' => 'Test 3',
74 'rc_cur_id' => 6,
75 'page_title' => 'MovedOut',
76 'page_namespace' => NS_MAIN,
77 'pp_propname' => null,
78 'cat_pages' => 10,
79 'cat_subcats' => 2,
80 'cat_files' => 1,
82 (object)[
83 'rc_title' => 'Test 4',
84 'rc_cur_id' => 7,
85 'page_title' => 'Already Done',
86 'page_namespace' => NS_CATEGORY,
87 'pp_propname' => null,
88 'cat_pages' => 10,
89 'cat_subcats' => 2,
90 'cat_files' => 1,
93 [ 7 => true ],
95 'restore deleted category' => [
96 __DIR__ . "/../data/categoriesrdf/restore.sparql",
97 'getRestoredCatsIterator',
98 'handleRestores',
100 (object)[
101 'rc_title' => 'Restored cat',
102 'rc_cur_id' => 10,
103 '_processed' => 10,
104 'pp_propname' => null,
105 'cat_pages' => 10,
106 'cat_subcats' => 2,
107 'cat_files' => 1,
109 (object)[
110 'rc_title' => 'Restored again',
111 'rc_cur_id' => 10,
112 'pp_propname' => null,
113 'cat_pages' => 10,
114 'cat_subcats' => 2,
115 'cat_files' => 1,
117 (object)[
118 'rc_title' => 'Already seen',
119 'rc_cur_id' => 11,
120 'pp_propname' => null,
121 'cat_pages' => 10,
122 'cat_subcats' => 2,
123 'cat_files' => 1,
126 [ 11 => true ],
128 'new page' => [
129 __DIR__ . "/../data/categoriesrdf/new.sparql",
130 'getNewCatsIterator',
131 'handleAdds',
133 (object)[
134 'rc_title' => 'New category',
135 'rc_cur_id' => 20,
136 '_processed' => 20,
137 'pp_propname' => null,
138 'cat_pages' => 10,
139 'cat_subcats' => 2,
140 'cat_files' => 1,
142 (object)[
143 'rc_title' => 'Новая категория 😃',
144 'rc_cur_id' => 21,
145 '_processed' => 21,
146 'pp_propname' => 'hiddencat',
147 'cat_pages' => 10,
148 'cat_subcats' => 2,
149 'cat_files' => 1,
151 (object)[
152 'rc_title' => 'Processed already',
153 'rc_cur_id' => 22,
156 [ 22 => true ],
158 'edit category' => [
159 __DIR__ . "/../data/categoriesrdf/edit.sparql",
160 'getChangedCatsIterator',
161 'handleEdits',
163 (object)[
164 'rc_title' => 'Changed category',
165 'rc_cur_id' => 30,
166 '_processed' => 30,
167 'pp_propname' => null,
168 'cat_pages' => 10,
169 'cat_subcats' => 2,
170 'cat_files' => 1,
172 (object)[
173 'rc_title' => 'Changed again',
174 'rc_cur_id' => 30,
175 'pp_propname' => null,
176 'cat_pages' => 12,
177 'cat_subcats' => 2,
178 'cat_files' => 1,
180 (object)[
181 'rc_title' => 'Processed already',
182 'rc_cur_id' => 31,
183 'pp_propname' => null,
184 'cat_pages' => 10,
185 'cat_subcats' => 2,
186 'cat_files' => 1,
189 [ 31 => true ],
191 // TODO: not sure how to test categorization changes, it uses the database select...
196 * Mock category links iterator.
197 * @param IDatabase $dbr
198 * @param array $ids
199 * @return array
201 public function getCategoryLinksIterator( $dbr, array $ids ) {
202 $res = [];
203 foreach ( $ids as $pageid ) {
204 $res[] = (object)[ 'cl_from' => $pageid, 'cl_to' => "Parent of $pageid" ];
206 return $res;
210 * @dataProvider provideCategoryData
211 * @param string $testFileName Name of the test, defines filename with expected results.
212 * @param string $iterator Iterator method name to mock
213 * @param string $handler Handler method to call
214 * @param array $result Result to be returned from mock iterator
215 * @param array $preProcessed List of pre-processed items
217 public function testSparqlUpdate( $testFileName, $iterator, $handler, $result,
218 array $preProcessed = [] ) {
219 $dumpScript =
220 $this->getMockBuilder( CategoryChangesAsRdf::class )
221 ->onlyMethods( [ $iterator, 'getCategoryLinksIterator' ] )
222 ->getMock();
224 $dumpScript->method( 'getCategoryLinksIterator' )
225 ->willReturnCallback( [ $this, 'getCategoryLinksIterator' ] );
227 $dumpScript->expects( $this->once() )
228 ->method( $iterator )
229 ->willReturn( [ $result ] );
231 $ref = new ReflectionObject( $dumpScript );
232 $processedProperty = $ref->getProperty( 'processed' );
233 $processedProperty->setAccessible( true );
234 $processedProperty->setValue( $dumpScript, $preProcessed );
236 $output = fopen( "php://memory", "w+b" );
237 $dbr = $this->getDb();
238 /** @var CategoryChangesAsRdf $dumpScript */
239 $dumpScript->initialize();
240 $dumpScript->getRdf();
241 $dumpScript->$handler( $dbr, $output );
243 rewind( $output );
244 $sparql = stream_get_contents( $output );
245 $this->assertFileContains( $testFileName, $sparql );
247 $processed = $processedProperty->getValue( $dumpScript );
248 $expectedProcessed = array_keys( $preProcessed );
249 foreach ( $result as $row ) {
250 if ( isset( $row->_processed ) ) {
251 $this->assertArrayHasKey( $row->_processed, $processed,
252 "ID {$row->_processed} was not processed!" );
253 $expectedProcessed[] = $row->_processed;
256 $this->assertSame( $expectedProcessed, array_keys( $processed ),
257 'Processed array has wrong items' );
260 public function testUpdateTs() {
261 $dumpScript = new CategoryChangesAsRdf();
262 $dumpScript->initialize();
263 $update = $dumpScript->updateTS( 1503620949 );
264 $outFile = __DIR__ . '/../data/categoriesrdf/updatets.txt';
265 $this->assertFileContains( $outFile, $update );
268 public function testCategorization() {
269 $this->overrideConfigValue(
270 MainConfigNames::RCWatchCategoryMembership,
271 true
273 $start = new MWTimestamp( "2020-07-31T10:00:00" );
274 $end = new MWTimestamp( "2020-07-31T10:01:00" );
275 ConvertibleTimestamp::setFakeTime( "2020-07-31T10:00:00" );
276 $l1 = Title::makeTitle( NS_CATEGORY, __CLASS__ . "_L1" );
277 $l2 = Title::makeTitle( NS_CATEGORY, __CLASS__ . "_L2" );
278 $pageInL2 = Title::makeTitle( NS_CATEGORY, __CLASS__ . "_Page" );
279 $this->editPage( $l1, "" );
280 $this->editPage( $l2, "[[{$l1->getPrefixedText()}]]" );
281 $this->editPage( $pageInL2, "[[{$l2->getPrefixedText()}]]" );
283 $output = fopen( "php://memory", "w+b" );
285 $this->runJobs( [], [
286 'type' => 'categoryMembershipChange'
287 ] );
289 $dbr = $this->getDb();
290 $categoryChangesAsRdf = new CategoryChangesAsRdf();
292 $ref = new ReflectionObject( $categoryChangesAsRdf );
293 $startTSProp = $ref->getProperty( 'startTS' );
294 $startTSProp->setAccessible( true );
295 $startTSProp->setValue( $categoryChangesAsRdf, $start->getTimestamp() );
296 $endTSProp = $ref->getProperty( 'endTS' );
297 $endTSProp->setAccessible( true );
298 $endTSProp->setValue( $categoryChangesAsRdf, $end->getTimestamp() );
300 $categoryChangesAsRdf->initialize();
301 $categoryChangesAsRdf->getRdf();
302 $categoryChangesAsRdf->handleCategorization( $dbr, $output );
303 rewind( $output );
304 $sparql = stream_get_contents( $output );
305 $outFile = __DIR__ . '/../data/categoriesrdf/categorization.txt';
306 $this->assertFileContains( $outFile, $sparql );