Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\image\FunctionalJavascript;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\file\Entity\File;
|
Chris@0
|
6 use Drupal\Tests\image\Kernel\ImageFieldCreationTrait;
|
Chris@17
|
7 use Drupal\Tests\quickedit\FunctionalJavascript\QuickEditJavascriptTestBase;
|
Chris@0
|
8 use Drupal\Tests\TestFileCreationTrait;
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@17
|
11 * @coversDefaultClass \Drupal\image\Plugin\InPlaceEditor\Image
|
Chris@0
|
12 * @group image
|
Chris@0
|
13 */
|
Chris@17
|
14 class QuickEditImageTest extends QuickEditJavascriptTestBase {
|
Chris@0
|
15
|
Chris@0
|
16 use ImageFieldCreationTrait;
|
Chris@0
|
17 use TestFileCreationTrait;
|
Chris@17
|
18 use QuickEditImageEditorTestTrait;
|
Chris@0
|
19
|
Chris@0
|
20 /**
|
Chris@0
|
21 * {@inheritdoc}
|
Chris@0
|
22 */
|
Chris@17
|
23 public static $modules = ['node', 'image', 'field_ui'];
|
Chris@0
|
24
|
Chris@0
|
25 /**
|
Chris@0
|
26 * A user with permissions to edit Articles and use Quick Edit.
|
Chris@0
|
27 *
|
Chris@0
|
28 * @var \Drupal\user\UserInterface
|
Chris@0
|
29 */
|
Chris@0
|
30 protected $contentAuthorUser;
|
Chris@0
|
31
|
Chris@0
|
32 /**
|
Chris@0
|
33 * {@inheritdoc}
|
Chris@0
|
34 */
|
Chris@0
|
35 protected function setUp() {
|
Chris@0
|
36 parent::setUp();
|
Chris@0
|
37
|
Chris@0
|
38 // Create the Article node type.
|
Chris@0
|
39 $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
Chris@0
|
40
|
Chris@0
|
41 // Log in as a content author who can use Quick Edit and edit Articles.
|
Chris@0
|
42 $this->contentAuthorUser = $this->drupalCreateUser([
|
Chris@0
|
43 'access contextual links',
|
Chris@0
|
44 'access toolbar',
|
Chris@0
|
45 'access in-place editing',
|
Chris@0
|
46 'access content',
|
Chris@0
|
47 'create article content',
|
Chris@0
|
48 'edit any article content',
|
Chris@0
|
49 'delete any article content',
|
Chris@0
|
50 ]);
|
Chris@0
|
51 $this->drupalLogin($this->contentAuthorUser);
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 /**
|
Chris@17
|
55 * Test that quick editor works correctly with images.
|
Chris@17
|
56 *
|
Chris@17
|
57 * @covers ::isCompatible
|
Chris@17
|
58 * @covers ::getAttachments
|
Chris@0
|
59 */
|
Chris@17
|
60 public function testImageInPlaceEditor() {
|
Chris@0
|
61 // Create a field with a basic filetype restriction.
|
Chris@0
|
62 $field_name = strtolower($this->randomMachineName());
|
Chris@0
|
63 $field_settings = [
|
Chris@0
|
64 'file_extensions' => 'png',
|
Chris@0
|
65 ];
|
Chris@0
|
66 $formatter_settings = [
|
Chris@0
|
67 'image_style' => 'large',
|
Chris@0
|
68 'image_link' => '',
|
Chris@0
|
69 ];
|
Chris@0
|
70 $this->createImageField($field_name, 'article', [], $field_settings, [], $formatter_settings);
|
Chris@0
|
71
|
Chris@0
|
72 // Find images that match our field settings.
|
Chris@0
|
73 $valid_images = [];
|
Chris@0
|
74 foreach ($this->getTestFiles('image') as $image) {
|
Chris@0
|
75 // This regex is taken from file_validate_extensions().
|
Chris@0
|
76 $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote($field_settings['file_extensions'])) . ')$/i';
|
Chris@0
|
77 if (preg_match($regex, $image->filename)) {
|
Chris@0
|
78 $valid_images[] = $image;
|
Chris@0
|
79 }
|
Chris@0
|
80 }
|
Chris@0
|
81
|
Chris@0
|
82 // Ensure we have at least two valid images.
|
Chris@0
|
83 $this->assertGreaterThanOrEqual(2, count($valid_images));
|
Chris@0
|
84
|
Chris@0
|
85 // Create a File entity for the initial image.
|
Chris@0
|
86 $file = File::create([
|
Chris@0
|
87 'uri' => $valid_images[0]->uri,
|
Chris@0
|
88 'uid' => $this->contentAuthorUser->id(),
|
Chris@0
|
89 'status' => FILE_STATUS_PERMANENT,
|
Chris@0
|
90 ]);
|
Chris@0
|
91 $file->save();
|
Chris@0
|
92
|
Chris@0
|
93 // Use the first valid image to create a new Node.
|
Chris@0
|
94 $image_factory = $this->container->get('image.factory');
|
Chris@0
|
95 $image = $image_factory->get($valid_images[0]->uri);
|
Chris@0
|
96 $node = $this->drupalCreateNode([
|
Chris@0
|
97 'type' => 'article',
|
Chris@0
|
98 'title' => t('Test Node'),
|
Chris@0
|
99 $field_name => [
|
Chris@0
|
100 'target_id' => $file->id(),
|
Chris@0
|
101 'alt' => 'Hello world',
|
Chris@0
|
102 'title' => '',
|
Chris@0
|
103 'width' => $image->getWidth(),
|
Chris@0
|
104 'height' => $image->getHeight(),
|
Chris@0
|
105 ],
|
Chris@0
|
106 ]);
|
Chris@0
|
107
|
Chris@0
|
108 // Visit the new Node.
|
Chris@0
|
109 $this->drupalGet('node/' . $node->id());
|
Chris@0
|
110
|
Chris@0
|
111 // Assemble common CSS selectors.
|
Chris@0
|
112 $entity_selector = '[data-quickedit-entity-id="node/' . $node->id() . '"]';
|
Chris@0
|
113 $field_selector = '[data-quickedit-field-id="node/' . $node->id() . '/' . $field_name . '/' . $node->language()->getId() . '/full"]';
|
Chris@0
|
114 $original_image_selector = 'img[src*="' . $valid_images[0]->filename . '"][alt="Hello world"]';
|
Chris@0
|
115 $new_image_selector = 'img[src*="' . $valid_images[1]->filename . '"][alt="New text"]';
|
Chris@0
|
116
|
Chris@0
|
117 // Assert that the initial image is present.
|
Chris@0
|
118 $this->assertSession()->elementExists('css', $entity_selector . ' ' . $field_selector . ' ' . $original_image_selector);
|
Chris@0
|
119
|
Chris@17
|
120 // Initial state.
|
Chris@17
|
121 $this->awaitQuickEditForEntity('node', 1);
|
Chris@17
|
122 $this->assertEntityInstanceStates([
|
Chris@17
|
123 'node/1[0]' => 'closed',
|
Chris@17
|
124 ]);
|
Chris@17
|
125 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
126 'node/1/title/en/full' => 'inactive',
|
Chris@17
|
127 'node/1/uid/en/full' => 'inactive',
|
Chris@17
|
128 'node/1/created/en/full' => 'inactive',
|
Chris@17
|
129 'node/1/body/en/full' => 'inactive',
|
Chris@17
|
130 'node/1/' . $field_name . '/en/full' => 'inactive',
|
Chris@17
|
131 ]);
|
Chris@0
|
132
|
Chris@17
|
133 // Start in-place editing of the article node.
|
Chris@17
|
134 $this->startQuickEditViaToolbar('node', 1, 0);
|
Chris@17
|
135 $this->assertEntityInstanceStates([
|
Chris@17
|
136 'node/1[0]' => 'opened',
|
Chris@17
|
137 ]);
|
Chris@17
|
138 $this->assertQuickEditEntityToolbar((string) $node->label(), NULL);
|
Chris@17
|
139 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
140 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
141 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
142 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
143 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
144 'node/1/' . $field_name . '/en/full' => 'candidate',
|
Chris@17
|
145 ]);
|
Chris@17
|
146
|
Chris@17
|
147 // Click the image field.
|
Chris@0
|
148 $this->click($field_selector);
|
Chris@17
|
149 $this->awaitImageEditor();
|
Chris@17
|
150 $this->assertSession()->elementExists('css', $field_selector . ' .quickedit-image-dropzone');
|
Chris@17
|
151 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
152 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
153 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
154 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
155 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
156 'node/1/' . $field_name . '/en/full' => 'active',
|
Chris@17
|
157 ]);
|
Chris@0
|
158
|
Chris@17
|
159 // Type new 'alt' text.
|
Chris@17
|
160 $this->typeInImageEditorAltTextInput('New text');
|
Chris@17
|
161 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
162 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
163 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
164 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
165 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
166 'node/1/' . $field_name . '/en/full' => 'changed',
|
Chris@17
|
167 ]);
|
Chris@0
|
168
|
Chris@17
|
169 // Drag and drop an image.
|
Chris@17
|
170 $this->dropImageOnImageEditor($valid_images[1]->uri);
|
Chris@0
|
171
|
Chris@0
|
172 // To prevent 403s on save, we re-set our request (cookie) state.
|
Chris@0
|
173 $this->prepareRequest();
|
Chris@0
|
174
|
Chris@17
|
175 // Click 'Save'.
|
Chris@17
|
176 $this->saveQuickEdit();
|
Chris@17
|
177 $this->assertEntityInstanceStates([
|
Chris@17
|
178 'node/1[0]' => 'committing',
|
Chris@17
|
179 ]);
|
Chris@17
|
180 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
181 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
182 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
183 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
184 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
185 'node/1/' . $field_name . '/en/full' => 'saving',
|
Chris@17
|
186 ]);
|
Chris@17
|
187 $this->assertEntityInstanceFieldMarkup('node', 1, 0, [
|
Chris@17
|
188 'node/1/' . $field_name . '/en/full' => '.quickedit-changed',
|
Chris@17
|
189 ]);
|
Chris@17
|
190
|
Chris@17
|
191 // Wait for the saving of the image field to complete.
|
Chris@17
|
192 $this->assertJsCondition("Drupal.quickedit.collections.entities.get('node/1[0]').get('state') === 'closed'");
|
Chris@17
|
193 $this->assertEntityInstanceStates([
|
Chris@17
|
194 'node/1[0]' => 'closed',
|
Chris@17
|
195 ]);
|
Chris@0
|
196
|
Chris@0
|
197 // Re-visit the page to make sure the edit worked.
|
Chris@0
|
198 $this->drupalGet('node/' . $node->id());
|
Chris@0
|
199
|
Chris@0
|
200 // Check that the new image appears as expected.
|
Chris@0
|
201 $this->assertSession()->elementNotExists('css', $entity_selector . ' ' . $field_selector . ' ' . $original_image_selector);
|
Chris@0
|
202 $this->assertSession()->elementExists('css', $entity_selector . ' ' . $field_selector . ' ' . $new_image_selector);
|
Chris@0
|
203 }
|
Chris@0
|
204
|
Chris@0
|
205 }
|