Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\quickedit\Tests;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Component\Serialization\Json;
|
Chris@0
|
6 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
Chris@0
|
7 use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
Chris@0
|
8 use Drupal\Core\Language\LanguageInterface;
|
Chris@0
|
9 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
Chris@0
|
10 use Drupal\simpletest\WebTestBase;
|
Chris@0
|
11 use Drupal\taxonomy\Entity\Vocabulary;
|
Chris@0
|
12 use Drupal\taxonomy\Entity\Term;
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Tests in-place editing of autocomplete tags.
|
Chris@0
|
16 *
|
Chris@0
|
17 * @group quickedit
|
Chris@0
|
18 */
|
Chris@0
|
19 class QuickEditAutocompleteTermTest extends WebTestBase {
|
Chris@0
|
20
|
Chris@0
|
21 use EntityReferenceTestTrait;
|
Chris@0
|
22
|
Chris@0
|
23 /**
|
Chris@0
|
24 * Modules to enable.
|
Chris@0
|
25 *
|
Chris@0
|
26 * @var array
|
Chris@0
|
27 */
|
Chris@0
|
28 public static $modules = ['node', 'taxonomy', 'quickedit'];
|
Chris@0
|
29
|
Chris@0
|
30 /**
|
Chris@0
|
31 * Stores the node used for the tests.
|
Chris@0
|
32 *
|
Chris@0
|
33 * @var \Drupal\node\NodeInterface
|
Chris@0
|
34 */
|
Chris@0
|
35 protected $node;
|
Chris@0
|
36
|
Chris@0
|
37 /**
|
Chris@0
|
38 * Stores the vocabulary used in the tests.
|
Chris@0
|
39 *
|
Chris@0
|
40 * @var \Drupal\taxonomy\VocabularyInterface
|
Chris@0
|
41 */
|
Chris@0
|
42 protected $vocabulary;
|
Chris@0
|
43
|
Chris@0
|
44 /**
|
Chris@0
|
45 * Stores the first term used in the tests.
|
Chris@0
|
46 *
|
Chris@0
|
47 * @var \Drupal\taxonomy\TermInterface
|
Chris@0
|
48 */
|
Chris@0
|
49 protected $term1;
|
Chris@0
|
50
|
Chris@0
|
51 /**
|
Chris@0
|
52 * Stores the second term used in the tests.
|
Chris@0
|
53 *
|
Chris@0
|
54 * @var \Drupal\taxonomy\TermInterface
|
Chris@0
|
55 */
|
Chris@0
|
56 protected $term2;
|
Chris@0
|
57
|
Chris@0
|
58 /**
|
Chris@0
|
59 * Stores the field name for the autocomplete field.
|
Chris@0
|
60 *
|
Chris@0
|
61 * @var string
|
Chris@0
|
62 */
|
Chris@0
|
63 protected $fieldName;
|
Chris@0
|
64
|
Chris@0
|
65 /**
|
Chris@0
|
66 * An user with permissions to access in-place editor.
|
Chris@0
|
67 *
|
Chris@0
|
68 * @var \Drupal\user\UserInterface
|
Chris@0
|
69 */
|
Chris@0
|
70 protected $editorUser;
|
Chris@0
|
71
|
Chris@0
|
72 protected function setUp() {
|
Chris@0
|
73 parent::setUp();
|
Chris@0
|
74
|
Chris@0
|
75 $this->drupalCreateContentType([
|
Chris@0
|
76 'type' => 'article',
|
Chris@0
|
77 ]);
|
Chris@0
|
78 // Create the vocabulary for the tag field.
|
Chris@0
|
79 $this->vocabulary = Vocabulary::create([
|
Chris@0
|
80 'name' => 'quickedit testing tags',
|
Chris@0
|
81 'vid' => 'quickedit_testing_tags',
|
Chris@0
|
82 ]);
|
Chris@0
|
83 $this->vocabulary->save();
|
Chris@0
|
84 $this->fieldName = 'field_' . $this->vocabulary->id();
|
Chris@0
|
85
|
Chris@0
|
86 $handler_settings = [
|
Chris@0
|
87 'target_bundles' => [
|
Chris@0
|
88 $this->vocabulary->id() => $this->vocabulary->id(),
|
Chris@0
|
89 ],
|
Chris@0
|
90 'auto_create' => TRUE,
|
Chris@0
|
91 ];
|
Chris@0
|
92 $this->createEntityReferenceField('node', 'article', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
Chris@0
|
93
|
Chris@0
|
94 entity_get_form_display('node', 'article', 'default')
|
Chris@0
|
95 ->setComponent($this->fieldName, [
|
Chris@0
|
96 'type' => 'entity_reference_autocomplete_tags',
|
Chris@0
|
97 'weight' => -4,
|
Chris@0
|
98 ])
|
Chris@0
|
99 ->save();
|
Chris@0
|
100
|
Chris@0
|
101 entity_get_display('node', 'article', 'default')
|
Chris@0
|
102 ->setComponent($this->fieldName, [
|
Chris@0
|
103 'type' => 'entity_reference_label',
|
Chris@0
|
104 'weight' => 10,
|
Chris@0
|
105 ])
|
Chris@0
|
106 ->save();
|
Chris@0
|
107 entity_get_display('node', 'article', 'teaser')
|
Chris@0
|
108 ->setComponent($this->fieldName, [
|
Chris@0
|
109 'type' => 'entity_reference_label',
|
Chris@0
|
110 'weight' => 10,
|
Chris@0
|
111 ])
|
Chris@0
|
112 ->save();
|
Chris@0
|
113
|
Chris@0
|
114 $this->term1 = $this->createTerm();
|
Chris@0
|
115 $this->term2 = $this->createTerm();
|
Chris@0
|
116
|
Chris@0
|
117 $node = [];
|
Chris@0
|
118 $node['type'] = 'article';
|
Chris@0
|
119 $node[$this->fieldName][]['target_id'] = $this->term1->id();
|
Chris@0
|
120 $node[$this->fieldName][]['target_id'] = $this->term2->id();
|
Chris@0
|
121 $this->node = $this->drupalCreateNode($node);
|
Chris@0
|
122
|
Chris@0
|
123 $this->editorUser = $this->drupalCreateUser(['access content', 'create article content', 'edit any article content', 'access in-place editing']);
|
Chris@0
|
124 }
|
Chris@0
|
125
|
Chris@0
|
126 /**
|
Chris@0
|
127 * Tests Quick Edit autocomplete term behavior.
|
Chris@0
|
128 */
|
Chris@0
|
129 public function testAutocompleteQuickEdit() {
|
Chris@0
|
130 $this->drupalLogin($this->editorUser);
|
Chris@0
|
131
|
Chris@0
|
132 $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full';
|
Chris@0
|
133 $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData();
|
Chris@0
|
134 $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
|
Chris@0
|
135 $ajax_commands = Json::decode($response);
|
Chris@0
|
136
|
Chris@0
|
137 // Prepare form values for submission. drupalPostAJAX() is not suitable for
|
Chris@0
|
138 // handling pages with JSON responses, so we need our own solution here.
|
Chris@0
|
139 $form_tokens_found = preg_match('/\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match) && preg_match('/\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match);
|
Chris@0
|
140 $this->assertTrue($form_tokens_found, 'Form tokens found in output.');
|
Chris@0
|
141
|
Chris@0
|
142 if ($form_tokens_found) {
|
Chris@0
|
143 $post = [
|
Chris@0
|
144 'form_id' => 'quickedit_field_form',
|
Chris@0
|
145 'form_token' => $token_match[1],
|
Chris@0
|
146 'form_build_id' => $build_id_match[1],
|
Chris@0
|
147 $this->fieldName . '[target_id]' => implode(', ', [$this->term1->getName(), 'new term', $this->term2->getName()]),
|
Chris@0
|
148 'op' => t('Save'),
|
Chris@0
|
149 ];
|
Chris@0
|
150
|
Chris@0
|
151 // Submit field form and check response. Should render back all the terms.
|
Chris@0
|
152 $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
|
Chris@0
|
153 $this->assertResponse(200);
|
Chris@0
|
154 $ajax_commands = Json::decode($response);
|
Chris@0
|
155 $this->setRawContent($ajax_commands[0]['data']);
|
Chris@0
|
156 $this->assertLink($this->term1->getName());
|
Chris@0
|
157 $this->assertLink($this->term2->getName());
|
Chris@0
|
158 $this->assertText('new term');
|
Chris@0
|
159 $this->assertNoLink('new term');
|
Chris@0
|
160
|
Chris@0
|
161 // Load the form again, which should now get it back from
|
Chris@0
|
162 // PrivateTempStore.
|
Chris@0
|
163 $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full';
|
Chris@0
|
164 $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData();
|
Chris@0
|
165 $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
|
Chris@0
|
166 $ajax_commands = Json::decode($response);
|
Chris@0
|
167
|
Chris@0
|
168 // The AjaxResponse's first command is an InsertCommand which contains
|
Chris@0
|
169 // the form to edit the taxonomy term field, it should contain all three
|
Chris@0
|
170 // taxonomy terms, including the one that has just been newly created and
|
Chris@0
|
171 // which is not yet stored.
|
Chris@0
|
172 $this->setRawContent($ajax_commands[0]['data']);
|
Chris@0
|
173 $expected = [
|
Chris@0
|
174 $this->term1->getName() . ' (' . $this->term1->id() . ')',
|
Chris@0
|
175 'new term',
|
Chris@0
|
176 $this->term2->getName() . ' (' . $this->term2->id() . ')',
|
Chris@0
|
177 ];
|
Chris@0
|
178 $this->assertFieldByName($this->fieldName . '[target_id]', implode(', ', $expected));
|
Chris@0
|
179
|
Chris@0
|
180 // Save the entity.
|
Chris@0
|
181 $post = ['nocssjs' => 'true'];
|
Chris@0
|
182 $response = $this->drupalPostWithFormat('quickedit/entity/node/' . $this->node->id(), 'json', $post);
|
Chris@0
|
183 $this->assertResponse(200);
|
Chris@0
|
184
|
Chris@0
|
185 // The full node display should now link to all entities, with the new
|
Chris@0
|
186 // one created in the database as well.
|
Chris@0
|
187 $this->drupalGet('node/' . $this->node->id());
|
Chris@0
|
188 $this->assertLink($this->term1->getName());
|
Chris@0
|
189 $this->assertLink($this->term2->getName());
|
Chris@0
|
190 $this->assertLink('new term');
|
Chris@0
|
191 }
|
Chris@0
|
192 }
|
Chris@0
|
193
|
Chris@0
|
194 /**
|
Chris@0
|
195 * Returns a new term with random name and description in $this->vocabulary.
|
Chris@0
|
196 *
|
Chris@0
|
197 * @return \Drupal\taxonomy\TermInterface
|
Chris@0
|
198 * The created taxonomy term.
|
Chris@0
|
199 */
|
Chris@0
|
200 protected function createTerm() {
|
Chris@0
|
201 $filter_formats = filter_formats();
|
Chris@0
|
202 $format = array_pop($filter_formats);
|
Chris@0
|
203 $term = Term::create([
|
Chris@0
|
204 'name' => $this->randomMachineName(),
|
Chris@0
|
205 'description' => $this->randomMachineName(),
|
Chris@0
|
206 // Use the first available text format.
|
Chris@0
|
207 'format' => $format->id(),
|
Chris@0
|
208 'vid' => $this->vocabulary->id(),
|
Chris@0
|
209 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
Chris@0
|
210 ]);
|
Chris@0
|
211 $term->save();
|
Chris@0
|
212 return $term;
|
Chris@0
|
213 }
|
Chris@0
|
214
|
Chris@0
|
215 }
|