Projet

Général

Profil

Paste
Télécharger (55,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media / tests / media.test @ e4215af7

1 85ad3d82 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * Tests for media.module.
6
 */
7
8
/**
9 ca0757b9 Assos Assos
 * Provides methods specifically for testing Media module's field handling.
10 85ad3d82 Assos Assos
 */
11 ca0757b9 Assos Assos
class MediaFileFieldTestCase extends DrupalWebTestCase {
12
  protected $admin_user;
13
14
  function setUp() {
15
    // Since this is a base class for many test cases, support the same
16
    // flexibility that DrupalWebTestCase::setUp() has for the modules to be
17
    // passed in as either an array or a variable number of string arguments.
18
    $modules = func_get_args();
19
    if (isset($modules[0]) && is_array($modules[0])) {
20
      $modules = $modules[0];
21
    }
22
    $modules[] = 'media';
23
    $modules[] = 'media_module_test';
24
    parent::setUp($modules);
25 fc3d89c3 Assos Assos
    $this->admin_user = $this->drupalCreateUser(array('access content', 'view files', 'view own files', 'access media browser', 'access administration pages', 'administer site configuration', 'administer users', 'administer permissions', 'administer content types', 'administer nodes', 'administer files', 'bypass node access', 'bypass file access', 'administer fields'));
26 ca0757b9 Assos Assos
    $this->drupalLogin($this->admin_user);
27
  }
28
29
  /**
30
   * Retrieves a sample file of the specified type.
31
   */
32
  function getTestFile($type_name, $size = NULL) {
33
    // Get a file to upload.
34
    $file = current($this->drupalGetTestFiles($type_name, $size));
35
36
    // Add a filesize property to files as would be read by file_load().
37
    $file->filesize = filesize($file->uri);
38
39
    return $file;
40
  }
41
42
  /**
43
   * Creates a new file entity.
44
   *
45
   * @param $settings
46
   *   A list of settings that will be added to the entity defaults.
47
   */
48
  protected function createFileEntity($settings = array()) {
49
    $file = new stdClass();
50
51
    // Populate defaults array.
52
    $settings += array(
53
      'filepath' => 'Файл для тестирования ' . $this->randomName(), // Prefix with non-latin characters to ensure that all file-related tests work with international filenames.
54
      'filemime' => 'text/plain',
55
      'uid' => 1,
56
      'timestamp' => REQUEST_TIME,
57
      'status' => FILE_STATUS_PERMANENT,
58
      'contents' => "file_put_contents() doesn't seem to appreciate empty strings so let's put in some data.",
59
      'scheme' => file_default_scheme(),
60
      'type' => NULL,
61
    );
62
63
    $filepath = $settings['scheme'] . '://' . $settings['filepath'];
64
65
    file_put_contents($filepath, $settings['contents']);
66
    $this->assertTrue(is_file($filepath), t('The test file exists on the disk.'), 'Create test file');
67
68
    $file = new stdClass();
69
    $file->uri = $filepath;
70
    $file->filename = drupal_basename($file->uri);
71
    $file->filemime = $settings['filemime'];
72
    $file->uid = $settings['uid'];
73
    $file->timestamp = $settings['timestamp'];
74
    $file->filesize = filesize($file->uri);
75
    $file->status = $settings['status'];
76
    $file->type = $settings['type'];
77
78
    // The file type is used as a bundle key, and therefore, must not be NULL.
79
    if (!isset($file->type)) {
80
      $file->type = FILE_TYPE_NONE;
81
    }
82
83
    // If the file isn't already assigned a real type, determine what type should
84
    // be assigned to it.
85
    if ($file->type === FILE_TYPE_NONE) {
86
      $type = file_get_type($file);
87
      if (isset($type)) {
88
        $file->type = $type;
89
      }
90
    }
91
92
    // Write the record directly rather than calling file_save() so we don't
93
    // invoke the hooks.
94
    $this->assertNotIdentical(drupal_write_record('file_managed', $file), FALSE, t('The file was added to the database.'), 'Create test file');
95
96
    return $file;
97
  }
98
99
  /**
100
   * Creates a new file field.
101
   *
102
   * @param $name
103
   *   The name of the new field (all lowercase), exclude the "field_" prefix.
104
   * @param $type_name
105
   *   The node type that this field will be added to.
106
   * @param $field_settings
107
   *   A list of field settings that will be added to the defaults.
108
   * @param $instance_settings
109
   *   A list of instance settings that will be added to the instance defaults.
110
   * @param $widget_settings
111
   *   A list of widget settings that will be added to the widget defaults.
112
   */
113
  function createFileField($name, $type_name, $field_settings = array(), $instance_settings = array(), $widget_settings = array()) {
114
    $field = array(
115
      'field_name' => $name,
116
      'type' => 'file',
117
      'settings' => array(),
118
      'cardinality' => !empty($field_settings['cardinality']) ? $field_settings['cardinality'] : 1,
119
    );
120
    $field['settings'] = array_merge($field['settings'], $field_settings);
121
    field_create_field($field);
122
123
    $this->attachFileField($name, 'node', $type_name, $instance_settings, $widget_settings);
124
  }
125
126
  /**
127
   * Attaches a file field to an entity.
128
   *
129
   * @param $name
130
   *   The name of the new field (all lowercase), exclude the "field_" prefix.
131
   * @param $entity_type
132
   *   The entity type this field will be added to.
133
   * @param $bundle
134
   *   The bundle this field will be added to.
135
   * @param $field_settings
136
   *   A list of field settings that will be added to the defaults.
137
   * @param $instance_settings
138
   *   A list of instance settings that will be added to the instance defaults.
139
   * @param $widget_settings
140
   *   A list of widget settings that will be added to the widget defaults.
141
   */
142
  function attachFileField($name, $entity_type, $bundle, $instance_settings = array(), $widget_settings = array()) {
143
    $instance = array(
144
      'field_name' => $name,
145
      'label' => $name,
146
      'entity_type' => $entity_type,
147
      'bundle' => $bundle,
148
      'required' => !empty($instance_settings['required']),
149
      'settings' => array(),
150
      'widget' => array(
151
        'type' => 'media_generic',
152
        'settings' => array(),
153
      ),
154
    );
155
    $instance['settings'] = array_merge($instance['settings'], $instance_settings);
156
    $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
157
    field_create_instance($instance);
158
  }
159
160
  /**
161
   * Attaches a file to a node.
162
   */
163
  function attachNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE, $extras = array()) {
164
    $langcode = LANGUAGE_NONE;
165
    $edit = array(
166
      "title" => $this->randomName(),
167
      'revision' => (string) (int) $new_revision,
168
    );
169
170
    if (is_numeric($nid_or_type)) {
171
      $nid = $nid_or_type;
172
    }
173
    else {
174
      // Add a new node.
175
      $extras['type'] = $nid_or_type;
176
      $node = $this->drupalCreateNode($extras);
177
      $nid = $node->nid;
178
      // Save at least one revision to better simulate a real site.
179
      $this->drupalCreateNode(get_object_vars($node));
180
      $node = node_load($nid, NULL, TRUE);
181
      $this->assertNotEqual($nid, $node->vid, 'Node revision exists.');
182
    }
183
184
    // Attach a file to the node.
185 fc3d89c3 Assos Assos
    $edit[$field_name . '[' . $langcode . '][0][fid]'] = $file->fid;
186 ca0757b9 Assos Assos
    $this->drupalPost("node/$nid/edit", $edit, t('Save'));
187
188
    return $nid;
189
  }
190
191
  /**
192
   * Replaces a file within a node.
193
   */
194
  function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE) {
195
    $edit = array(
196
      $field_name . '[' . LANGUAGE_NONE . '][0][fid]' => $file->fid,
197
      'revision' => (string) (int) $new_revision,
198
    );
199
200
    $this->drupalPost('node/' . $nid . '/edit', array(), t('Remove'));
201
    $this->drupalPost(NULL, $edit, t('Save'));
202
  }
203
204
  /**
205
   * Asserts that a file exists physically on disk.
206
   */
207
  function assertFileExists($file, $message = NULL) {
208
    $message = isset($message) ? $message : format_string('File %file exists on the disk.', array('%file' => $file->uri));
209
    $this->assertTrue(is_file($file->uri), $message);
210
  }
211
212
  /**
213
   * Asserts that a file exists in the database.
214
   */
215
  function assertFileEntryExists($file, $message = NULL) {
216
    entity_get_controller('file')->resetCache();
217
    $db_file = file_load($file->fid);
218
    $message = isset($message) ? $message : format_string('File %file exists in database at the correct path.', array('%file' => $file->uri));
219
    $this->assertEqual($db_file->uri, $file->uri, $message);
220
  }
221
222
  /**
223
   * Asserts that a file does not exist on disk.
224
   */
225
  function assertFileNotExists($file, $message = NULL) {
226
    $message = isset($message) ? $message : format_string('File %file exists on the disk.', array('%file' => $file->uri));
227
    $this->assertFalse(is_file($file->uri), $message);
228
  }
229
230
  /**
231
   * Asserts that a file does not exist in the database.
232
   */
233
  function assertFileEntryNotExists($file, $message) {
234
    entity_get_controller('file')->resetCache();
235
    $message = isset($message) ? $message : format_string('File %file exists in database at the correct path.', array('%file' => $file->uri));
236
    $this->assertFalse(file_load($file->fid), $message);
237
  }
238
239
  /**
240
   * Asserts that a file's status is set to permanent in the database.
241
   */
242
  function assertFileIsPermanent($file, $message = NULL) {
243
    $message = isset($message) ? $message : format_string('File %file is permanent.', array('%file' => $file->uri));
244
    $this->assertTrue($file->status == FILE_STATUS_PERMANENT, $message);
245
  }
246
}
247
248
/**
249
 * Tests the 'media' element type.
250
 *
251
 * @todo Create a MediaFileTestCase base class and move MediaFileFieldTestCase
252
 *   methods that aren't related to fields into it.
253
 */
254
class MediaElementTestCase extends MediaFileFieldTestCase {
255
  public static function getInfo() {
256
    return array(
257
      'name' => 'Media element test',
258
      'description' => 'Tests the media element type.',
259
      'group' => 'Media',
260
    );
261
  }
262
263
  /**
264
   * Tests the media element type.
265
   */
266
  function testMedia() {
267
    // Check that $element['#size'] is passed to the child upload element.
268
    $this->drupalGet('media/test');
269
    $this->assertFieldByXpath('//input[@name="media[nested_media]" and @size="13"]', NULL, 'The custom #size attribute is passed to the child upload element.');
270
271
    // Perform the tests with all permutations of $form['#tree'] and
272
    // $element['#extended'].
273
    foreach (array(0, 1) as $tree) {
274
      foreach (array(0, 1) as $extended) {
275
        $test_file = $this->getTestFile('text');
276
        $test_file->uid = $this->admin_user->uid;
277
        $test_file = file_save($test_file);
278
        $path = 'media/test/' . $tree . '/' . $extended;
279
        $input_base_name = $tree ? 'nested_media' : 'media';
280
281
        // Submit without a file.
282
        $this->drupalPost($path, array(), t('Save'));
283
        $this->assertRaw(t('The file id is %fid.', array('%fid' => 0)), 'Submitted without a file.');
284
285
        // Submit a new file, without using the Attach button.
286
        $edit = array('media[' . $input_base_name . ']' => $test_file->fid);
287
        $this->drupalPost($path, $edit, t('Save'));
288
        $this->assertRaw(t('The file id is %fid.', array('%fid' => $test_file->fid)), 'Submit handler has correct file info.');
289
290
        // Now, test the Attach and Remove buttons, with and without Ajax.
291
        foreach (array(FALSE) as $ajax) {
292
          // Attach, then Submit.
293
          $this->drupalGet($path);
294
          $edit = array('media[' . $input_base_name . ']' => $test_file->fid);
295
          if ($ajax) {
296
            $this->drupalPostAJAX(NULL, $edit, $input_base_name . '_attach_button');
297
          }
298
          else {
299
            $this->drupalPost(NULL, $edit, t('Attach'));
300
          }
301
          $this->drupalPost(NULL, array(), t('Save'));
302
          $this->assertRaw(t('The file id is %fid.', array('%fid' => $test_file->fid)), 'Submit handler has correct file info.');
303
304
          // Attach, then Remove, then Submit.
305
          $this->drupalGet($path);
306
          $edit = array('media[' . $input_base_name . ']' => $test_file->fid);
307
          if ($ajax) {
308
            $this->drupalPostAJAX(NULL, $edit, $input_base_name . '_attach_button');
309
            $this->drupalPostAJAX(NULL, array(), $input_base_name . '_remove_button');
310
          }
311
          else {
312
            $this->drupalPost(NULL, $edit, t('Attach'));
313
            $this->drupalPost(NULL, array(), t('Remove'));
314
          }
315
          $this->drupalPost(NULL, array(), t('Save'));
316
          $this->assertRaw(t('The file id is %fid.', array('%fid' => 0)), 'Submission after file attachment and removal was successful.');
317
        }
318
      }
319
    }
320
  }
321
}
322
323
/**
324
 * Test media file administration page functionality.
325
 */
326
class MediaAdminTestCase extends MediaFileFieldTestCase {
327
  public static function getInfo() {
328
    return array(
329
      'name' => 'Media file administration',
330
      'description' => 'Test media file administration page functionality.',
331
      'group' => 'Media',
332
    );
333
  }
334
335
  function setUp() {
336
    parent::setUp();
337
    // Remove the "view files" permission which is set
338
    // by default for all users so we can test this permission
339
    // correctly.
340
    $roles = user_roles();
341
    foreach ($roles as $rid => $role) {
342
      user_role_revoke_permissions($rid, array('view files'));
343
    }
344
345
    $this->base_user_1 = $this->drupalCreateUser(array('administer files'));
346
    $this->base_user_2 = $this->drupalCreateUser(array('administer files', 'view own private files'));
347
    $this->base_user_3 = $this->drupalCreateUser(array('administer files', 'view private files'));
348
    $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'));
349
  }
350
351
  /**
352
   * Tests that the table sorting works on the files admin pages.
353
   */
354
  function testFilesAdminSort() {
355
    $i = 0;
356
    foreach (array('dd', 'aa', 'DD', 'bb', 'cc', 'CC', 'AA', 'BB') as $prefix) {
357
      $this->createFileEntity(array('filepath' => $prefix . $this->randomName(6), 'timestamp' => $i));
358
      $i++;
359
    }
360
361
    // Test that the default sort by file_managed.timestamp DESC actually fires properly.
362
    $files_query = db_select('file_managed', 'fm')
363
      ->fields('fm', array('fid'))
364
      ->orderBy('timestamp', 'DESC')
365
      ->execute()
366
      ->fetchCol();
367
368
    $files_form = array();
369
    $this->drupalGet('admin/content/file/thumbnails');
370
    foreach ($this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]/@data-fid') as $input) {
371
      $files_form[] = $input;
372
    }
373
    $this->assertEqual($files_query, $files_form, 'Files are sorted in the form according to the default query.');
374
375
    // Compare the rendered HTML node list to a query for the files ordered by
376
    // filename to account for possible database-dependent sort order.
377
    $files_query = db_select('file_managed', 'fm')
378
      ->fields('fm', array('fid'))
379
      ->orderBy('filename')
380
      ->execute()
381
      ->fetchCol();
382
383
    $files_form = array();
384
    $this->drupalGet('admin/content/file/thumbnails', array('query' => array('sort' => 'asc', 'order' => 'Title')));
385
    foreach ($this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]/@data-fid') as $input) {
386
      $files_form[] = $input;
387
    }
388
    $this->assertEqual($files_query, $files_form, 'Files are sorted in the form the same as they are in the query.');
389
  }
390
391
  /**
392
   * Tests files overview with different user permissions.
393
   */
394
  function testFilesAdminPages() {
395
    $files['public_image'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_1->uid, 'type' => 'image'));
396
    $files['public_document'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_2->uid, 'type' => 'document'));
397
    $files['private_image'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_1->uid, 'type' => 'image'));
398
    $files['private_document'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_2->uid, 'type' => 'document'));
399
400
    // Verify view and edit links for any file.
401
    $this->drupalGet('admin/content/file/thumbnails');
402
    $this->assertResponse(200);
403
    foreach ($files as $file) {
404
      $this->assertLinkByHref('file/' . $file->fid);
405
      $this->assertLinkByHref('file/' . $file->fid . '/edit');
406
      // Verify tableselect.
407
      $this->assertFieldByName('files[' . $file->fid . ']', '', t('Tableselect found.'));
408
    }
409
410
    // Verify no operation links are displayed for regular users.
411
    $this->drupalLogout();
412
    $this->drupalLogin($this->base_user_1);
413
    $this->drupalGet('admin/content/file/thumbnails');
414
    $this->assertResponse(200);
415
    $this->assertLinkByHref('file/' . $files['public_image']->fid);
416
    $this->assertLinkByHref('file/' . $files['public_document']->fid);
417
    $this->assertNoLinkByHref('file/' . $files['public_image']->fid . '/edit');
418
    $this->assertNoLinkByHref('file/' . $files['public_document']->fid . '/edit');
419
420
    // Verify no tableselect.
421
    $this->assertNoFieldByName('files[' . $files['public_image']->fid . ']', '', t('No tableselect found.'));
422
423
    // Verify private file is displayed with permission.
424
    $this->drupalLogout();
425
    $this->drupalLogin($this->base_user_2);
426
    $this->drupalGet('admin/content/file/thumbnails');
427
    $this->assertResponse(200);
428
    $this->assertLinkByHref('file/' . $files['private_document']->fid);
429
    // Verify no operation links are displayed.
430
    $this->assertNoLinkByHref('file/' . $files['private_document']->fid . '/edit');
431
432
    // Verify user cannot see private file of other users.
433
    $this->assertNoLinkByHref('file/' . $files['private_image']->fid);
434
    $this->assertNoLinkByHref('file/' . $files['private_image']->fid . '/edit');
435
436
    // Verify no tableselect.
437
    $this->assertNoFieldByName('files[' . $files['private_document']->fid . ']', '', t('No tableselect found.'));
438
439
    // Verify private file is displayed with permission.
440
    $this->drupalLogout();
441
    $this->drupalLogin($this->base_user_3);
442
    $this->drupalGet('admin/content/file/thumbnails');
443
    $this->assertResponse(200);
444
445
    // Verify user can see private file of other users.
446
    $this->assertLinkByHref('file/' . $files['private_document']->fid);
447
    $this->assertLinkByHref('file/' . $files['private_image']->fid);
448
449
    // Verify operation links are displayed for users with appropriate permission.
450
    $this->drupalLogout();
451
    $this->drupalLogin($this->base_user_4);
452
    $this->drupalGet('admin/content/file/thumbnails');
453
    $this->assertResponse(200);
454
    foreach ($files as $file) {
455
      $this->assertLinkByHref('file/' . $file->fid);
456
      $this->assertLinkByHref('file/' . $file->fid . '/edit');
457
    }
458
459
    // Verify file access can be bypassed.
460
    $this->drupalLogout();
461
    $this->drupalLogin($this->admin_user);
462
    $this->drupalGet('admin/content/file/thumbnails');
463
    $this->assertResponse(200);
464
    foreach ($files as $file) {
465
      $this->assertLinkByHref('file/' . $file->fid);
466
      $this->assertLinkByHref('file/' . $file->fid . '/edit');
467
    }
468
  }
469
}
470
471 bf3c8457 Florent Torregrosa
/**
472
 * Tests the media hooks.
473
 */
474
class MediaHooksTestCase extends MediaFileFieldTestCase {
475
  public static function getInfo() {
476
    return array(
477
      'name' => 'Media hooks test',
478
      'description' => 'Tests the Media hooks.',
479
      'group' => 'Media',
480
    );
481
  }
482
483
  function setUp() {
484
    parent::setUp();
485
  }
486
487
  /**
488
   * Tests that the media browser hooks.
489
   */
490
  function testMediaBrowserHooks() {
491
    // Enable media_module_test.module's hook_media_browser_plugin_info()
492
    // implementation and ensure it is working as designed.
493
    variable_set('media_module_test_media_browser_plugin_info', TRUE);
494
495
    $this->drupalGet('media/browser');
496
    $this->assertRaw(t('Media module test'), 'Custom browser plugin found.');
497
498
    // Enable media_module_test.module's hook_media_browser_plugin_info_alter()
499
    // implementation and ensure it is working as designed.
500
    variable_set('media_module_test_media_browser_plugin_info_alter', TRUE);
501
502
    $this->drupalGet('media/browser');
503
    $this->assertRaw(t('Altered plugin title'), 'Custom browser plugin was successfully altered.');
504
505
    // Enable media_module_test.module's hook_media_browser_plugins_alter()
506
    // implementation and ensure it is working as designed.
507
    variable_set('media_module_test_media_browser_plugins_alter', TRUE);
508
509
    $this->drupalGet('media/browser');
510
    $this->assertRaw(t('Altered browser plugin output.'), 'Custom browser plugin was successfully altered before being rendered.');
511
  }
512
}
513
514 ca0757b9 Assos Assos
/**
515
 * Tests the media browser 'Library' tab.
516
 */
517
class MediaBrowserLibraryTestCase extends MediaFileFieldTestCase {
518
  public static function getInfo() {
519
    return array(
520
      'name' => 'Media browser library test',
521
      'description' => 'Tests the media browser library tab.',
522
      'group' => 'Media',
523
    );
524
  }
525
526
  function setUp() {
527
    parent::setUp();
528
    $this->base_user_1 = $this->drupalCreateUser(array('access media browser', 'create files', 'administer files'));
529
    $this->base_user_2 = $this->drupalCreateUser(array('access media browser', 'create files', 'administer files', 'view own private files'));
530
    $this->base_user_3 = $this->drupalCreateUser(array('access media browser', 'create files', 'administer files', 'view private files'));
531
  }
532
533
  /**
534
   * Tests that the views sorting works on the media browser 'Library' tab.
535
   */
536
  function testFilesBrowserSort() {
537
    // Load only the 'Library' tab of the media browser.
538
    $options = array(
539
      'query' => array(
540
        'enabledPlugins' => array(
541
          'media_default--media_browser_1' => 'media_default--media_browser_1',
542
        ),
543
      ),
544
    );
545
546
    $i = 0;
547
    foreach (array('dd', 'aa', 'DD', 'bb', 'cc', 'CC', 'AA', 'BB') as $prefix) {
548
      $this->createFileEntity(array('filepath' => $prefix . $this->randomName(6), 'timestamp' => $i));
549
      $i++;
550
    }
551
552
    // Test that the default sort by file_managed.timestamp DESC actually fires properly.
553
    $files_query = db_select('file_managed', 'fm')
554
      ->fields('fm', array('fid'))
555
      ->orderBy('timestamp', 'DESC')
556
      ->execute()
557
      ->fetchCol();
558
559
    $files_form = array();
560
    $this->drupalGet('media/browser', $options);
561
    foreach ($this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]/@data-fid') as $input) {
562
      $files_form[] = $input;
563
    }
564
    $this->assertEqual($files_query, $files_form, 'Files are sorted in the form according to the default query.');
565
  }
566 85ad3d82 Assos Assos
567
  /**
568 ca0757b9 Assos Assos
   * Tests media browser 'Library' tab with different user permissions.
569 85ad3d82 Assos Assos
   */
570 ca0757b9 Assos Assos
  function testFilesBrowserLibrary() {
571
    // Load only the 'Library' tab of the media browser.
572
    $options = array(
573
      'query' => array(
574
        'enabledPlugins' => array(
575
          'media_default--media_browser_1' => 'media_default--media_browser_1',
576
        ),
577
      ),
578
    );
579
580
    $files['public_image'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_1->uid, 'type' => 'image'));
581
    $files['public_document'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_2->uid, 'type' => 'document'));
582
    $files['private_image'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_1->uid, 'type' => 'image'));
583
    $files['private_document'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_2->uid, 'type' => 'document'));
584
585
    // Verify all files are displayed for administrators.
586
    $this->drupalGet('media/browser', $options);
587
    $this->assertResponse(200);
588
    foreach ($files as $file) {
589
      $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
590
        ':fid' => $file->fid,
591
      ));
592
      $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $file->fid)));
593
    }
594
595
    // Verify public files are displayed.
596
    $this->drupalLogout();
597
    $this->drupalLogin($this->base_user_1);
598
    $this->drupalGet('media/browser', $options);
599
    $this->assertResponse(200);
600
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
601
      ':fid' => $files['public_image']->fid,
602
    ));
603
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['public_image']->fid)));
604
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
605
      ':fid' => $files['public_document']->fid,
606
    ));
607
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['public_document']->fid)));
608
609
    // Verify private file is displayed with permission.
610
    $this->drupalLogout();
611
    $this->drupalLogin($this->base_user_2);
612
    $this->drupalGet('media/browser', $options);
613
    $this->assertResponse(200);
614
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
615
      ':fid' => $files['private_document']->fid,
616
    ));
617
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['private_document']->fid)));
618
619
    // Verify user cannot see private file of other users.
620
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
621
      ':fid' => $files['private_image']->fid,
622
    ));
623
    $this->assertNoFieldByXPath($xpath, TRUE, format_string('File with file ID %fid not found.', array('%fid' => $files['private_image']->fid)));
624
625
    // Verify private file is displayed with permission.
626
    $this->drupalLogout();
627
    $this->drupalLogin($this->base_user_3);
628
    $this->drupalGet('media/browser', $options);
629
    $this->assertResponse(200);
630
631
    // Verify user can see private file of other users.
632
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
633
      ':fid' => $files['private_document']->fid,
634
    ));
635
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['private_document']->fid)));
636
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
637
      ':fid' => $files['private_image']->fid,
638
    ));
639
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['private_image']->fid)));
640
641
    // Verify file access can be bypassed.
642
    $this->drupalLogout();
643
    $this->drupalLogin($this->admin_user);
644
    $this->drupalGet('media/browser', $options);
645
    $this->assertResponse(200);
646
    foreach ($files as $file) {
647
      $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
648
        ':fid' => $file->fid,
649
      ));
650
      $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $file->fid)));
651
    }
652
  }
653
}
654
655
/**
656
 * Tests the media browser settings.
657
 */
658
class MediaBrowserSettingsTestCase extends MediaFileFieldTestCase {
659
  public static function getInfo() {
660
    return array(
661
      'name' => 'Media browser settings test',
662
      'description' => 'Tests the media browser settings.',
663
      'group' => 'Media',
664
    );
665
  }
666
667
  function setUp() {
668
    parent::setUp('file_test');
669
  }
670
671
  /**
672
   * Tests the media browser settings.
673
   */
674
  function testBrowserSettings() {
675
    $settings = array(
676
      'scheme' => array('public', 'private'),
677
      'type' => array('image', 'document'),
678
      'extension' => array('jpg', 'txt'),
679
    );
680
681
    // Perform the tests with unique permutations of $scheme, $type and
682
    // $extension.
683
    foreach ($settings['scheme'] as $scheme) {
684
      foreach ($settings['type'] as $type) {
685
        foreach ($settings['extension'] as $extension) {
686
          $file = $this->createFileEntity(array('scheme' => $scheme, 'uid' => $this->admin_user->uid, 'type' => $type, 'filemime' => media_get_extension_mimetype($extension)));
687
688 388c412d Assos Assos
          // Some of the settings such as the scheme and extension are unsafe to
689
          // pass as query arguments, cache them and pass the cache ID.
690 ca0757b9 Assos Assos
          $options = array(
691 388c412d Assos Assos
            'enabledPlugins' => array(
692
              'media_default--media_browser_1' => 'media_default--media_browser_1',
693 ca0757b9 Assos Assos
            ),
694 388c412d Assos Assos
          'schemes' => array($scheme),
695
            'types' => array($type),
696
            'file_extensions' => $extension,
697 ca0757b9 Assos Assos
          );
698
699 388c412d Assos Assos
          $cid = drupal_get_token(drupal_random_bytes(32));
700
          cache_set('media_options:' . $cid, $options, 'cache_form', REQUEST_TIME + 21600);
701
702 ca0757b9 Assos Assos
          // Verify that the file is displayed.
703 388c412d Assos Assos
          $this->drupalGet('media/browser', array('query' => array('options' => $cid)));
704 ca0757b9 Assos Assos
          $this->assertResponse(200);
705
          $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
706
            ':fid' => $file->fid,
707
          ));
708
          $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $file->fid)));
709
710
          // Verify that no other files are also displayed.
711
          $files = $this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]');
712
          $this->assertEqual(count($files), 1, 'There is only one file that matches the current browser configuration.');
713
        }
714
      }
715
    }
716
717
    // Perform the tests with none and all of the restrictions.
718
    foreach (array('none', 'all') as $restrictions) {
719
      $options = array(
720 388c412d Assos Assos
        'enabledPlugins' => array(
721
          'media_default--media_browser_1' => 'media_default--media_browser_1',
722 ca0757b9 Assos Assos
        ),
723
      );
724
725
      switch ($restrictions) {
726
        case 'none':
727 388c412d Assos Assos
          $options['schemes'] = array();
728
          $options['types'] = array();
729
          $options['file_extensions'] = array();
730 ca0757b9 Assos Assos
          break;
731
        case 'all':
732 388c412d Assos Assos
          $options['schemes'] = $settings['scheme'];
733
          $options['types'] = $settings['type'];
734
          $options['file_extensions'] = implode(' ', $settings['extension']);
735 ca0757b9 Assos Assos
          break;
736
      }
737
738 388c412d Assos Assos
      $cid = drupal_get_token(drupal_random_bytes(32));
739
      cache_set('media_options:' . $cid, $options, 'cache_form', REQUEST_TIME + 21600);
740
741 ca0757b9 Assos Assos
      // Verify that all of the files are displayed.
742 388c412d Assos Assos
      $this->drupalGet('media/browser', array('query' => array('options' => $cid)));
743 ca0757b9 Assos Assos
      $this->assertResponse(200);
744
      $files = $this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]');
745
      $this->assertEqual(count($files), 8, format_string('All of the files were displayed when %restrictions of the restrictions were enabled.', array('%restrictions' => $restrictions)));
746
    }
747
748
    // Verify that extension restrictions do not affect remote files.
749
    $scheme = 'dummy-remote';
750
    $type = 'video';
751
    $extension = 'mp4';
752
753
    $file = $this->createFileEntity(array('scheme' => $scheme, 'uid' => $this->admin_user->uid, 'type' => $type, 'filemime' => media_get_extension_mimetype($extension)));
754
755
    $options = array(
756 388c412d Assos Assos
      'enabledPlugins' => array(
757
        'media_default--media_browser_1' => 'media_default--media_browser_1',
758 ca0757b9 Assos Assos
      ),
759 388c412d Assos Assos
      'schemes' => array($scheme, 'public'), // Include a local stream wrapper in order to trigger extension restrictions.
760
      'types' => array($type),
761
      'file_extensions' => 'fake', // Use an invalid file extension to ensure that it does not affect restrictions.
762 ca0757b9 Assos Assos
    );
763
764 388c412d Assos Assos
    $cid = drupal_get_token(drupal_random_bytes(32));
765
    cache_set('media_options:' . $cid, $options, 'cache_form', REQUEST_TIME + 21600);
766
767 ca0757b9 Assos Assos
    // Verify that the file is displayed.
768 388c412d Assos Assos
    $this->drupalGet('media/browser', array('query' => array('options' => $cid)));
769 ca0757b9 Assos Assos
    $this->assertResponse(200);
770
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
771
      ':fid' => $file->fid,
772
    ));
773
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $file->fid)));
774
775
    // Verify that no other files are also displayed.
776
    $files = $this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]');
777
    $this->assertEqual(count($files), 1, 'There is only one file that matches the current browser configuration.');
778
  }
779
}
780
781
/**
782
 * Tests the media browser 'My files' tab.
783
 */
784
class MediaBrowserMyFilesTestCase extends MediaFileFieldTestCase {
785
  public static function getInfo() {
786
    return array(
787
      'name' => 'Media browser my files test',
788
      'description' => 'Tests the media browser my files tab.',
789
      'group' => 'Media',
790
    );
791
  }
792
793
  function setUp() {
794
    parent::setUp();
795
    $this->base_user_1 = $this->drupalCreateUser(array('access media browser', 'create files', 'administer files'));
796
    $this->base_user_2 = $this->drupalCreateUser(array('access media browser', 'create files', 'administer files', 'view own files'));
797
    $this->base_user_3 = $this->drupalCreateUser(array('access media browser', 'create files', 'administer files', 'view own files', 'view own private files'));
798
  }
799
800
  /**
801
   * Tests media browser 'My files' tab with different user permissions.
802
   */
803
  function testFilesBrowserMyFiles() {
804
    // Load only the 'My files' tab of the media browser.
805
    $options = array(
806
      'query' => array(
807
        'enabledPlugins' => array(
808
          'media_default--media_browser_my_files' => 'media_default--media_browser_my_files',
809
        ),
810
      ),
811
    );
812
813
    $files['public_image'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_2->uid, 'type' => 'image'));
814
    $files['public_document'] = $this->createFileEntity(array('scheme' => 'public', 'uid' => $this->base_user_3->uid, 'type' => 'document'));
815
    $files['private_image'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_2->uid, 'type' => 'image'));
816
    $files['private_document'] = $this->createFileEntity(array('scheme' => 'private', 'uid' => $this->base_user_3->uid, 'type' => 'document'));
817
818
    // Verify administrators do not have any special access to files.
819
    $this->drupalGet('media/browser', $options);
820
    $this->assertResponse(200);
821
    foreach ($files as $file) {
822
      $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
823
        ':fid' => $file->fid,
824
      ));
825
      $this->assertNoFieldByXPath($xpath, TRUE, format_string('File with file ID %fid not found.', array('%fid' => $file->fid)));
826
    }
827
828
    // Verify users require the 'view own files' permission in order to access
829
    // the 'My files' tab.
830
    $this->drupalLogout();
831
    $this->drupalLogin($this->base_user_1);
832
    $this->drupalGet('media/browser', $options);
833
    $this->assertResponse(200);
834
    $xpath = $this->buildXPathQuery('//div[@class="media_default--media_browser_my_files"]');
835
    $this->assertNoFieldByXPath($xpath, TRUE, 'User with insufficient permissions was unable to view the My files tab.');
836
837
    // Verify own public files are displayed.
838
    $this->drupalLogout();
839
    $this->drupalLogin($this->base_user_2);
840
    $this->drupalGet('media/browser', $options);
841
    $this->assertResponse(200);
842
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
843
      ':fid' => $files['public_image']->fid,
844
    ));
845
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['public_image']->fid)));
846
847
    // Verify own private file is displayed with permission.
848
    $this->drupalLogout();
849
    $this->drupalLogin($this->base_user_3);
850
    $this->drupalGet('media/browser', $options);
851
    $this->assertResponse(200);
852
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
853
      ':fid' => $files['private_document']->fid,
854
    ));
855
    $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $files['private_document']->fid)));
856
857
    // Verify user cannot see files of other users.
858
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
859
      ':fid' => $files['public_image']->fid,
860
    ));
861
    $this->assertNoFieldByXPath($xpath, TRUE, format_string('File with file ID %fid not found.', array('%fid' => $files['public_image']->fid)));
862
    $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array(
863
      ':fid' => $files['private_image']->fid,
864
    ));
865
    $this->assertNoFieldByXPath($xpath, TRUE, format_string('File with file ID %fid not found.', array('%fid' => $files['private_image']->fid)));
866
  }
867
}
868
869
/**
870
 * Tests the 'media' element type settings.
871
 */
872
class MediaElementSettingsTestCase extends MediaFileFieldTestCase {
873
  public static function getInfo() {
874
    return array(
875
      'name' => 'Media element settings test',
876
      'description' => 'Tests the media element type JavaScript settings.',
877
      'group' => 'Media',
878
    );
879
  }
880
881
  /**
882
   * Tests the media element type settings.
883
   */
884
  function testElementSettings() {
885
    $form = array(
886
      '#type' => 'media',
887
    );
888
    drupal_render($form);
889
    $javascript = drupal_get_js();
890
    $global = array(
891
      'media' => array(
892
        'global' => array(
893
          'global' => array(
894
            'types' => array(),
895
            'schemes' => array(),
896
          ),
897
        ),
898
      ),
899
    );
900
    $settings = drupal_json_encode(drupal_array_merge_deep_array($global));
901
    $this->assertTrue(strpos($javascript, $settings) > 0, 'Rendered media element adds the global settings.');
902
  }
903
904 388c412d Assos Assos
  /**
905
   * Tests that the field widget does not contain the insecure settings.
906
   */
907
  function testInsecureSettings() {
908
    // Use 'page' instead of 'article', so that the 'article' image field does
909
    // not conflict with this test. If in the future the 'page' type gets its
910
    // own default file or image field, this test can be made more robust by
911
    // using a custom node type.
912
    $type_name = 'page';
913
    $field_name = strtolower($this->randomName());
914
    $this->createFileField($field_name, $type_name);
915
    $this->drupalGet("node/add/$type_name");
916
917
    $insecure_settings = array(
918
      'file_directory',
919
      'file_extensions',
920
      'max_filesize',
921
      'uri_scheme',
922
    );
923
    foreach ($insecure_settings as $setting) {
924
      $this->assertNoRaw($setting, format_string('Media file field widget does not contain the insecure element-specific setting @setting.', array(
925
        '@setting' => $setting,
926
      )));
927
    }
928
  }
929
930 b1ab1c0c Assos Assos
  /**
931
   * Tests that insecure settings are not processed when sent via query parameters.
932
   */
933
  function testBrowserInsecureQueryParameters() {
934
    // Test file directory override.
935
    $path = file_unmanaged_save_data('directorytest', 'temporary://directorytest.txt');
936
    $data = array('files[upload]' => drupal_realpath($path));
937
    $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('file_directory' => 'insecure_upload')));
938
    // Verify that the file was placed in the normal public:// path instead of the folder we specified.
939
    $this->assertFalse(is_file('public://insecure_upload/directorytest.txt'), 'File was not uploaded to the directory specified in the query parameters.');
940
    $this->assertTrue(is_file('public://directorytest.txt'), 'File was uploaded to the default public directory.');
941
942
    // Test file_extensions override.
943
    $path = file_unmanaged_save_data('extensiontest', 'temporary://extensiontest.exe');
944
    $data = array('files[upload]' => drupal_realpath($path));
945
    $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('file_extensions' => 'exe')));
946
    $this->assertFalse(is_file('public://extensiontest.exe'), 'File with extension passed via query parameter was not uploaded.');
947
948
    // Test max_filesize override.
949
    variable_set('file_entity_max_filesize', '8 bytes');
950
    $path = file_unmanaged_save_data('maxfilesize', 'temporary://maxfilesize.txt');
951
    $data = array('files[upload]' => drupal_realpath($path));
952
    $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('max_filesize' => '100 bytes')));
953
    $this->assertFalse(is_file('public://maxfilesize.txt'), 'File larger than max file size was not uploaded with larger query parameter.');
954
    variable_del('file_entity_max_filesize');
955
956
    // Test uri_scheme override.
957
    $path = file_unmanaged_save_data('urischeme', 'temporary://urischeme.txt');
958
    $data = array('files[upload]' => drupal_realpath($path));
959
    $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('uri_scheme' => 'private')));
960
    $this->assertFalse(is_file('private://urischeme.txt'), 'File was not uploaded to scheme set in URL.');
961
    $this->assertTrue(is_file('public://urischeme.txt'), 'File was uploaded to default scheme instead of scheme set in URL.');
962
963
    // Test upload_validators override.
964
    $path = file_unmanaged_save_data('uploadvalidators', 'temporary://uploadvalidators.txt');
965
    $data = array('files[upload]' => drupal_realpath($path));
966
    $this->drupalPost('media/browser', $data, t('Upload'), array('query' => array('upload_validators' => array('file_move' => array('public://exploit.php')))));
967
    $this->assertFalse(is_file('public://exploit.php'), 'file_move() was not triggered by upload_validators parameter.');
968
    $this->assertTrue(is_file('public://uploadvalidators.txt'), 'File was uploaded without triggering file_move().');
969
  }
970
971 ca0757b9 Assos Assos
  /**
972
   * Tests the media file field widget settings.
973
   */
974
  function testWidgetSettings() {
975
    // Use 'page' instead of 'article', so that the 'article' image field does
976
    // not conflict with this test. If in the future the 'page' type gets its
977
    // own default file or image field, this test can be made more robust by
978
    // using a custom node type.
979
    $type_name = 'page';
980
    $field_name = strtolower($this->randomName());
981
    $this->createFileField($field_name, $type_name);
982
    $field = field_info_field($field_name);
983
    $instance = field_info_instance('node', $field_name, $type_name);
984
985
    $javascript = $this->drupalGet("node/add/$type_name");
986 fc3d89c3 Assos Assos
987
    $multiselect = ($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED);
988 ca0757b9 Assos Assos
    $field_widget = array(
989
        'elements' => array(
990 0939d55c Assos Assos
          '.js-media-element-edit-' . $field_name . '-' . LANGUAGE_NONE . '-0-upload' => array(
991 ca0757b9 Assos Assos
            'global' => array(
992
              'types' => array(
993 bf3c8457 Florent Torregrosa
                'image' => 'image',
994 ca0757b9 Assos Assos
              ),
995
              'enabledPlugins' => array(),
996
              'schemes' => array(
997 bf3c8457 Florent Torregrosa
                'public' => 'public',
998 ca0757b9 Assos Assos
              ),
999
              'file_directory' => '',
1000
              'file_extensions' => 'txt',
1001
              'max_filesize' => '',
1002
              'uri_scheme' => 'public',
1003 fc3d89c3 Assos Assos
              'multiselect' => $multiselect,
1004 18596a08 Assos Assos
              'field' => $field_name,
1005 ca0757b9 Assos Assos
            ),
1006
          ),
1007
        ),
1008
    );
1009
    $settings = drupal_json_encode(drupal_array_merge_deep_array($field_widget));
1010 388c412d Assos Assos
    $string_with_options = '-0-upload":{"global":{"options":"';
1011
    $index_of_cid = strpos($javascript, $string_with_options) + strlen($string_with_options);
1012
    $index_end_of_cid = strpos($javascript, '"', $index_of_cid + 1);
1013
    $cid = substr($javascript, $index_of_cid, ($index_end_of_cid - $index_of_cid));
1014
1015
    // Retrieve the security sensitive options from the cache using the cid parsed out from the $javascript variable
1016
    $retrieved_settings = cache_get('media_options:' . $cid, 'cache_form');
1017
    $retrieved_settings = array('.js-media-element-edit-' . $field_name . '-' . LANGUAGE_NONE . '-0-upload' => array(
1018
                                  'global' => $retrieved_settings->data));
1019
    $retrieved_settings_json = drupal_json_encode($retrieved_settings);
1020
1021
    $this->assertTrue($retrieved_settings_json == $settings, 'Media file field widget retrieved from cache and has element-specific settings.');
1022
    $this->assertTrue(strpos($javascript, $cid) > 0, 'Media file field widget is cached and its` cache id is found.');
1023 ca0757b9 Assos Assos
  }
1024
}
1025
1026
/**
1027
 * Tests file handling with node revisions.
1028
 */
1029
class MediaFileFieldRevisionTestCase extends MediaFileFieldTestCase {
1030
  public static function getInfo() {
1031
    return array(
1032
      'name' => 'Media file field revision test',
1033
      'description' => 'Test creating and deleting revisions with files attached.',
1034
      'group' => 'Media',
1035
    );
1036
  }
1037
1038
  /**
1039
   * Tests creating multiple revisions of a node and managing attached files.
1040
   *
1041
   * Expected behaviors:
1042
   *  - Adding a new revision will make another entry in the field table, but
1043
   *    the original file will not be duplicated.
1044
   *  - Deleting a revision should not delete the original file if the file
1045
   *    is in use by another revision.
1046
   *  - When the last revision that uses a file is deleted, the original file
1047
   *    should be deleted also.
1048
   */
1049
  function testRevisions() {
1050
    $type_name = 'article';
1051
    $field_name = strtolower($this->randomName());
1052
    $this->createFileField($field_name, $type_name);
1053
    $field = field_info_field($field_name);
1054
    $instance = field_info_instance('node', $field_name, $type_name);
1055
1056
    // Attach the same fields to users.
1057
    $this->attachFileField($field_name, 'user', 'user');
1058
1059
    $test_file = $this->getTestFile('text');
1060
    $test_file->uid = $this->admin_user->uid;
1061
    $test_file = file_save($test_file);
1062
1063
    // Create a new node with the uploaded file.
1064
    $nid = $this->attachNodeFile($test_file, $field_name, $type_name);
1065
1066
    // Check that the file exists on disk and in the database.
1067
    $node = node_load($nid, NULL, TRUE);
1068
    $node_file_r1 = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1069
    $node_vid_r1 = $node->vid;
1070
    $this->assertFileExists($node_file_r1, 'New file saved to disk on node creation.');
1071
    $this->assertFileEntryExists($node_file_r1, 'File entry exists in database on node creation.');
1072
    $this->assertFileIsPermanent($node_file_r1, 'File is permanent.');
1073
1074
    // Upload another file to the same node in a new revision.
1075
    $this->replaceNodeFile($test_file, $field_name, $nid);
1076
    $node = node_load($nid, NULL, TRUE);
1077
    $node_file_r2 = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1078
    $node_vid_r2 = $node->vid;
1079
    $this->assertFileExists($node_file_r2, 'Replacement file exists on disk after creating new revision.');
1080
    $this->assertFileEntryExists($node_file_r2, 'Replacement file entry exists in database after creating new revision.');
1081
    $this->assertFileIsPermanent($node_file_r2, 'Replacement file is permanent.');
1082
1083
    // Check that the original file is still in place on the first revision.
1084
    $node = node_load($nid, $node_vid_r1, TRUE);
1085
    $this->assertEqual($node_file_r1, (object) $node->{$field_name}[LANGUAGE_NONE][0], 'Original file still in place after replacing file in new revision.');
1086
    $this->assertFileExists($node_file_r1, 'Original file still in place after replacing file in new revision.');
1087
    $this->assertFileEntryExists($node_file_r1, 'Original file entry still in place after replacing file in new revision');
1088
    $this->assertFileIsPermanent($node_file_r1, 'Original file is still permanent.');
1089
1090
    // Save a new version of the node without any changes.
1091
    // Check that the file is still the same as the previous revision.
1092
    $this->drupalPost('node/' . $nid . '/edit', array('revision' => '1'), t('Save'));
1093
    $node = node_load($nid, NULL, TRUE);
1094
    $node_file_r3 = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1095
    $node_vid_r3 = $node->vid;
1096
    $this->assertEqual($node_file_r2, $node_file_r3, 'Previous revision file still in place after creating a new revision without a new file.');
1097
    $this->assertFileIsPermanent($node_file_r3, 'New revision file is permanent.');
1098
1099
    // Revert to the first revision and check that the original file is active.
1100
    $this->drupalPost('node/' . $nid . '/revisions/' . $node_vid_r1 . '/revert', array(), t('Revert'));
1101
    $node = node_load($nid, NULL, TRUE);
1102
    $node_file_r4 = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1103
    $node_vid_r4 = $node->vid;
1104
    $this->assertEqual($node_file_r1, $node_file_r4, 'Original revision file still in place after reverting to the original revision.');
1105
    $this->assertFileIsPermanent($node_file_r4, 'Original revision file still permanent after reverting to the original revision.');
1106
1107
    // Delete the second revision and check that the file is kept (since it is
1108
    // still being used by the third revision).
1109
    $this->drupalPost('node/' . $nid . '/revisions/' . $node_vid_r2 . '/delete', array(), t('Delete'));
1110
    $this->assertFileExists($node_file_r3, 'Second file is still available after deleting second revision, since it is being used by the third revision.');
1111
    $this->assertFileEntryExists($node_file_r3, 'Second file entry is still available after deleting second revision, since it is being used by the third revision.');
1112
    $this->assertFileIsPermanent($node_file_r3, 'Second file entry is still permanent after deleting second revision, since it is being used by the third revision.');
1113
1114
    // Attach the second file to a user.
1115
    $user = $this->drupalCreateUser();
1116
    $edit = (array) $user;
1117
    $edit[$field_name][LANGUAGE_NONE][0] = (array) $node_file_r3;
1118
    user_save($user, $edit);
1119
    $this->drupalGet('user/' . $user->uid . '/edit');
1120
1121
    // Delete the third revision and check that the file is not deleted yet.
1122
    $this->drupalPost('node/' . $nid . '/revisions/' . $node_vid_r3 . '/delete', array(), t('Delete'));
1123
    $this->assertFileExists($node_file_r3, 'Second file is still available after deleting third revision, since it is being used by the user.');
1124
    $this->assertFileEntryExists($node_file_r3, 'Second file entry is still available after deleting third revision, since it is being used by the user.');
1125
    $this->assertFileIsPermanent($node_file_r3, 'Second file entry is still permanent after deleting third revision, since it is being used by the user.');
1126
1127
    // Delete the user and check that the file still exists.
1128
    user_delete($user->uid);
1129
    // TODO: This seems like a bug in File API. Clearing the stat cache should
1130
    // not be necessary here. The file really exists, but stream wrappers
1131
    // doesn't seem to think so unless we clear the PHP file stat() cache.
1132
    clearstatcache();
1133
    // @todo Files referenced from entity revisions cannot currently be deleted after the entity is deleted.
1134
    // @see https://drupal.org/node/1613290
1135
    // $this->assertFileNotExists($node_file_r3, 'Second file is now deleted after deleting third revision, since it is no longer being used by any other nodes.');
1136
    // $this->assertFileEntryNotExists($node_file_r3, 'Second file entry is now deleted after deleting third revision, since it is no longer being used by any other nodes.');
1137
1138
    // Delete the entire node and check that the original file is deleted.
1139
    $this->drupalPost('node/' . $nid . '/delete', array(), t('Delete'));
1140
    $this->assertFileNotExists($node_file_r1, 'Original file is deleted after deleting the entire node with two revisions remaining.');
1141
    $this->assertFileEntryNotExists($node_file_r1, 'Original file entry is deleted after deleting the entire node with two revisions remaining.');
1142
  }
1143
}
1144
1145
/**
1146
 * Tests various validations.
1147
 */
1148
class MediaFileFieldValidateTestCase extends MediaFileFieldTestCase {
1149
  protected $field;
1150
1151
  public static function getInfo() {
1152
    return array(
1153
      'name' => 'Media file field validation tests',
1154
      'description' => 'Tests validation functions such as required.',
1155
      'group' => 'Media',
1156
    );
1157
  }
1158
1159
  /**
1160
   * Tests the required property on file fields.
1161
   */
1162
  function testRequired() {
1163
    $type_name = 'article';
1164
    $field_name = strtolower($this->randomName());
1165
    $this->createFileField($field_name, $type_name, array(), array('required' => '1'));
1166
    $field = field_info_field($field_name);
1167
    $instance = field_info_instance('node', $field_name, $type_name);
1168
1169
    $test_file = $this->getTestFile('text');
1170
    $test_file->uid = $this->admin_user->uid;
1171
    $test_file = file_save($test_file);
1172
1173
    // Try to post a new node without attaching a file.
1174
    $langcode = LANGUAGE_NONE;
1175
    $edit = array("title" => $this->randomName());
1176
    $this->drupalPost('node/add/' . $type_name, $edit, t('Save'));
1177
    $this->assertRaw(t('!title field is required.', array('!title' => $instance['label'])), 'Node save failed when required file field was empty.');
1178
1179
    // Create a new node with the attached file.
1180
    $nid = $this->attachNodeFile($test_file, $field_name, $type_name);
1181
    $this->assertTrue($nid !== FALSE, format_string('attachNodeFile(@test_file, @field_name, @type_name) succeeded', array('@test_file' => $test_file->uri, '@field_name' => $field_name, '@type_name' => $type_name)));
1182
1183
    $node = node_load($nid, NULL, TRUE);
1184
1185
    $node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1186
    $this->assertFileExists($node_file, 'File exists after attaching to the required field.');
1187
    $this->assertFileEntryExists($node_file, 'File entry exists after attaching to the required field.');
1188
1189
    // Try again with a multiple value field.
1190
    field_delete_field($field_name);
1191
    $this->createFileField($field_name, $type_name, array('cardinality' => FIELD_CARDINALITY_UNLIMITED), array('required' => '1'));
1192
1193
    // Try to post a new node without attaching a file in the multivalue field.
1194
    $edit = array('title' => $this->randomName());
1195
    $this->drupalPost('node/add/' . $type_name, $edit, t('Save'));
1196
    $this->assertRaw(t('!title field is required.', array('!title' => $instance['label'])), 'Node save failed when required multiple value file field was empty.');
1197
1198
    // Create a new node with the attached file into the multivalue field.
1199
    $nid = $this->attachNodeFile($test_file, $field_name, $type_name);
1200
    $node = node_load($nid, NULL, TRUE);
1201
    $node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1202
    $this->assertFileExists($node_file, 'File exists after attaching to the required multiple value field.');
1203 fc3d89c3 Assos Assos
    $this->assertFileEntryExists($node_file, 'File entry exists after attaching to the required multiple value field.');
1204 ca0757b9 Assos Assos
1205
    // Remove our file field.
1206
    field_delete_field($field_name);
1207
  }
1208
}
1209
1210
/**
1211
 * Tests that formatters are working properly.
1212
 */
1213
class MediaFileFieldDisplayTestCase extends MediaFileFieldTestCase {
1214
  public static function getInfo() {
1215
    return array(
1216
      'name' => 'Media file field display tests',
1217
      'description' => 'Test the display of file fields in node and views.',
1218
      'group' => 'Media',
1219
    );
1220
  }
1221
1222
  /**
1223
   * Tests normal formatter display on node display.
1224
   */
1225
  function testNodeDisplay() {
1226
    $field_name = strtolower($this->randomName());
1227
    $type_name = 'article';
1228
    $field_settings = array(
1229
      'display_field' => '1',
1230
      'display_default' => '1',
1231
    );
1232
    $instance_settings = array(
1233
      'description_field' => '1',
1234
    );
1235
    $widget_settings = array();
1236
    $this->createFileField($field_name, $type_name, $field_settings, $instance_settings, $widget_settings);
1237
    $field = field_info_field($field_name);
1238
    $instance = field_info_instance('node', $field_name, $type_name);
1239
1240
    // Create a new node *without* the file field set, and check that the field
1241
    // is not shown for each node display.
1242
    $node = $this->drupalCreateNode(array('type' => $type_name));
1243
    $file_formatters = array('file_default', 'file_table', 'file_url_plain', 'hidden');
1244
    foreach ($file_formatters as $formatter) {
1245
      $edit = array(
1246
        "fields[$field_name][type]" => $formatter,
1247
      );
1248
      $this->drupalPost("admin/structure/types/manage/$type_name/display", $edit, t('Save'));
1249
      $this->drupalGet('node/' . $node->nid);
1250
      $this->assertNoText($field_name, format_string('Field label is hidden when no file attached for formatter %formatter', array('%formatter' => $formatter)));
1251
    }
1252
1253
    $test_file = $this->getTestFile('text');
1254
    $test_file->uid = $this->admin_user->uid;
1255
    $test_file = file_save($test_file);
1256
1257
    // Create a new node with the attached file.
1258
    $nid = $this->attachNodeFile($test_file, $field_name, $type_name);
1259
    $this->drupalGet('node/' . $nid . '/edit');
1260
1261
    // Check that the media thumbnail is displaying with the file name.
1262
    $node = node_load($nid, NULL, TRUE);
1263
    $node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0];
1264
    $thumbnail = media_get_thumbnail_preview($node_file);
1265
    $default_output = drupal_render($thumbnail);
1266
    $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
1267
1268
    // Turn the "display" option off and check that the file is no longer displayed.
1269
    $edit = array($field_name . '[' . LANGUAGE_NONE . '][0][display]' => FALSE);
1270
    $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save'));
1271
1272
    $this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
1273
1274 85ad3d82 Assos Assos
  }
1275
}