Mercurial > hg > isophonics-drupal-site
comparison core/modules/taxonomy/tests/src/Functional/TermAutocompleteTest.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\taxonomy\Functional; | |
4 | |
5 use Drupal\Component\Serialization\Json; | |
6 use Drupal\Core\Entity\Entity\EntityFormDisplay; | |
7 use Drupal\Core\Entity\Entity\EntityViewDisplay; | |
8 use Drupal\Core\Field\FieldStorageDefinitionInterface; | |
9 use Drupal\field\Entity\FieldConfig; | |
10 use Drupal\field\Entity\FieldStorageConfig; | |
11 | |
12 /** | |
13 * Tests the autocomplete implementation of the taxonomy class. | |
14 * | |
15 * @group taxonomy | |
16 */ | |
17 class TermAutocompleteTest extends TaxonomyTestBase { | |
18 | |
19 /** | |
20 * Modules to enable. | |
21 * | |
22 * @var array | |
23 */ | |
24 public static $modules = ['node']; | |
25 | |
26 /** | |
27 * The vocabulary. | |
28 * | |
29 * @var \Drupal\taxonomy\Entity\Vocabulary | |
30 */ | |
31 protected $vocabulary; | |
32 | |
33 /** | |
34 * The field to add to the content type for the taxonomy terms. | |
35 * | |
36 * @var string | |
37 */ | |
38 protected $fieldName; | |
39 | |
40 /** | |
41 * The admin user. | |
42 * | |
43 * @var \Drupal\user\Entity\User | |
44 */ | |
45 protected $adminUser; | |
46 | |
47 /** | |
48 * The autocomplete URL to call. | |
49 * | |
50 * @var string | |
51 */ | |
52 protected $autocompleteUrl; | |
53 | |
54 /** | |
55 * The term IDs indexed by term names. | |
56 * | |
57 * @var array | |
58 */ | |
59 protected $termIds; | |
60 | |
61 /** | |
62 * {@inheritdoc} | |
63 */ | |
64 protected function setUp() { | |
65 parent::setUp(); | |
66 | |
67 // Create a vocabulary. | |
68 $this->vocabulary = $this->createVocabulary(); | |
69 | |
70 // Create 11 terms, which have some sub-string in common, in a | |
71 // non-alphabetical order, so that we will have more than 10 matches later | |
72 // when we test the correct number of results is returned, and we can test | |
73 // the order of the results. The location of the sub-string to match varies | |
74 // also, since it should not be necessary to start with the sub-string to | |
75 // match it. Save term IDs to reuse later. | |
76 $termNames = [ | |
77 'aaa 20 bbb', | |
78 'aaa 70 bbb', | |
79 'aaa 10 bbb', | |
80 'aaa 12 bbb', | |
81 'aaa 40 bbb', | |
82 'aaa 11 bbb', | |
83 'aaa 30 bbb', | |
84 'aaa 50 bbb', | |
85 'aaa 80', | |
86 'aaa 90', | |
87 'bbb 60 aaa', | |
88 ]; | |
89 foreach ($termNames as $termName) { | |
90 $term = $this->createTerm($this->vocabulary, ['name' => $termName]); | |
91 $this->termIds[$termName] = $term->id(); | |
92 } | |
93 | |
94 // Create a taxonomy_term_reference field on the article Content Type that | |
95 // uses a taxonomy_autocomplete widget. | |
96 $this->fieldName = mb_strtolower($this->randomMachineName()); | |
97 FieldStorageConfig::create([ | |
98 'field_name' => $this->fieldName, | |
99 'entity_type' => 'node', | |
100 'type' => 'entity_reference', | |
101 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, | |
102 'settings' => [ | |
103 'target_type' => 'taxonomy_term', | |
104 ], | |
105 ])->save(); | |
106 FieldConfig::create([ | |
107 'field_name' => $this->fieldName, | |
108 'bundle' => 'article', | |
109 'entity_type' => 'node', | |
110 'settings' => [ | |
111 'handler' => 'default', | |
112 'handler_settings' => [ | |
113 // Restrict selection of terms to a single vocabulary. | |
114 'target_bundles' => [ | |
115 $this->vocabulary->id() => $this->vocabulary->id(), | |
116 ], | |
117 ], | |
118 ], | |
119 ])->save(); | |
120 EntityFormDisplay::load('node.article.default') | |
121 ->setComponent($this->fieldName, [ | |
122 'type' => 'entity_reference_autocomplete', | |
123 ]) | |
124 ->save(); | |
125 EntityViewDisplay::load('node.article.default') | |
126 ->setComponent($this->fieldName, [ | |
127 'type' => 'entity_reference_label', | |
128 ]) | |
129 ->save(); | |
130 | |
131 // Create a user and then login. | |
132 $this->adminUser = $this->drupalCreateUser(['create article content']); | |
133 $this->drupalLogin($this->adminUser); | |
134 | |
135 // Retrieve the autocomplete url. | |
136 $this->drupalGet('node/add/article'); | |
137 $result = $this->xpath('//input[@name="' . $this->fieldName . '[0][target_id]"]'); | |
138 $this->autocompleteUrl = $this->getAbsoluteUrl($result[0]->getAttribute('data-autocomplete-path')); | |
139 } | |
140 | |
141 /** | |
142 * Helper function for JSON formatted requests. | |
143 * | |
144 * @param string|\Drupal\Core\Url $path | |
145 * Drupal path or URL to load into Mink controlled browser. | |
146 * @param array $options | |
147 * (optional) Options to be forwarded to the url generator. | |
148 * @param string[] $headers | |
149 * (optional) An array containing additional HTTP request headers. | |
150 * | |
151 * @return string[] | |
152 * Array representing decoded JSON response. | |
153 */ | |
154 protected function drupalGetJson($path, array $options = [], array $headers = []) { | |
155 $options = array_merge_recursive(['query' => ['_format' => 'json']], $options); | |
156 return Json::decode($this->drupalGet($path, $options, $headers)); | |
157 } | |
158 | |
159 /** | |
160 * Tests that the autocomplete method returns the good number of results. | |
161 * | |
162 * @see \Drupal\taxonomy\Controller\TermAutocompleteController::autocomplete() | |
163 */ | |
164 public function testAutocompleteCountResults() { | |
165 // Test that no matching term found. | |
166 $data = $this->drupalGetJson( | |
167 $this->autocompleteUrl, | |
168 ['query' => ['q' => 'zzz']] | |
169 ); | |
170 $this->assertTrue(empty($data), 'Autocomplete returned no results'); | |
171 | |
172 // Test that only one matching term found, when only one matches. | |
173 $data = $this->drupalGetJson( | |
174 $this->autocompleteUrl, | |
175 ['query' => ['q' => 'aaa 10']] | |
176 ); | |
177 $this->assertEqual(1, count($data), 'Autocomplete returned 1 result'); | |
178 | |
179 // Test the correct number of matches when multiple are partial matches. | |
180 $data = $this->drupalGetJson( | |
181 $this->autocompleteUrl, | |
182 ['query' => ['q' => 'aaa 1']] | |
183 ); | |
184 $this->assertEqual(3, count($data), 'Autocomplete returned 3 results'); | |
185 | |
186 // Tests that only 10 results are returned, even if there are more than 10 | |
187 // matches. | |
188 $data = $this->drupalGetJson( | |
189 $this->autocompleteUrl, | |
190 ['query' => ['q' => 'aaa']] | |
191 ); | |
192 $this->assertEqual(10, count($data), 'Autocomplete returned only 10 results (for over 10 matches)'); | |
193 } | |
194 | |
195 /** | |
196 * Tests that the autocomplete method returns properly ordered results. | |
197 * | |
198 * @see \Drupal\taxonomy\Controller\TermAutocompleteController::autocomplete() | |
199 */ | |
200 public function testAutocompleteOrderedResults() { | |
201 $expectedResults = [ | |
202 'aaa 10 bbb', | |
203 'aaa 11 bbb', | |
204 'aaa 12 bbb', | |
205 'aaa 20 bbb', | |
206 'aaa 30 bbb', | |
207 'aaa 40 bbb', | |
208 'aaa 50 bbb', | |
209 'aaa 70 bbb', | |
210 'bbb 60 aaa', | |
211 ]; | |
212 // Build $expected to match the autocomplete results. | |
213 $expected = []; | |
214 foreach ($expectedResults as $termName) { | |
215 $expected[] = [ | |
216 'value' => $termName . ' (' . $this->termIds[$termName] . ')', | |
217 'label' => $termName, | |
218 ]; | |
219 } | |
220 | |
221 $data = $this->drupalGetJson( | |
222 $this->autocompleteUrl, | |
223 ['query' => ['q' => 'bbb']] | |
224 ); | |
225 | |
226 $this->assertIdentical($expected, $data); | |
227 } | |
228 | |
229 } |