added simple math and charts modules
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
name: Charts test
|
||||
type: module
|
||||
description: 'Provides functionality for testing the charts module.'
|
||||
package: Testing
|
||||
core_version_requirement: ^8.8 || ^9 || ^10 || ^11
|
||||
dependencies:
|
||||
- charts:charts
|
||||
|
||||
# Information added by Drupal.org packaging script on 2024-12-02
|
||||
version: '5.1.1'
|
||||
project: 'charts'
|
||||
datestamp: 1733170633
|
||||
8
web/modules/charts/tests/modules/charts_test/charts_test.routing.yml
Executable file
8
web/modules/charts/tests/modules/charts_test/charts_test.routing.yml
Executable file
@@ -0,0 +1,8 @@
|
||||
charts_test.data_collector_table_test_form:
|
||||
path: '/charts_test/data_collector_table_test_form'
|
||||
defaults:
|
||||
_form: '\Drupal\charts_test\Form\DataCollectorTableTestForm'
|
||||
_title: 'Data collector table test form'
|
||||
requirements:
|
||||
# Needs to be accessed by an anonymous user.
|
||||
_access: 'TRUE'
|
||||
@@ -0,0 +1,6 @@
|
||||
charts.settings.library_plugin.charts_test_library:
|
||||
type: mapping
|
||||
mapping:
|
||||
foo:
|
||||
label: Foo
|
||||
type: string
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\charts_test\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* The data collector table test form to test the DataCollectorTable element.
|
||||
*
|
||||
* @package Drupal\charts_test\Form
|
||||
*/
|
||||
class DataCollectorTableTestForm extends FormBase {
|
||||
|
||||
const INITIAL_ROWS = 3;
|
||||
const INITIAL_COLUMNS = 2;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'charts_data_collector_table_test_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$config = $this->config('charts.settings');
|
||||
$form['series'] = [
|
||||
'#type' => 'chart_data_collector_table',
|
||||
'#initial_rows' => self::INITIAL_ROWS,
|
||||
'#initial_columns' => self::INITIAL_COLUMNS,
|
||||
'#table_drag' => FALSE,
|
||||
'#default_colors' => $config->get('charts_default_settings.display.colors') ?? [],
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
// {"name":"Number of players","color":"#0d233a","data":
|
||||
// [50,60,100,132,133,234]},{"name":"Number of coaches","color":.
|
||||
// "#ff0000","data":
|
||||
// [50,80,100,32,133,234]}.
|
||||
// A,b,c,d,e,f
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\charts_test\Plugin\chart\Library;
|
||||
|
||||
use Drupal\charts\Plugin\chart\Library\ChartBase;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\Render\ElementInfoManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Define a library to use for testing purposes.
|
||||
*
|
||||
* @Chart(
|
||||
* id = "charts_test_library",
|
||||
* name = @Translation("Charts Test Library"),
|
||||
* types = {
|
||||
* "area",
|
||||
* "bar",
|
||||
* "bubble",
|
||||
* "column",
|
||||
* "donut",
|
||||
* "gauge",
|
||||
* "line",
|
||||
* "pie",
|
||||
* "scatter",
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
class ChartsTestLibrary extends ChartBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The element info manager.
|
||||
*
|
||||
* @var \Drupal\Core\Render\ElementInfoManagerInterface
|
||||
*/
|
||||
protected $elementInfo;
|
||||
|
||||
/**
|
||||
* Constructs a \Drupal\views\Plugin\Block\ViewsBlockBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info
|
||||
* The element info manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, ElementInfoManagerInterface $element_info) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->elementInfo = $element_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('element_info')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'foo' => 'bar',
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preRender(array $element) {
|
||||
// Populate chart settings.
|
||||
$chart_definition = [];
|
||||
|
||||
$chart_definition = $this->populateOptions($element, $chart_definition);
|
||||
$chart_definition = $this->populateData($element, $chart_definition);
|
||||
|
||||
if (!empty($element['#height']) || !empty($element['#width'])) {
|
||||
$element['#attributes']['style'] = 'height:' . $element['#height'] . $element['#height_units'] . ';width:' . $element['#width'] . $element['#width_units'] . ';';
|
||||
}
|
||||
|
||||
if (!isset($element['#id'])) {
|
||||
$element['#id'] = Html::getUniqueId('charts-charts-test-library-chart');
|
||||
}
|
||||
|
||||
$element['#attributes']['class'][] = 'charts-charts-test-library-chart-container';
|
||||
$element['#chart_definition'] = $chart_definition;
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate options.
|
||||
*
|
||||
* @param array $element
|
||||
* The element.
|
||||
* @param array $chart_definition
|
||||
* The chart definition.
|
||||
*
|
||||
* @return array
|
||||
* Return the chart definition.
|
||||
*/
|
||||
private function populateOptions(array $element, array $chart_definition) {
|
||||
$chart_definition['title']['text'] = $element['#title'];
|
||||
$chart_definition['title']['color'] = $element['#title_color'];
|
||||
$chart_definition['title']['position'] = $element['#title_position'];
|
||||
$chart_definition['subtitle']['text'] = $element['#subtitle'];
|
||||
$chart_definition['type'] = $element['#chart_type'];
|
||||
$chart_definition['title']['font'] = [
|
||||
'weight' => $element['#title_font_weight'],
|
||||
'style' => $element['#title_font_style'],
|
||||
'size' => $element['#title_font_size'],
|
||||
];
|
||||
$chart_definition['colors'] = $element['#colors'];
|
||||
$chart_definition['tooltips'] = $element['#tooltips'];
|
||||
$chart_definition['foo_configuration'] = $this->configuration['foo'] ?? '';
|
||||
|
||||
// Merge in chart raw options.
|
||||
if (!empty($element['#raw_options'])) {
|
||||
$chart_definition = NestedArray::mergeDeep($chart_definition, $element['#raw_options']);
|
||||
}
|
||||
|
||||
return $chart_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate data.
|
||||
*
|
||||
* @param array $element
|
||||
* The element.
|
||||
* @param array $chart_definition
|
||||
* The chart definition.
|
||||
*
|
||||
* @return array
|
||||
* Return the chart definition.
|
||||
*/
|
||||
private function populateData(array &$element, array $chart_definition) {
|
||||
$chart_definition['series'] = [];
|
||||
foreach (Element::children($element) as $key) {
|
||||
$type = $element[$key]['#type'];
|
||||
if ($type !== 'chart_data') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$chart_definition['series'][] = [
|
||||
'name' => $element[$key]['#title'],
|
||||
'color' => $element[$key]['#color'],
|
||||
'value' => $element[$key]['#data'],
|
||||
];
|
||||
}
|
||||
|
||||
return $chart_definition;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
id: test_charts
|
||||
label: ''
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: views_test_data
|
||||
base_field: nid
|
||||
display:
|
||||
default:
|
||||
id: default
|
||||
display_title: Default
|
||||
display_plugin: default
|
||||
position: 0
|
||||
display_options:
|
||||
title: 'Test charts style'
|
||||
defaults:
|
||||
fields: false
|
||||
pager: false
|
||||
sorts: false
|
||||
fields:
|
||||
age:
|
||||
id: age
|
||||
field: age
|
||||
relationship: none
|
||||
table: views_test_data
|
||||
plugin_id: numeric
|
||||
id:
|
||||
id: id
|
||||
field: id
|
||||
relationship: none
|
||||
table: views_test_data
|
||||
plugin_id: numeric
|
||||
name:
|
||||
id: name
|
||||
field: name
|
||||
relationship: none
|
||||
table: views_test_data
|
||||
plugin_id: string
|
||||
job:
|
||||
id: job
|
||||
field: job
|
||||
relationship: none
|
||||
table: views_test_data
|
||||
plugin_id: string
|
||||
pager:
|
||||
type: none
|
||||
options:
|
||||
offset: 0
|
||||
empty:
|
||||
area_text_custom:
|
||||
id: area_text_custom
|
||||
table: views
|
||||
field: area_text_custom
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
plugin_id: text_custom
|
||||
empty: true
|
||||
content: 'custom text for charts'
|
||||
tokenize: false
|
||||
sorts:
|
||||
id:
|
||||
field: id
|
||||
id: id
|
||||
order: ASC
|
||||
relationship: none
|
||||
table: views_test_data
|
||||
plugin_id: numeric
|
||||
style:
|
||||
type: chart
|
||||
options:
|
||||
grouping: { }
|
||||
chart_settings:
|
||||
library: charts_test_library
|
||||
type: column
|
||||
fields:
|
||||
label: name
|
||||
stacking: false
|
||||
data_providers:
|
||||
age:
|
||||
enabled: true
|
||||
color: '#ff9300'
|
||||
weight: 4
|
||||
id:
|
||||
enabled: false
|
||||
color: '#72fcd5'
|
||||
weight: 4
|
||||
name:
|
||||
enabled: false
|
||||
color: '#d783ff'
|
||||
weight: 4
|
||||
job:
|
||||
enabled: false
|
||||
color: '#b76b1f'
|
||||
weight: 4
|
||||
display:
|
||||
title: 'Test charts'
|
||||
title_position: out
|
||||
subtitle: ''
|
||||
data_labels: true
|
||||
data_markers: true
|
||||
legend_position: bottom
|
||||
background: ''
|
||||
three_dimensional: 0
|
||||
polar: 0
|
||||
tooltips: true
|
||||
dimensions:
|
||||
width: ''
|
||||
width_units: ''
|
||||
height: ''
|
||||
height_units: ''
|
||||
gauge:
|
||||
max: ''
|
||||
min: ''
|
||||
green_from: ''
|
||||
green_to: ''
|
||||
yellow_from: ''
|
||||
yellow_to: ''
|
||||
red_from: ''
|
||||
red_to: ''
|
||||
color_changer: false
|
||||
xaxis:
|
||||
title: Date
|
||||
labels_rotation: '0'
|
||||
yaxis:
|
||||
title: Downloads
|
||||
min: ''
|
||||
max: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
decimal_count: ''
|
||||
labels_rotation: '0'
|
||||
row:
|
||||
type: fields
|
||||
page_1:
|
||||
id: page_1
|
||||
display_title: 'Page display'
|
||||
display_plugin: page
|
||||
position: 1
|
||||
display_options:
|
||||
path: test-charts
|
||||
7
web/modules/charts/tests/resources/csv/first_column.csv
Executable file
7
web/modules/charts/tests/resources/csv/first_column.csv
Executable file
@@ -0,0 +1,7 @@
|
||||
Categories,Number of players,Number of coaches
|
||||
a,50,50
|
||||
b,60,80
|
||||
c,100,100
|
||||
d,132,32
|
||||
e,133,133
|
||||
f,234,234
|
||||
|
2
web/modules/charts/tests/resources/csv/first_row.csv
Executable file
2
web/modules/charts/tests/resources/csv/first_row.csv
Executable file
@@ -0,0 +1,2 @@
|
||||
Categories,a,b
|
||||
Label,200,400
|
||||
|
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Functional\Plugin;
|
||||
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Tests the chart style views plugin.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class StyleChartsTest extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_charts'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $modules = ['charts', 'charts_test', 'views'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE, $modules = ['charts_test']): void {
|
||||
parent::setUp($import_test_views, $modules);
|
||||
|
||||
$this->enableViewsTestModule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the generated JSON generated from the views.
|
||||
*/
|
||||
public function testGeneratedJson() {
|
||||
$this->drupalGet('test-charts');
|
||||
|
||||
$this->assertSession()->statusCodeEquals(Response::HTTP_OK);
|
||||
|
||||
$attribute = 'data-chart';
|
||||
$chart_container = $this->assertSession()->elementAttributeExists('css', '#chart-test-charts-page-1', $attribute);
|
||||
|
||||
$actual = str_replace('"', '"', (string) $chart_container->getAttribute($attribute));
|
||||
$expected = '{"title":{"text":"Test charts","color":"#000","position":"out","font":{"weight":"normal","style":"normal","size":14}},"subtitle":{"text":""},"type":"column","colors":["#006fb0","#f07c33","#342e9c","#579b17","#3f067a","#cbde67","#7643b6","#738d00","#c157c7","#02dab1","#ed56b4","#d8d981","#004695","#736000","#a5a5ff","#833a00","#ff9ee9","#684507","#fe4f85","#5d0011","#ffa67b","#88005c","#ff9b8f","#85000f","#ff7581"],"tooltips":true,"foo_configuration":"","series":[]}';
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\FunctionalJavascript;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\Tests\charts\Traits\ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* Tests that chart configuration can be overridden.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class ConfigOverrideTest extends WebDriverTestBase {
|
||||
|
||||
use ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'charts',
|
||||
'charts_chartjs',
|
||||
];
|
||||
|
||||
/**
|
||||
* Tests that charts config can be overridden.
|
||||
*/
|
||||
public function testOverridingConfig() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// Set up an override of the cdn.
|
||||
$settings['config']['charts.settings']['advanced']['requirements']['cdn'] = (object) [
|
||||
'value' => FALSE,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
|
||||
// Check the error message.
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertSession()->pageTextContains('You are missing the Chart.js library in your Drupal installation directory and you have opted not to use a CDN.');
|
||||
}
|
||||
|
||||
}
|
||||
289
web/modules/charts/tests/src/FunctionalJavascript/DataCollectorTableTest.php
Executable file
289
web/modules/charts/tests/src/FunctionalJavascript/DataCollectorTableTest.php
Executable file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\FunctionalJavascript;
|
||||
|
||||
use Drupal\charts_test\Form\DataCollectorTableTestForm;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\Tests\charts\Traits\ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* Tests the data collector table element.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class DataCollectorTableTest extends WebDriverTestBase {
|
||||
|
||||
use ConfigUpdateTrait;
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Default theme.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* List modules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $modules = [
|
||||
'charts',
|
||||
'charts_test',
|
||||
];
|
||||
|
||||
const TABLE_SELECTOR = 'table[data-drupal-selector="edit-series-data-collector-table"]';
|
||||
|
||||
const TABLE_ROW_SELECTOR = 'table[data-drupal-selector="edit-series-data-collector-table"] tr.data-collector-table--row';
|
||||
|
||||
const TABLE_COLUMN_SELECTOR = 'table[data-drupal-selector="edit-series-data-collector-table"] tbody tr:nth-child(1) td:not(.data-collector-table--row--delete)';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->updateFooConfiguration('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the data collector table.
|
||||
*/
|
||||
public function testDataCollectorTable() {
|
||||
$this->drupalGet('/charts_test/data_collector_table_test_form');
|
||||
$table_id_selector = static::TABLE_SELECTOR;
|
||||
|
||||
// Count generated rows.
|
||||
$rows = $this->cssSelect(static::TABLE_ROW_SELECTOR);
|
||||
$this->assertTrue(count($rows) === DataCollectorTableTestForm::INITIAL_ROWS, 'Expected rows were found.');
|
||||
|
||||
// Count generated columns.
|
||||
// Only using the first row to count columns.
|
||||
$columns = $this->cssSelect(static::TABLE_COLUMN_SELECTOR);
|
||||
$this->assertTrue(count($columns) === DataCollectorTableTestForm::INITIAL_COLUMNS, 'Expected columns were found.');
|
||||
|
||||
// Fill the table.
|
||||
$cell_input_selector = $table_id_selector . ' tr.data-collector-table--row td > .data-collector-table--row--cell .form-text';
|
||||
$cell_inputs = $this->cssSelect($cell_input_selector);
|
||||
$this->assertNotEmpty($cell_inputs, $this->t('@count inputs were found', [
|
||||
'@count' => count($cell_inputs),
|
||||
]));
|
||||
$this->fillInputs($cell_inputs);
|
||||
|
||||
// Test adding a row.
|
||||
$this->doTableOperation('add', 'row');
|
||||
// The New row should not have any data.
|
||||
$this->assertNewCellIsEmpty('row');
|
||||
|
||||
// Test adding a column.
|
||||
$this->doTableOperation('add', 'column');
|
||||
// The New column should not have any data.
|
||||
$this->assertNewCellIsEmpty('column');
|
||||
|
||||
// Delete the second and third row.
|
||||
$this->doTableOperation('delete', 'row', [2, 3]);
|
||||
// Remove the middle column.
|
||||
$this->doTableOperation('delete', 'column', [2]);
|
||||
|
||||
// Import csv from resources.
|
||||
// Opening the dom "details" element.
|
||||
$series_import_details = $this->getSession()->getPage()->find('css', 'details[data-drupal-selector="edit-series-import"]');
|
||||
$this->assertFalse($series_import_details->hasAttribute('open'), 'Details closed');
|
||||
$this->getSession()->executeScript("document.querySelector('details[data-drupal-selector=edit-series-import]').setAttribute('open', true);");
|
||||
$this->assertTrue($series_import_details->hasAttribute('open'), 'Details open');
|
||||
// Add the CSV file containing the test data.
|
||||
$file_field_name = 'files[series]';
|
||||
$filename = $this->getResourcePath() . '/csv/first_column.csv';
|
||||
$this->getSession()->getPage()->attachFileToField($file_field_name, $filename);
|
||||
// Submit upload the file and wait for ajax processing.
|
||||
$button_selector = 'details[data-drupal-selector="edit-series-import"] input[value="Upload CSV"]';
|
||||
$this->pressAjaxButton($button_selector);
|
||||
$this->assertSession()->assertWaitOnAjaxRequest(20000);
|
||||
|
||||
// Verify the uploaded data.
|
||||
$page = $this->getSession()->getPage();
|
||||
$targets = $page->findAll('css', static::TABLE_ROW_SELECTOR);
|
||||
$this->assertEquals(7, count($targets), 'The count of number of expected rows match.');
|
||||
$targets = $page->findAll('css', static::TABLE_COLUMN_SELECTOR);
|
||||
$this->assertEquals(3, count($targets), 'The count of number of expected columns match.');
|
||||
$cell_input = $page->find('css', 'input[name="series[data_collector_table][0][0][data]"]');
|
||||
$this->assertEquals('Categories', $cell_input->getValue(), 'The cell value of row 1 at column 1 match.');
|
||||
$cell_input = $page->find('css', 'input[name="series[data_collector_table][6][2][data]"]');
|
||||
$this->assertEquals(234, $cell_input->getValue(), 'The last uploaded value in the cell match.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the default colors pn the "chart_data_collector_table" element.
|
||||
*/
|
||||
public function testColorDefaultColors() {
|
||||
$chart_config = \Drupal::config('charts.settings');
|
||||
$default_colors = $chart_config->get('charts_default_settings.display.colors');
|
||||
$this->drupalGet('/charts_test/data_collector_table_test_form');
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
// Get the first row, then inside the first row get the color input and
|
||||
// check its value.
|
||||
$first_row_color_input = $page->find('css', static::TABLE_ROW_SELECTOR . ':first-child td:nth-child(2) input[type="color"]');
|
||||
$this->assertEquals($default_colors[0], $first_row_color_input->getValue());
|
||||
|
||||
// Adding one column.
|
||||
$this->doTableOperation('add', 'column');
|
||||
|
||||
// Checking if the added column also has the expected color.
|
||||
$first_row_color_input = $page->find('css', static::TABLE_ROW_SELECTOR . ':first-child td:nth-child(3) input[type="color"]');
|
||||
$this->assertEquals($default_colors[1], $first_row_color_input->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do table operation.
|
||||
*
|
||||
* @param string $operation
|
||||
* The operation.
|
||||
* @param string $on
|
||||
* The element.
|
||||
* @param array $positions
|
||||
* The position.
|
||||
*/
|
||||
protected function doTableOperation(string $operation, string $on, array $positions = []) {
|
||||
$value = ucfirst($operation) . ' ' . $on;
|
||||
|
||||
if ($operation === 'add') {
|
||||
$selector = static::TABLE_SELECTOR . ' input[value="' . $value . '"]';
|
||||
$this->pressAjaxButton($selector);
|
||||
|
||||
if ($on === 'row') {
|
||||
$this->assertRowsIncreased();
|
||||
}
|
||||
else {
|
||||
$this->assertColumnsIncreased();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$on_row = $on === 'row';
|
||||
if ($on_row) {
|
||||
$counter = DataCollectorTableTestForm::INITIAL_ROWS + 1;
|
||||
$locator = static::TABLE_ROW_SELECTOR;
|
||||
}
|
||||
else {
|
||||
$counter = DataCollectorTableTestForm::INITIAL_COLUMNS + 1;
|
||||
$locator = static::TABLE_COLUMN_SELECTOR;
|
||||
}
|
||||
foreach ($positions as $position) {
|
||||
if ($on_row) {
|
||||
$button_selector = static::TABLE_ROW_SELECTOR . ':nth-child(' . $position . ') .data-collector-table--row--delete input[value="Delete row"]';
|
||||
}
|
||||
else {
|
||||
$button_selector = static::TABLE_SELECTOR . ' .data-collector-table--column-deletes-row';
|
||||
$button_selector .= ' .data-collector-table--column--delete:nth-child(' . $position . ') input[value="Delete column"]';
|
||||
}
|
||||
$this->pressAjaxButton($button_selector);
|
||||
$this->assertDeletionOperation($counter, $locator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert rows.
|
||||
*/
|
||||
protected function assertRowsIncreased() {
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertTrue($page->waitFor(10, function ($page) {
|
||||
$expected_rows = DataCollectorTableTestForm::INITIAL_ROWS + 1;
|
||||
$rows = $page->findAll('css', static::TABLE_ROW_SELECTOR);
|
||||
return count($rows) === $expected_rows;
|
||||
}), 'Expected rows were increased by one after add row click.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert columns.
|
||||
*/
|
||||
protected function assertColumnsIncreased() {
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertTrue($page->waitFor(10, function ($page) {
|
||||
$expected_rows = DataCollectorTableTestForm::INITIAL_COLUMNS + 1;
|
||||
$columns = $page->findAll('css', static::TABLE_COLUMN_SELECTOR);
|
||||
return count($columns) === $expected_rows;
|
||||
}), 'Expected columns were increased by one after add column click.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert new cell.
|
||||
*
|
||||
* @param string $on
|
||||
* The element.
|
||||
*/
|
||||
protected function assertNewCellIsEmpty(string $on) {
|
||||
$page = $this->getSession()->getPage();
|
||||
if ($on === 'row') {
|
||||
$counter = DataCollectorTableTestForm::INITIAL_ROWS + 1;
|
||||
$selector = static::TABLE_ROW_SELECTOR . ':nth-child(' . $counter . ') td:first-child input';
|
||||
}
|
||||
else {
|
||||
$counter = DataCollectorTableTestForm::INITIAL_COLUMNS + 1;
|
||||
$selector = static::TABLE_COLUMN_SELECTOR . ':nth-child(' . $counter . ') input';
|
||||
}
|
||||
$cell_input = $page->find('css', $selector);
|
||||
$this->assertEmpty($cell_input->getValue(), 'Added row cells are empty.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert Deletion operation.
|
||||
*
|
||||
* @param int $current_count
|
||||
* Current count.
|
||||
* @param string $locator
|
||||
* The locator.
|
||||
*/
|
||||
protected function assertDeletionOperation(int &$current_count, string $locator) {
|
||||
$web_assert = $this->assertSession();
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
$current_count--;
|
||||
$page = $this->getSession()->getPage();
|
||||
$targets = $page->findAll('css', $locator);
|
||||
$this->assertTrue(count($targets) === $current_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Press the ajax button.
|
||||
*
|
||||
* @param string $selector
|
||||
* The selector.
|
||||
*/
|
||||
protected function pressAjaxButton(string $selector) {
|
||||
$button = $this->assertSession()->waitForElementVisible('css', $selector);
|
||||
$this->assertNotEmpty($button);
|
||||
$button->click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill inputs.
|
||||
*
|
||||
* @param array $inputs
|
||||
* Input to fill.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement[]
|
||||
* The node element.
|
||||
*/
|
||||
protected function fillInputs(array $inputs) {
|
||||
/** @var \Behat\Mink\Element\NodeElement[] $inputs */
|
||||
foreach ($inputs as $input) {
|
||||
$value = rand(0, count($inputs));
|
||||
$input->setValue((string) $value);
|
||||
}
|
||||
return $inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path of the resource.
|
||||
*
|
||||
* @return string
|
||||
* The resource folder path.
|
||||
*/
|
||||
protected function getResourcePath() {
|
||||
return \Drupal::root() . '/' . \Drupal::service('extension.list.module')->getPath('charts') . '/tests/resources';
|
||||
}
|
||||
|
||||
}
|
||||
53
web/modules/charts/tests/src/Kernel/ChartElementTest.php
Normal file
53
web/modules/charts/tests/src/Kernel/ChartElementTest.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Kernel;
|
||||
|
||||
use Drupal\Tests\charts\Traits\ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* Tests the chart type element.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class ChartElementTest extends ChartsKernelTestBase {
|
||||
|
||||
use ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'charts',
|
||||
'charts_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->updateFooConfiguration('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the chart test element.
|
||||
*/
|
||||
public function testChartElement() {
|
||||
$element = [
|
||||
'#type' => 'chart',
|
||||
'#library' => 'charts_test_library',
|
||||
'#chart_type' => 'column',
|
||||
];
|
||||
|
||||
$json = "{'title':{'text':null,'color':'#000','position':'out','font':{'weight':'normal','style':'normal','size':14}},'subtitle':{'text':null},'type':'column','colors':['#2f7ed8','#0d233a','#8bbc21','#910000','#1aadce','#492970','#f28f43','#77a1e5','#c42525','#a6c96a'],'tooltips':true,'foo_configuration':'bar','series':[]}";
|
||||
$this->assertElementJson($element, $json);
|
||||
|
||||
// Testing raw options.
|
||||
$element['#raw_options'] = ['title' => ['text' => 'Foo']];
|
||||
$path = ['title', 'text'];
|
||||
$this->assertJsonPropertyHasValue($element, $path, 'Foo');
|
||||
$this->assertJsonPropertyHasValue($element, ['type'], 'column');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Kernel;
|
||||
|
||||
use Drupal\Tests\charts\Traits\ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* Tests the chart library configurations that are part of default config.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class ChartLibraryConfigTest extends ChartsKernelTestBase {
|
||||
|
||||
use ConfigUpdateTrait;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'charts',
|
||||
'charts_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->updateFooConfiguration('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if library config is available after rendering.
|
||||
*/
|
||||
public function testLibraryConfigIsAvailable() {
|
||||
$element = [
|
||||
'#type' => 'chart',
|
||||
'#library' => 'charts_test_library',
|
||||
'#chart_type' => 'column',
|
||||
];
|
||||
|
||||
$path = ['foo_configuration'];
|
||||
// Confirm that 'foo_configuration' option is set to 'bar'.
|
||||
$this->assertJsonPropertyHasValue($element, $path, 'bar');
|
||||
|
||||
// Check if we change the default config for the library config it will
|
||||
// pick up after rendering.
|
||||
$new_value = $this->randomString();
|
||||
$this->updateFooConfiguration($new_value);
|
||||
$this->assertJsonPropertyHasValue($element, $path, $new_value);
|
||||
}
|
||||
|
||||
}
|
||||
83
web/modules/charts/tests/src/Kernel/ChartTypeSupportTest.php
Normal file
83
web/modules/charts/tests/src/Kernel/ChartTypeSupportTest.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Kernel;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\Tests\charts\Traits\ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* Tests the chart types support functionality.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class ChartTypeSupportTest extends ChartsKernelTestBase {
|
||||
|
||||
use ConfigUpdateTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'charts',
|
||||
'charts_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->updateFooConfiguration('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the chart type support functionality.
|
||||
*
|
||||
* @param string $chart_type
|
||||
* The chart type to test.
|
||||
* @param string $expected_exception
|
||||
* The expected exception.
|
||||
* @param string $expected_exception_message
|
||||
* The expected exception message.
|
||||
*
|
||||
* @dataProvider provideChartTypesData
|
||||
*/
|
||||
public function testNotSupportedChartType(string $chart_type, string $expected_exception, string $expected_exception_message) {
|
||||
$element = [
|
||||
'#type' => 'chart',
|
||||
'#library' => 'charts_test_library',
|
||||
'#chart_type' => $chart_type,
|
||||
];
|
||||
|
||||
$this->expectException($expected_exception);
|
||||
$this->expectExceptionMessage($expected_exception_message);
|
||||
$this->renderer->renderRoot($element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for chart types support test.
|
||||
*
|
||||
* @return array[]
|
||||
* The chart types test cases.
|
||||
*/
|
||||
public function provideChartTypesData(): array {
|
||||
return [
|
||||
// Asserting that a chart type that is not a valid plugin chart type will
|
||||
// throw a plugin not found exception during discovery.
|
||||
'chart type plugin does not exist' => [
|
||||
'not_supported',
|
||||
PluginNotFoundException::class,
|
||||
'The "not_supported" plugin does not exist. Valid plugin IDs for Drupal\charts\TypeManager are: area, bar, bubble, column, donut, gauge, line, pie, scatter, spline',
|
||||
],
|
||||
// Asserting that a chart type not supported by a chart library plugin
|
||||
// will throw a logic exception.
|
||||
'chart type plugin exists but not supported by the chart library plugin' => [
|
||||
'spline',
|
||||
\LogicException::class,
|
||||
'The provided chart type "spline" is not supported by "Charts Test Library" chart plugin library.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
110
web/modules/charts/tests/src/Kernel/ChartsKernelTestBase.php
Normal file
110
web/modules/charts/tests/src/Kernel/ChartsKernelTestBase.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
/**
|
||||
* Base class for chart kernel tests.
|
||||
*/
|
||||
abstract class ChartsKernelTestBase extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* The renderer service.
|
||||
*
|
||||
* @var \Drupal\Core\Render\Renderer
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->renderer = $this->container->get('renderer');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given element returned the expected json.
|
||||
*
|
||||
* @param array $element
|
||||
* The element to check.
|
||||
* @param string $expected_json
|
||||
* The expected json.
|
||||
*/
|
||||
public function assertElementJson(array $element, string $expected_json) {
|
||||
$this->assertEquals($expected_json, $this->getDataChartJson($element));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that json property has value by given element.
|
||||
*
|
||||
* @param array $element
|
||||
* The element structure.
|
||||
* @param array $parents
|
||||
* The parent structure where the value is.
|
||||
* @param string $expected_value
|
||||
* The expected value.
|
||||
*/
|
||||
public function assertJsonPropertyHasValue(array $element, array $parents, string $expected_value) {
|
||||
$json = $this->getDataChartJson($element);
|
||||
$decoded_json = json_decode(str_replace("'", '"', $json), TRUE);
|
||||
$actual_value = NestedArray::getValue($decoded_json, $parents);
|
||||
$this->assertEquals($expected_value, $actual_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the json data.
|
||||
*
|
||||
* @param array $element
|
||||
* The element to be rendered.
|
||||
*
|
||||
* @return string
|
||||
* The string with the data from the chart.
|
||||
*/
|
||||
private function getDataChartJson(array $element): string {
|
||||
$renderer_output = $this->renderer->renderRoot($element);
|
||||
$crawler = new Crawler();
|
||||
$crawler->addHtmlContent(str_replace('"', "'", $renderer_output));
|
||||
return $crawler->filter('[data-chart]')->attr('data-chart');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chart style from the element.
|
||||
*
|
||||
* @param array $element
|
||||
* The element to be tested.
|
||||
* @param string $filter_selector
|
||||
* The selector to use for crawler filter.
|
||||
*
|
||||
* @return array
|
||||
* The styles as an array.
|
||||
*/
|
||||
protected function getChartStyle(array $element, string $filter_selector = '[data-chart]'): array {
|
||||
$renderer_output = $this->renderer->renderRoot($element);
|
||||
$crawler = new Crawler();
|
||||
$crawler->addHtmlContent(str_replace('"', "'", $renderer_output));
|
||||
if (!$crawler->filter($filter_selector)->count()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$style_attribute = $crawler->filter($filter_selector)->attr('style');
|
||||
// Explode the style attribute, filtering out the last (empty) element.
|
||||
$styles = $style_attribute ? explode(';', rtrim($style_attribute, ';')) : [];
|
||||
|
||||
// Convert the string into an array of key/value pairs.
|
||||
$parsed_styles = [];
|
||||
foreach ($styles as $style) {
|
||||
if (strlen(trim($style)) > 0) {
|
||||
[$property, $value] = explode(':', trim($style));
|
||||
$parsed_styles[$property] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed_styles;
|
||||
}
|
||||
|
||||
}
|
||||
72
web/modules/charts/tests/src/Kernel/DimensionsTest.php
Normal file
72
web/modules/charts/tests/src/Kernel/DimensionsTest.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Kernel;
|
||||
|
||||
/**
|
||||
* Test the dimensions element property behavior.
|
||||
*
|
||||
* @group charts
|
||||
*/
|
||||
class DimensionsTest extends ChartsKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'charts',
|
||||
'charts_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* Test that the set dimensions are correctly added on the element.
|
||||
*
|
||||
* @param array $element
|
||||
* The element to be tested.
|
||||
* @param string|null $expected_width
|
||||
* The expected width to be found on the element.
|
||||
* @param string|null $expected_height
|
||||
* The expected height to be found on the element.
|
||||
*
|
||||
* @dataProvider provideChartElements
|
||||
*/
|
||||
public function testDimensions(array $element, string $expected_width = NULL, string $expected_height = NULL) {
|
||||
$styles = $this->getChartStyle($element);
|
||||
$width = $styles['width'] ?? NULL;
|
||||
$height = $styles['height'] ?? NULL;
|
||||
$this->assertEquals($expected_width, $width);
|
||||
$this->assertEquals($expected_height, $height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides chart elements for the test dimensions test.
|
||||
*
|
||||
* @return array[]
|
||||
* the chart elements.
|
||||
*/
|
||||
public function provideChartElements(): array {
|
||||
// A simple chart element with no dimensions set.
|
||||
$element = [
|
||||
'#type' => 'chart',
|
||||
'#chart_type' => 'column',
|
||||
'series' => [
|
||||
'#type' => 'chart_data',
|
||||
'#title' => '5.0.x',
|
||||
'#data' => [257, 235, 325, 340],
|
||||
'#color' => '#1d84c3',
|
||||
],
|
||||
];
|
||||
// Element with the dimensions set.
|
||||
$element_filled_dimensions = $element + [
|
||||
'#width' => 50,
|
||||
'#width_units' => '%',
|
||||
'#height' => 225,
|
||||
'#height_units' => 'px',
|
||||
];
|
||||
|
||||
return [
|
||||
'empty dimensions' => [$element, NULL, NULL],
|
||||
'filled dimensions' => [$element_filled_dimensions, '50%', '225px'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
27
web/modules/charts/tests/src/Traits/ConfigUpdateTrait.php
Normal file
27
web/modules/charts/tests/src/Traits/ConfigUpdateTrait.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\charts\Traits;
|
||||
|
||||
/**
|
||||
* Provides a trait to update the configuration.
|
||||
*/
|
||||
trait ConfigUpdateTrait {
|
||||
|
||||
/**
|
||||
* Updates the foo configuration.
|
||||
*
|
||||
* @param string $value
|
||||
* The value to set.
|
||||
* @param string $library
|
||||
* Library to be rendered.
|
||||
*/
|
||||
protected function updateFooConfiguration(string $value, $library = 'charts_test_library'): void {
|
||||
$config = $this->config('charts.settings');
|
||||
$settings = $config->get('charts_default_settings');
|
||||
$settings['library'] = $library;
|
||||
$settings['library_config'] = ['foo' => $value];
|
||||
$config->set('charts_default_settings', $settings);
|
||||
$config->save();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user