Chris@18: httpClient = $this->container->get('http_client_factory') Chris@18: ->fromOptions(['base_uri' => $this->baseUrl]); Chris@18: Chris@18: // Create Basic page and Article node types. Chris@18: if ($this->profile != 'standard') { Chris@18: $this->drupalCreateContentType([ Chris@18: 'type' => 'article', Chris@18: 'name' => 'Article', Chris@18: ]); Chris@18: Chris@18: // Setup vocabulary. Chris@18: Vocabulary::create([ Chris@18: 'vid' => 'tags', Chris@18: 'name' => 'Tags', Chris@18: ])->save(); Chris@18: Chris@18: // Add tags and field_image to the article. Chris@18: $this->createEntityReferenceField( Chris@18: 'node', Chris@18: 'article', Chris@18: 'field_tags', Chris@18: 'Tags', Chris@18: 'taxonomy_term', Chris@18: 'default', Chris@18: [ Chris@18: 'target_bundles' => [ Chris@18: 'tags' => 'tags', Chris@18: ], Chris@18: 'auto_create' => TRUE, Chris@18: ], Chris@18: FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED Chris@18: ); Chris@18: $this->createImageField('field_image', 'article'); Chris@18: $this->createImageField('field_heroless', 'article'); Chris@18: } Chris@18: Chris@18: FieldStorageConfig::create([ Chris@18: 'field_name' => 'field_link', Chris@18: 'entity_type' => 'node', Chris@18: 'type' => 'link', Chris@18: 'settings' => [], Chris@18: 'cardinality' => 1, Chris@18: ])->save(); Chris@18: Chris@18: $field_config = FieldConfig::create([ Chris@18: 'field_name' => 'field_link', Chris@18: 'label' => 'Link', Chris@18: 'entity_type' => 'node', Chris@18: 'bundle' => 'article', Chris@18: 'required' => FALSE, Chris@18: 'settings' => [], Chris@18: 'description' => '', Chris@18: ]); Chris@18: $field_config->save(); Chris@18: Chris@18: // Field for testing sorting. Chris@18: FieldStorageConfig::create([ Chris@18: 'field_name' => 'field_sort1', Chris@18: 'entity_type' => 'node', Chris@18: 'type' => 'integer', Chris@18: ])->save(); Chris@18: FieldConfig::create([ Chris@18: 'field_name' => 'field_sort1', Chris@18: 'entity_type' => 'node', Chris@18: 'bundle' => 'article', Chris@18: ])->save(); Chris@18: Chris@18: // Another field for testing sorting. Chris@18: FieldStorageConfig::create([ Chris@18: 'field_name' => 'field_sort2', Chris@18: 'entity_type' => 'node', Chris@18: 'type' => 'integer', Chris@18: ])->save(); Chris@18: FieldConfig::create([ Chris@18: 'field_name' => 'field_sort2', Chris@18: 'entity_type' => 'node', Chris@18: 'bundle' => 'article', Chris@18: ])->save(); Chris@18: Chris@18: $this->user = $this->drupalCreateUser([ Chris@18: 'create article content', Chris@18: 'edit any article content', Chris@18: 'delete any article content', Chris@18: ]); Chris@18: Chris@18: // Create a user that can. Chris@18: $this->userCanViewProfiles = $this->drupalCreateUser([ Chris@18: 'access user profiles', Chris@18: ]); Chris@18: Chris@18: $this->grantPermissions(Role::load(RoleInterface::ANONYMOUS_ID), [ Chris@18: 'access user profiles', Chris@18: 'administer taxonomy', Chris@18: ]); Chris@18: Chris@18: drupal_flush_all_caches(); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Performs a HTTP request. Wraps the Guzzle HTTP client. Chris@18: * Chris@18: * Why wrap the Guzzle HTTP client? Because any error response is returned via Chris@18: * an exception, which would make the tests unnecessarily complex to read. Chris@18: * Chris@18: * @param string $method Chris@18: * HTTP method. Chris@18: * @param \Drupal\Core\Url $url Chris@18: * URL to request. Chris@18: * @param array $request_options Chris@18: * Request options to apply. Chris@18: * Chris@18: * @return \Psr\Http\Message\ResponseInterface Chris@18: * The request response. Chris@18: * Chris@18: * @throws \GuzzleHttp\Exception\GuzzleException Chris@18: * Chris@18: * @see \GuzzleHttp\ClientInterface::request Chris@18: */ Chris@18: protected function request($method, Url $url, array $request_options) { Chris@18: try { Chris@18: $response = $this->httpClient->request($method, $url->toString(), $request_options); Chris@18: } Chris@18: catch (ClientException $e) { Chris@18: $response = $e->getResponse(); Chris@18: } Chris@18: catch (ServerException $e) { Chris@18: $response = $e->getResponse(); Chris@18: } Chris@18: Chris@18: return $response; Chris@18: } Chris@18: Chris@18: /** Chris@18: * Creates default content to test the API. Chris@18: * Chris@18: * @param int $num_articles Chris@18: * Number of articles to create. Chris@18: * @param int $num_tags Chris@18: * Number of tags to create. Chris@18: * @param bool $article_has_image Chris@18: * Set to TRUE if you want to add an image to the generated articles. Chris@18: * @param bool $article_has_link Chris@18: * Set to TRUE if you want to add a link to the generated articles. Chris@18: * @param bool $is_multilingual Chris@18: * (optional) Set to TRUE if you want to enable multilingual content. Chris@18: * @param bool $referencing_twice Chris@18: * (optional) Set to TRUE if you want articles to reference the same tag Chris@18: * twice. Chris@18: */ Chris@18: protected function createDefaultContent($num_articles, $num_tags, $article_has_image, $article_has_link, $is_multilingual, $referencing_twice = FALSE) { Chris@18: $random = $this->getRandomGenerator(); Chris@18: for ($created_tags = 0; $created_tags < $num_tags; $created_tags++) { Chris@18: $term = Term::create([ Chris@18: 'vid' => 'tags', Chris@18: 'name' => $random->name(), Chris@18: ]); Chris@18: Chris@18: if ($is_multilingual) { Chris@18: $term->addTranslation('ca', ['name' => $term->getName() . ' (ca)']); Chris@18: } Chris@18: Chris@18: $term->save(); Chris@18: $this->tags[] = $term; Chris@18: } Chris@18: for ($created_nodes = 0; $created_nodes < $num_articles; $created_nodes++) { Chris@18: $values = [ Chris@18: 'uid' => ['target_id' => $this->user->id()], Chris@18: 'type' => 'article', Chris@18: ]; Chris@18: Chris@18: if ($referencing_twice) { Chris@18: $values['field_tags'] = [ Chris@18: ['target_id' => 1], Chris@18: ['target_id' => 1], Chris@18: ]; Chris@18: } Chris@18: else { Chris@18: // Get N random tags. Chris@18: $selected_tags = mt_rand(1, $num_tags); Chris@18: $tags = []; Chris@18: while (count($tags) < $selected_tags) { Chris@18: $tags[] = mt_rand(1, $num_tags); Chris@18: $tags = array_unique($tags); Chris@18: } Chris@18: $values['field_tags'] = array_map(function ($tag) { Chris@18: return ['target_id' => $tag]; Chris@18: }, $tags); Chris@18: } Chris@18: if ($article_has_image) { Chris@18: $file = File::create([ Chris@18: 'uri' => 'vfs://' . $random->name() . '.png', Chris@18: ]); Chris@18: $file->setPermanent(); Chris@18: $file->save(); Chris@18: $this->files[] = $file; Chris@18: $values['field_image'] = ['target_id' => $file->id(), 'alt' => 'alt text']; Chris@18: } Chris@18: if ($article_has_link) { Chris@18: $values['field_link'] = [ Chris@18: 'title' => $this->getRandomGenerator()->name(), Chris@18: 'uri' => sprintf( Chris@18: '%s://%s.%s', Chris@18: 'http' . (mt_rand(0, 2) > 1 ? '' : 's'), Chris@18: $this->getRandomGenerator()->name(), Chris@18: 'org' Chris@18: ), Chris@18: ]; Chris@18: } Chris@18: Chris@18: // Create values for the sort fields, to allow for testing complex Chris@18: // sorting: Chris@18: // - field_sort1 increments every 5 articles, starting at zero Chris@18: // - field_sort2 decreases every article, ending at zero. Chris@18: $values['field_sort1'] = ['value' => floor($created_nodes / 5)]; Chris@18: $values['field_sort2'] = ['value' => $num_articles - $created_nodes]; Chris@18: Chris@18: $node = $this->createNode($values); Chris@18: Chris@18: if ($is_multilingual === static::IS_MULTILINGUAL) { Chris@18: $values['title'] = $node->getTitle() . ' (ca)'; Chris@18: $values['field_image']['alt'] = 'alt text (ca)'; Chris@18: $node->addTranslation('ca', $values); Chris@18: } Chris@18: $node->save(); Chris@18: Chris@18: $this->nodes[] = $node; Chris@18: } Chris@18: if ($article_has_link) { Chris@18: // Make sure that there is at least 1 https link for ::testRead() #19. Chris@18: $this->nodes[0]->field_link = [ Chris@18: 'title' => 'Drupal', Chris@18: 'uri' => 'https://drupal.org', Chris@18: ]; Chris@18: $this->nodes[0]->save(); Chris@18: } Chris@18: } Chris@18: Chris@18: }