~ubuntu-branches/ubuntu/quantal/gallery2/quantal

« back to all changes in this revision

Viewing changes to modules/core/test/phpunit/FileSystemTest.class

  • Committer: Bazaar Package Importer
  • Author(s): Michael C. Schultheiss
  • Date: 2005-11-29 15:50:12 UTC
  • Revision ID: james.westby@ubuntu.com-20051129155012-wtophp03lu01kdgl
Tags: upstream-2.0.2
ImportĀ upstreamĀ versionĀ 2.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/*
 
3
 * $RCSfile: FileSystemTest.class,v $
 
4
 *
 
5
 * Gallery - a web based photo album viewer and editor
 
6
 * Copyright (C) 2000-2005 Bharat Mediratta
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or (at
 
11
 * your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful, but
 
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 
21
 */
 
22
/**
 
23
 * @version $Revision: 1.16 $ $Date: 2005/08/23 03:49:33 $
 
24
 * @package GalleryCore
 
25
 * @subpackage PHPUnit
 
26
 * @author Bharat Mediratta <bharat@menalto.com>
 
27
 */
 
28
 
 
29
/**
 
30
 * Test FileSystem functionality
 
31
 *
 
32
 * @package GalleryCore
 
33
 * @subpackage PHPUnit
 
34
 *
 
35
 */
 
36
class FileSystemTest extends GalleryTestCase {
 
37
 
 
38
    function FileSystemTest($methodName) {
 
39
        $this->GalleryTestCase($methodName);
 
40
    }
 
41
 
 
42
    function setUp() {
 
43
        global $gallery;
 
44
 
 
45
        parent::setUp();
 
46
 
 
47
        $iterations = 3;
 
48
        $parentId = $this->_getRootId();
 
49
        for ($i = 0; $i < $iterations; $i++) {
 
50
            $gallery->guaranteeTimeLimit(5);
 
51
 
 
52
            list ($ret, $this->_albums[$i]) = $this->_createRandomAlbum($parentId);
 
53
            if ($ret->isError()) {
 
54
                print $ret->getAsHtml();
 
55
                return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
56
            }
 
57
 
 
58
            $parentId = $this->_albums[$i]->getId();
 
59
        }
 
60
 
 
61
        /* delete the top album */
 
62
        $this->_markForCleanup($this->_albums[0]);
 
63
    }
 
64
 
 
65
    function testFetchItemIdByPath() {
 
66
        $path = '/';
 
67
        for ($i = 0; $i < sizeof($this->_albums); $i++) {
 
68
            $path .= $this->_albums[$i]->getPathComponent() . '/';
 
69
        }
 
70
        list ($ret, $id) = GalleryCoreApi::fetchItemIdByPath($path);
 
71
        if ($ret->isError()) {
 
72
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
73
        }
 
74
 
 
75
        $this->assertEquals($this->_albums[2]->getId(), $id);
 
76
    }
 
77
 
 
78
    function testFetchLogicalPath() {
 
79
        list ($ret, $root) = GalleryCoreApi::loadEntitiesById($this->_getRootId());
 
80
        if ($ret->isError()) {
 
81
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
82
        }
 
83
 
 
84
        list ($ret, $logicalPath) = $root->fetchLogicalPath();
 
85
        if ($ret->isError()) {
 
86
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
87
        }
 
88
 
 
89
        $this->assertEquals('/', $logicalPath);
 
90
 
 
91
        list ($ret, $logicalPath) = $this->_albums[1]->fetchLogicalPath();
 
92
        if ($ret->isError()) {
 
93
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
94
        }
 
95
 
 
96
        $this->assertEquals(sprintf('/%s/%s/',
 
97
                                    $this->_albums[0]->getPathComponent(),
 
98
                                    $this->_albums[1]->getPathComponent()),
 
99
                            $logicalPath);
 
100
 
 
101
        list ($ret, $item) = $this->_createRandomDataItem($this->_albums[1]->getId());
 
102
        if ($ret->isError()) {
 
103
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
104
        }
 
105
 
 
106
        list ($ret, $logicalPath) = $item->fetchLogicalPath();
 
107
        if ($ret->isError()) {
 
108
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
109
        }
 
110
 
 
111
        $this->assertEquals(sprintf('/%s/%s/%s',
 
112
                                    $this->_albums[0]->getPathComponent(),
 
113
                                    $this->_albums[1]->getPathComponent(),
 
114
                                    $item->getPathComponent()),
 
115
                            $logicalPath);
 
116
    }
 
117
 
 
118
    function testFetchPath() {
 
119
        global $gallery;
 
120
        $originalPlatform = $gallery->getPlatform();
 
121
        $gallery->_platform = new FileSystemTestPlatform('/');
 
122
        $originalAlbumsDir = $gallery->getConfig('data.gallery.albums');
 
123
        $gallery->setConfig('data.gallery.albums', '');
 
124
 
 
125
        list ($ret, $path) = $this->_albums[1]->fetchPath();
 
126
        if ($ret->isError()) {
 
127
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
128
        }
 
129
 
 
130
        $this->assertEquals(sprintf('%s/%s/',
 
131
                                    $this->_albums[0]->getPathComponent(),
 
132
                                    $this->_albums[1]->getPathComponent()),
 
133
                            $path);
 
134
 
 
135
        $gallery->_platform = new FileSystemTestPlatform('\\');
 
136
 
 
137
        list ($ret, $path) = $this->_albums[1]->fetchPath();
 
138
        if ($ret->isError()) {
 
139
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
140
        }
 
141
 
 
142
        $this->assertEquals(sprintf('%s\\%s\\',
 
143
                                    $this->_albums[0]->getPathComponent(),
 
144
                                    $this->_albums[1]->getPathComponent()),
 
145
                            $path);
 
146
 
 
147
        $gallery->_platform = $originalPlatform;
 
148
        $gallery->setConfig('data.gallery.albums', $originalAlbumsDir);
 
149
    }
 
150
 
 
151
    function testFetchChildIdByPathComponent() {
 
152
        list ($ret, $id) = GalleryCoreApi::fetchChildIdByPathComponent(
 
153
            $this->_albums[1]->getId(), $this->_albums[2]->getPathComponent());
 
154
 
 
155
        $this->assertEquals($this->_albums[2]->getId(), $id);
 
156
    }
 
157
 
 
158
    /**
 
159
     * Verify that creating a second filesystem entity with the same path as
 
160
     * an existing one throws a collision error.
 
161
     */
 
162
    function testCreateCollision() {
 
163
        global $gallery;
 
164
 
 
165
        list ($ret, $lockId) = GalleryCoreApi::acquireWriteLock($this->_albums[0]->getId());
 
166
        if ($ret->isError()) {
 
167
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
168
        }
 
169
 
 
170
        for ($i = 0; $i < 3; $i++) {
 
171
            $entity[$i] = new GalleryFileSystemEntity();
 
172
            $ret = $entity[$i]->create($this->_albums[0]->getId(), 'valid_path.jpg');
 
173
            if ($ret->isError()) {
 
174
                return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
175
            }
 
176
 
 
177
            $ret = $entity[$i]->save();
 
178
            if ($ret->isError()) {
 
179
                return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
180
            }
 
181
 
 
182
            if ($i > 0) {
 
183
                $this->assertEquals(sprintf('valid_path_%03d.jpg', $i),
 
184
                                    $entity[$i]->getPathComponent());
 
185
            }
 
186
        }
 
187
 
 
188
        $ret = GalleryCoreApi::releaseLocks($lockId);
 
189
        if ($ret->isError()) {
 
190
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
191
        }
 
192
    }
 
193
 
 
194
    function testMoveCollision() {
 
195
        list ($ret, $lockId) = GalleryCoreApi::acquireWriteLock(array($this->_albums[0]->getId(),
 
196
                                                                      $this->_albums[1]->getId(),
 
197
                                                                      $this->_albums[2]->getId()));
 
198
        if ($ret->isError()) {
 
199
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
200
        }
 
201
 
 
202
        $ret = $this->_albums[1]->rename('foo');
 
203
        if ($ret->isError()) {
 
204
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
205
        }
 
206
        $ret = $this->_albums[1]->save();
 
207
 
 
208
        $ret = $this->_albums[1]->move($this->_albums[0]->getId());
 
209
        if ($ret->isError()) {
 
210
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
211
        }
 
212
 
 
213
        $ret = $this->_albums[2]->rename('foo');
 
214
        if ($ret->isError()) {
 
215
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
216
        }
 
217
        $ret = $this->_albums[2]->move($this->_albums[0]->getId());
 
218
        if ($ret->isError()) {
 
219
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
220
        }
 
221
 
 
222
        $this->assertEquals('foo_001', $this->_albums[2]->getPathComponent());
 
223
 
 
224
        $ret = GalleryCoreApi::releaseLocks($lockId);
 
225
        if ($ret->isError()) {
 
226
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
227
        }
 
228
    }
 
229
 
 
230
    /*
 
231
     * Test the platform->rename($old,$newpath) call of FileSystemEntity::move.
 
232
     * The call should have legal platformspecific slashes.
 
233
     *
 
234
     * It tests not the functionality of FileSystemEntity::move, it only tests if
 
235
     * FileSystemEntity::move uses valid paths (no incorrect slashes) in its call to the platform
 
236
     * specific "rename($oldname, $newname)" function.
 
237
     */
 
238
    function testMoveRenameCall() {
 
239
        global $gallery;
 
240
        /* Use a windows alike mock platfrom */
 
241
        $originalPlatform = $gallery->getPlatform();
 
242
        $gallery->_platform = new FileSystemTestPlatformForRename('\\');
 
243
        /* Acquire the write locks */
 
244
        list ($ret, $lockId) = GalleryCoreApi::acquireWriteLock(array($this->_albums[0]->getId(),
 
245
                                                                      $this->_albums[1]->getId(),
 
246
                                                                      $this->_albums[2]->getId()));
 
247
        if ($ret->isError()) {
 
248
            $gallery->_platform = $originalPlatform;
 
249
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
250
        }
 
251
        /* Execute the move command, success expected*/
 
252
        $ret = $this->_albums[2]->move($this->_albums[0]->getId());
 
253
        if ($ret->isError()) {
 
254
            $gallery->_platform = $originalPlatform;
 
255
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
256
        }
 
257
        /* Now change the mock platform to a unix alike system */
 
258
        $gallery->_platform = new FileSystemTestPlatformForRename('/');
 
259
        /* And move again album 1 (back, but all virtual move command), success expected */
 
260
        $ret = $this->_albums[2]->move($this->_albums[1]->getId());
 
261
        if ($ret->isError()) {
 
262
            $gallery->_platform = $originalPlatform;
 
263
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
264
        }
 
265
 
 
266
        $gallery->_platform = $originalPlatform;
 
267
        $ret = GalleryCoreApi::releaseLocks($lockId);
 
268
        if ($ret->isError()) {
 
269
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
270
        }
 
271
        $gallery->_platform = $originalPlatform;
 
272
    }
 
273
 
 
274
    function testGetLegalPathComponent() {
 
275
        /* Simple case, no collision */
 
276
        list ($ret, $path) =
 
277
            GalleryCoreApi::getLegalPathComponent('testpath', $this->_albums[2]->getId());
 
278
        if ($ret->isError()) {
 
279
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
280
        }
 
281
        $this->assertEquals('testpath', $path, 'no collision');
 
282
 
 
283
        /* Collision with existing album: _001 gets added */
 
284
        list ($ret, $path) = GalleryCoreApi::getLegalPathComponent(
 
285
                             $this->_albums[1]->getPathComponent(), $this->_albums[0]->getId());
 
286
        if ($ret->isError()) {
 
287
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
288
        }
 
289
        $this->assertEquals($this->_albums[1]->getPathComponent() . '_001', $path,
 
290
                            'avoid collision');
 
291
 
 
292
        /* Ignore self-collision */
 
293
        list ($ret, $path) = GalleryCoreApi::getLegalPathComponent(
 
294
                             $this->_albums[1]->getPathComponent(), $this->_albums[0]->getId(),
 
295
                             $this->_albums[1]->getId());
 
296
        if ($ret->isError()) {
 
297
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
298
        }
 
299
        $this->assertEquals($this->_albums[1]->getPathComponent(), $path, 'ignore self-collision');
 
300
 
 
301
        /* Filename with some invalid path characters and .php extension */
 
302
        list ($ret, $path) = GalleryCoreApi::getLegalPathComponent(
 
303
                             'my/test&file!.php', $this->_albums[1]->getId());
 
304
        if ($ret->isError()) {
 
305
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
306
        }
 
307
        $this->assertEquals('my_test_file__php', $path, 'a few bad characters');
 
308
 
 
309
        /* Filename of all extended characters, except extension: we rewrite with date-filename */
 
310
        list ($ret, $path) = GalleryCoreApi::getLegalPathComponent(
 
311
                             "\xe6\xaa\x94\xe6\xa1\x88.jpg", $this->_albums[1]->getId());
 
312
        if ($ret->isError()) {
 
313
            return $this->failWithStatus($ret->wrap(__FILE__, __LINE__));
 
314
        }
 
315
        $this->assertEquals(strftime('%Y%m%d') . '.jpg', $path, 'extended characters');
 
316
    }
 
317
}
 
318
 
 
319
/**
 
320
 * Mock platform
 
321
 *
 
322
 * @package GalleryCore
 
323
 * @subpackage PHPUnit
 
324
 */
 
325
class FileSystemTestPlatform {
 
326
    function FileSystemTestPlatform($separator) {
 
327
        $this->_separator = $separator;
 
328
    }
 
329
 
 
330
    function getDirectorySeparator() {
 
331
        return $this->_separator;
 
332
    }
 
333
}
 
334
 
 
335
 
 
336
/**
 
337
 * Mock platform for the rename method
 
338
 *
 
339
 * Implements all methods used by FileSystemEntity::move()
 
340
 *
 
341
 * @package GalleryCore
 
342
 * @subpackage PHPUnit
 
343
 */
 
344
class FileSystemTestPlatformForRename extends GalleryPlatform {
 
345
    function FileSystemTestPlatformForRename($separator) {
 
346
        $this->_separator = $separator;
 
347
    }
 
348
 
 
349
    function getDirectorySeparator() {
 
350
        return $this->_separator;
 
351
    }
 
352
 
 
353
    /**
 
354
     * Rename a file/dir
 
355
     *
 
356
     * Override rename method for the testMoveRenamePaths
 
357
     * It won't rename the item actually, just check if the paths contain no invalid slashs
 
358
     */
 
359
    function rename($oldname, $newname) {
 
360
        global $gallery;
 
361
        if ($gallery->getDebug()) {
 
362
            $gallery->debug("rename($oldname, $newname)");
 
363
        }
 
364
        /*
 
365
         * Check if there are some platform specific slash problems in the paths
 
366
         * The platform should be forced to have a '\' separator and thus, no '/'
 
367
         * should be found in the paths.
 
368
         */
 
369
        /*
 
370
         * Strip off the g2data path part of the $oldname and $newname, because they are platform
 
371
         * specific and correct anyway.
 
372
         */
 
373
        $oldname = substr($oldname,
 
374
                          strlen($gallery->getConfig('data.gallery.albums')));
 
375
        $newname = substr($newname,
 
376
                          strlen($gallery->getConfig('data.gallery.albums')));
 
377
        /* We had a case where FileSystemEntity::move produced a rename(a,b) path b, which had a
 
378
         * separator too much and this additional seapartor wasn't even platform specific, but
 
379
         * just '/'. The consequence: ->move() didn't work on windows xp.
 
380
         * What we do here is: Force a windows xp separator '\' and check if no '/' separator is
 
381
         * found in the paths. nested ifs are not necessary, but more readable.
 
382
         * And we don't accept // or \\ in our paths. Most probably this won't be an issue, but
 
383
         * it's good to create exactly the paths that we actually indend to create.
 
384
         */
 
385
        if ($this->_separator == '\\') {
 
386
            if (strrchr($oldname, '/') || strrchr($newname, '/')
 
387
                    || strpos($oldname, '\\\\') || strpos($newname, '\\\\')) {
 
388
                return false;
 
389
            }
 
390
        }  else if ($this->_separator == '/') {
 
391
            if (strrchr($oldname, '\\') || strrchr($newname, '\\')
 
392
                    || strpos($oldname, '//') || strpos($newname, '//')) {
 
393
                return false;
 
394
            }
 
395
        }
 
396
 
 
397
        /* Now pretend the rename command was successful */
 
398
        return true;
 
399
    }
 
400
}
 
401
?>