/**
 	@covers ModerationApproveHook
 */
 public function testReupload()
 {
     $t = new ModerationTestsuite();
     $title = "Test image 1.png";
     # Upload the image first
     $t->loginAs($t->automoderated);
     $t->doTestUpload($title, __DIR__ . "/../resources/image640x50.png", "Text 1");
     # Now queue reupload for moderation
     $t->loginAs($t->unprivilegedUser);
     $error = $t->doTestUpload($title, __DIR__ . "/../resources/image100x100.png", "Text 2");
     $t->fetchSpecial();
     # Was the reupload queued for moderation?
     $this->assertEquals('(moderation-image-queued)', $error);
     # Is the data on Special:Moderation correct?
     $entry = $t->new_entries[0];
     $this->assertCount(1, $t->new_entries, "testReupload(): One upload was queued for moderation, but number of added entries in Pending folder isn't 1");
     $this->assertCount(0, $t->deleted_entries, "testReupload(): Something was deleted from Pending folder during the queueing");
     $this->assertEquals($t->lastEdit['User'], $entry->user);
     $this->assertEquals($t->lastEdit['Title'], $entry->title);
     # Does modaction=show display (moderation-diff-reupload) message?
     $this->assertRegExp('/\\(moderation-diff-reupload\\)/', $t->html->getMainText($entry->showLink), "testReupload(): (moderation-diff-reupload) not found in the output of modaction=show");
     # Can we approve this reupload?
     $this->assertNotNull($entry->approveLink, "testReupload(): Approve link not found");
     $t->html->loadFromURL($entry->approveLink);
     $this->assertRegExp('/\\(moderation-approved-ok: 1\\)/', $t->html->getMainText(), "testReupload(): Result page doesn't contain (moderation-approved-ok: 1)");
     # Has the file been reuploaded after the approval?
     $ret = $t->query(array('action' => 'query', 'prop' => 'imageinfo', 'iilimit' => 1, 'iiprop' => 'user|timestamp|comment|size|url|sha1', 'titles' => $entry->title));
     $ret_page = array_shift($ret['query']['pages']);
     $ii = $ret_page['imageinfo'][0];
     $this->assertEquals($t->lastEdit['User'], $ii['user']);
     $this->assertEquals($t->lastEdit['Text'], $ii['comment']);
     $this->assertEquals($t->lastEdit['SHA1'], $ii['sha1']);
     # Check image page history: performUpload(... $user) mistakenly
     # tags image reuploads as made by moderator (and not $user).
     # Was that fixed? (via ModerationApproveHook class)
     $ret = $t->query(array('action' => 'query', 'prop' => 'revisions', 'rvlimit' => 2, 'rvprop' => 'user|timestamp|comment|content|ids', 'titles' => $entry->title));
     # Because API orders entries by timestamp (up to seconds), and
     # it's likely that two uploads we just made will have the same
     # timestamp, they may be ordered incorrectly ([0] not being the
     # most recent). So find the entry with 'parentid' referring to
     # the other entry.
     $ret_page = array_shift($ret['query']['pages']);
     $rev1 = $ret_page['revisions'][0];
     $rev2 = $ret_page['revisions'][1];
     # Make $rev1 the most recent edit
     if ($rev2['parentid'] == $rev1['revid']) {
         $tmp = $rev1;
         $rev1 = $rev2;
         $rev2 = $tmp;
     }
     $this->assertEquals($rev2['revid'], $rev1['parentid'], "testReupload(): parentid of new revision doesn't match revid of the previous revision");
     $this->assertNotEquals($t->moderator->getName(), $rev1['user'], "testReupload(): Image reupload was attributed to the moderator who approved it (instead of the user who made the reupload)");
     $this->assertEquals($t->lastEdit['User'], $rev1['user'], "testReupload(): Image reupload wasn't attributed to the user who made it");
 }
 /**
 	@requires extension curl
 	@note Only cURL version of MWHttpRequest supports uploads.
 */
 public function testMissingStashedImage()
 {
     $t = new ModerationTestsuite();
     $t->loginAs($t->unprivilegedUser);
     $t->doTestUpload();
     $t->fetchSpecial();
     $entry = $t->new_entries[0];
     $dbw = wfGetDB(DB_MASTER);
     $row = $dbw->selectRow('moderation', array('mod_stash_key AS stash_key'), array('mod_id' => $entry->id), __METHOD__);
     $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();
     $stash->removeFileNoAuth($row->stash_key);
     $error = $t->html->getModerationError($entry->approveLink);
     $this->assertEquals('(moderation-missing-stashed-image)', $error);
 }
 /**
 	@covers ModerationActionShowImage
 	@requires extension curl
 	@note Only cURL version of MWHttpRequest supports uploads.
 */
 public function testShowUpload()
 {
     $t = new ModerationTestsuite();
     /*
     	When testing thumbnails, we check two images -
     	one smaller than thumbnail's width, one larger,
     	because they are handled differently.
     
     	First test is on image640x50.png (large image),
     	second on image100x100.png (smaller image).
     */
     $t->loginAs($t->unprivilegedUser);
     $error = $t->doTestUpload("Test image 1.png", __DIR__ . "/../resources/image640x50.png", "");
     $t->fetchSpecial();
     $entry = $t->new_entries[0];
     $url = $entry->showLink;
     $this->assertNotNull($url, "testShowUpload(): Show link not found");
     $title = $t->html->getTitle($url);
     $this->assertRegExp('/\\(difference-title: ' . $t->lastEdit['Title'] . '\\)/', $title, "testShowUpload(): Difference page has a wrong HTML title");
     $this->assertRegExp('/\\(moderation-diff-upload-notext\\)/', $t->html->getMainText(), "testShowUpload(): File was uploaded without description, but (moderation-diff-upload-notext) is not shown");
     # Is the image thumbnail displayed on the difference page?
     $images = $t->html->getElementsByTagName('img');
     $thumb = null;
     $src = null;
     foreach ($images as $img) {
         $src = $img->getAttribute('src');
         if (strpos($src, 'modaction=showimg') !== false) {
             $thumb = $img;
             break;
         }
     }
     $this->assertNotNull($thumb, "testShowUpload(): Thumbnail image not found");
     $this->assertRegExp('/thumb=1/', $src, "testShowUpload(): Thumbnail image URL doesn't contain thumb=1");
     # Is the image thumbnail inside the link to the full image?
     $link = $thumb->parentNode;
     $this->assertEquals('a', $link->nodeName, "testShowUpload(): Thumbnail image isn't encased in <a> tag");
     $href = $link->getAttribute('href');
     $this->assertEquals($entry->expectedShowImgLink(), $href, "testShowUpload(): Full image URL doesn't match expected URL");
     $nonthumb_src = str_replace('&thumb=1', '', $src);
     $this->assertEquals($nonthumb_src, $href, "testShowUpload(): Full image URL doesn't match thumbnail image URL without '&thumb=1'");
     $this->assertNotRegExp('/token=/', $href, "testShowUpload(): Token was found in the read-only ShowImage link");
     # Check the full image
     $req = $t->httpGet($href);
     $this->assertEquals('image/png', $req->getResponseHeader('Content-Type'), "testShowUpload(): Wrong Content-Type header from modaction=showimg");
     $this->assertEquals($t->lastEdit['SHA1'], sha1($req->getContent()), "testShowUpload(): Checksum of image downloaded via modaction=showimg doesn't match the checksum of original image");
     $this->assertEquals("inline;filename*=UTF-8''Test%20image%201.png", $req->getResponseHeader('Content-Disposition'), "testShowUpload(640x50): Wrong Content-Disposition header from modaction=showimg");
     # Check the thumbnail
     $req = $t->httpGet($src);
     # Content-type check will catch HTML errors from StreamFile
     $this->assertRegExp('/^image\\//', $req->getResponseHeader('Content-Type'), "testShowUpload(640x50): Wrong Content-Type header from modaction=showimg&thumb=1");
     $this->assertEquals("inline;filename*=UTF-8''" . ModerationActionShowImage::THUMB_WIDTH . "px-Test%20image%201.png", $req->getResponseHeader('Content-Disposition'), "testShowUpload(640x50): Wrong Content-Disposition header from modaction=showimg&thumb=1");
     list($original_width, $original_height) = getimagesize($t->lastEdit['Source']);
     list($width, $height) = getImageSizeFromString($req->getContent());
     $orig_ratio = round($original_width / $original_height, 2);
     $ratio = round($width / $height, 2);
     # As this image is larger than THUMB_WIDTH,
     # its thumbnail must be exactly THUMB_WIDTH wide.
     $this->assertEquals(ModerationActionShowImage::THUMB_WIDTH, $width, "testShowUpload(): Thumbnail's width doesn't match expected");
     $this->assertEquals($orig_ratio, $ratio, "testShowUpload(): Thumbnail's ratio doesn't match original");
     # Check the thumbnail of image smaller than THUMB_WIDTH.
     # Its thumbnail must be exactly the same size as original image.
     $t->loginAs($t->unprivilegedUser);
     $t->doTestUpload("Test image 2.png", __DIR__ . "/../resources/image100x100.png", "Non-empty image description");
     $t->fetchSpecial();
     $req = $t->httpGet($t->new_entries[0]->expectedShowImgLink());
     list($original_width, $original_height) = getimagesize($t->lastEdit['Source']);
     list($width, $height) = getImageSizeFromString($req->getContent());
     $this->assertRegExp('/^image\\//', $req->getResponseHeader('Content-Type'), "testShowUpload(100x100): Wrong Content-Type header from modaction=showimg&thumb=1");
     # No "px-" in the filename, because this thumbnail isn't different from the original file
     $this->assertEquals("inline;filename*=UTF-8''Test%20image%202.png", $req->getResponseHeader('Content-Disposition'), "testShowUpload(100x100): Wrong Content-Disposition header from modaction=showimg&thumb=1");
     $this->assertEquals($original_width, $width, "testShowUpload(): Original image is smaller than THUMB_WIDTH, but thumbnail width doesn't match the original width");
     $this->assertEquals($original_height, $height, "testShowUpload(): Original image is smaller than THUMB_WIDTH, but thumbnail height doesn't match the original height");
     # Ensure absence of (moderation-diff-upload-notext)
     $this->assertNotRegExp('/\\(moderation-diff-upload-notext\\)/', $t->html->getMainText($t->new_entries[0]->showLink), "testShowUpload(): File was uploaded with description, but (moderation-diff-upload-notext) is shown");
 }