summaryrefslogtreecommitdiff
path: root/tests/phpunit/includes/filerepo/StoreBatchTest.php
blob: b33c1bbb398620b502dcf4e6af6dbea38fae17df (plain)
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
<?php

/**
 * @group FileRepo
 * @group medium
 */
class StoreBatchTest extends MediaWikiTestCase {

	protected $createdFiles;
	protected $date;
	/** @var FileRepo */
	protected $repo;

	protected function setUp() {
		global $wgFileBackends;
		parent::setUp();

		# Forge a FSRepo object to not have to rely on local wiki settings
		$tmpPrefix = wfTempDir() . '/storebatch-test-' . time() . '-' . mt_rand();
		if ( $this->getCliArg( 'use-filebackend=' ) ) {
			$name = $this->getCliArg( 'use-filebackend=' );
			$useConfig = array();
			foreach ( $wgFileBackends as $conf ) {
				if ( $conf['name'] == $name ) {
					$useConfig = $conf;
				}
			}
			$useConfig['name'] = 'local-testing'; // swap name
			$class = $useConfig['class'];
			$backend = new $class( $useConfig );
		} else {
			$backend = new FSFileBackend( array(
				'name' => 'local-testing',
				'lockManager' => 'nullLockManager',
				'containerPaths' => array(
					'unittests-public' => "{$tmpPrefix}-public",
					'unittests-thumb' => "{$tmpPrefix}-thumb",
					'unittests-temp' => "{$tmpPrefix}-temp",
					'unittests-deleted' => "{$tmpPrefix}-deleted",
				)
			) );
		}
		$this->repo = new FileRepo( array(
			'name' => 'unittests',
			'backend' => $backend
		) );

		$this->date = gmdate( "YmdHis" );
		$this->createdFiles = array();
	}

	protected function tearDown() {
		$this->repo->cleanupBatch( $this->createdFiles ); // delete files
		foreach ( $this->createdFiles as $tmp ) { // delete dirs
			$tmp = $this->repo->resolveVirtualUrl( $tmp );
			while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) {
				$this->repo->getBackend()->clean( array( 'dir' => $tmp ) );
			}
		}
		parent::tearDown();
	}

	/**
	 * Store a file or virtual URL source into a media file name.
	 *
	 * @param $originalName string The title of the image
	 * @param $srcPath string The filepath or virtual URL
	 * @param $flags integer Flags to pass into repo::store().
	 * @return FileRepoStatus
	 */
	private function storeit( $originalName, $srcPath, $flags ) {
		$hashPath = $this->repo->getHashPath( $originalName );
		$dstRel = "$hashPath{$this->date}!$originalName";
		$dstUrlRel = $hashPath . $this->date . '!' . rawurlencode( $originalName );

		$result = $this->repo->store( $srcPath, 'temp', $dstRel, $flags );
		$result->value = $this->repo->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel;
		$this->createdFiles[] = $result->value;

		return $result;
	}

	/**
	 * Test storing a file using different flags.
	 *
	 * @param $fn string The title of the image
	 * @param $infn string The name of the file (in the filesystem)
	 * @param $otherfn string The name of the different file (in the filesystem)
	 * @param $fromrepo bool 'true' if we want to copy from a virtual URL out of the Repo.
	 */
	private function storecohort( $fn, $infn, $otherfn, $fromrepo ) {
		$f = $this->storeit( $fn, $infn, 0 );
		$this->assertTrue( $f->isOK(), 'failed to store a new file' );
		$this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
		$this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
		if ( $fromrepo ) {
			$f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE );
			$infn = $f->value;
		}
		// This should work because we're allowed to overwrite
		$f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE );
		$this->assertTrue( $f->isOK(), 'We should be allowed to overwrite' );
		$this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
		$this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
		// This should fail because we're overwriting.
		$f = $this->storeit( $fn, $infn, 0 );
		$this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite' );
		$this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
		$this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
		// This should succeed because we're overwriting the same content.
		$f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE_SAME );
		$this->assertTrue( $f->isOK(), 'We should be able to overwrite the same content' );
		$this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
		$this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
		// This should fail because we're overwriting different content.
		if ( $fromrepo ) {
			$f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE );
			$otherfn = $f->value;
		}
		$f = $this->storeit( $fn, $otherfn, FileRepo::OVERWRITE_SAME );
		$this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite different content' );
		$this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
		$this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
	}

	/**
	 * @covers FileRepo::store
	 */
	public function teststore() {
		global $IP;
		$this->storecohort( "Test1.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", false );
		$this->storecohort( "Test2.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", true );
	}
}