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