summaryrefslogtreecommitdiff
path: root/tests/phpunit/includes/filerepo/StoreBatchTest.php
blob: 9cc2efbfe933876faf7fd56a417549266aef1ab1 (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
135
136
137
138
139
140
141
142
143
144
145
146
<?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['lockManager'] = LockManagerGroup::singleton()->get( $useConfig['lockManager'] );
			unset( $useConfig['fileJournal'] );
			$useConfig['name'] = 'local-testing'; // swap name
			$class = $useConfig['class'];
			$backend = new $class( $useConfig );
		} else {
			$backend = new FSFileBackend( array(
				'name' => 'local-testing',
				'wikiId' => wfWikiID(),
				'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 string $originalName The title of the image
	 * @param string $srcPath The filepath or virtual URL
	 * @param int $flags 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 string $fn The title of the image
	 * @param string $infn The name of the file (in the filesystem)
	 * @param string $otherfn The name of the different file (in the filesystem)
	 * @param bool $fromrepo '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/tests/phpunit/data/filerepo/wiki.png",
			"$IP/tests/phpunit/data/filerepo/video.png",
			false
		);
		$this->storecohort(
			"Test2.png",
			"$IP/tests/phpunit/data/filerepo/wiki.png",
			"$IP/tests/phpunit/data/filerepo/video.png",
			true
		);
	}
}