external_entities-8.x-2.x-dev/tests/src/Functional/RestClientFunctionalTest.php

tests/src/Functional/RestClientFunctionalTest.php
<?php

namespace Drupal\Tests\external_entities\Functional;

use Drupal\filter\Entity\FilterFormat;

/**
 * Tests Rest storage client for external entity.
 *
 * @group ExternalEntities
 */
class RestClientFunctionalTest extends ExternalEntitiesBrowserTestBase {

  /**
   * A user with administration permissions.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $account;

  /**
   * The entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $storage;

  /**
   * {@inheritdoc}
   */
  protected function setUp() :void {
    parent::setUp();

    global $base_url;
    $this->storage = $this->container->get('entity_type.manager')->getStorage('external_entity_type');

    // Setup datasets.
    $xntt_json_controller = $this
      ->container
      ->get('controller_resolver')
      ->getControllerFromDefinition(
        '\Drupal\external_entities_test\Controller\ExternalEntitiesJsonController::listItems'
      )[0];
    $xntt_json_controller->setRawData('simple', [
      '2596b1ba-43bb-4440-9f0c-f1974f733336' => [
        'id' => '2596b1ba-43bb-4440-9f0c-f1974f733336',
        'title' => 'Simple title 1',
        'short_text' => 'Just a short string',
        'rich_text' => '<h2>Some HTML tags</h2>',
        'rich_text_2' => '<h2>Other HTML tags</h2>',
        'status' => TRUE,
        'refs' => [
          'ref2',
          'ref3',
        ],
      ],
      '2596b1ba-43bb-4440-9f0c-f1974f733337' => [
        'id' => '2596b1ba-43bb-4440-9f0c-f1974f733337',
        'title' => 'Simple title 2',
        'short_text' => 'Just another short string',
        'status' => FALSE,
      ],
    ]);
    $xntt_json_controller->setRawData('ref', [
      'ref1' => [
        'id' => 'ref1',
        'label' => 'Term 1',
      ],
      'ref2' => [
        'id' => 'ref2',
        'label' => 'Term 2',
      ],
      'ref3' => [
        'id' => 'ref3',
        'label' => 'Term 3',
      ],
      'ref4' => [
        'id' => 'ref4',
        'label' => 'Term 4',
      ],
    ]);

    // Setup reference external entity type.
    /** @var \Drupal\external_entities\Entity\ExternalEntityType $ref */
    $ref = $this->container->get('entity_type.manager')->getStorage('external_entity_type')->create([
      'id' => 'ref',
      'label' => 'Ref',
      'label_plural' => 'Refs',
      'base_path' => 'ref',
      'description' => '',
      'read_only' => FALSE,
      'debug_level' => 0,
      'field_mappers' => [],
      'storage_clients' => [],
      'data_aggregator' => [],
      'persistent_cache_max_age' => 0,
    ]);

    // Sets aggregator.
    $ref->setDataAggregatorId('single')->setDataAggregatorConfig([
      'storage_clients' => [
        [
          'id' => 'rest',
          'config' => [
            'endpoint' => $base_url . '/external-entities-test/ref',
            'endpoint_options' => [
              'single' => '',
              'count' => '',
              'count_mode' => NULL,
              'cache' => FALSE,
              'limit_qcount' => 0,
              'limit_qtime' => 0,
            ],
            'response_format' => 'json',
            'data_path' => [
              'list' => '',
              'single' => '',
              'keyed_by_id' => FALSE,
              'count' => '',
            ],
            'pager' => [
              'default_limit' => 50,
              'type' => 'pagination',
              'page_parameter' => 'page',
              'page_parameter_type' => 'pagenum',
              'page_start_one' => FALSE,
              'page_size_parameter' => 'pageSize',
              'page_size_parameter_type' => 'pagesize',
            ],
            'api_key' => [
              'type' => 'none',
              'header_name' => '',
              'key' => '',
            ],
            'http' => [
              'headers' => '',
            ],
            'parameters' => [
              'list' => [],
              'list_param_mode' => 'query',
              'single' => [],
              'single_param_mode' => 'query',
            ],
            'filtering' => [
              'drupal' => FALSE,
              'basic' => FALSE,
              'basic_fields' => [],
              'list_support' => 'none',
              'list_join' => '',
            ],
          ],
        ],
      ],
    ]);

    // We need to save here to have base fields mappable.
    $ref->save();
    $ref
      // ID field mapping.
      ->setFieldMapperId('id', 'generic')
      ->setFieldMapperConfig(
        'id',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'direct',
              'config' => [
                'mapping' => 'id',
                'required_field' => TRUE,
                'main_property' => TRUE,
                'data_processors' => [
                  [],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // UUID field mapping.
      ->setFieldMapperId('uuid', 'generic')
      ->setFieldMapperConfig(
        'uuid',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'direct',
              'config' => [
                'mapping' => 'id',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Title field mapping.
      ->setFieldMapperId('title', 'generic')
      ->setFieldMapperConfig(
        'title',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'direct',
              'config' => [
                'mapping' => 'label',
                'required_field' => TRUE,
                'main_property' => TRUE,
                'data_processors' => [],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      );
    $ref->save();
    // Create a new filter format for next formatted text fields.
    $full_html_format = FilterFormat::create([
      'format' => 'full_html',
      'name' => 'Full HTML',
      'weight' => 1,
      'filters' => [],
    ]);
    $full_html_format->save();

    // Setup tested simple external entity type.
    /** @var \Drupal\external_entities\Entity\ExternalEntityType $type */
    $type = $this->container->get('entity_type.manager')->getStorage('external_entity_type')->create([
      'id' => 'simple_external_entity',
      'label' => 'Simple external entity',
      'label_plural' => 'Simple external entities',
      'base_path' => 'simple-external-entity',
      'description' => '',
      'read_only' => FALSE,
      'debug_level' => 0,
      'field_mappers' => [],
      'storage_clients' => [],
      'data_aggregator' => [],
      'persistent_cache_max_age' => 0,
    ]);

    // Sets aggregator.
    $type->setDataAggregatorId('single')->setDataAggregatorConfig([
      'storage_clients' => [
        [
          'id' => 'rest',
          'config' => [
            'endpoint' => $base_url . '/external-entities-test/simple',
            'endpoint_options' => [
              'single' => '',
              'count' => '',
              'count_mode' => NULL,
              'cache' => FALSE,
              'limit_qcount' => 0,
              'limit_qtime' => 0,
            ],
            'response_format' => 'json',
            'data_path' => [
              'list' => '',
              'single' => '',
              'keyed_by_id' => FALSE,
              'count' => '',
            ],
            'pager' => [
              'default_limit' => 50,
              'type' => 'pagination',
              'page_parameter' => 'page',
              'page_parameter_type' => 'pagenum',
              'page_start_one' => FALSE,
              'page_size_parameter' => 'pageSize',
              'page_size_parameter_type' => 'pagesize',
            ],
            'api_key' => [
              'type' => 'none',
              'header_name' => '',
              'key' => '',
            ],
            'http' => [
              'headers' => '',
            ],
            'parameters' => [
              'list' => [],
              'list_param_mode' => 'query',
              'single' => [],
              'single_param_mode' => 'query',
            ],
            'filtering' => [
              'drupal' => FALSE,
              'basic' => FALSE,
              'basic_fields' => [],
              'list_support' => 'none',
              'list_join' => '',
            ],
          ],
        ],
      ],
    ]);
    $type->save();

    // Add fields.
    $this
      ->createField('simple_external_entity', 'plain_text', 'string')
      ->createField('simple_external_entity', 'fixed_string', 'string')
      ->createField('simple_external_entity', 'a_boolean', 'boolean')
      ->createField('simple_external_entity', 'a_rich_text', 'text')
      ->createField('simple_external_entity', 'a_plain_text', 'text')
      ->createField('simple_external_entity', 'multi_string', 'string', ['multiple' => TRUE])
      ->createReferenceField('simple_external_entity', 'ref', 'ref', NULL, ['multiple' => TRUE]);

    // Set field mappers...
    $type
      // ID field mapping.
      ->setFieldMapperId('id', 'generic')
      ->setFieldMapperConfig(
        'id',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'direct',
              'config' => [
                'mapping' => 'id',
                'required_field' => TRUE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // UUID field mapping.
      ->setFieldMapperId('uuid', 'generic')
      ->setFieldMapperConfig(
        'uuid',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'direct',
              'config' => [
                'mapping' => 'id',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Title field mapping.
      ->setFieldMapperId('title', 'generic')
      ->setFieldMapperConfig(
        'title',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'direct',
              'config' => [
                'mapping' => 'title',
                'required_field' => TRUE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Plain text field mapping.
      ->setFieldMapperId('plain_text', 'generic')
      ->setFieldMapperConfig(
        'plain_text',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'simple',
              'config' => [
                'mapping' => 'short_text',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Fixed string field mapping.
      ->setFieldMapperId('fixed_string', 'generic')
      ->setFieldMapperConfig(
        'fixed_string',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'constant',
              'config' => [
                'mapping' => 'A fixed string',
                'required_field' => FALSE,
                'main_property' => TRUE,
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Multi-string field mapping.
      ->setFieldMapperId('multi_string', 'generic')
      ->setFieldMapperConfig(
        'multi_string',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'simple',
              'config' => [
                'mapping' => 'multival.*.val',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Rich text field mapping.
      ->setFieldMapperId('a_rich_text', 'text')
      ->setFieldMapperConfig(
        'a_rich_text',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'simple',
              'config' => [
                'mapping' => 'rich_text',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'format' => 'full_html',
          'debug_level' => 0,
        ]
      )
      // Formatted plain text field mapping.
      ->setFieldMapperId('a_plain_text', 'text')
      ->setFieldMapperConfig(
        'a_plain_text',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'simple',
              'config' => [
                'mapping' => 'rich_text_2',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'default',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'format' => 'plain_text',
          'debug_level' => 0,
        ]
      )
      // Boolean field mapping.
      ->setFieldMapperId('a_boolean', 'generic')
      ->setFieldMapperConfig(
        'a_boolean',
        [
          'property_mappings' => [
            'value' => [
              'id' => 'simple',
              'config' => [
                'mapping' => 'status',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [
                  [
                    'id' => 'boolean',
                    'config' => [],
                  ],
                ],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      )
      // Entity reference field mapping.
      ->setFieldMapperId('ref', 'generic')
      ->setFieldMapperConfig(
        'ref',
        [
          'property_mappings' => [
            'target_id' => [
              'id' => 'simple',
              'config' => [
                'mapping' => 'refs.*',
                'required_field' => FALSE,
                'main_property' => TRUE,
                'data_processors' => [],
              ],
            ],
          ],
          'debug_level' => 0,
        ]
      );
    $type->save();

    // Create the user with all needed permissions.
    $this->account = $this->drupalCreateUser([
      'administer external entity types',
      'view simple_external_entity external entity',
      'view simple_external_entity external entity collection',
    ]);
    $this->drupalLogin($this->account);
  }

  /**
   * Tests REST storage client global features.
   *
   * Other technical features are tested into unit tests.
   */
  public function testRestClient() {
    global $base_url;
    /** @var \Drupal\Tests\WebAssert $assert */
    $assert = $this->assertSession();

    // Edit external entity.
    $this->drupalGet('admin/structure/external-entity-types');
    $this->drupalGet('admin/structure/external-entity-types/simple_external_entity');
    $assert->pageTextContains('Simple external entity');

    // @todo Check if static cache works properly: mock endpoint to make sure we
    // only got on query for the list and none for single entity loading when
    // listing and loading. And then, make sure we still load if entity is not
    // in static cache.
    $this->fillField('storages_tab[config][storage_clients][0][config][endpoint_options][cache]', TRUE);

    // @todo Check no URL for a single entity.
    $this->fillField('storages_tab[config][storage_clients][0][config][endpoint_options][single]', '');
    // @todo Check URL for a single entity with id replacement.
    $this->fillField('storages_tab[config][storage_clients][0][config][endpoint_options][single]', $base_url . '/external-entities-test/simple/{id}/details');
    // @todo Check URL for a single entity without {id} placeholders and no replacement (id in the query part).
    $this->fillField('storages_tab[config][storage_clients][0][config][endpoint_options][single]', $base_url . '/external-entities-test/simple/');

    // @todo Check other response format: serialized and yml.
    // Field storages_tab[config][storage_clients][0][config][response_format].
    $this->fillField('storages_tab[config][storage_clients][0][config][response_format]', 'yml');
    $this->fillField('storages_tab[config][storage_clients][0][config][response_format]', 'serialized');
    $this->fillField('storages_tab[config][storage_clients][0][config][response_format]', 'json');

    // @todo Test if list parameter string is properly parsed and turned into an
    // array in config.
    $this->fillField('storages_tab[config][storage_clients][0][config][parameters][list]', "testpropa|a_value\ntestpropb|2,3,4");

    // @todo Test if single parameter string is properly parsed and turned into
    // an array in config with '{id}' placeholders replaced at runtime.
    $this->fillField('storages_tab[config][storage_clients][0][config][parameters][single]', "propc|other_value\nidfield|ent{id}x");

    // @todo Test single entities keyed by their ID in a list.
    $this->fillField('storages_tab[config][storage_clients][0][config][data_path][keyed_by_id]', TRUE);

    // Save changes.
    $this->pressButton('edit-actions-submit');

    // @todo Implement tests (see above).
    $this->markTestIncomplete('A couple of elements remains to be tested.');
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc