<?php
namespace tests\Zeedhi\ZhuLog\Logger\Processor;

use Zeedhi\ZhuLog\Logger\Processor\Processor;
use Zeedhi\ZhuLog\Logger\Processor\CompositeProcessor;

class CompositeProcessorTest extends \PHPUnit_Framework_TestCase {

    protected $firstProcessor;
    protected $secondProcessor;
    protected $compositeProcessor;

    public function setUp() {
        $this->firstProcessor  = $this->getMockBuilder(Processor::class)
                                      ->setMethods(['processRequest', 'processResponse', 'processException'])
                                      ->disableOriginalConstructor()
                                      ->getMock();

        $this->secondProcessor = $this->getMockBuilder(Processor::class)
                                      ->setMethods(['processRequest', 'processResponse', 'processException'])
                                      ->disableOriginalConstructor()
                                      ->getMock();

        $this->compositeProcessor = new CompositeProcessor($this->firstProcessor, $this->secondProcessor);
    }

    public function testProcessRequest() {
        $originalRequest = [
            'dataset' => [
                [
                    '_id' => 0,
                    'foo' => 'FIELD_THAT_WILL_BE_REMOVED_ON_FIRST_PROCESSOR',
                    'bar' => 'FIELD_THAT_WILL_HAVE_AN_STRING_APPENDED'
                ],
                [
                    '_id' => 1,
                    'foo' => 'FIELD_THAT_WILL_BE_REMOVED_ON_FIRST_PROCESSOR',
                    'bar' => 'FIELD_THAT_WILL_HAVE_AN_STRING_APPENDED'
                ]
            ]
        ];

        $route = '/route';
        $method = 'POST';

        $requestWithFirstProcess = [
            'dataset' => [
                [
                    '_id' => 0,
                    'bar' => 'FIELD_THAT_WILL_HAVE_AN_STRING_APPENDED'
                ],
                [
                    '_id' => 1,
                    'bar' => 'FIELD_THAT_WILL_HAVE_AN_STRING_APPENDED'
                ]
            ]
        ];
        $this->firstProcessor->expects($this->once())
                             ->method('processRequest')
                             ->with($originalRequest, $route, $method)
                             ->will($this->returnValue($requestWithFirstProcess));

        $finalRequest = [
            'dataset' => [
                [
                    '_id' => 0,
                    'bar' => 'FIELD_THAT_WILL_HAVE_AN_STRING_APPENDED_TEST'
                ],
                [
                '_id' => 1,
                'bar' => 'FIELD_THAT_WILL_HAVE_AN_STRING_APPENDED_TEST'
                ]
            ]
        ];
        $this->secondProcessor->expects($this->once())
                              ->method('processRequest')
                              ->with($requestWithFirstProcess, $route, $method)
                              ->will($this->returnValue($finalRequest));

        $result = $this->compositeProcessor->processRequest($originalRequest, $route, $method);

        $this->assertEquals($finalRequest, $result);
    }

    public function testProcessResponse() {
        $originalResponse = [
            'foo' => [
                ['id' => 0],
                ['id' => 1],
                ['id' => 2],
                ['id' => 3]
            ]
        ];

        $requestWithFirstProcess = [
            'foo' => 4
        ];

        $this->firstProcessor->expects($this->once())
                             ->method('processResponse')
                             ->with($originalResponse)
                             ->will($this->returnValue($requestWithFirstProcess));

        $finalResponse = [
            'foo' => 4,
            'rowCount' => 4
        ];
        $this->secondProcessor->expects($this->once())
                              ->method('processResponse')
                              ->with($requestWithFirstProcess)
                              ->will($this->returnValue($finalResponse));

        $result = $this->compositeProcessor->processResponse($originalResponse);

        $this->assertEquals($finalResponse, $result);
    }

}