1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
<?php
namespace MediaWiki\Tests\Api;
use Exception;
use MediaWiki\MainConfigNames;
use MediaWiki\Page\File\FileDeleteForm;
use MediaWiki\Title\Title;
use Wikimedia\FileBackend\FSFile\FSFile;
use Wikimedia\Rdbms\IDBAccessObject;
/**
* Abstract class to support upload tests
*/
abstract class ApiUploadTestCase extends ApiTestCase {
/**
* @since 1.37
* @var array Used to fake $_FILES in tests and given to MediaWiki\Request\FauxRequest
*/
protected $requestDataFiles = [];
/**
* Fixture -- run before every test
*/
protected function setUp(): void {
parent::setUp();
$this->overrideConfigValue( MainConfigNames::EnableUploads, true );
$this->clearFakeUploads();
}
/**
* Helper function -- remove files and associated articles by Title
*
* @param Title $title Title to be removed
*
* @return bool
*/
public function deleteFileByTitle( $title ) {
if ( $title->exists() ) {
$file = $this->getServiceContainer()->getRepoGroup()
->findFile( $title, [ 'ignoreRedirect' => true ] );
$noOldArchive = ""; // yes this really needs to be set this way
$comment = "removing for test";
$restrictDeletedVersions = false;
$user = $this->getTestSysop()->getUser();
$status = FileDeleteForm::doDelete(
$title,
$file,
$noOldArchive,
$comment,
$restrictDeletedVersions,
$user
);
if ( !$status->isGood() ) {
return false;
}
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
$this->deletePage( $page, "removing for test" );
}
return !( $title && $title instanceof Title && $title->exists( IDBAccessObject::READ_LATEST ) );
}
/**
* Helper function -- remove files and associated articles with a particular filename
*
* @param string $fileName Filename to be removed
*
* @return bool
*/
public function deleteFileByFileName( $fileName ) {
return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) );
}
/**
* Helper function -- given a file on the filesystem, find matching
* content in the db (and associated articles) and remove them.
*
* @param string $filePath Path to file on the filesystem
*
* @return bool
*/
public function deleteFileByContent( $filePath ) {
$hash = FSFile::getSha1Base36FromPath( $filePath );
$dupes = $this->getServiceContainer()->getRepoGroup()->findBySha1( $hash );
$success = true;
foreach ( $dupes as $dupe ) {
$success &= $this->deleteFileByTitle( $dupe->getTitle() );
}
return $success;
}
/**
* Fake an upload by dumping the file into temp space, and adding info to $_FILES.
* (This is what PHP would normally do).
*
* @param string $fieldName Name this would have in the upload form
* @param string $fileName Name to title this
* @param string $type MIME type
* @param string $filePath Path where to find file contents
*
* @throws Exception
* @return bool
*/
protected function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) {
$tmpName = $this->getNewTempFile();
if ( !is_file( $filePath ) ) {
$this->fail( "$filePath doesn't exist!" );
}
if ( !copy( $filePath, $tmpName ) ) {
$this->fail( "couldn't copy $filePath to $tmpName" );
}
clearstatcache();
$size = filesize( $tmpName );
if ( $size === false ) {
$this->fail( "couldn't stat $tmpName" );
}
$this->requestDataFiles[$fieldName] = [
'name' => $fileName,
'type' => $type,
'tmp_name' => $tmpName,
'size' => $size,
'error' => UPLOAD_ERR_OK,
];
return true;
}
public function fakeUploadChunk( $fieldName, $fileName, $type, &$chunkData ) {
$tmpName = $this->getNewTempFile();
// copy the chunk data to temp location:
if ( !file_put_contents( $tmpName, $chunkData ) ) {
$this->fail( "couldn't copy chunk data to $tmpName" );
}
clearstatcache();
$size = filesize( $tmpName );
if ( $size === false ) {
$this->fail( "couldn't stat $tmpName" );
}
$this->requestDataFiles[$fieldName] = [
'name' => $fileName,
'type' => $type,
'tmp_name' => $tmpName,
'size' => $size,
'error' => UPLOAD_ERR_OK,
];
}
/** @inheritDoc */
protected function buildFauxRequest( $params, $session ) {
$request = parent::buildFauxRequest( $params, $session );
$request->setUploadData( $this->requestDataFiles );
return $request;
}
/**
* Remove traces of previous fake uploads
*/
public function clearFakeUploads() {
$this->requestDataFiles = [];
}
}
/** @deprecated class alias since 1.42 */
class_alias( ApiUploadTestCase::class, 'ApiUploadTestCase' );
|