Commit 77f79791 authored by Steven Jones's avatar Steven Jones
Browse files

[#3551130] feat: Improve cloning in views to prevent crashes.

By: vladimiraus
By: steven jones
parent f6711c01
Loading
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -1045,4 +1045,31 @@ class DataExport extends RestExport {
    return $route;
  }

  /**
   * {@inheritdoc}
   */
  public function validate() {
    $errors = parent::validate();

    // Validate that the style plugin is valid for our display.
    $style_plugin = $this->getPlugin('style');
    if (!empty($style_plugin)) {
      $plugin_definition = $style_plugin->getPluginDefinition();
      if (!in_array($this->getType(), $plugin_definition['display_types'])) {
        $errors[] = $this->t('Display "@display" does not use a valid style plugin.', ['@display' => $this->display['display_title']]);
      }
    }

    // Validate that the row plugin is valid for our display.
    $row_plugin = $this->getPlugin('row');
    if (!empty($row_plugin)) {
      $plugin_definition = $row_plugin->getPluginDefinition();
      if (!in_array($this->getType(), $plugin_definition['display_types'])) {
        $errors[] = $this->t('Display "@display" does not use a valid row plugin.', ['@display' => $this->display['display_title']]);
      }
    }

    return $errors;
  }

}
+59 −0
Original line number Diff line number Diff line
langcode: en
status: true
dependencies:
  module:
    - rest
    - user
id: test_data_export_validate
label: 'test_data_export_validate'
module: views_data_export
description: ''
tag: ''
base_table: entity_test
base_field: id
core: 8.x
display:
  default:
    display_plugin: default
    id: default
    display_title: Master
    position: null
    display_options:
      access:
        type: perm
        options:
          perm: 'access content'
      cache:
        type: tag
      query:
        type: views_query
      exposed_form:
        type: basic
      style:
        type: default
      row:
        type: entity:entity_test
      sorts:
        id:
          id: standard
          table: entity_test
          field: id
          order: DESC
          plugin_id: date
          entity_type: entity_test
          entity_field: id
      title: 'Test serialize'
      arguments: {  }
  block_1:
    display_plugin: block
    id: block_1
    display_title: block_1
    position: null
    display_options:
      defaults:
        style: false
        row: false
      style:
        type: default
      row:
        type: entity:entity_test
+105 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\views_data_export\Functional;

use Drupal\Tests\views\Functional\ViewTestBase;

/**
 * Tests views data export views validation.
 *
 * @group views_data_export
 */
class ViewsDataExportValidateTest extends ViewTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'entity_test',
    'rest',
    'views_data_export',
    'views_data_export_test',
    'csv_serialization',
    'views_ui',
  ];

  /**
   * {@inheritdoc}
   */
  public static $testViews = ['test_data_export_validate'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp($import_test_views = TRUE, $modules = ['views_test_config']): void {
    parent::setUp($import_test_views, ['views_data_export_test']);
    $account = $this->drupalCreateUser(['administer views']);
    $this->drupalLogin($account);
  }

  /**
   * Test our validation code.
   *
   * @covers \Drupal\views_data_export\Plugin\views\display\DataExport::validate
   */
  public function testCloneDisplayValidate() {
    // We have a view that has a block display that uses an overridden style
    // and row plugin.
    $this->drupalGet('admin/structure/views/view/test_data_export_validate/edit/block_1');
    $this->assertSession()->statusCodeEquals(200);

    // Duplicate this as a data export display.
    $this->submitForm([], 'Duplicate as Data export');

    // Now we're going to set the path for the new display, so that we can
    // save it.
    $this->drupalGet('admin/structure/views/nojs/display/test_data_export_validate/data_export_1/path');
    $this->submitForm([
      'path' => 'test/data_export/validate/export',
    ], 'Apply');

    // Views will have copied the style and row plugin from the block display,
    // which are not valid for a data export display. Try saving the view.
    $this->drupalGet('admin/structure/views/view/test_data_export_validate/edit/data_export_1');
    $this->submitForm([], 'Save');

    // It should complain about the style plugin first.
    $this->assertSession()->pageTextContains('does not use a valid style plugin.');

    // Set the valid style plugin.
    $this->drupalGet('admin/structure/views/nojs/display/test_data_export_validate/data_export_1/style');
    $this->submitForm([
      'style[type]' => 'data_export',
    ], 'Apply');

    // Try saving the view again.
    $this->drupalGet('admin/structure/views/view/test_data_export_validate/edit/data_export_1');
    $this->submitForm([], 'Save');

    // Now it should complain about the row plugin.
    $this->assertSession()->pageTextContains('does not use a valid row plugin.');

    // Now set the valid row plugin.
    $this->drupalGet('admin/structure/views/nojs/display/test_data_export_validate/data_export_1/row');
    $this->submitForm([
      'row[type]' => 'data_entity',
    ], 'Apply');

    // Try saving the view again.
    $this->drupalGet('admin/structure/views/view/test_data_export_validate/edit/data_export_1');
    $this->submitForm([], 'Save');

    // Now both errors should be cleared.
    $this->assertSession()->pageTextNotContains('does not use a valid style plugin.');
    $this->assertSession()->pageTextNotContains('does not use a valid row plugin.');

    // Finally, the view should save properly.
    $this->assertSession()->pageTextContains('The view test_data_export_validate has been saved.');
  }

}