ImageFieldDefaultImagesTest.php 15.4 KB
Newer Older
1
2
3
<?php

namespace Drupal\image\Tests;
4

5
use Drupal\Component\Utility\Unicode;
6
use Drupal\Core\Entity\Entity\EntityViewDisplay;
7
use Drupal\field\Entity\FieldConfig;
8
use Drupal\file\Entity\File;
9
use Drupal\field\Entity\FieldStorageConfig;
10
11

/**
12
 * Tests setting up default images both to the field and field storage.
13
14
 *
 * @group image
15
16
17
 */
class ImageFieldDefaultImagesTest extends ImageFieldTestBase {

18
19
20
21
22
  /**
   * Modules to enable.
   *
   * @var array
   */
23
  public static $modules = ['field_ui'];
24

25
  /**
26
   * Tests CRUD for fields and field storages with default images.
27
   */
28
  public function testDefaultImages() {
29
    $node_storage = $this->container->get('entity.manager')->getStorage('node');
30
31
    // Create files to use as the default images.
    $files = $this->drupalGetTestFiles('image');
32
33
    // Create 10 files so the default image fids are not a single value.
    for ($i = 1; $i <= 10; $i++) {
34
      $filename = $this->randomMachineName() . "$i";
35
36
      $desired_filepath = 'public://' . $filename;
      file_unmanaged_copy($files[0]->uri, $desired_filepath, FILE_EXISTS_ERROR);
37
      $file = File::create(['uri' => $desired_filepath, 'filename' => $filename, 'name' => $filename]);
38
39
      $file->save();
    }
40
    $default_images = [];
41
    foreach (['field_storage', 'field', 'field2', 'field_storage_new', 'field_new', 'field_storage_private', 'field_private'] as $image_target) {
42
      $file = File::create((array) array_pop($files));
43
44
45
46
      $file->save();
      $default_images[$image_target] = $file;
    }

47
48
    // Create an image field storage and add a field to the article content
    // type.
49
    $field_name = strtolower($this->randomMachineName());
50
    $storage_settings['default_image'] = [
51
      'uuid' => $default_images['field_storage']->uuid(),
52
53
54
55
      'alt' => '',
      'title' => '',
      'width' => 0,
      'height' => 0,
56
57
    ];
    $field_settings['default_image'] = [
58
      'uuid' => $default_images['field']->uuid(),
59
60
61
62
      'alt' => '',
      'title' => '',
      'width' => 0,
      'height' => 0,
63
64
    ];
    $widget_settings = [
65
      'preview_image_style' => 'medium',
66
    ];
67
    $field = $this->createImageField($field_name, 'article', $storage_settings, $field_settings, $widget_settings);
68

69
    // The field default image id should be 2.
70
    $this->assertEqual($field->getSetting('default_image')['uuid'], $default_images['field']->uuid());
71

72
    // Also test \Drupal\field\Entity\FieldConfig::getSettings().
73
    $this->assertEqual($field->getSettings()['default_image']['uuid'], $default_images['field']->uuid());
74

75
    $field_storage = $field->getFieldStorageDefinition();
76

77
78
    // The field storage default image id should be 1.
    $this->assertEqual($field_storage->getSetting('default_image')['uuid'], $default_images['field_storage']->uuid());
79

80
    // Also test \Drupal\field\Entity\FieldStorageConfig::getSettings().
81
    $this->assertEqual($field_storage->getSettings()['default_image']['uuid'], $default_images['field_storage']->uuid());
82

83
    // Add another field with another default image to the page content type.
84
    $field2 = FieldConfig::create([
85
      'field_storage' => $field_storage,
86
      'bundle' => 'page',
87
      'label' => $field->label(),
88
      'required' => $field->isRequired(),
89
90
      'settings' => [
        'default_image' => [
91
          'uuid' => $default_images['field2']->uuid(),
92
93
94
95
          'alt' => '',
          'title' => '',
          'width' => 0,
          'height' => 0,
96
97
        ],
      ],
98
    ]);
99
    $field2->save();
100

101
    $widget_settings = entity_get_form_display('node', $field->getTargetBundle(), 'default')->getComponent($field_name);
102
    entity_get_form_display('node', 'page', 'default')
103
      ->setComponent($field_name, $widget_settings)
104
      ->save();
105
    entity_get_display('node', 'page', 'default')
106
      ->setComponent($field_name)
107
      ->save();
108

109
110
    // Confirm the defaults are present on the article field storage settings
    // form.
111
112
    $field_id = $field->id();
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id/storage");
113
    $this->assertFieldByXpath(
114
      '//input[@name="settings[default_image][uuid][fids]"]',
115
      $default_images['field_storage']->id(),
116
      format_string(
117
118
        'Article image field storage default equals expected file ID of @fid.',
        ['@fid' => $default_images['field_storage']->id()]
119
120
      )
    );
121
    // Confirm the defaults are present on the article field edit form.
122
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
123
    $this->assertFieldByXpath(
124
      '//input[@name="settings[default_image][uuid][fids]"]',
125
      $default_images['field']->id(),
126
      format_string(
127
        'Article image field default equals expected file ID of @fid.',
128
        ['@fid' => $default_images['field']->id()]
129
130
131
      )
    );

132
    // Confirm the defaults are present on the page field storage settings form.
133
    $this->drupalGet("admin/structure/types/manage/page/fields/$field_id/storage");
134
    $this->assertFieldByXpath(
135
      '//input[@name="settings[default_image][uuid][fids]"]',
136
      $default_images['field_storage']->id(),
137
      format_string(
138
139
        'Page image field storage default equals expected file ID of @fid.',
        ['@fid' => $default_images['field_storage']->id()]
140
141
      )
    );
142
    // Confirm the defaults are present on the page field edit form.
143
144
    $field2_id = $field2->id();
    $this->drupalGet("admin/structure/types/manage/page/fields/$field2_id");
145
    $this->assertFieldByXpath(
146
      '//input[@name="settings[default_image][uuid][fids]"]',
147
      $default_images['field2']->id(),
148
      format_string(
149
        'Page image field default equals expected file ID of @fid.',
150
        ['@fid' => $default_images['field2']->id()]
151
152
153
154
      )
    );

    // Confirm that the image default is shown for a new article node.
155
    $article = $this->drupalCreateNode(['type' => 'article']);
156
    $article_built = $this->drupalBuildEntityView($article);
157
    $this->assertEqual(
158
      $article_built[$field_name][0]['#item']->target_id,
159
      $default_images['field']->id(),
160
161
      format_string(
        'A new article node without an image has the expected default image file ID of @fid.',
162
        ['@fid' => $default_images['field']->id()]
163
164
165
      )
    );

166
167
168
    // Also check that the field renders without warnings when the label is
    // hidden.
    EntityViewDisplay::load('node.article.default')
169
      ->setComponent($field_name, ['label' => 'hidden', 'type' => 'image'])
170
171
172
      ->save();
    $this->drupalGet('node/' . $article->id());

173
    // Confirm that the image default is shown for a new page node.
174
    $page = $this->drupalCreateNode(['type' => 'page']);
175
    $page_built = $this->drupalBuildEntityView($page);
176
    $this->assertEqual(
177
      $page_built[$field_name][0]['#item']->target_id,
178
      $default_images['field2']->id(),
179
180
      format_string(
        'A new page node without an image has the expected default image file ID of @fid.',
181
        ['@fid' => $default_images['field2']->id()]
182
183
184
      )
    );

185
    // Upload a new default for the field storage.
186
    $default_image_settings = $field_storage->getSetting('default_image');
187
    $default_image_settings['uuid'] = $default_images['field_storage_new']->uuid();
188
    $field_storage->setSetting('default_image', $default_image_settings);
189
    $field_storage->save();
190

191
192
    // Confirm that the new default is used on the article field storage
    // settings form.
193
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id/storage");
194
    $this->assertFieldByXpath(
195
      '//input[@name="settings[default_image][uuid][fids]"]',
196
      $default_images['field_storage_new']->id(),
197
      format_string(
198
199
        'Updated image field storage default equals expected file ID of @fid.',
        ['@fid' => $default_images['field_storage_new']->id()]
200
201
202
      )
    );

203
    // Reload the nodes and confirm the field defaults are used.
204
    $node_storage->resetCache([$article->id(), $page->id()]);
205
206
    $article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
    $page_built = $this->drupalBuildEntityView($page = $node_storage->load($page->id()));
207
    $this->assertEqual(
208
      $article_built[$field_name][0]['#item']->target_id,
209
      $default_images['field']->id(),
210
211
      format_string(
        'An existing article node without an image has the expected default image file ID of @fid.',
212
        ['@fid' => $default_images['field']->id()]
213
214
215
      )
    );
    $this->assertEqual(
216
      $page_built[$field_name][0]['#item']->target_id,
217
      $default_images['field2']->id(),
218
219
      format_string(
        'An existing page node without an image has the expected default image file ID of @fid.',
220
        ['@fid' => $default_images['field2']->id()]
221
222
223
      )
    );

224
    // Upload a new default for the article's field.
225
226
227
    $default_image_settings = $field->getSetting('default_image');
    $default_image_settings['uuid'] = $default_images['field_new']->uuid();
    $field->setSetting('default_image', $default_image_settings);
228
    $field->save();
229

230
    // Confirm the new field default is used on the article field admin form.
231
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
232
    $this->assertFieldByXpath(
233
      '//input[@name="settings[default_image][uuid][fids]"]',
234
      $default_images['field_new']->id(),
235
      format_string(
236
        'Updated article image field default equals expected file ID of @fid.',
237
        ['@fid' => $default_images['field_new']->id()]
238
239
240
241
      )
    );

    // Reload the nodes.
242
    $node_storage->resetCache([$article->id(), $page->id()]);
243
244
    $article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
    $page_built = $this->drupalBuildEntityView($page = $node_storage->load($page->id()));
245
246
247

    // Confirm the article uses the new default.
    $this->assertEqual(
248
      $article_built[$field_name][0]['#item']->target_id,
249
      $default_images['field_new']->id(),
250
251
      format_string(
        'An existing article node without an image has the expected default image file ID of @fid.',
252
        ['@fid' => $default_images['field_new']->id()]
253
254
255
256
      )
    );
    // Confirm the page remains unchanged.
    $this->assertEqual(
257
      $page_built[$field_name][0]['#item']->target_id,
258
      $default_images['field2']->id(),
259
260
      format_string(
        'An existing page node without an image has the expected default image file ID of @fid.',
261
        ['@fid' => $default_images['field2']->id()]
262
263
264
      )
    );

265
    // Confirm the default image is shown on the node form.
266
    $file = File::load($default_images['field_new']->id());
267
268
269
    $this->drupalGet('node/add/article');
    $this->assertRaw($file->getFilename());

270
    // Remove the field default from articles.
271
272
273
    $default_image_settings = $field->getSetting('default_image');
    $default_image_settings['uuid'] = 0;
    $field->setSetting('default_image', $default_image_settings);
274
    $field->save();
275

276
    // Confirm the article field default has been removed.
277
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
278
    $this->assertFieldByXpath(
279
      '//input[@name="settings[default_image][uuid][fids]"]',
280
      '',
281
      'Updated article image field default has been successfully removed.'
282
283
284
    );

    // Reload the nodes.
285
    $node_storage->resetCache([$article->id(), $page->id()]);
286
287
    $article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
    $page_built = $this->drupalBuildEntityView($page = $node_storage->load($page->id()));
288
    // Confirm the article uses the new field storage (not field) default.
289
    $this->assertEqual(
290
      $article_built[$field_name][0]['#item']->target_id,
291
      $default_images['field_storage_new']->id(),
292
293
      format_string(
        'An existing article node without an image has the expected default image file ID of @fid.',
294
        ['@fid' => $default_images['field_storage_new']->id()]
295
296
297
298
      )
    );
    // Confirm the page remains unchanged.
    $this->assertEqual(
299
      $page_built[$field_name][0]['#item']->target_id,
300
      $default_images['field2']->id(),
301
302
      format_string(
        'An existing page node without an image has the expected default image file ID of @fid.',
303
        ['@fid' => $default_images['field2']->id()]
304
305
      )
    );
306
307

    $non_image = $this->drupalGetTestFiles('text');
308
    $this->drupalPostForm(NULL, ['files[settings_default_image_uuid]' => drupal_realpath($non_image[0]->uri)], t("Upload"));
309
310
    $this->assertText('The specified file text-0.txt could not be uploaded.');
    $this->assertText('Only files with the following extensions are allowed: png gif jpg jpeg.');
311
312

    // Confirm the default image is shown on the node form.
313
    $file = File::load($default_images['field_storage_new']->id());
314
315
    $this->drupalGet('node/add/article');
    $this->assertRaw($file->getFilename());
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

    // Change the default image for the field storage and also change the upload
    // destination to the private filesystem at the same time.
    $default_image_settings = $field_storage->getSetting('default_image');
    $default_image_settings['uuid'] = $default_images['field_storage_private']->uuid();
    $field_storage->setSetting('default_image', $default_image_settings);
    $field_storage->setSetting('uri_scheme', 'private');
    $field_storage->save();

    // Confirm that the new default is used on the article field storage
    // settings form.
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id/storage");
    $this->assertFieldByXpath(
      '//input[@name="settings[default_image][uuid][fids]"]',
      $default_images['field_storage_private']->id(),
      format_string(
        'Updated image field storage default equals expected file ID of @fid.',
        ['@fid' => $default_images['field_storage_private']->id()]
      )
    );

    // Upload a new default for the article's field after setting the field
    // storage upload destination to 'private'.
    $default_image_settings = $field->getSetting('default_image');
    $default_image_settings['uuid'] = $default_images['field_private']->uuid();
    $field->setSetting('default_image', $default_image_settings);
    $field->save();

    // Confirm the new field field default is used on the article field
    // admin form.
    $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
    $this->assertFieldByXpath(
      '//input[@name="settings[default_image][uuid][fids]"]',
      $default_images['field_private']->id(),
      format_string(
        'Updated article image field default equals expected file ID of @fid.',
        ['@fid' => $default_images['field_private']->id()]
      )
    );
355
  }
356

357
  /**
358
   * Tests image field and field storage having an invalid default image.
359
   */
360
  public function testInvalidDefaultImage() {
361
    $field_storage = FieldStorageConfig::create([
362
      'field_name' => Unicode::strtolower($this->randomMachineName()),
363
364
      'entity_type' => 'node',
      'type' => 'image',
365
366
      'settings' => [
        'default_image' => [
367
          'uuid' => 100000,
368
369
370
        ]
      ],
    ]);
371
372
373
    $field_storage->save();
    $settings = $field_storage->getSettings();
    // The non-existent default image should not be saved.
374
    $this->assertNull($settings['default_image']['uuid']);
375

376
    $field = FieldConfig::create([
377
      'field_storage' => $field_storage,
378
      'bundle' => 'page',
379
      'label' => $this->randomMachineName(),
380
381
      'settings' => [
        'default_image' => [
382
          'uuid' => 100000,
383
384
        ]
      ],
385
    ]);
386
387
    $field->save();
    $settings = $field->getSettings();
388
    // The non-existent default image should not be saved.
389
    $this->assertNull($settings['default_image']['uuid']);
390
391
  }

392
}