comparison core/modules/jsonapi/tests/src/Functional/JsonApiFunctionalTestBase.php @ 18:af1871eacc83

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:33:08 +0100
parents
children
comparison
equal deleted inserted replaced
17:129ea1e6d783 18:af1871eacc83
1 <?php
2
3 namespace Drupal\Tests\jsonapi\Functional;
4
5 use Drupal\Core\Field\FieldStorageDefinitionInterface;
6 use Drupal\Core\Url;
7 use Drupal\field\Entity\FieldConfig;
8 use Drupal\field\Entity\FieldStorageConfig;
9 use Drupal\file\Entity\File;
10 use Drupal\taxonomy\Entity\Term;
11 use Drupal\taxonomy\Entity\Vocabulary;
12 use Drupal\Tests\BrowserTestBase;
13 use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
14 use Drupal\Tests\image\Kernel\ImageFieldCreationTrait;
15 use Drupal\user\Entity\Role;
16 use Drupal\user\RoleInterface;
17 use GuzzleHttp\Exception\ClientException;
18 use GuzzleHttp\Exception\ServerException;
19
20 /**
21 * Provides helper methods for the JSON:API module's functional tests.
22 *
23 * @internal
24 */
25 abstract class JsonApiFunctionalTestBase extends BrowserTestBase {
26
27 use EntityReferenceTestTrait;
28 use ImageFieldCreationTrait;
29
30 const IS_MULTILINGUAL = TRUE;
31 const IS_NOT_MULTILINGUAL = FALSE;
32
33 /**
34 * {@inheritdoc}
35 */
36 public static $modules = [
37 'jsonapi',
38 'serialization',
39 'node',
40 'image',
41 'taxonomy',
42 'link',
43 ];
44
45 /**
46 * Test user.
47 *
48 * @var \Drupal\user\Entity\User
49 */
50 protected $user;
51
52 /**
53 * Test user with access to view profiles.
54 *
55 * @var \Drupal\user\Entity\User
56 */
57 protected $userCanViewProfiles;
58
59 /**
60 * Test nodes.
61 *
62 * @var \Drupal\node\Entity\Node[]
63 */
64 protected $nodes = [];
65
66 /**
67 * Test taxonomy terms.
68 *
69 * @var \Drupal\taxonomy\Entity\Term[]
70 */
71 protected $tags = [];
72
73 /**
74 * Test files.
75 *
76 * @var \Drupal\file\Entity\File[]
77 */
78 protected $files = [];
79
80 /**
81 * The HTTP client.
82 *
83 * @var \GuzzleHttp\ClientInterface
84 */
85 protected $httpClient;
86
87 /**
88 * {@inheritdoc}
89 */
90 protected function setUp() {
91 parent::setUp();
92
93 // Set up a HTTP client that accepts relative URLs.
94 $this->httpClient = $this->container->get('http_client_factory')
95 ->fromOptions(['base_uri' => $this->baseUrl]);
96
97 // Create Basic page and Article node types.
98 if ($this->profile != 'standard') {
99 $this->drupalCreateContentType([
100 'type' => 'article',
101 'name' => 'Article',
102 ]);
103
104 // Setup vocabulary.
105 Vocabulary::create([
106 'vid' => 'tags',
107 'name' => 'Tags',
108 ])->save();
109
110 // Add tags and field_image to the article.
111 $this->createEntityReferenceField(
112 'node',
113 'article',
114 'field_tags',
115 'Tags',
116 'taxonomy_term',
117 'default',
118 [
119 'target_bundles' => [
120 'tags' => 'tags',
121 ],
122 'auto_create' => TRUE,
123 ],
124 FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
125 );
126 $this->createImageField('field_image', 'article');
127 $this->createImageField('field_heroless', 'article');
128 }
129
130 FieldStorageConfig::create([
131 'field_name' => 'field_link',
132 'entity_type' => 'node',
133 'type' => 'link',
134 'settings' => [],
135 'cardinality' => 1,
136 ])->save();
137
138 $field_config = FieldConfig::create([
139 'field_name' => 'field_link',
140 'label' => 'Link',
141 'entity_type' => 'node',
142 'bundle' => 'article',
143 'required' => FALSE,
144 'settings' => [],
145 'description' => '',
146 ]);
147 $field_config->save();
148
149 // Field for testing sorting.
150 FieldStorageConfig::create([
151 'field_name' => 'field_sort1',
152 'entity_type' => 'node',
153 'type' => 'integer',
154 ])->save();
155 FieldConfig::create([
156 'field_name' => 'field_sort1',
157 'entity_type' => 'node',
158 'bundle' => 'article',
159 ])->save();
160
161 // Another field for testing sorting.
162 FieldStorageConfig::create([
163 'field_name' => 'field_sort2',
164 'entity_type' => 'node',
165 'type' => 'integer',
166 ])->save();
167 FieldConfig::create([
168 'field_name' => 'field_sort2',
169 'entity_type' => 'node',
170 'bundle' => 'article',
171 ])->save();
172
173 $this->user = $this->drupalCreateUser([
174 'create article content',
175 'edit any article content',
176 'delete any article content',
177 ]);
178
179 // Create a user that can.
180 $this->userCanViewProfiles = $this->drupalCreateUser([
181 'access user profiles',
182 ]);
183
184 $this->grantPermissions(Role::load(RoleInterface::ANONYMOUS_ID), [
185 'access user profiles',
186 'administer taxonomy',
187 ]);
188
189 drupal_flush_all_caches();
190 }
191
192 /**
193 * Performs a HTTP request. Wraps the Guzzle HTTP client.
194 *
195 * Why wrap the Guzzle HTTP client? Because any error response is returned via
196 * an exception, which would make the tests unnecessarily complex to read.
197 *
198 * @param string $method
199 * HTTP method.
200 * @param \Drupal\Core\Url $url
201 * URL to request.
202 * @param array $request_options
203 * Request options to apply.
204 *
205 * @return \Psr\Http\Message\ResponseInterface
206 * The request response.
207 *
208 * @throws \GuzzleHttp\Exception\GuzzleException
209 *
210 * @see \GuzzleHttp\ClientInterface::request
211 */
212 protected function request($method, Url $url, array $request_options) {
213 try {
214 $response = $this->httpClient->request($method, $url->toString(), $request_options);
215 }
216 catch (ClientException $e) {
217 $response = $e->getResponse();
218 }
219 catch (ServerException $e) {
220 $response = $e->getResponse();
221 }
222
223 return $response;
224 }
225
226 /**
227 * Creates default content to test the API.
228 *
229 * @param int $num_articles
230 * Number of articles to create.
231 * @param int $num_tags
232 * Number of tags to create.
233 * @param bool $article_has_image
234 * Set to TRUE if you want to add an image to the generated articles.
235 * @param bool $article_has_link
236 * Set to TRUE if you want to add a link to the generated articles.
237 * @param bool $is_multilingual
238 * (optional) Set to TRUE if you want to enable multilingual content.
239 * @param bool $referencing_twice
240 * (optional) Set to TRUE if you want articles to reference the same tag
241 * twice.
242 */
243 protected function createDefaultContent($num_articles, $num_tags, $article_has_image, $article_has_link, $is_multilingual, $referencing_twice = FALSE) {
244 $random = $this->getRandomGenerator();
245 for ($created_tags = 0; $created_tags < $num_tags; $created_tags++) {
246 $term = Term::create([
247 'vid' => 'tags',
248 'name' => $random->name(),
249 ]);
250
251 if ($is_multilingual) {
252 $term->addTranslation('ca', ['name' => $term->getName() . ' (ca)']);
253 }
254
255 $term->save();
256 $this->tags[] = $term;
257 }
258 for ($created_nodes = 0; $created_nodes < $num_articles; $created_nodes++) {
259 $values = [
260 'uid' => ['target_id' => $this->user->id()],
261 'type' => 'article',
262 ];
263
264 if ($referencing_twice) {
265 $values['field_tags'] = [
266 ['target_id' => 1],
267 ['target_id' => 1],
268 ];
269 }
270 else {
271 // Get N random tags.
272 $selected_tags = mt_rand(1, $num_tags);
273 $tags = [];
274 while (count($tags) < $selected_tags) {
275 $tags[] = mt_rand(1, $num_tags);
276 $tags = array_unique($tags);
277 }
278 $values['field_tags'] = array_map(function ($tag) {
279 return ['target_id' => $tag];
280 }, $tags);
281 }
282 if ($article_has_image) {
283 $file = File::create([
284 'uri' => 'vfs://' . $random->name() . '.png',
285 ]);
286 $file->setPermanent();
287 $file->save();
288 $this->files[] = $file;
289 $values['field_image'] = ['target_id' => $file->id(), 'alt' => 'alt text'];
290 }
291 if ($article_has_link) {
292 $values['field_link'] = [
293 'title' => $this->getRandomGenerator()->name(),
294 'uri' => sprintf(
295 '%s://%s.%s',
296 'http' . (mt_rand(0, 2) > 1 ? '' : 's'),
297 $this->getRandomGenerator()->name(),
298 'org'
299 ),
300 ];
301 }
302
303 // Create values for the sort fields, to allow for testing complex
304 // sorting:
305 // - field_sort1 increments every 5 articles, starting at zero
306 // - field_sort2 decreases every article, ending at zero.
307 $values['field_sort1'] = ['value' => floor($created_nodes / 5)];
308 $values['field_sort2'] = ['value' => $num_articles - $created_nodes];
309
310 $node = $this->createNode($values);
311
312 if ($is_multilingual === static::IS_MULTILINGUAL) {
313 $values['title'] = $node->getTitle() . ' (ca)';
314 $values['field_image']['alt'] = 'alt text (ca)';
315 $node->addTranslation('ca', $values);
316 }
317 $node->save();
318
319 $this->nodes[] = $node;
320 }
321 if ($article_has_link) {
322 // Make sure that there is at least 1 https link for ::testRead() #19.
323 $this->nodes[0]->field_link = [
324 'title' => 'Drupal',
325 'uri' => 'https://drupal.org',
326 ];
327 $this->nodes[0]->save();
328 }
329 }
330
331 }