<commit_before><?php

namespace Oro\Bundle\ReportBundle\Tests\Unit\Grid;

use Oro\Bundle\DataGridBundle\Datagrid\Common\DatagridConfiguration;
use Oro\Bundle\QueryDesignerBundle\Form\Type\DateGroupingType;
use Oro\Bundle\QueryDesignerBundle\QueryDesigner\JoinIdentifierHelper;
use Oro\Bundle\ReportBundle\Entity\CalendarDate;
use Oro\Bundle\ReportBundle\Entity\Report;
use Oro\Bundle\ReportBundle\Grid\DatagridDateGroupingBuilder;
use Oro\Bundle\ReportBundle\Exception\InvalidDatagridConfigException;
use Oro\Bundle\UserBundle\Entity\Group;
use Oro\Bundle\UserBundle\Entity\User;

/**
 * @SuppressWarnings("PMD.ExcessiveMethodLength")
 */
class DatagridDateGroupingBuilderTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var |\PHPUnit_Framework_MockObject_MockObject
     */
    protected $calendarDateEntity = CalendarDate::class;

    /**
     * @var DatagridDateGroupingBuilder
     */
    protected $datagridDateGroupingBuilder;

    /**
     * @var DatagridConfiguration|\PHPUnit_Framework_MockObject_MockObject $config
     */
    protected $config;

    /**
     * @var JoinIdentifierHelper|\PHPUnit_Framework_MockObject_MockObject
     */
    protected $joinIdHelper;

    protected function setUp()
    {
        $this->config = DatagridConfiguration::create([]);
        $this->joinIdHelper = $this->getMockBuilder(JoinIdentifierHelper::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->datagridDateGroupingBuilder = new DatagridDateGroupingBuilder(
            $this->calendarDateEntity,
            $this->joinIdHelper
        );
    }

    public function testIgnoreIfGroupingNotRequired()
    {
        $report = new Report();
        $this->joinIdHelper->expects($this->never())->method('getFieldName');

        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);

        $report->setDefinition(json_encode([DateGroupingType::DATE_GROUPING_NAME => []]));
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);

        $report->setDefinition(
            json_encode([DateGroupingType::DATE_GROUPING_NAME => [DateGroupingType::FIELD_NAME_ID => 'ddd']])
        );
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);
        $report->setDefinition(
            json_encode([DateGroupingType::DATE_GROUPING_NAME => [DateGroupingType::FIELD_NAME_ID => 'ddd']])
        );
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);
    }

    /**
     * @param array $params
     * @dataProvider exceptionTestProvider
     */
    public function testThrowsIfInvalidGrid($params)
    {
        $this->expectException(InvalidDatagridConfigException::class);
        $this->joinIdHelper->expects($this->never())->method('getFieldName');
        $this->config->merge($params);
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired(
            $this->config,
            $this->getPreconfiguredReport()
        );
    }

    /**
     * @return array
     */
    public function exceptionTestProvider()
    {
        return [
            [
                [
                    DatagridDateGroupingBuilder::SOURCE_KEY_NAME => [],
                ],
            ],
            [
                [
                    DatagridDateGroupingBuilder::SOURCE_KEY_NAME => ['query_config' => []],
                ],
            ],
            [
                [
                    DatagridDateGroupingBuilder::SOURCE_KEY_NAME => ['query_config' => ['column_aliases']],
                ],
            ],
        ];
    }

    public function testConfigPassesButTableAliasThrows()
    {
        $this->joinIdHelper->expects($this->once())->method('getFieldName');
        $this->joinIdHelper->expects($this->once())->method('explodeColumnName')->willReturn(['noneValidValue']);
        $this->expectException(InvalidDatagridConfigException::class);
        $this->config->merge($this->getPreconfiguredConfig());
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired(
            $this->config,
            $this->getPreconfiguredReport()
        );
    }

    /**
     * @dataProvider validConfigurationProvider
     * @param Report $report
     * @param [] $inputConfig
     * @param [] $expectedConfig
     */
    public function testValidDateGroupingConfiguration($report, $inputConfig, $expectedConfig)
    {
        $this->joinIdHelper->expects($this->once())->method('getFieldName');
        $this->joinIdHelper->expects($this->once())->method('explodeColumnName')->willReturn(['']);
        $this->config->merge($inputConfig);
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired(
            $this->config,
            $report
        );
        $this->assertSame($this->config->toArray(), $expectedConfig);
    }

    /**
     * @return array
     */
    public function validConfigurationProvider()
    {
        $originalConfig3 = $this->getPreconfiguredConfig();
        $originalConfig3['source']['query']['join']['left'][0] = [
            'join' => Group::class,
            'alias' => 't2',
        ];
        $expectedException3 = $this->getExpectedConfig(true);
        $expectedException3['source']['query']['join']['left'][1] =
            $originalConfig3['source']['query']['join']['left'][0];

        return [
            [$this->getPreconfiguredReport(), $this->getPreconfiguredConfig(), $this->getExpectedConfig(true)],
            [<commit_msg>BB-8403: Grouping filter not working - datagriddategroupingbuildertest fix<commit_after><?php

namespace Oro\Bundle\ReportBundle\Tests\Unit\Grid;

use Oro\Bundle\DataGridBundle\Datagrid\Common\DatagridConfiguration;
use Oro\Bundle\QueryDesignerBundle\Form\Type\DateGroupingType;
use Oro\Bundle\QueryDesignerBundle\QueryDesigner\JoinIdentifierHelper;
use Oro\Bundle\ReportBundle\Entity\CalendarDate;
use Oro\Bundle\ReportBundle\Entity\Report;
use Oro\Bundle\ReportBundle\Grid\DatagridDateGroupingBuilder;
use Oro\Bundle\ReportBundle\Exception\InvalidDatagridConfigException;
use Oro\Bundle\UserBundle\Entity\Group;
use Oro\Bundle\UserBundle\Entity\User;

/**
 * @SuppressWarnings("PMD.ExcessiveMethodLength")
 */
class DatagridDateGroupingBuilderTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var |\PHPUnit_Framework_MockObject_MockObject
     */
    protected $calendarDateEntity = CalendarDate::class;

    /**
     * @var DatagridDateGroupingBuilder
     */
    protected $datagridDateGroupingBuilder;

    /**
     * @var DatagridConfiguration|\PHPUnit_Framework_MockObject_MockObject $config
     */
    protected $config;

    /**
     * @var JoinIdentifierHelper|\PHPUnit_Framework_MockObject_MockObject
     */
    protected $joinIdHelper;

    protected function setUp()
    {
        $this->config = DatagridConfiguration::create([]);
        $this->joinIdHelper = $this->getMockBuilder(JoinIdentifierHelper::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->datagridDateGroupingBuilder = new DatagridDateGroupingBuilder(
            $this->calendarDateEntity,
            $this->joinIdHelper
        );
    }

    public function testIgnoreIfGroupingNotRequired()
    {
        $report = new Report();
        $this->joinIdHelper->expects($this->never())->method('getFieldName');

        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);

        $report->setDefinition(json_encode([DateGroupingType::DATE_GROUPING_NAME => []]));
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);

        $report->setDefinition(
            json_encode([DateGroupingType::DATE_GROUPING_NAME => [DateGroupingType::FIELD_NAME_ID => 'ddd']])
        );
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);
        $report->setDefinition(
            json_encode([DateGroupingType::DATE_GROUPING_NAME => [DateGroupingType::FIELD_NAME_ID => 'ddd']])
        );
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired($this->config, $report);
    }

    /**
     * @param array $params
     * @dataProvider exceptionTestProvider
     */
    public function testThrowsIfInvalidGrid($params)
    {
        $this->expectException(InvalidDatagridConfigException::class);
        $this->joinIdHelper->expects($this->never())->method('getFieldName');
        $this->config->merge($params);
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired(
            $this->config,
            $this->getPreconfiguredReport()
        );
    }

    /**
     * @return array
     */
    public function exceptionTestProvider()
    {
        return [
            [
                [
                    DatagridDateGroupingBuilder::SOURCE_KEY_NAME => [],
                ],
            ],
            [
                [
                    DatagridDateGroupingBuilder::SOURCE_KEY_NAME => ['query_config' => []],
                ],
            ],
            [
                [
                    DatagridDateGroupingBuilder::SOURCE_KEY_NAME => ['query_config' => ['column_aliases']],
                ],
            ],
        ];
    }

    public function testConfigPassesButTableAliasThrows()
    {
        $this->joinIdHelper->expects($this->once())->method('getFieldName');
        $this->joinIdHelper->expects($this->once())->method('explodeColumnName')->willReturn(['noneValidValue']);
        $this->expectException(InvalidDatagridConfigException::class);
        $this->config->merge($this->getPreconfiguredConfig());
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired(
            $this->config,
            $this->getPreconfiguredReport()
        );
    }

    /**
     * @dataProvider validConfigurationProvider
     * @param Report $report
     * @param [] $inputConfig
     * @param [] $expectedConfig
     */
    public function testValidDateGroupingConfiguration($report, $inputConfig, $expectedConfig)
    {
        $this->joinIdHelper->expects($this->once())->method('getFieldName');
        $this->joinIdHelper->expects($this->once())->method('explodeColumnName')->willReturn(['']);
        $this->config->merge($inputConfig);
        $this->datagridDateGroupingBuilder->applyDateGroupingFilterIfRequired(
            $this->config,
            $report
        );

        // Shifting select array to match convention for calendar date as first select item
        $expectedSelect = $expectedConfig['source']['query']['select'];
        array_unshift($expectedSelect, array_pop($expectedSelect));
        $expectedConfig['source']['query']['select'] = $expectedSelect ;

        $this->assertSame($this->config->toArray(), $expectedConfig);
    }

    /**
     * @return array
     */
    public function validConfigurationProvider()
    {
        $originalConfig3 = $this->getPreconfiguredConfig();
        $originalConfig3['source']['query']['join']['left'][0] = [
            'join' => Group::class,
            'alias' => 't2',
        ];
        $expectedException3 = $this->getExpectedConfig(true);
        $expectedException3['source']['query']['join']['left'][1] =
            $originalConfig3['source']['query']['join']['left'][0];

        return [
            [$this->getPreconfiguredReport(), $this->getPreconfiguredConfig(), $this->getExpectedConfig(true)],
            [
{'fraction_non_alphanumeric': 0.13699462085719244, 'fraction_numerical': 0.0019087280930071143, 'mean_word_length': 3.0290108353722474, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 181, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2280093', 'n_tokens_mistral': 3182, 'n_tokens_neox': 3135, 'n_words': 345}