Projet

Général

Profil

Paste
Télécharger (52,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / file_entity / file_entity.test @ ca0757b9

1
<?php
2

    
3
/**
4
 * @file
5
 * Test integration for the file_entity module.
6
 */
7

    
8
class FileEntityTestHelper extends DrupalWebTestCase {
9
  protected $files = array();
10

    
11
  function setUp() {
12
    $modules = func_get_args();
13
    if (isset($modules[0]) && is_array($modules[0])) {
14
      $modules = $modules[0];
15
    }
16
    $modules[] = 'file_entity';
17
    parent::setUp($modules);
18
  }
19

    
20
  protected function setUpFiles($defaults = array()) {
21
    // Populate defaults array.
22
    $defaults += array(
23
      'uid' => 1,
24
      'status' => FILE_STATUS_PERMANENT,
25
    );
26

    
27
    $types = array('text', 'image');
28
    foreach ($types as $type) {
29
      foreach ($this->drupalGetTestFiles($type) as $file) {
30
        foreach ($defaults as $key => $value) {
31
          $file->$key = $value;
32
        }
33
        $this->files[$type][] = file_save($file);
34
      }
35
    }
36
  }
37

    
38
  protected function createFileType($overrides = array()) {
39
    $type = new stdClass();
40
    $type->type = 'test';
41
    $type->label = "Test";
42
    $type->description = '';
43
    $type->mimetypes = array('image/jpeg', 'image/gif', 'image/png', 'image/tiff');
44

    
45
    foreach ($overrides as $k => $v) {
46
      $type->$k = $v;
47
    }
48

    
49
    file_type_save($type);
50
    return $type;
51
  }
52

    
53
  /**
54
   * Helper for testFileEntityPrivateDownloadAccess() test.
55
   *
56
   * Defines several cases for accesing private files.
57
   *
58
   * @return array
59
   *   Array of associative arrays, each one having the next keys:
60
   *   - "message" string with the assertion message.
61
   *   - "permissions" array of permissions or NULL for anonymous user.
62
   *   - "expect" expected HTTP response code.
63
   *   - "owner" Optional boolean indicating if the user is a file owner.
64
   */
65
  protected function getPrivateDownloadAccessCases() {
66
    return array(
67
      array(
68
        'message' => "File owners cannot download their own files unless they are granted the 'view own private files' permission.",
69
        'permissions' => array(),
70
        'expect' => 403,
71
        'owner' => TRUE,
72
      ),
73
      array(
74
        'message' => "File owners can download their own files as they have been granted the 'view own private files' permission.",
75
        'permissions' => array('view own private files'),
76
        'expect' => 200,
77
        'owner' => TRUE,
78
      ),
79
      array(
80
        'message' => "Anonymous users cannot download private files.",
81
        'permissions' => NULL,
82
        'expect' => 403,
83
      ),
84
      array(
85
        'message' => "Authenticated users cannot download each other's private files.",
86
        'permissions' => array(),
87
        'expect' => 403,
88
      ),
89
      array(
90
        'message' => "Users who can view public files are not able to download private files.",
91
        'permissions' => array('view files'),
92
        'expect' => 403,
93
      ),
94
      array(
95
        'message' => "Users who bypass file access can download any file.",
96
        'permissions' => array('bypass file access'),
97
        'expect' => 200,
98
      ),
99
    );
100
  }
101

    
102
  /**
103
   * Retrieves a sample file of the specified type.
104
   */
105
  function getTestFile($type_name, $size = NULL) {
106
    // Get a file to upload.
107
    $file = current($this->drupalGetTestFiles($type_name, $size));
108

    
109
    // Add a filesize property to files as would be read by file_load().
110
    $file->filesize = filesize($file->uri);
111

    
112
    return $file;
113
  }
114

    
115
  /**
116
   * Get a file from the database based on its filename.
117
   *
118
   * @param $filename
119
   *   A file filename, usually generated by $this->randomName().
120
   * @param $reset
121
   *   (optional) Whether to reset the internal file_load() cache.
122
   *
123
   * @return
124
   *   A file object matching $filename.
125
   */
126
  function getFileByFilename($filename, $reset = FALSE) {
127
    $files = file_load_multiple(array(), array('filename' => $filename), $reset);
128
    // Load the first file returned from the database.
129
    $returned_file = reset($files);
130
    return $returned_file;
131
  }
132

    
133
  protected function createFileEntity($settings = array()) {
134
    $file = new stdClass();
135

    
136
    // Populate defaults array.
137
    $settings += array(
138
      'filepath' => 'Файл для тестирования ' . $this->randomName(), // Prefix with non-latin characters to ensure that all file-related tests work with international filenames.
139
      'filemime' => 'text/plain',
140
      'uid' => 1,
141
      'timestamp' => REQUEST_TIME,
142
      'status' => FILE_STATUS_PERMANENT,
143
      'contents' => "file_put_contents() doesn't seem to appreciate empty strings so let's put in some data.",
144
      'scheme' => file_default_scheme(),
145
      'type' => NULL,
146
    );
147

    
148
    $filepath = $settings['scheme'] . '://' . $settings['filepath'];
149

    
150
    file_put_contents($filepath, $settings['contents']);
151
    $this->assertTrue(is_file($filepath), t('The test file exists on the disk.'), 'Create test file');
152

    
153
    $file = new stdClass();
154
    $file->uri = $filepath;
155
    $file->filename = drupal_basename($file->uri);
156
    $file->filemime = $settings['filemime'];
157
    $file->uid = $settings['uid'];
158
    $file->timestamp = $settings['timestamp'];
159
    $file->filesize = filesize($file->uri);
160
    $file->status = $settings['status'];
161
    $file->type = $settings['type'];
162

    
163
    // The file type is used as a bundle key, and therefore, must not be NULL.
164
    if (!isset($file->type)) {
165
      $file->type = FILE_TYPE_NONE;
166
    }
167

    
168
    // If the file isn't already assigned a real type, determine what type should
169
    // be assigned to it.
170
    if ($file->type === FILE_TYPE_NONE) {
171
      $type = file_get_type($file);
172
      if (isset($type)) {
173
        $file->type = $type;
174
      }
175
    }
176

    
177
    // Write the record directly rather than calling file_save() so we don't
178
    // invoke the hooks.
179
    $this->assertNotIdentical(drupal_write_record('file_managed', $file), FALSE, t('The file was added to the database.'), 'Create test file');
180

    
181
    return $file;
182
  }
183

    
184
  /**
185
   * Overrides DrupalWebTestCase::drupalGetToken() to support the hash salt.
186
   *
187
   * @todo Remove when http://drupal.org/node/1555862 is fixed in core.
188
   */
189
  protected function drupalGetToken($value = '') {
190
    $private_key = drupal_get_private_key();
191
    return drupal_hmac_base64($value, $this->session_id . $private_key . drupal_get_hash_salt());
192
  }
193
}
194

    
195
class FileEntityFileTypeClassificationTestCase extends DrupalWebTestCase {
196
  public static function getInfo() {
197
    return array(
198
      'name' => 'File entity classification',
199
      'description' => 'Test existing file entity classification functionality.',
200
      'group' => 'File entity',
201
    );
202
  }
203

    
204
  function setUp() {
205
    parent::setUp();
206
  }
207

    
208
  /**
209
   * Get the file type of a given file.
210
   *
211
   * @param $file
212
   *   A file object.
213
   *
214
   * @return
215
   *   The file's file type as a string.
216
   */
217
  function getFileType($file) {
218
    $type = db_select('file_managed', 'fm')
219
      ->fields('fm', array('type'))
220
      ->condition('fid', $file->fid, '=')
221
      ->execute()
222
      ->fetchAssoc();
223

    
224
    return $type;
225
  }
226

    
227
  /**
228
   * Test that existing files are properly classified by file type.
229
   */
230
  function testFileTypeClassification() {
231
    // Get test text and image files.
232
    $file = current($this->drupalGetTestFiles('text'));
233
    $text_file = file_save($file);
234
    $file = current($this->drupalGetTestFiles('image'));
235
    $image_file = file_save($file);
236

    
237
    // Enable file entity which adds adds a file type property to files and
238
    // queues up existing files for classification.
239
    module_enable(array('file_entity'));
240

    
241
    // Existing files have yet to be classified and should have an undefined
242
    // file type.
243
    $file_type = $this->getFileType($text_file);
244
    $this->assertEqual($file_type['type'], 'undefined', t('The text file has an undefined file type.'));
245
    $file_type = $this->getFileType($image_file);
246
    $this->assertEqual($file_type['type'], 'undefined', t('The image file has an undefined file type.'));
247

    
248
    // The classification queue is processed during cron runs. Run cron to
249
    // trigger the classification process.
250
    $this->cronRun();
251

    
252
    // The classification process should assign a file type to any file whose
253
    // MIME type is assigned to a file type. Check to see if each file was
254
    // assigned a proper file type.
255
    $file_type = $this->getFileType($text_file);
256
    $this->assertEqual($file_type['type'], 'document', t('The text file was properly assigned the Document file type.'));
257
    $file_type = $this->getFileType($image_file);
258
    $this->assertEqual($file_type['type'], 'image', t('The image file was properly assigned the Image file type.'));
259
  }
260
}
261

    
262
class FileEntityUnitTestCase extends FileEntityTestHelper {
263
  public static function getInfo() {
264
    return array(
265
      'name' => 'File entity unit tests',
266
      'description' => 'Test basic file entity functionality.',
267
      'group' => 'File entity',
268
    );
269
  }
270

    
271
  function setUp() {
272
    parent::setUp();
273
    $this->setUpFiles();
274
  }
275

    
276
  /**
277
   * Regression tests for core issue http://drupal.org/node/1239376.
278
   */
279
  function testMimeTypeMappings() {
280
    $tests = array(
281
      'public://test.ogg' => 'audio/ogg',
282
      'public://test.mkv' => 'video/x-m4v',
283
      'public://test.mka' => 'audio/x-matroska',
284
      'public://test.mkv' => 'video/x-matroska',
285
      'public://test.webp' => 'image/webp',
286
    );
287
    foreach ($tests as $input => $expected) {
288
      $this->assertEqual(file_get_mimetype($input), $expected);
289
    }
290
  }
291

    
292
  function testFileEntity() {
293
    $file = reset($this->files['text']);
294

    
295
    // Test entity ID, revision ID, and bundle.
296
    $ids = entity_extract_ids('file', $file);
297
    $this->assertIdentical($ids, array($file->fid, NULL, 'document'));
298

    
299
    // Test the entity URI callback.
300
    $uri = entity_uri('file', $file);
301
    $this->assertEqual($uri['path'], "file/{$file->fid}");
302
  }
303

    
304
  function testImageDimensions() {
305
    $files = array();
306
    $text_fids = array();
307
    // Test hook_file_insert().
308
    // Files have been saved as part of setup (in FileEntityTestHelper::setUpFiles).
309
    foreach ($this->files['image'] as $file) {
310
      $files[$file->fid] = $file->metadata;
311
      $this->assertTrue(isset($file->metadata['height']), 'Image height retrieved on file_save() for an image file.');
312
      $this->assertTrue(isset($file->metadata['width']), 'Image width retrieved on file_save() for an image file.');
313
    }
314
    foreach ($this->files['text'] as $file) {
315
      $text_fids[] = $file->fid;
316
      $this->assertFalse(isset($file->metadata['height']), 'No image height retrieved on file_save() for an text file.');
317
      $this->assertFalse(isset($file->metadata['width']), 'No image width retrieved on file_save() for an text file.');
318
    }
319

    
320
    // Test hook_file_load().
321
    // Clear the cache and load fresh files objects to test file_load behavior.
322
    entity_get_controller('file')->resetCache();
323
    foreach (file_load_multiple(array_keys($files)) as $file) {
324
      $this->assertTrue(isset($file->metadata['height']), 'Image dimensions retrieved on file_load() for an image file.');
325
      $this->assertTrue(isset($file->metadata['width']), 'Image dimensions retrieved on file_load() for an image file.');
326
      $this->assertEqual($file->metadata['height'], $files[$file->fid]['height'], 'Loaded image height is equal to saved image height.');
327
      $this->assertEqual($file->metadata['width'], $files[$file->fid]['width'], 'Loaded image width is equal to saved image width.');
328
    }
329
    foreach (file_load_multiple($text_fids) as $file) {
330
      $this->assertFalse(isset($file->metadata['height']), 'No image height retrieved on file_load() for an text file.');
331
      $this->assertFalse(isset($file->metadata['width']), 'No image width retrieved on file_load() for an text file.');
332
    }
333

    
334
    // Test hook_file_update().
335
    // Load the first image file and resize it.
336
    $image_files = array_keys($files);
337
    $file = file_load(reset($image_files));
338
    $image = image_load($file->uri);
339
    image_resize($image, $file->metadata['width'] / 2, $file->metadata['height'] / 2);
340
    image_save($image);
341
    file_save($file);
342
    $this->assertEqual($file->metadata['height'], $files[$file->fid]['height'] / 2, 'Image file height updated by file_save().');
343
    $this->assertEqual($file->metadata['width'], $files[$file->fid]['width'] / 2, 'Image file width updated by file_save().');
344
    // Clear the cache and reload the file.
345
    entity_get_controller('file')->resetCache();
346
    $file = file_load($file->fid);
347
    $this->assertEqual($file->metadata['height'], $files[$file->fid]['height'] / 2, 'Updated image height retrieved by file_load().');
348
    $this->assertEqual($file->metadata['width'], $files[$file->fid]['width'] / 2, 'Updated image width retrieved by file_load().');
349

    
350
    //Test hook_file_delete().
351
    file_delete($file, TRUE);
352
    $this->assertFalse(db_query('SELECT COUNT(*) FROM {file_metadata} WHERE fid = :fid', array(':fid' => 'fid'))->fetchField(), 'Row deleted in {file_dimensions} on file_delete().');
353
  }
354
}
355

    
356
class FileEntityEditTestCase extends FileEntityTestHelper {
357
  protected $web_user;
358
  protected $admin_user;
359

    
360
  public static function getInfo() {
361
    return array(
362
      'name' => 'File entity edit',
363
      'description' => 'Create a file and test file edit functionality.',
364
      'group' => 'File entity',
365
    );
366
  }
367

    
368
  function setUp() {
369
    parent::setUp();
370

    
371
    $this->web_user = $this->drupalCreateUser(array('edit own document files', 'create files'));
372
    $this->admin_user = $this->drupalCreateUser(array('bypass file access', 'administer files'));
373
  }
374

    
375
  /**
376
   * Check file edit functionality.
377
   */
378
  function testFileEntityEdit() {
379
    $this->drupalLogin($this->web_user);
380

    
381
    $test_file = $this->getTestFile('text');
382
    $name_key = "filename";
383

    
384
    // Create file to edit.
385
    $edit = array();
386
    $edit['files[upload]'] = drupal_realpath($test_file->uri);
387
    $this->drupalPost('file/add', $edit, t('Next'));
388
    if ($this->xpath('//input[@name="scheme"]')) {
389
      $this->drupalPost(NULL, array(), t('Next'));
390
    }
391

    
392
    // Check that the file exists in the database.
393
    $file = $this->getFileByFilename($test_file->filename);
394
    $this->assertTrue($file, t('File found in database.'));
395

    
396
    // Check that "edit" link points to correct page.
397
    $this->clickLink(t('Edit'));
398
    $edit_url = url("file/$file->fid/edit", array('absolute' => TRUE));
399
    $actual_url = $this->getURL();
400
    $this->assertEqual($edit_url, $actual_url, t('On edit page.'));
401

    
402
    // Check that the name field is displayed with the correct value.
403
    $active = '<span class="element-invisible">' . t('(active tab)') . '</span>';
404
    $link_text = t('!local-task-title!active', array('!local-task-title' => t('Edit'), '!active' => $active));
405
    $this->assertText(strip_tags($link_text), 0, t('Edit tab found and marked active.'));
406
    $this->assertFieldByName($name_key, $file->filename, t('Name field displayed.'));
407

    
408
    // The user does not have "delete" permissions so no delete button should be found.
409
    $this->assertNoFieldByName('op', t('Delete'), 'Delete button not found.');
410

    
411
    // Edit the content of the file.
412
    $edit = array();
413
    $edit[$name_key] = $this->randomName(8);
414
    // Stay on the current page, without reloading.
415
    $this->drupalPost(NULL, $edit, t('Save'));
416

    
417
    // Check that the name field is displayed with the updated values.
418
    $this->assertText($edit[$name_key], t('Name displayed.'));
419
  }
420

    
421
  /**
422
   * Check changing file associated user fields.
423
   */
424
  function testFileEntityAssociatedUser() {
425
    $this->drupalLogin($this->admin_user);
426

    
427
    // Create file to edit.
428
    $test_file = $this->getTestFile('text');
429
    $name_key = "filename";
430
    $edit = array();
431
    $edit['files[upload]'] = drupal_realpath($test_file->uri);
432
    $this->drupalPost('file/add', $edit, t('Next'));
433

    
434
    // Check that the file was associated with the currently logged in user.
435
    $file = $this->getFileByFilename($test_file->filename);
436
    $this->assertIdentical($file->uid, $this->admin_user->uid, 'File associated with admin user.');
437

    
438
    // Try to change the 'associated user' field to an invalid user name.
439
    $edit = array(
440
      'name' => 'invalid-name',
441
    );
442
    $this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save'));
443
    $this->assertText('The username invalid-name does not exist.');
444

    
445
    // Change the associated user field to an empty string, which should assign
446
    // association to the anonymous user (uid 0).
447
    $edit['name'] = '';
448
    $this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save'));
449
    $file = file_load($file->fid);
450
    $this->assertIdentical($file->uid, '0', 'File associated with anonymous user.');
451

    
452
    // Change the associated user field to another user's name (that is not
453
    // logged in).
454
    $edit['name'] = $this->web_user->name;
455
    $this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save'));
456
    $file = file_load($file->fid);
457
    $this->assertIdentical($file->uid, $this->web_user->uid, 'File associated with normal user.');
458

    
459
    // Check that normal users cannot change the associated user information.
460
    $this->drupalLogin($this->web_user);
461
    $this->drupalGet('file/' . $file->fid . '/edit');
462
    $this->assertNoFieldByName('name');
463
  }
464
}
465

    
466
class FileEntityCreationTestCase extends FileEntityTestHelper {
467
  public static function getInfo() {
468
    return array(
469
      'name' => 'File entity creation',
470
      'description' => 'Create a file and test saving it.',
471
      'group' => 'File entity',
472
    );
473
  }
474

    
475
  function setUp() {
476
    parent::setUp();
477

    
478
    $web_user = $this->drupalCreateUser(array('create files', 'edit own document files'));
479
    $this->drupalLogin($web_user);
480
  }
481

    
482
  /**
483
   * Create a "document" file and verify its consistency in the database.
484
   */
485
  function testFileEntityCreation() {
486
    $test_file = $this->getTestFile('text');
487
    // Create a file.
488
    $edit = array();
489
    $edit['files[upload]'] = drupal_realpath($test_file->uri);
490
    $this->drupalPost('file/add', $edit, t('Next'));
491

    
492
    // Step 2: Scheme selection
493
    if ($this->xpath('//input[@name="scheme"]')) {
494
      $this->drupalPost(NULL, array(), t('Next'));
495
    }
496

    
497
    // Check that the document file has been uploaded.
498
    $this->assertRaw(t('!type %name was uploaded.', array('!type' => 'Document', '%name' => $test_file->filename)), t('Document file uploaded.'));
499

    
500
    // Check that the file exists in the database.
501
    $file = $this->getFileByFilename($test_file->filename);
502
    $this->assertTrue($file, t('File found in database.'));
503
  }
504
}
505

    
506
/**
507
 * Test file administration page functionality.
508
 */
509
class FileEntityAdminTestCase extends FileEntityTestHelper {
510
  public static function getInfo() {
511
    return array(
512
      'name' => 'File administration',
513
      'description' => 'Test file administration page functionality.',
514
      'group' => 'File entity',
515
    );
516
  }
517

    
518
  function setUp() {
519
    parent::setUp();
520

    
521
    // Remove the "view files" permission which is set
522
    // by default for all users so we can test this permission
523
    // correctly.
524
    $roles = user_roles();
525
    foreach ($roles as $rid => $role) {
526
      user_role_revoke_permissions($rid, array('view files'));
527
    }
528

    
529
    $this->admin_user = $this->drupalCreateUser(array('administer files', 'bypass file access'));
530
    $this->base_user_1 = $this->drupalCreateUser(array('administer files'));
531
    $this->base_user_2 = $this->drupalCreateUser(array('administer files', 'view own private files'));
532
    $this->base_user_3 = $this->drupalCreateUser(array('administer files', 'view private files'));
533
    $this->base_user_4 = $this->drupalCreateUser(array('administer files', 'edit any document files', 'delete any document files', 'edit any image files', 'delete any image files'));
534
  }
535

    
536
  /**
537
   * Tests that the table sorting works on the files admin pages.
538
   */
539
  function testFilesAdminSort() {
540
    $this->drupalLogin($this->admin_user);
541
    $i = 0;
542
    foreach (array('dd', 'aa', 'DD', 'bb', 'cc', 'CC', 'AA', 'BB') as $prefix) {
543
      $this->createFileEntity(array('filepath' => $prefix . $this->randomName(6), 'timestamp' => $i));
544
      $i++;
545
    }
546

    
547
    // Test that the default sort by file_managed.timestamp DESC actually fires properly.
548
    $files_query = db_select('file_managed', 'fm')
549
      ->fields('fm', array('fid'))
550
      ->orderBy('timestamp', 'DESC')
551
      ->execute()
552
      ->fetchCol();
553

    
554
    $files_form = array();
555
    $this->drupalGet('admin/content/file');
556
    foreach ($this->xpath('//table/tbody/tr/td/div/input/@value') as $input) {
557
      $files_form[] = $input;
558
    }
559
    $this->assertEqual($files_query, $files_form, 'Files are sorted in the form according to the default query.');
560

    
561
    // Compare the rendered HTML node list to a query for the files ordered by
562
    // filename to account for possible database-dependent sort order.
563
    $files_query = db_select('file_managed', 'fm')
564
      ->fields('fm', array('fid'))
565
      ->orderBy('filename')
566
      ->execute()
567
      ->fetchCol();
568

    
569
    $files_form = array();
570
    $this->drupalGet('admin/content/file', array('query' => array('sort' => 'asc', 'order' => 'Title')));
571
    foreach ($this->xpath('//table/tbody/tr/td/div/input/@value') as $input) {
572
      $files_form[] = $input;
573
    }
574
    $this->assertEqual($files_query, $files_form, 'Files are sorted in the form the same as they are in the query.');
575
  }
576

    
577
  /**
578
   * Tests files overview with different user permissions.
579
   */
580
  function testFilesAdminPages() {
581
    $this->drupalLogin($this->admin_user);
582

    
583
    $files['public_image'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_1->uid, 'type' => 'image'));
584
    $files['public_document'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_2->uid, 'type' => 'document'));
585
    $files['private_image'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_1->uid, 'type' => 'image'));
586
    $files['private_document'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_2->uid, 'type' => 'document'));
587

    
588
    // Verify view, edit, and delete links for any file.
589
    $this->drupalGet('admin/content/file');
590
    $this->assertResponse(200);
591
    foreach ($files as $file) {
592
      $this->assertLinkByHref('file/' . $file->fid);
593
      $this->assertLinkByHref('file/' . $file->fid . '/edit');
594
      $this->assertLinkByHref('file/' . $file->fid . '/delete');
595
      // Verify tableselect.
596
      $this->assertFieldByName('files[' . $file->fid . ']', '', t('Tableselect found.'));
597
    }
598

    
599
    // Verify no operation links are displayed for regular users.
600
    $this->drupalLogout();
601
    $this->drupalLogin($this->base_user_1);
602
    $this->drupalGet('admin/content/file');
603
    $this->assertResponse(200);
604
    $this->assertLinkByHref('file/' . $files['public_image']->fid);
605
    $this->assertLinkByHref('file/' . $files['public_document']->fid);
606
    $this->assertNoLinkByHref('file/' . $files['public_image']->fid . '/edit');
607
    $this->assertNoLinkByHref('file/' . $files['public_image']->fid . '/delete');
608
    $this->assertNoLinkByHref('file/' . $files['public_document']->fid . '/edit');
609
    $this->assertNoLinkByHref('file/' . $files['public_document']->fid . '/delete');
610

    
611
    // Verify no tableselect.
612
    $this->assertNoFieldByName('files[' . $files['public_image']->fid . ']', '', t('No tableselect found.'));
613

    
614
    // Verify private file is displayed with permission.
615
    $this->drupalLogout();
616
    $this->drupalLogin($this->base_user_2);
617
    $this->drupalGet('admin/content/file');
618
    $this->assertResponse(200);
619
    $this->assertLinkByHref('file/' . $files['private_document']->fid);
620
    // Verify no operation links are displayed.
621
    $this->assertNoLinkByHref('file/' . $files['private_document']->fid . '/edit');
622
    $this->assertNoLinkByHref('file/' . $files['private_document']->fid . '/delete');
623

    
624
    // Verify user cannot see private file of other users.
625
    $this->assertNoLinkByHref('file/' . $files['private_image']->fid);
626
    $this->assertNoLinkByHref('file/' . $files['private_image']->fid . '/edit');
627
    $this->assertNoLinkByHref('file/' . $files['private_image']->fid . '/delete');
628

    
629
    // Verify no tableselect.
630
    $this->assertNoFieldByName('files[' . $files['private_document']->fid . ']', '', t('No tableselect found.'));
631

    
632
    // Verify private file is displayed with permission.
633
    $this->drupalLogout();
634
    $this->drupalLogin($this->base_user_3);
635
    $this->drupalGet('admin/content/file');
636
    $this->assertResponse(200);
637

    
638
    // Verify user can see private file of other users.
639
    $this->assertLinkByHref('file/' . $files['private_document']->fid);
640
    $this->assertLinkByHref('file/' . $files['private_image']->fid);
641

    
642
    // Verify operation links are displayed for users with appropriate permission.
643
    $this->drupalLogout();
644
    $this->drupalLogin($this->base_user_4);
645
    $this->drupalGet('admin/content/file');
646
    $this->assertResponse(200);
647
    foreach ($files as $file) {
648
      $this->assertLinkByHref('file/' . $file->fid);
649
      $this->assertLinkByHref('file/' . $file->fid . '/edit');
650
      $this->assertLinkByHref('file/' . $file->fid . '/delete');
651
    }
652

    
653
    // Verify file access can be bypassed.
654
    $this->drupalLogout();
655
    $this->drupalLogin($this->admin_user);
656
    $this->drupalGet('admin/content/file');
657
    $this->assertResponse(200);
658
    foreach ($files as $file) {
659
      $this->assertLinkByHref('file/' . $file->fid);
660
      $this->assertLinkByHref('file/' . $file->fid . '/edit');
661
      $this->assertLinkByHref('file/' . $file->fid . '/delete');
662
    }
663
  }
664
}
665

    
666
class FileEntityReplaceTestCase extends FileEntityTestHelper {
667
  public static function getInfo() {
668
    return array(
669
      'name' => 'File replacement',
670
      'description' => 'Test file replace functionality.',
671
      'group' => 'File entity',
672
    );
673
  }
674

    
675
  function setUp() {
676
    parent::setUp();
677
    $this->setUpFiles();
678
  }
679

    
680
  /**
681
   * @todo Test image dimensions for an image field are reset when a file is replaced.
682
   * @todo Test image styles are cleared when an image is updated.
683
   */
684
  function testReplaceFile() {
685
    // Select the first text test file to use.
686
    $file = reset($this->files['text']);
687

    
688
    // Create a user with file edit permissions.
689
    $user = $this->drupalCreateUser(array('edit any document files'));
690
    $this->drupalLogin($user);
691

    
692
    // Test that the Upload widget appears for a local file.
693
    $this->drupalGet('file/' . $file->fid . '/edit');
694
    $this->assertFieldByName('files[replace_upload]');
695

    
696
    // Test that file saves without uploading a file.
697
    $this->drupalPost(NULL, array(), t('Save'));
698
    $this->assertText(t('Document @file has been updated.', array('@file' => $file->filename)), 'File was updated without file upload.');
699

    
700
    // Get the next text file to use as a replacement.
701
    $original = clone $file;
702
    $replacement = next($this->files['text']);
703

    
704
    // Test that the file saves when uploading a replacement file.
705
    $edit = array();
706
    $edit['files[replace_upload]'] = drupal_realpath($replacement->uri);
707
    $this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save'));
708
    $this->assertText(t('Document @file has been updated.', array('@file' => $file->filename)), 'File was updated with file upload.');
709

    
710
    // Re-load the file from the database.
711
    $file = file_load($file->fid);
712

    
713
    // Test how file properties changed after the file has been replaced.
714
    $this->assertEqual($file->filename, $original->filename, 'Updated file name did not change.');
715
    $this->assertNotEqual($file->filesize, $original->filesize, 'Updated file size changed from previous file.');
716
    $this->assertEqual($file->filesize, $replacement->filesize, 'Updated file size matches uploaded file.');
717
    $this->assertEqual(file_get_contents($file->uri), file_get_contents($replacement->uri), 'Updated file contents matches uploaded file.');
718
    $this->assertFalse(entity_load('file', FALSE, array('status' => 0)), 'Temporary file used for replacement was deleted.');
719

    
720
    // Get an image file.
721
    $image = reset($this->files['image']);
722
    $edit['files[replace_upload]'] = drupal_realpath($image->uri);
723

    
724
    // Test that validation works by uploading a non-text file as a replacement.
725
    $this->drupalPost('file/' . $file->fid . '/edit', $edit, t('Save'));
726
    $this->assertRaw(t('The specified file %file could not be uploaded. Only files with the following extensions are allowed:', array('%file' => $image->filename)), 'File validation works, upload failed correctly.');
727

    
728
    // Create a non-local file record.
729
    $file2 = new stdClass();
730
    $file2->uri = 'oembed://' . $this->randomName();
731
    $file2->filename = drupal_basename($file2->uri);
732
    $file2->filemime = 'image/oembed';
733
    $file2->type = 'image';
734
    $file2->uid = 1;
735
    $file2->timestamp = REQUEST_TIME;
736
    $file2->filesize = 0;
737
    $file2->status = 0;
738
    // Write the record directly rather than calling file_save() so we don't
739
    // invoke the hooks.
740
    $this->assertTrue(drupal_write_record('file_managed', $file2), 'Non-local file was added to the database.');
741

    
742
    // Test that Upload widget does not appear for non-local file.
743
    $this->drupalGet('file/' . $file2->fid . '/edit');
744
    $this->assertNoFieldByName('files[replace_upload]');
745
  }
746
}
747

    
748
class FileEntityTokenTestCase extends FileEntityTestHelper {
749
  public static function getInfo() {
750
    return array(
751
      'name' => 'File entity tokens',
752
      'description' => 'Test the file entity tokens.',
753
      'group' => 'File entity',
754
    );
755
  }
756

    
757
  function setUp() {
758
    parent::setUp();
759
    $this->setUpFiles();
760
  }
761

    
762
  function testFileEntityTokens() {
763
    $tokens = array(
764
      'type' => 'Document',
765
      'type:name' => 'Document',
766
      'type:machine-name' => 'document',
767
      'type:count' => count($this->files['text']),
768
    );
769
    $this->assertTokens('file', array('file' => $this->files['text'][0]), $tokens);
770

    
771
    $tokens = array(
772
      'type' => 'Image',
773
      'type:name' => 'Image',
774
      'type:machine-name' => 'image',
775
      'type:count' => count($this->files['image']),
776
    );
777
    $this->assertTokens('file', array('file' => $this->files['image'][0]), $tokens);
778
  }
779

    
780
  function assertTokens($type, array $data, array $tokens, array $options = array()) {
781
    $token_input = drupal_map_assoc(array_keys($tokens));
782
    $values = token_generate($type, $token_input, $data, $options);
783
    foreach ($tokens as $token => $expected) {
784
      if (!isset($expected)) {
785
        $this->assertTrue(!isset($values[$token]), t("Token value for [@type:@token] was not generated.", array('@type' => $type, '@token' => $token)));
786
      }
787
      elseif (!isset($values[$token])) {
788
        $this->fail(t("Token value for [@type:@token] was not generated.", array('@type' => $type, '@token' => $token)));
789
      }
790
      elseif (!empty($options['regex'])) {
791
        $this->assertTrue(preg_match('/^' . $expected . '$/', $values[$token]), t("Token value for [@type:@token] was '@actual', matching regular expression pattern '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $values[$token], '@expected' => $expected)));
792
      }
793
      else {
794
        $this->assertIdentical($values[$token], $expected, t("Token value for [@type:@token] was '@actual', expected value '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $values[$token], '@expected' => $expected)));
795
      }
796
    }
797

    
798
    return $values;
799
  }
800
}
801

    
802
class FileEntityTypeTestCase extends FileEntityTestHelper {
803
  public static function getInfo() {
804
    return array(
805
      'name' => 'File entity types',
806
      'description' => 'Test the file entity types.',
807
      'group' => 'File entity',
808
    );
809
  }
810

    
811
  function setUp() {
812
    parent::setUp();
813
    $this->setUpFiles();
814
  }
815

    
816
  /**
817
   * Test admin pages access and functionality.
818
   */
819
  function testAdminPages() {
820
    // Create a user with file type administration access.
821
    $user = $this->drupalCreateUser(array('administer file types'));
822
    $this->drupalLogin($user);
823

    
824
    $this->drupalGet('admin/structure/file-types');
825
    $this->assertResponse(200, 'File types admin page is accessible');
826
  }
827

    
828
  /**
829
   * Test creating a new type. Basic CRUD.
830
   */
831
  function testCreate() {
832
    $type_machine_type = 'foo';
833
    $type_machine_label = 'foobar';
834
    $type = $this->createFileType(array('type' => $type_machine_type, 'label' => $type_machine_label));
835
    $loaded_type = file_type_load($type_machine_type);
836
    $this->assertEqual($loaded_type->label, $type_machine_label, "Was able to create a type and retreive it.");
837
  }
838

    
839

    
840
  /**
841
   * Ensures that the weight is respected when types are created.
842
   * @return unknown_type
843
   */
844
  function testOrder() {
845
//    $type = $this->createFileType(array('name' => 'last', 'label' => 'Last', 'weight' => 100));
846
//    $type = $this->createFileType(array('name' => 'first', 'label' => 'First'));
847
//    $types = media_type_get_types();
848
//    $keys = array_keys($types);
849
//    $this->assertTrue(isset($types['last']) && isset($types['first']), "Both types saved");
850
//    $this->assertTrue(array_search('last', $keys) > array_search('first', $keys), 'Type which was supposed to be first came first');
851
  }
852

    
853
  /**
854
   * Test view mode assignment.  Currently fails, don't know why.
855
   * @return unknown_type
856
   */
857
  function testViewModesAssigned() {
858
  }
859

    
860
  /**
861
   * Make sure candidates are presented in the case of multiple
862
   * file types.
863
   */
864
  function testTypeWithCandidates() {
865
    // Create multiple file types with the same mime types.
866
    $types = array(
867
      'image1' => $this->createFileType(array('type' => 'image1', 'label' => 'Image 1')),
868
      'image2' => $this->createFileType(array('type' => 'image2', 'label' => 'Image 2'))
869
    );
870

    
871
    // Attach a text field to one of the file types.
872
    $field = array(
873
      'field_name' => drupal_strtolower($this->randomName()),
874
      'type' => 'text',
875
      'settings' => array(
876
        'max_length' => 255,
877
      )
878
    );
879
    field_create_field($field);
880
    $instance = array(
881
      'field_name' => $field['field_name'],
882
      'entity_type' => 'file',
883
      'bundle' => 'image2',
884
      'widget' => array(
885
        'type' => 'text_textfield',
886
      ),
887
      'display' => array(
888
        'default' => array(
889
          'type' => 'text_default',
890
        ),
891
      ),
892
    );
893
    field_create_instance($instance);
894

    
895
    // Create a user with file creation access.
896
    $user = $this->drupalCreateUser(array('create files'));
897
    $this->drupalLogin($user);
898

    
899
    // Step 1: Upload file
900
    $file = reset($this->files['image']);
901
    $edit = array();
902
    $edit['files[upload]'] = drupal_realpath($file->uri);
903
    $this->drupalPost('file/add', $edit, t('Next'));
904

    
905
    // Step 2: Select file type candidate
906
    $this->assertText('Image 1', 'File type candidate list item found.');
907
    $this->assertText('Image 2', 'File type candidate list item found.');
908
    $edit = array();
909
    $edit['type'] = 'image2';
910
    $this->drupalPost(NULL, $edit, t('Next'));
911

    
912
    // Step 3: Select file scheme candidate
913
    $this->assertText('Public local files served by the webserver.', 'File scheme candidate list item found.');
914
    $this->assertText('Private local files served by Drupal.', 'File scheme candidate list item found.');
915
    $edit = array();
916
    $edit['scheme'] = 'public';
917
    $this->drupalPost(NULL, $edit, t('Next'));
918

    
919
    // Step 4: Complete field widgets
920
    $langcode = LANGUAGE_NONE;
921
    $edit = array();
922
    $edit["{$field['field_name']}[$langcode][0][value]"] = $this->randomName();
923
    $this->drupalPost(NULL, $edit, t('Save'));
924
    $this->assertRaw(t('!type %name was uploaded.', array('!type' => 'Image 2', '%name' => $file->filename)), t('Image 2 file updated.'));
925
    $this->assertText($field['field_name'], 'File text field was found.');
926
  }
927

    
928
  /**
929
   * Make sure no candidates appear when only one mime type is available.
930
   * NOTE: Depends on file_entity.module default 'image' type.
931
   */
932
  function testTypeWithoutCandidates() {
933
    // Attach a text field to the default image file type.
934
    $field = array(
935
      'field_name' => drupal_strtolower($this->randomName()),
936
      'type' => 'text',
937
      'settings' => array(
938
        'max_length' => 255,
939
      )
940
    );
941
    field_create_field($field);
942
    $instance = array(
943
      'field_name' => $field['field_name'],
944
      'entity_type' => 'file',
945
      'bundle' => 'image',
946
      'widget' => array(
947
        'type' => 'text_textfield',
948
      ),
949
      'display' => array(
950
        'default' => array(
951
          'type' => 'text_default',
952
        ),
953
      ),
954
    );
955
    field_create_instance($instance);
956

    
957
    // Create a user with file creation access.
958
    $user = $this->drupalCreateUser(array('create files'));
959
    $this->drupalLogin($user);
960

    
961
    // Step 1: Upload file
962
    $file = reset($this->files['image']);
963
    $edit = array();
964
    $edit['files[upload]'] = drupal_realpath($file->uri);
965
    $this->drupalPost('file/add', $edit, t('Next'));
966

    
967
    // Step 2: Scheme selection
968
    if ($this->xpath('//input[@name="scheme"]')) {
969
      $this->drupalPost(NULL, array(), t('Next'));
970
    }
971

    
972
    // Step 3: Complete field widgets
973
    $langcode = LANGUAGE_NONE;
974
    $edit = array();
975
    $edit["{$field['field_name']}[$langcode][0][value]"] = $this->randomName();
976
    $this->drupalPost(NULL, $edit, t('Save'));
977
    $this->assertRaw(t('!type %name was uploaded.', array('!type' => 'Image', '%name' => $file->filename)), t('Image file uploaded.'));
978
    $this->assertText($field['field_name'], 'File text field was found.');
979
  }
980

    
981
  /**
982
   * Test file types CRUD UI.
983
   */
984
  function testTypesCrudUi() {
985
    $this->drupalGet('admin/structure/file-types');
986
    $this->assertResponse(403, 'File types UI page is not accessible to unauthorized users.');
987

    
988
    $user = $this->drupalCreateUser(array('administer file types'));
989
    $this->drupalLogin($user);
990

    
991
    $this->drupalGet('admin/structure/file-types');
992
    $this->assertResponse(200, 'File types UI page is accessible to users with adequate permission.');
993

    
994
    // Create new file type.
995
    $edit = array(
996
      'label' => t('Test type'),
997
      'type' => 'test_type',
998
      'description' => t('This is dummy file type used just for testing.'),
999
      'mimetypes' => 'image/png',
1000
    );
1001
    $this->drupalGet('admin/structure/file-types/add');
1002
    $this->drupalPost(NULL, $edit, t('Save'));
1003
    $this->assertText(t('The file type @type has been updated.', array('@type' => $edit['label'])), 'New file type successfully created.');
1004
    $this->assertText($edit['label'], 'New file type created: label found.');
1005
    $this->assertText($edit['description'], 'New file type created: description found.');
1006
    $this->assertFieldByXPath("//table//tr[1]//td[7]", t('Normal'), 'Newly created file type is stored in DB.');
1007
    $this->assertLink(t('disable'), 0, 'Able to disable newly created file type.');
1008
    $this->assertLink(t('delete'), 0, 'Able to delete newly created file type.');
1009
    $this->assertLinkByHref('admin/structure/file-types/manage/' . $edit['type'] . '/disable', 0, 'Disable link points to disable confirmation page.');
1010
    $this->assertLinkByHref('admin/structure/file-types/manage/' . $edit['type'] . '/delete', 0, 'Delete link points to delete confirmation page.');
1011

    
1012
    // Edit file type.
1013
    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/edit');
1014
    $this->assertRaw(t('Save'), 'Save button found on edit page.');
1015
    $this->assertRaw(t('Delete'), 'Delete button found on edit page.');
1016
    $this->assertRaw($edit['label'], 'Label found on file type edit page');
1017
    $this->assertText($edit['description'], 'Description found on file type edit page');
1018
    $this->assertText($edit['mimetypes'], 'Mime-type configuration found on file type edit page');
1019
    $this->assertText(t('Mimetype List'), 'Mimetype list present on edit form.');
1020

    
1021
    // Modify file type.
1022
    $edit['label'] = t('New type label');
1023
    $this->drupalPost(NULL, array('label' => $edit['label']), t('Save'));
1024
    $this->assertText(t('The file type @type has been updated.', array('@type' => $edit['label'])), 'File type was modified.');
1025
    $this->assertText($edit['label'], 'Modified label found on file types list.');
1026

    
1027
    // Disable and re-enable file type.
1028
    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/disable');
1029
    $this->assertText(t('Are you sure you want to disable the file type @type?', array('@type' => $edit['label'])), 'Disable confirmation page found.');
1030
    $this->drupalPost(NULL, array(), t('Disable'));
1031
    $this->assertText(t('The file type @type has been disabled.', array('@type' => $edit['label'])), 'Disable confirmation message found.');
1032
    $this->assertFieldByXPath("//table//tr[5]//td[1]", $edit['label'], 'Disabled type moved to the tail of the list.');
1033
    $this->assertLink(t('enable'), 0, 'Able to re-enable newly created file type.');
1034
    $this->assertLinkByHref('admin/structure/file-types/manage/' . $edit['type'] . '/enable', 0, 'Enable link points to enable confirmation page.');
1035
    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/enable');
1036
    $this->assertText(t('Are you sure you want to enable the file type @type?', array('@type' => $edit['label'])), 'Enable confirmation page found.');
1037
    $this->drupalPost(NULL, array(), t('Enable'));
1038
    $this->assertText(t('The file type @type has been enabled.', array('@type' => $edit['label'])), 'Enable confirmation message found.');
1039
    $this->assertFieldByXPath("//table//tr[1]//td[1]", $edit['label'], 'Enabled type moved to the top of the list.');
1040

    
1041
    // Delete newly created type.
1042
    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/delete');
1043
    $this->assertText(t('Are you sure you want to delete the file type @type?', array('@type' => $edit['label'])), 'Delete confirmation page found.');
1044
    $this->drupalPost(NULL, array(), t('Delete'));
1045
    $this->assertText(t('The file type @type has been deleted.', array('@type' => $edit['label'])), 'Delete confirmation message found.');
1046
    $this->drupalGet('admin/structure/file-types');
1047
    $this->assertNoText($edit['label'], 'File type successfully deleted.');
1048

    
1049
    // Edit exported file type.
1050
    $this->drupalGet('admin/structure/file-types/manage/image/edit');
1051
    $this->assertRaw(t('Image'), 'Label found on file type edit page');
1052
    $this->assertText("image/*", 'Mime-type configuration found on file type edit page');
1053
    $this->drupalPost(NULL, array('label' => t('Funky images')), t('Save'));
1054
    $this->assertText(t('The file type @type has been updated.', array('@type' => t('Funky images'))), 'File type was modified.');
1055
    $this->assertText(t('Funky image'), 'Modified label found on file types list.');
1056
    $this->assertFieldByXPath("//table//tr[1]//td[7]", t('Overridden'), 'Modified type overrides configuration from code.');
1057
    $this->assertLink(t('revert'), 0, 'Able to revert overridden file type.');
1058
    $this->assertLinkByHref('admin/structure/file-types/manage/image/revert', 0, 'Revert link points to revert confirmation page.');
1059

    
1060
    // Revert file type.
1061
    $this->drupalGet('admin/structure/file-types/manage/image/revert');
1062
    $this->assertText(t('Are you sure you want to revert the file type @type?', array('@type' => t('Funky images'))), 'Revert confirmation page found.');
1063
    $this->drupalPost(NULL, array(), t('Revert'));
1064
    $this->assertText(t('The file type @type has been reverted.', array('@type' => t('Funky images'))), 'Revert confirmation message found.');
1065
    $this->assertText(t('Image'), 'Reverted file type found in list.');
1066
    $this->assertFieldByXPath("//table//tr[1]//td[7]", t('Default'), 'Reverted file type shows correct state.');
1067
  }
1068
}
1069

    
1070
class FileEntityAccessTestCase extends FileEntityTestHelper {
1071

    
1072
  public static function getInfo() {
1073
    return array(
1074
      'name' => 'File entity access',
1075
      'description' => 'Test the access aspects of file entity.',
1076
      'group' => 'File entity',
1077
    );
1078
  }
1079

    
1080
  function setUp() {
1081
    parent::setUp();
1082
    $this->setUpFiles(array('uid' => 0));
1083

    
1084
    // Unset the fact that file_entity_install() adds the 'view files'
1085
    // permission to all user roles. This messes with being able to fully unit
1086
    // test the file_entity_access() function.
1087
    $roles = user_roles();
1088
    foreach ($roles as $rid => $role) {
1089
      user_role_revoke_permissions($rid, array('view files'));
1090
    }
1091
  }
1092

    
1093
  /**
1094
   * Asserts file_entity_access correctly grants or denies access.
1095
   */
1096
  function assertFileEntityAccess($ops, $file, $account) {
1097
    drupal_static_reset('file_entity_access');
1098
    foreach ($ops as $op => $result) {
1099
      $msg = t("file_entity_access returns @result with operation '@op'.", array('@result' => $result ? 'true' : 'false', '@op' => $op));
1100
      $this->assertEqual($result, file_entity_access($op, $file, $account), $msg);
1101
    }
1102
  }
1103

    
1104
  /**
1105
   * Runs basic tests for file_entity_access function.
1106
   */
1107
  function testFileEntityAccess() {
1108
    $file = reset($this->files['image']);
1109

    
1110
    // Ensures user with 'bypass file access' permission can do everything.
1111
    $web_user = $this->drupalCreateUser(array('bypass file access'));
1112
    $this->assertFileEntityAccess(array('create' => TRUE), NULL, $web_user);
1113
    $this->assertFileEntityAccess(array('view' => TRUE, 'download' => TRUE, 'update' => TRUE, 'delete' => TRUE), $file, $web_user);
1114

    
1115
    // A user with 'administer files' should not access CRUD operations.
1116
    $web_user = $this->drupalCreateUser(array('administer files'));
1117
    $this->assertFileEntityAccess(array('view' => FALSE, 'download' => FALSE, 'update' => FALSE, 'delete' => FALSE), $file, $web_user);
1118

    
1119
    // User cannot 'view files'.
1120
    $web_user = $this->drupalCreateUser(array('create files'));
1121
    $this->assertFileEntityAccess(array('view' => FALSE), $file, $web_user);
1122
    // But can upload new ones.
1123
    $this->assertFileEntityAccess(array('create' => TRUE), NULL, $web_user);
1124

    
1125
    // User can view own files but no other files.
1126
    $web_user = $this->drupalCreateUser(array('create files', 'view own files'));
1127
    $this->assertFileEntityAccess(array('view' => FALSE), $file, $web_user);
1128
    $file->uid = $web_user->uid;
1129
    $this->assertFileEntityAccess(array('view' => TRUE), $file, $web_user);
1130

    
1131
    // User can download own files but no other files.
1132
    $web_user = $this->drupalCreateUser(array('create files', 'download own image files'));
1133
    $this->assertFileEntityAccess(array('download' => FALSE), $file, $web_user);
1134
    $file->uid = $web_user->uid;
1135
    $this->assertFileEntityAccess(array('download' => TRUE), $file, $web_user);
1136

    
1137
    // User can update own files but no other files.
1138
    $web_user = $this->drupalCreateUser(array('create files', 'view own files', 'edit own image files'));
1139
    $this->assertFileEntityAccess(array('update' => FALSE), $file, $web_user);
1140
    $file->uid = $web_user->uid;
1141
    $this->assertFileEntityAccess(array('update' => TRUE), $file, $web_user);
1142

    
1143
    // User can delete own files but no other files.
1144
    $web_user = $this->drupalCreateUser(array('create files', 'view own files', 'edit own image files', 'delete own image files'));
1145
    $this->assertFileEntityAccess(array('delete' => FALSE), $file, $web_user);
1146
    $file->uid = $web_user->uid;
1147
    $this->assertFileEntityAccess(array('delete' => TRUE), $file, $web_user);
1148

    
1149
    // User can view any file.
1150
    $web_user = $this->drupalCreateUser(array('create files', 'view files'));
1151
    $this->assertFileEntityAccess(array('view' => TRUE), $file, $web_user);
1152

    
1153
    // User can download any file.
1154
    $web_user = $this->drupalCreateUser(array('create files', 'download any image files'));
1155
    $this->assertFileEntityAccess(array('download' => TRUE), $file, $web_user);
1156

    
1157
    // User can edit any file.
1158
    $web_user = $this->drupalCreateUser(array('create files', 'view files', 'edit any image files'));
1159
    $this->assertFileEntityAccess(array('update' => TRUE), $file, $web_user);
1160

    
1161
    // User can delete any file.
1162
    $web_user = $this->drupalCreateUser(array('create files', 'view files', 'edit any image files', 'delete any image files'));
1163
    $this->assertFileEntityAccess(array('delete' => TRUE), $file, $web_user);
1164
  }
1165

    
1166
  /**
1167
   * Test to see if we have access to view files when granted the permissions.
1168
   * In this test we aim to prove the permissions work in the following pages:
1169
   *  file/add
1170
   *  file/%/view
1171
   *  file/%/download
1172
   *  file/%/edit
1173
   *  file/%/delete
1174
   */
1175
  function testFileEntityPageAccess() {
1176
    $web_user = $this->drupalCreateUser(array());
1177
    $this->drupalLogin($web_user);
1178
    $this->drupalGet('file/add');
1179
    $this->assertResponse(403, 'Users without access can not access the file add page');
1180
    $web_user = $this->drupalCreateUser(array('create files'));
1181
    $this->drupalLogin($web_user);
1182
    $this->drupalGet('file/add');
1183
    $this->assertResponse(200, 'Users with access can access the file add page');
1184

    
1185
    $file = reset($this->files['text']);
1186

    
1187
    // This fails.. No clue why but, tested manually and works as should.
1188
    //$web_user = $this->drupalCreateUser(array('view own files'));
1189
    //$this->drupalLogin($web_user);
1190
    //$this->drupalGet("file/{$file->fid}/view");
1191
    //$this->assertResponse(403, 'Users without access can not access the file view page');
1192
    $web_user = $this->drupalCreateUser(array('view files'));
1193
    $this->drupalLogin($web_user);
1194
    $this->drupalGet("file/{$file->fid}/view");
1195
    $this->assertResponse(200, 'Users with access can access the file view page');
1196

    
1197
    $url = "file/{$file->fid}/download";
1198
    $web_user = $this->drupalCreateUser(array());
1199
    $this->drupalLogin($web_user);
1200
    $this->drupalGet($url, array('query' => array('token' => file_entity_get_download_token($file))));
1201
    $this->assertResponse(403, 'Users without access can not download the file');
1202
    $web_user = $this->drupalCreateUser(array('download any document files'));
1203
    $this->drupalLogin($web_user);
1204
    $this->drupalGet($url, array('query' => array('token' => file_entity_get_download_token($file))));
1205
    $this->assertResponse(200, 'Users with access can download the file');
1206
    $this->drupalGet($url, array('query' => array('token' => 'invalid-token')));
1207
    $this->assertResponse(403, 'Cannot download file with in invalid token.');
1208
    $this->drupalGet($url);
1209
    $this->assertResponse(403, 'Cannot download file without a token.');
1210
    variable_set('file_entity_allow_insecure_download', TRUE);
1211
    $this->drupalGet($url);
1212
    $this->assertResponse(200, 'Users with access can download the file without a token when file_entity_allow_insecure_download is set.');
1213

    
1214
    $web_user = $this->drupalCreateUser(array());
1215
    $this->drupalLogin($web_user);
1216
    $this->drupalGet("file/{$file->fid}/edit");
1217
    $this->assertResponse(403, 'Users without access can not access the file edit page');
1218
    $web_user = $this->drupalCreateUser(array('edit any document files'));
1219
    $this->drupalLogin($web_user);
1220
    $this->drupalGet("file/{$file->fid}/edit");
1221
    $this->assertResponse(200, 'Users with access can access the file add page');
1222

    
1223
    $web_user = $this->drupalCreateUser(array());
1224
    $this->drupalLogin($web_user);
1225
    $this->drupalGet("file/{$file->fid}/delete");
1226
    $this->assertResponse(403, 'Users without access can not access the file view page');
1227
    $web_user = $this->drupalCreateUser(array('delete any document files'));
1228
    $this->drupalLogin($web_user);
1229
    $this->drupalGet("file/{$file->fid}/delete");
1230
    $this->assertResponse(200, 'Users with access can access the file add page');
1231
  }
1232

    
1233
  /**
1234
   * Test to see if we have access to download private files when granted the permissions.
1235
   */
1236
  function testFileEntityPrivateDownloadAccess() {
1237
    foreach ($this->getPrivateDownloadAccessCases() as $case) {
1238
      // Create users and login only if non-anonymous.
1239
      $authenticated_user = !is_null($case['permissions']);
1240
      if ($authenticated_user) {
1241
        $account = $this->drupalCreateUser($case['permissions']);
1242
        $this->drupalLogin($account);
1243
      }
1244

    
1245
      // Create private, permanent files owned by this user only he's an owner.
1246
      if (!empty($case['owner'])) {
1247
        $file = next($this->files['text']);
1248
        $file->uid = $account->uid;
1249
        file_save($file);
1250
        $file = file_move($file, 'private://');
1251

    
1252
        // Check if the physical file is there.
1253
        $arguments = array('%name' => $file->filename, '%username' => $account->name, '%uri' => $file->uri);
1254
        $this->assertTrue(is_file($file->uri), format_string('File %name owned by %username successfully created at %uri.', $arguments));
1255
        $url = file_create_url($file->uri);
1256
        $message_file_info = ' ' . format_string('File %uri was checked.', array('%uri' => $file->uri));
1257
      }
1258

    
1259
      // Try to download the file.
1260
      $this->drupalGet($url);
1261
      $this->assertResponse($case['expect'], $case['message'] . $message_file_info);
1262

    
1263
      // Logout authenticated users.
1264
      if ($authenticated_user) {
1265
        $this->drupalLogout();
1266
      }
1267
    }
1268
  }
1269
}
1270

    
1271
class FileEntityAttributeOverrideTestCase extends FileEntityTestHelper {
1272

    
1273
  public static function getInfo() {
1274
    return array(
1275
      'name' => 'File entity attribute override',
1276
      'description' => 'Test overriding file entity attributes.',
1277
      'group' => 'File entity',
1278
    );
1279
  }
1280

    
1281
  function setUp() {
1282
    parent::setUp();
1283
    $this->setUpFiles();
1284
  }
1285

    
1286
  /**
1287
   * Test to see if file attributes can be overridden.
1288
   */
1289
  function testFileEntityFileAttributeOverrides() {
1290
    $overrides = array(
1291
      'width' => 40,
1292
      'height' => 20,
1293
      'alt' => $this->randomName(),
1294
      'title' => $this->randomName(),
1295

    
1296
    );
1297

    
1298
    // Retrieve an image file entity for testing.
1299
    $file = reset($this->files['image']);
1300

    
1301
    // Override a variety of attributes.
1302
    foreach ($overrides as $override => $value) {
1303
      $file->override['attributes'][$override] = $value;
1304
    }
1305

    
1306
    // Test that the attributes have been overridden.
1307
    $build = file_view_file($file, 'full');
1308

    
1309
    foreach ($overrides as $attribute => $expected_value) {
1310
      $this->assertEqual($build['#item'][$attribute], $expected_value, format_string('The %attribute was overridden correctly.', array('%attribute' => $attribute)));
1311
    }
1312
  }
1313
}