1
0
قرینه از https://github.com/matomo-org/matomo.git synced 2025-08-25 00:17:37 +00:00
Files
matomo/tests/PHPUnit/Unit/DataTable/RowTest.php
Stefan Giehl d6d72d1fa7 [Coding Style] Enable rule PSR1.Methods.CamelCapsMethodName.NotCamelCaps (#22144)
* [Coding Style] Enable rule PSR1.Methods.CamelCapsMethodName.NotCamelCaps

* [Coding Style] Use camel case for method names in API plugin tests (#22145)

* [Coding Style] Use camel case for method names in Core* plugin tests (#22147)

* [Coding Style] Use camel case for method names in core Unit tests (#22149)

* [Coding Style] Use camel case for method names in Actions and BulkTracking plugin tests (#22146)

* [Coding Style] Use camel case for method names in CustomDimensions and CustomJSTracker plugin tests (#22148)

* [Coding Style] Use camel case for method names in core Integration tests (#22151)

* [Coding Style] Use camel case for method names in more core plugin tests (#22153)

* [Coding Style] Use camel case for method names in more core plugin tests (#22157)

* [Coding Style] Use camel case for method names in more core plugin tests

* Update plugins/Monolog/tests/Unit/Processor/ExceptionToTextProcessorTest.php

Co-authored-by: Michal Kleiner <michal@innocraft.com>

---------

Co-authored-by: Michal Kleiner <michal@innocraft.com>

* [Coding Style] Use camel case for method names in more core plugin tests (#22159)

* [Coding Style] Use camel case for method names in remaining tests (#22160)

* [Coding Style] Use camel case for method names in remaining tests

* rename expected test files

---------

Co-authored-by: Michal Kleiner <michal@innocraft.com>
2024-04-25 20:57:55 +02:00

483 خطوط
17 KiB
PHP

<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Tests\Unit\DataTable;
use Piwik\DataTable;
use Piwik\DataTable\Row;
/**
* @group DataTableTest
*/
class RowTest extends \PHPUnit\Framework\TestCase
{
/**
* @var Row
*/
private $row;
public function setUp(): void
{
$this->row = new Row();
}
public function testIsSubtableLoadedReturnsTrueIfDataTableAssociatedIsLoaded()
{
$testRow = $this->getTestRowWithSubDataTableLoaded();
$this->assertTrue($testRow->isSubtableLoaded());
$this->assertGreaterThanOrEqual(1, $testRow->getIdSubDataTable());
}
public function testIsSubtableLoadedReturnsTrueWhenSubDataTableSetted()
{
$testRow = $this->getTestRowWithSubDataTableNotLoaded();
$this->assertFalse($testRow->isSubtableLoaded()); // verify not already loaded
$this->assertEquals(50, $testRow->getIdSubDataTable());
$testRow->setSubtable($this->getTestSubDataTable());
$this->assertTrue($testRow->isSubtableLoaded());
$this->assertGreaterThanOrEqual(1, $testRow->getIdSubDataTable());
}
public function testGetIdSubDataTableShouldBeNullIfNoSubtableIsSet()
{
$testRow = $this->getTestRowWithNoSubDataTable();
$this->assertEquals(null, $testRow->getIdSubDataTable());
}
public function testRemoveSubtableShouldRemoveASetSubtable()
{
$testRow = $this->getTestRowWithSubDataTableLoaded();
$this->assertTrue($testRow->isSubtableLoaded());
$testRow->removeSubtable();
$this->assertFalse($testRow->isSubtableLoaded());
$this->assertEquals(null, $testRow->getIdSubDataTable());
}
public function testDestructShouldRemoveASetSubtable()
{
$testRow = $this->getTestRowWithSubDataTableLoaded();
$this->assertTrue($testRow->isSubtableLoaded());
$testRow->__destruct();
$this->assertFalse($testRow->isSubtableLoaded());
$this->assertEquals(null, $testRow->getIdSubDataTable());
}
public function testCanBeClonedShouldRemoveASetSubtable()
{
$testRow = $this->getTestRowWithNoSubDataTable();
$testRow->setColumn('label', 'test');
$testRow2 = clone $testRow;
$this->assertNotSame($testRow2, $testRow);
$this->assertEquals('test', $testRow2->getColumn('label'));
$this->assertEquals('test', $testRow->getColumn('label'));
$testRow->setColumn('label', 'different');
// only row 2 changes
$this->assertEquals('test', $testRow2->getColumn('label'));
$this->assertEquals('different', $testRow->getColumn('label'));
}
public function testExportShouldExportColumnsMetadataAndSubtableId()
{
$columns = array('label' => 'test', 'nb_visits' => 5);
$testRow = $this->getTestRowWithSubDataTableLoaded();
$testRow->setColumns($columns);
$testRow->setMetadata('test1', 'val1');
$testRow->setMetadata('url', 'http://piwik.org');
$export = $testRow->export();
$expected = array(
Row::COLUMNS => $columns,
Row::METADATA => array('test1' => 'val1', 'url' => 'http://piwik.org')
);
// we cannot really test for exact match since the subtableId might change when other tests are changed
$this->assertGreaterThan(1, $export[Row::DATATABLE_ASSOCIATED]);
unset($export[Row::DATATABLE_ASSOCIATED]);
$this->assertSame($expected, $export);
}
public function testIsSubtableLoadedShouldReturnFalseWhenRestoringAnExportedRow()
{
$testRow = $this->getTestRowWithSubDataTableLoaded();
// serialize and unserialize is not needed for this test case, the export is the important part.
// we still do it, to have it more "realistic"
$serializedTestRow = serialize($testRow->export());
$unserializedTestRow = unserialize($serializedTestRow);
/** @var Row $unserializedTestRow */
$row = new Row($unserializedTestRow);
$this->assertTrue($row->getIdSubDataTable() > 0);
$this->assertFalse($row->isSubtableLoaded());
}
public function testIsSubDataTableLoadedIsTrueWhenSubDataTableInMemory()
{
$testRow = $this->getTestRowWithSubDataTableLoaded();
$this->assertTrue($testRow->isSubtableLoaded());
}
public function testIsSubDataTableLoadedIsFalseWhenSubDataTableNotInMemory()
{
$testRow = $this->getTestRowWithSubDataTableNotLoaded();
$this->assertFalse($testRow->isSubtableLoaded());
}
public function testGetMetadataSetMetadataShouldReturnRawScalarValue()
{
$this->assertMetadataSavesValue(5, 'testInteger', 5);
$this->assertMetadataSavesValue(5.444, 'testFloat', 5.444);
$this->assertMetadataSavesValue('MyString', 'testString', 'MyString');
$this->assertMetadataSavesValue(array(array(1 => '5')), 'testArray', array(array(1 => '5')));
}
public function testGetMetadataShouldReturnFalseIfMetadataKeyDoesNotExists()
{
$this->assertFalse($this->row->getMetadata('anyKey_thatDoesNotExist'));
}
public function testGetMetadataShouldReturnEmptyArrayIfNoParticularOneIsRequestedAndNoneAreSet()
{
$this->assertEquals(array(), $this->row->getMetadata());
}
public function testGetMetadataShouldReturnAllMetadataValuesIfNoParticularOneIsRequested()
{
$this->row->setMetadata('url', 'http://piwik.org');
$this->row->setMetadata('segmentValue', 'test==piwik');
$this->assertEquals(array(
'url' => 'http://piwik.org',
'segmentValue' => 'test==piwik'
), $this->row->getMetadata());
}
public function testDeleteMetadataShouldReturnDeleteAllValuesWhenNoSpecificOneIsRequestedToBeDeleted()
{
$this->row->setMetadata('url', 'http://piwik.org');
$this->row->setMetadata('segmentValue', 'test==piwik');
$this->assertNotEmpty($this->row->getMetadata()); // make sure it is actually set
$this->row->deleteMetadata();
$this->assertSame(array(), $this->row->getMetadata());
}
public function testDeleteMetadataShouldOnlyDeleteARequestedMetadataEntryWhileKeepingOthersUntouched()
{
$this->row->setMetadata('url', 'http://piwik.org');
$this->row->setMetadata('segmentValue', 'test==piwik');
$this->assertTrue($this->row->deleteMetadata('url'));
$this->assertFalse($this->row->getMetadata('url'));
$this->assertEquals('test==piwik', $this->row->getMetadata('segmentValue'));
}
public function testDeleteMetadataShouldReturnFalseAndKeepOtherEntriesUntouchedIfMetadataNameDidNotExist()
{
$this->row->setMetadata('segmentValue', 'test==piwik');
$this->assertFalse($this->row->deleteMetadata('url'));
$this->assertEquals('test==piwik', $this->row->getMetadata('segmentValue'));
}
public function testGetColumnShouldReturnRawScalarValue()
{
$this->assertColumnSavesValue(5, 'testInteger', 5);
$this->assertColumnSavesValue(5.444, 'testFloat', 5.444);
$this->assertColumnSavesValue('MyString', 'testString', 'MyString');
$this->assertColumnSavesValue(array(array(1 => '5')), 'testArray', array(array(1 => '5')));
}
public function testGetColumnShouldReturnFalseIfValueIsNull()
{
$this->assertColumnSavesValue(false, 'testScalar', null);
}
public function testGetColumnsShouldNotCallAnyCallableForSecurity()
{
$this->assertColumnSavesValue('print_r', 'testScalar', 'print_r');
$this->assertColumnSavesValue(array('print_r'), 'testScalar', array('print_r'));
$this->assertColumnSavesValue(array(null, 'print_r'), 'testScalar', array(null, 'print_r'));
$this->assertColumnSavesValue('phpinfo', 'testScalar', 'phpinfo');
$this->assertColumnSavesValue(array('phpinfo'), 'testScalar', array('phpinfo'));
$this->assertColumnSavesValue(array(null, 'phpinfo'), 'testScalar', array(null, 'phpinfo'));
}
public function testGetColumnsSetColumnsShouldReturnAllColumns()
{
$this->row->setColumns(array(
'nb_visits' => 4,
'label' => 'Test',
'goals' => array(1 => array())
));
$expected = array(
'nb_visits' => 4,
'label' => 'Test',
'goals' => array(1 => array())
);
$this->assertEquals($expected, $this->row->getColumns());
$this->assertEquals('Test', $this->row->getColumn('label'));
$this->assertEquals(4, $this->row->getColumn('nb_visits'));
}
public function testDeleteColumnShouldOnlyDeleteARequestedColumnEntryWhileKeepingOthersUntouched()
{
$this->row->setColumn('label', 'http://piwik.org');
$this->row->setColumn('nb_visits', '1');
$this->assertTrue($this->row->deleteColumn('nb_visits'));
$this->assertFalse($this->row->hasColumn('nb_visits')); // verify
$this->assertFalse($this->row->getMetadata('nb_visits')); // verify
$this->assertEquals('http://piwik.org', $this->row->getColumn('label')); // make sure not deleted
}
public function testDeleteColumnShouldReturnFalseAndKeepOtherEntriesUntouchedIfColumnNameDidNotExist()
{
$this->row->setColumn('label', 'http://piwik.org');
$this->assertFalse($this->row->deleteColumn('nb_visits'));
$this->assertFalse($this->row->hasColumn('nb_visits'));
$this->assertEquals('http://piwik.org', $this->row->getColumn('label'));
}
public function testDeleteColumnShouldReturnAColumnValueThatIsNull()
{
$this->row->setColumn('label', null);
$this->assertTrue($this->row->hasColumn('label'));
$this->assertTrue($this->row->deleteColumn('label'));
$this->assertFalse($this->row->hasColumn('label'));
}
public function testRenameColumnShouldReturnAColumnOnlyIfAValueIsSetForThatColumn()
{
$this->row->setColumn('nb_visits', 10);
$this->row->renameColumn('nb_visits', 'nb_hits');
$this->assertFalse($this->row->hasColumn('nb_visits'));
$this->assertTrue($this->row->hasColumn('nb_hits'));
$this->assertEquals(10, $this->row->getColumn('nb_hits'));
}
public function testRenameColumnShouldNotReturnAColumnIfValueIsNotSetButRemoveColumn()
{
$this->row->setColumn('nb_visits', null);
$this->row->renameColumn('nb_visits', 'nb_hits');
$this->assertFalse($this->row->hasColumn('nb_visits'));
$this->assertFalse($this->row->hasColumn('nb_hits'));
}
public function testRenameColumnShouldDoNothingIfGivenColumnDoesNotExist()
{
$this->row->setColumn('nb_visits', 11);
$this->row->renameColumn('nb_hits', 'nb_pageviews');
$this->assertFalse($this->row->hasColumn('nb_hits'));
$this->assertFalse($this->row->hasColumn('nb_pageviews'));
$this->assertEquals(11, $this->row->getColumn('nb_visits'));
}
public function testGetSubtableShouldReturnSubtableIfLoaded()
{
$testRow = $this->getTestRowWithSubDataTableNotLoaded();
$subTable = $this->getTestSubDataTable();
$testRow->setSubtable($subTable);
$this->assertSame($subTable, $testRow->getSubtable());
}
public function testGetSubtableShouldReturnFalseIfSubtableExistsButIsNotLoaded()
{
$testRow = $this->getTestRowWithSubDataTableNotLoaded();
$this->assertFalse($testRow->getSubtable());
}
public function testGetSubtableShouldReturnFalseIfHasNoSubtableAtAll()
{
$testRow = $this->getTestRowWithNoSubDataTable();
$this->assertFalse($testRow->getSubtable());
}
public function testSumSubTableWhenSubTableAlreadyExistsOverwriteExistingSubtable()
{
$testRow = $this->getTestRowWithSubDataTableNotLoaded();
$this->assertFalse($testRow->isSubtableLoaded());
$subTable = $this->getTestSubDataTable();
$testRow->setSubtable($subTable);
$this->assertTrue($testRow->isSubtableLoaded());
$testRow->sumSubtable($subTable);
$this->assertTrue(DataTable::isEqual($testRow->getSubtable(), $subTable));
}
public function testHasColumn()
{
$this->row->setColumns(array('test1' => 'yes', 'test2' => false, 'test3' => 5, 'test4' => array()));
$this->assertFalse($this->row->hasColumn('test')); // does not exist
$this->assertTrue($this->row->hasColumn('test1'));
$this->assertTrue($this->row->hasColumn('test2')); // even if value is false it still exists
$this->assertTrue($this->row->hasColumn('test3'));
$this->assertTrue($this->row->hasColumn('test4'));
}
public function testHasColumnShouldReturnTrueEvenIfColumnValueIsNull()
{
$this->assertFalse($this->row->hasColumn('test'));
$this->row->setColumn('test', null);
$this->assertTrue($this->row->hasColumn('test'));
}
public function testSumRowMetadataShouldSumMetadataAccordingToAggregationOperations()
{
$this->row->setColumn('nb_visits', 10);
$this->row->setMetadata('my_sum', 5);
$this->row->setMetadata('my_max', 4);
$this->row->setMetadata('my_array', array(array('test' => 1, 'value' => 1), array('test' => 2, 'value' => 2)));
$row = $this->getTestRowWithNoSubDataTable();
$row->setColumn('nb_visits', 15);
$row->setMetadata('my_sum', 7);
$row->setMetadata('my_max', 2);
$row->setMetadata('my_array', array(array('test' => 3, 'value' => 3), array('test' => 2, 'value' => 2)));
$aggregations = array(
'nosuchcolumn' => 'max', // this metadata name does not exist and should be ignored
'my_sum' => 'sum',
'my_max' => 'max',
'my_array' => 'uniquearraymerge'
);
$this->row->sumRowMetadata($row, $aggregations);
$metadata = $this->row->getMetadata();
$expected = array(
'my_sum' => 12,
'my_max' => 4,
'my_array' => array(array('test' => 1, 'value' => 1), array('test' => 2, 'value' => 2), array('test' => 3, 'value' => 3))
);
$this->assertSame($expected, $metadata);
}
public function testSumRowMetadataUniquearraymergeShouldUseArrayFromOtherRowIfNoMetadataForThisRowSpecified()
{
$row = $this->getTestRowWithNoSubDataTable();
$arrayValue = array(array('test' => 3, 'value' => 3), array('test' => 2, 'value' => 2));
$row->setMetadata('my_array', $arrayValue);
$aggregations = array('my_array' => 'uniquearraymerge');
$this->row->sumRowMetadata($row, $aggregations);
$this->assertSame(array('my_array' => $arrayValue), $this->row->getMetadata());
}
public function testSumRowMetadataUniquearraymergeShouldUseArrayFromThisRowIfNoMetadataForOtherRowSpecified()
{
$row = $this->getTestRowWithNoSubDataTable();
$arrayValue = array(array('test' => 3, 'value' => 3), array('test' => 2, 'value' => 2));
$this->row->setMetadata('my_array', $arrayValue);
$aggregations = array('my_array' => 'uniquearraymerge');
$this->row->sumRowMetadata($row, $aggregations);
$this->assertSame(array('my_array' => $arrayValue), $this->row->getMetadata());
}
public function testSumRowThrowsIfAddingUnsupportedTypes()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Trying to sum unsupported operands for column mycol in row with label = row1: array + integer');
$row1 = new Row();
$row1->addColumn('label', 'row1');
$row1->addColumn('mycol', ['a']);
$row2 = new Row();
$row2->addColumn('label', 'row2');
$row2->addColumn('mycol', 45);
$row1->sumRow($row2);
}
private function assertColumnSavesValue($expectedValue, $columnName, $valueToSet)
{
$this->row->setColumn($columnName, $valueToSet);
$this->assertSame($expectedValue, $this->row->getColumn($columnName));
}
private function assertMetadataSavesValue($expectedValue, $metadataName, $valueToSet)
{
$this->row->setMetadata($metadataName, $valueToSet);
$this->assertSame($expectedValue, $this->row->getMetadata($metadataName));
}
protected function getTestRowWithSubDataTableLoaded()
{
$testSubDataTable = $this->getTestSubDataTable();
$testRow = new Row(array(
Row::DATATABLE_ASSOCIATED => $testSubDataTable
));
return $testRow;
}
protected function getTestRowWithNoSubDataTable()
{
return new Row(array());
}
protected function getTestSubDataTable()
{
return new DataTable();
}
protected function getTestRowWithSubDataTableNotLoaded()
{
$testRow = new Row(array(
Row::DATATABLE_ASSOCIATED => 50
));
return $testRow;
}
}