<commit_before><?php

/**
 * Author: imsamurai <<EMAIL>>
 * Date: 20.08.2014
 * Time: 14:54:41
 * Format: http://book.cakephp.org/2.0/en/development/testing.html
 */
App::uses('Model', 'Model');
App::uses('CakeSchema', 'Model');
App::uses('HttpSource', 'HttpSource.Model/Datasource');
App::uses('HttpSourceConnection', 'HttpSource.Model/Datasource');
App::uses('HttpSourceConfigFactory', 'HttpSource.Lib/Config');

/**
 * HttpSourceTest
 * 
 * @package HttpSourceTest
 * @subpackage Model.Datasource
 */
class HttpSourceTest extends CakeTestCase {

	/**
	 * {@inheritdoc}
	 */
	public function tearDown() {
		parent::tearDown();
		Cache::clear(false, '__test_cache__');
	}

	/**
	 * {@inheritdoc}
	 */
	public function setUp() {
		parent::setUp();
		Cache::config('__test_cache__', array(
			'engine' => 'File',
			'prefix' => '__test_cache__',
			'path' => CACHE,
			'serialize' => true,
			'duration' => '1 hour'
		));

		$CF = HttpSourceConfigFactory::instance();
		Configure::write('HttpSource', array(
			'config_version' => 2,
			'config' => $CF->config()->cacheName('__test_cache__')
					->add(
							$CF->endpoint()
							->id(1)
							->table('endpoint1')
							->addCondition(
									$CF->condition()->name('condition1')
							)
							->cacheName(false)
					)
					->add(
							$CF->endpoint()
							->id(2)
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(3)
							->methodCreate()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(4)
							->methodUpdate()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
							->addCondition(
									$CF->condition()->name('condition1')
							)
					)
					->add(
							$CF->endpoint()
							->id(5)
							->methodDelete()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(6)
							->methodCheck()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(7)
							->methodCreate()
							->table('app_models2')
							->addCondition(
									$CF->condition()->name('condition3')
							)
							->addCondition(
									$CF->condition()->name('condition4')
							)
					)
					->add(
							$CF->endpoint()
							->id(8)
							->methodDelete()
							->table('app_models2')
							->addCondition(
									$CF->condition()->name('condition3')
							)
							->addCondition(
									$CF->condition()->name('condition4')
							)
					)
		));
	}

	/**
	 * Test construct
	 * 
	 * @param array $sourceConfig
	 * @param array $config
	 * @param string|HttpSourceConnection|null $Connection
	 * @param string $exception
	 * @param int $debugLevel
	 * @dataProvider constructProvider
	 */
	public function testConstruct($sourceConfig, $config, $Connection, $exception, $debugLevel) {
		if ($exception) {
			$this->expectException($exception);
		}

		if (!empty($sourceConfig['datasource'])) {
			list($plugin) = pluginSplit($sourceConfig['datasource']);
			Configure::write($plugin, $config);
		}

		$Source = $this->getMockBuilder('HttpTestSource')
				->disableOriginalConstructor()
				->setMethods(array('_loadConfig'))
				->getMock();
		$Source->expects($this->exactly((empty($config) && !empty($sourceConfig['datasource'])) ? 1 : 0))
				->method('_loadConfig')
				->with(isset($plugin) ? $plugin : null);

		$reflectedClass = new ReflectionClass('HttpTestSource');
		$constructor = $reflectedClass->getConstructor();
		$oldDebugLevel = Configure::read('debug');
		Configure::write('debug', $debugLevel);
		$constructor->invoke($Source, $sourceConfig, $Connection);
		Configure::write('debug', $oldDebugLevel);
		$this->assertSame($debugLevel > 1, $Source->fullDebug);

		if (is_object($Connection)) {
			$this->assertSame($Connection, $Source->getConnection());
		} else {
			$this->assertSame('HttpSourceConnection', get_class($Source->getConnection()));
		}

		$this->assertSame($config['config'], $Source->getConfig());
	}

	/**
	 * Data provider for 
	 * 
	 * @return array
	 */
	public function constructProvider() {
		return array(
			//set #0
			array(
				//sourceConfig
				array(),
				//config,
				array(),
				//Connection
				null,
				//exception
				'HttpSourceException',
				1
			),
			//set #1
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(),
				//Connection
				null,
				//exception
				'HttpSourceException',
				0
			),
			//set #2
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(),
				//Connection
				null,
				//exception
				'HttpSourceException',
				2
			),
			//set #3
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 1
				),
				//Connection
				null,
				//exception
				'NotImplementedException',
				3
			),
			//set #4
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => new stdClass
				),
				//Connection
				null,
				//exception
				'HttpSourceException',
				1
			),
			//set #5
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => HttpSourceConfigFactory::instance()->config()
				),
				//Connection
				null,
				//exception
				'',
				0
			),
			//set #6
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => HttpSourceConfigFactory::instance()->config()
				),
				//Connection
				new HttpSourceConnection,
				//exception
				'',
				0
			),
			//set #7
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => HttpSourceConfigFactory::instance()->config()
				),
				//Connection
				new HttpSourceConnection,
				//exception
				'',
				2
			),
		);
	}

	/**
	 * Test credentials
	 */
	public function testCredentials() {
		$Source = new HttpTestSource(array('datasource' => 'HttpSource.Http/HttpSource'));
		$credentials = array(
			'user' => 'root',
			'pass' => '<PASSWORD>***',
			'a' => 'b'
		);
		$Source->setCredentials($credentials);
		$this->assertSame($credentials, $Source->getCredentials());
	}
	
	/**
	 * Test transaction params
	 */
	public function testTransactionParams() {
		$Source = new HttpTestSource(array('datasource' => 'HttpSource.Http/HttpSource'));
		$params = array(
			'table' => 'transactions_table', 
			'params' => array(
				'param1' => true
			), 
			'transactionsField' => 'transactions', 
			'method' => HttpSource::METHOD_CREATE
		);
		$Source->setTransactionParams($params['table'], $params['params'], $params['transactionsField'], $params['method']);
		$this->assertSame($params, $Source->getTransactionParams());
	}

	/**
	 * Test decoders
	 */
	public function testDecoders() {
		$Source = new HttpTestSource(array('datasource' => 'HttpSource.Http/HttpSource'));
		$contentType = 'test/test';
		$callback = function ($v) {
			return 123;
		};
		$Source->setDecoder($contentType, $callback, true);
		$decoder = $Source->getDecoder($contentType);
		$this->assertSame(123, $decoder(444));
	}

	/**
	 * Test query
	 * 
	 * @param array $request
	 * @param mixed $otherArg
	 * @dataProvider queryProvider
	 */
	public function testQuery($request, $otherArg) {
		if ($otherArg) {
			$this->expectException('NotImplementedException');
		}

		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource')))
				->setMethods(array('request'))
				->getMock();

		if ($otherArg) {
			$this->assertTrue($Source->query($request, $otherArg));
		} else {
			$Source->expects($this->once())
					->method('request')
					->with(null, $request)
					->will($this->returnValue(true));
			$this->assertTrue($Source->query($request));
		}
	}

	/**
	 * Data provider for testQuery
	 * 
	 * @return array
	 */
	public function queryProvider() {
		return array(
			//set #0
			array(
				//request
				array('a' => 'b'),
				//otherArg
				null
			),
			//set #1
			array(
				//request
				array('a' => 'b'),
				//otherArg
				'some arg'
			),
		);
	}

	/**
	 * Test execute
	 * 
	 * @param array $request
	 * @param array $result
	 * @dataProvider executeProvider
	 */
	public function testExecute($request, $result) {
		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource')))
				->setMethods(array('query'))
				->getMock();

		$Source->expects($this->any())
				->method('query')
				->will($this->returnArgument(0));

		$this->assertSame($result, $Source->execute($request));
	}

	/**
	 * Data provider for testExecute
	 * 
	 * @return array
	 */
	public function executeProvider() {
		return array(
			//set #0
			array(
				//request
				array(),
				//result
				array()
			),
			//set #1
			array(
				//request
				array('a' => 'b'),
				//result
				array('a' => 'b')
			),
			//set #2
			array(
				//request
				array(
					1 => array('a' => 'b'),
					5 => array('c' => 'd'),
					10 => array('e' => 'f')
				),
				//result
				array(
					array('a' => 'b'),
					array('c' => 'd'),
					array('e' => 'f')
				)
			),
		);
	}

	/**
	 * Test request method flow
	 * 
	 * @param Model $Model
	 * @param string|array $requestData
	 * @param string $requestMethod
	 * @param array $request
	 * @dataProvider requestFlowProvider
	 */
	public function testRequestFlow(Model $Model = null, $requestData = null, $requestMethod = null, $request = null) {
		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource')))
				->setMethods(array(
					'_splitRequest',
					'_singleRequest',
					'_joinResponses',
					'afterRequest'
				))
				->getMock();

		$response1 = array('test response 1');
		$response2 = array('test response 2');
		$response = array_merge($response1, $response2);

		if ($request === null) {
			$this->expectException('HttpSourceException');
			$this->assertSame($response, $Source->request($Model, $requestData, $requestMethod));
		}

		$Source->expects($this->once())->method('_splitRequest')->with($request)->will($this->returnValue(array($request, $request)));
		$Source->expects($this->at(1))->method('_singleRequest')->with($request, $requestMethod, $Model)->will($this->returnValue($response1));
		$Source->expects($this->at(2))->method('_singleRequest')->with($request, $requestMethod, $Model)->will($this->returnValue($response2));
		$Source->expects($this->once())->method('_joinResponses')->with(array($response1, $response2))->will($this->returnValue($response));
		if ($Model) {
			$Source->expects($this->once())->method('afterRequest')->with($Model, $response, $requestMethod)->will($this->returnValue($response));
		}

		$this->assertSame($response, $Source->request($Model, $requestData, $requestMethod));
	}

	/**
	 * Data provider for testRequestFlow
	 * 
	 * @return array
	 */
	public function requestFlowProvider() {
		$Model = new Model;
		$Model->request = array('key2' => 'value2');
		return array(
			//set #0
			array(
				//Model
				null,
				//requestData
				null,
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				null
			),
			//set #1
			array(
				//Model
				null,
				//requestData
				array('key' => 'value'),
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('key' => 'value')
			),
			//set #2
			array(
				//Model
				$Model,
				//requestData
				null,
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('key2' => 'value2')
			),
			//set #3
			array(
				//Model
				$Model,
				//requestData
				array('key' => 'value'),
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('key2' => 'value2')
			),
			//set #4
			array(
				//Model
				null,
				//requestData
				'blahblah',
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('uri' => 'blahblah')
			),
		);
	}

	/**
	 * Test single request
	 * 
	 * @param array $request
	 * @param array $requestFull
	 * @param array $response
	 * @param array $responseResult
	 * @param bool $asModel
	 * @param string $requestMethod
	 * @param array $config
	 * @param array $connectionData
	 * @param string $log
	 * @param HttpSourceEndpoint $Endpoint
	 * @dataProvider singleRequestProvider
	 */
	public function testSingleRequest($request, $requestFull, $response, $responseResult, $asModel, $requestMethod, array $config, array $connectionData, $log, $Endpoint = null) {
		$Connection = $this->getMockBuilder('HttpSourceConnection')
				->setMethods(array(
					'request',
					'getError',
					'getTook',
					'getQuery',
					'getAffected',
					'getNumRows'
				))
				->getMock();
		$Connection->expects($this->once())->method('request')->with($requestFull)->will($this->returnValue($response));
		$Connection->expects($this->once())->method('getError')->will($this->returnValue($connectionData['error']));
		$Connection->expects($this->once())->method('getTook')->will($this->returnValue($connectionData['took']));
		$Connection->expects($this->once())->method('getQuery')->will($this->returnValue($connectionData['query']));
		$Connection->expects($this->once())->method('getAffected')->will($this->returnValue($connectionData['affected']));

		if (isset($connectionData['numRows'])) {
			$Connection->expects($this->once())->method('getNumRows')->with($responseResult)->will($this->returnValue($connectionData['numRows']));
		} else {
			$Connection->expects($this->never())->method('getNumRows');
			$connectionData['numRows'] = 1;
		}

		$sourceMethods = array(
			'afterRequest',
			'beforeRequest',
			'swapTokens',
			'logRequest',
			'log'
		);
		if ($Endpoint) {
			$sourceMethods[] = '_getCurrentEndpoint';
		} else {
			$sourceMethods[] = '_extractResult';
		}
		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource') + $config, $Connection))
				->setMethods($sourceMethods)
				->getMock();
		$Source->expects($this->once())->method('logRequest');
		$Source->expects($this->once())->method('swapTokens')->with($requestFull);
		$Source->expects($this->once())->method('beforeRequest')->with($requestFull, $requestMethod)->will($this->returnArgument(0));

		if ($connectionData['error']) {
			$Source->expects($this->once())->method('log')->with($log, LOG_ERR);
		}

		if (!$asModel) {
			$this->assertSame($responseResult, $Source->request(null, $request, $requestMethod));
		} else {
			$Source->expects($this->once())->method('afterRequest')->will($this->returnArgument(1));
			$Model = $this->getMockBuilder('Model')
					->setMethods(array(
						'onError'
					))
					->getMock();
			$Model->request = $request;
			if (!$responseResult || $connectionData['error']) {
				$Model->expects($this->once())->method('onError');
			}

			if ($responseResult && $Endpoint) {
				$Source->expects($this->any())->method('_getCurrentEndpoint')->will($this->returnValue($Endpoint));
			} elseif ($responseResult) {
				$Source->expects($this->once())->method('_extractResult')->with($Model, $responseResult, $requestMethod)->will($this->returnArgument(1));
			} else {
				$Source->expects($this->never())->method('_extractResult');
			}

			$this->assertSame($responseResult, $Source->request($Model, null, $requestMethod));
			$this->assertSame($responseResult, $Model->response);
			$this->assertSame($requestFull, $Model->request);
		}
		$this->assertSame($connectionData['error'], $Source->error);
		$this->assertSame($connectionData['took'], $Source->took);
		$this->assertSame($connectionData['query'], $Source->query);
		$this->assertSame($connectionData['affected'], $Source->affected);
		$this->assertSame($connectionData['numRows'], $Source->numRows);
	}

	/**
	 * Data provider for testSingleRequest
	 * 
	 * @return array
	 */
	public function singleRequestProvider() {
		$CF = HttpSourceConfigFactory::instance();
		return array(
			//set #0
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #1
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #2
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #3
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #4
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #5
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #6
			array(
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #7
			array(
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #8
			array(
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #9
			array(
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #10
			array(
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #11
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
			),
			//set #12
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
			),
			//set #13
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly', 'Hi Jack!'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
						->result($CF->result()
								->map(function($result) {
									return array_merge($result, array('Hi Jack!'));
								}))
			),
			//set #14
			array(
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
						->result($CF->result()
								->map(function($result) {
									return array_merge($result, array('Hi Jack!'));
								})
						)
			),
		);<commit_msg>turn off log request when no debug<commit_after><?php

/**
 * Author: imsamurai <<EMAIL>>
 * Date: 20.08.2014
 * Time: 14:54:41
 * Format: http://book.cakephp.org/2.0/en/development/testing.html
 */
App::uses('Model', 'Model');
App::uses('CakeSchema', 'Model');
App::uses('HttpSource', 'HttpSource.Model/Datasource');
App::uses('HttpSourceConnection', 'HttpSource.Model/Datasource');
App::uses('HttpSourceConfigFactory', 'HttpSource.Lib/Config');

/**
 * HttpSourceTest
 * 
 * @package HttpSourceTest
 * @subpackage Model.Datasource
 */
class HttpSourceTest extends CakeTestCase {

	/**
	 * {@inheritdoc}
	 */
	public function tearDown() {
		parent::tearDown();
		Cache::clear(false, '__test_cache__');
	}

	/**
	 * {@inheritdoc}
	 */
	public function setUp() {
		parent::setUp();
		Cache::config('__test_cache__', array(
			'engine' => 'File',
			'prefix' => '__test_cache__',
			'path' => CACHE,
			'serialize' => true,
			'duration' => '1 hour'
		));

		$CF = HttpSourceConfigFactory::instance();
		Configure::write('HttpSource', array(
			'config_version' => 2,
			'config' => $CF->config()->cacheName('__test_cache__')
					->add(
							$CF->endpoint()
							->id(1)
							->table('endpoint1')
							->addCondition(
									$CF->condition()->name('condition1')
							)
							->cacheName(false)
					)
					->add(
							$CF->endpoint()
							->id(2)
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(3)
							->methodCreate()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(4)
							->methodUpdate()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
							->addCondition(
									$CF->condition()->name('condition1')
							)
					)
					->add(
							$CF->endpoint()
							->id(5)
							->methodDelete()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(6)
							->methodCheck()
							->table('app_models')
							->addCondition(
									$CF->condition()->name('condition2')
							)
					)
					->add(
							$CF->endpoint()
							->id(7)
							->methodCreate()
							->table('app_models2')
							->addCondition(
									$CF->condition()->name('condition3')
							)
							->addCondition(
									$CF->condition()->name('condition4')
							)
					)
					->add(
							$CF->endpoint()
							->id(8)
							->methodDelete()
							->table('app_models2')
							->addCondition(
									$CF->condition()->name('condition3')
							)
							->addCondition(
									$CF->condition()->name('condition4')
							)
					)
		));
	}

	/**
	 * Test construct
	 * 
	 * @param array $sourceConfig
	 * @param array $config
	 * @param string|HttpSourceConnection|null $Connection
	 * @param string $exception
	 * @param int $debugLevel
	 * @dataProvider constructProvider
	 */
	public function testConstruct($sourceConfig, $config, $Connection, $exception, $debugLevel) {
		if ($exception) {
			$this->expectException($exception);
		}

		if (!empty($sourceConfig['datasource'])) {
			list($plugin) = pluginSplit($sourceConfig['datasource']);
			Configure::write($plugin, $config);
		}

		$Source = $this->getMockBuilder('HttpTestSource')
				->disableOriginalConstructor()
				->setMethods(array('_loadConfig'))
				->getMock();
		$Source->expects($this->exactly((empty($config) && !empty($sourceConfig['datasource'])) ? 1 : 0))
				->method('_loadConfig')
				->with(isset($plugin) ? $plugin : null);

		$reflectedClass = new ReflectionClass('HttpTestSource');
		$constructor = $reflectedClass->getConstructor();
		$oldDebugLevel = Configure::read('debug');
		Configure::write('debug', $debugLevel);
		$constructor->invoke($Source, $sourceConfig, $Connection);
		Configure::write('debug', $oldDebugLevel);
		$this->assertSame($debugLevel > 1, $Source->fullDebug);

		if (is_object($Connection)) {
			$this->assertSame($Connection, $Source->getConnection());
		} else {
			$this->assertSame('HttpSourceConnection', get_class($Source->getConnection()));
		}

		$this->assertSame($config['config'], $Source->getConfig());
	}

	/**
	 * Data provider for 
	 * 
	 * @return array
	 */
	public function constructProvider() {
		return array(
			//set #0
			array(
				//sourceConfig
				array(),
				//config,
				array(),
				//Connection
				null,
				//exception
				'HttpSourceException',
				1
			),
			//set #1
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(),
				//Connection
				null,
				//exception
				'HttpSourceException',
				0
			),
			//set #2
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(),
				//Connection
				null,
				//exception
				'HttpSourceException',
				2
			),
			//set #3
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 1
				),
				//Connection
				null,
				//exception
				'NotImplementedException',
				3
			),
			//set #4
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => new stdClass
				),
				//Connection
				null,
				//exception
				'HttpSourceException',
				1
			),
			//set #5
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => HttpSourceConfigFactory::instance()->config()
				),
				//Connection
				null,
				//exception
				'',
				0
			),
			//set #6
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => HttpSourceConfigFactory::instance()->config()
				),
				//Connection
				new HttpSourceConnection,
				//exception
				'',
				0
			),
			//set #7
			array(
				//sourceConfig
				array(
					'datasource' => 'HttpSource.Http/HttpSource'
				),
				//config,
				array(
					'config_version' => 2,
					'config' => HttpSourceConfigFactory::instance()->config()
				),
				//Connection
				new HttpSourceConnection,
				//exception
				'',
				2
			),
		);
	}

	/**
	 * Test credentials
	 */
	public function testCredentials() {
		$Source = new HttpTestSource(array('datasource' => 'HttpSource.Http/HttpSource'));
		$credentials = array(
			'user' => 'root',
			'pass' => '<PASSWORD>***',
			'a' => 'b'
		);
		$Source->setCredentials($credentials);
		$this->assertSame($credentials, $Source->getCredentials());
	}
	
	/**
	 * Test transaction params
	 */
	public function testTransactionParams() {
		$Source = new HttpTestSource(array('datasource' => 'HttpSource.Http/HttpSource'));
		$params = array(
			'table' => 'transactions_table', 
			'params' => array(
				'param1' => true
			), 
			'transactionsField' => 'transactions', 
			'method' => HttpSource::METHOD_CREATE
		);
		$Source->setTransactionParams($params['table'], $params['params'], $params['transactionsField'], $params['method']);
		$this->assertSame($params, $Source->getTransactionParams());
	}

	/**
	 * Test decoders
	 */
	public function testDecoders() {
		$Source = new HttpTestSource(array('datasource' => 'HttpSource.Http/HttpSource'));
		$contentType = 'test/test';
		$callback = function ($v) {
			return 123;
		};
		$Source->setDecoder($contentType, $callback, true);
		$decoder = $Source->getDecoder($contentType);
		$this->assertSame(123, $decoder(444));
	}

	/**
	 * Test query
	 * 
	 * @param array $request
	 * @param mixed $otherArg
	 * @dataProvider queryProvider
	 */
	public function testQuery($request, $otherArg) {
		if ($otherArg) {
			$this->expectException('NotImplementedException');
		}

		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource')))
				->setMethods(array('request'))
				->getMock();

		if ($otherArg) {
			$this->assertTrue($Source->query($request, $otherArg));
		} else {
			$Source->expects($this->once())
					->method('request')
					->with(null, $request)
					->will($this->returnValue(true));
			$this->assertTrue($Source->query($request));
		}
	}

	/**
	 * Data provider for testQuery
	 * 
	 * @return array
	 */
	public function queryProvider() {
		return array(
			//set #0
			array(
				//request
				array('a' => 'b'),
				//otherArg
				null
			),
			//set #1
			array(
				//request
				array('a' => 'b'),
				//otherArg
				'some arg'
			),
		);
	}

	/**
	 * Test execute
	 * 
	 * @param array $request
	 * @param array $result
	 * @dataProvider executeProvider
	 */
	public function testExecute($request, $result) {
		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource')))
				->setMethods(array('query'))
				->getMock();

		$Source->expects($this->any())
				->method('query')
				->will($this->returnArgument(0));

		$this->assertSame($result, $Source->execute($request));
	}

	/**
	 * Data provider for testExecute
	 * 
	 * @return array
	 */
	public function executeProvider() {
		return array(
			//set #0
			array(
				//request
				array(),
				//result
				array()
			),
			//set #1
			array(
				//request
				array('a' => 'b'),
				//result
				array('a' => 'b')
			),
			//set #2
			array(
				//request
				array(
					1 => array('a' => 'b'),
					5 => array('c' => 'd'),
					10 => array('e' => 'f')
				),
				//result
				array(
					array('a' => 'b'),
					array('c' => 'd'),
					array('e' => 'f')
				)
			),
		);
	}

	/**
	 * Test request method flow
	 * 
	 * @param Model $Model
	 * @param string|array $requestData
	 * @param string $requestMethod
	 * @param array $request
	 * @dataProvider requestFlowProvider
	 */
	public function testRequestFlow(Model $Model = null, $requestData = null, $requestMethod = null, $request = null) {
		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource')))
				->setMethods(array(
					'_splitRequest',
					'_singleRequest',
					'_joinResponses',
					'afterRequest'
				))
				->getMock();

		$response1 = array('test response 1');
		$response2 = array('test response 2');
		$response = array_merge($response1, $response2);

		if ($request === null) {
			$this->expectException('HttpSourceException');
			$this->assertSame($response, $Source->request($Model, $requestData, $requestMethod));
		}

		$Source->expects($this->once())->method('_splitRequest')->with($request)->will($this->returnValue(array($request, $request)));
		$Source->expects($this->at(1))->method('_singleRequest')->with($request, $requestMethod, $Model)->will($this->returnValue($response1));
		$Source->expects($this->at(2))->method('_singleRequest')->with($request, $requestMethod, $Model)->will($this->returnValue($response2));
		$Source->expects($this->once())->method('_joinResponses')->with(array($response1, $response2))->will($this->returnValue($response));
		if ($Model) {
			$Source->expects($this->once())->method('afterRequest')->with($Model, $response, $requestMethod)->will($this->returnValue($response));
		}

		$this->assertSame($response, $Source->request($Model, $requestData, $requestMethod));
	}

	/**
	 * Data provider for testRequestFlow
	 * 
	 * @return array
	 */
	public function requestFlowProvider() {
		$Model = new Model;
		$Model->request = array('key2' => 'value2');
		return array(
			//set #0
			array(
				//Model
				null,
				//requestData
				null,
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				null
			),
			//set #1
			array(
				//Model
				null,
				//requestData
				array('key' => 'value'),
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('key' => 'value')
			),
			//set #2
			array(
				//Model
				$Model,
				//requestData
				null,
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('key2' => 'value2')
			),
			//set #3
			array(
				//Model
				$Model,
				//requestData
				array('key' => 'value'),
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('key2' => 'value2')
			),
			//set #4
			array(
				//Model
				null,
				//requestData
				'blahblah',
				//requestMethod
				HttpSource::METHOD_READ,
				//request
				array('uri' => 'blahblah')
			),
		);
	}

	/**
	 * Test single request
	 * 
	 * @param int $debug
	 * @param array $request
	 * @param array $requestFull
	 * @param array $response
	 * @param array $responseResult
	 * @param bool $asModel
	 * @param string $requestMethod
	 * @param array $config
	 * @param array $connectionData
	 * @param string $log
	 * @param HttpSourceEndpoint $Endpoint
	 * @dataProvider singleRequestProvider
	 */
	public function testSingleRequest($debug, $request, $requestFull, $response, $responseResult, $asModel, $requestMethod, array $config, array $connectionData, $log, $Endpoint = null) {
		Configure::write('debug', $debug);
		$Connection = $this->getMockBuilder('HttpSourceConnection')
				->setMethods(array(
					'request',
					'getError',
					'getTook',
					'getQuery',
					'getAffected',
					'getNumRows'
				))
				->getMock();
		$Connection->expects($this->once())->method('request')->with($requestFull)->will($this->returnValue($response));
		$Connection->expects($this->once())->method('getError')->will($this->returnValue($connectionData['error']));
		$Connection->expects($this->once())->method('getTook')->will($this->returnValue($connectionData['took']));
		$Connection->expects($this->once())->method('getQuery')->will($this->returnValue($connectionData['query']));
		$Connection->expects($this->once())->method('getAffected')->will($this->returnValue($connectionData['affected']));

		if (isset($connectionData['numRows'])) {
			$Connection->expects($this->once())->method('getNumRows')->with($responseResult)->will($this->returnValue($connectionData['numRows']));
		} else {
			$Connection->expects($this->never())->method('getNumRows');
			$connectionData['numRows'] = 1;
		}

		$sourceMethods = array(
			'afterRequest',
			'beforeRequest',
			'swapTokens',
			'logRequest',
			'log'
		);
		if ($Endpoint) {
			$sourceMethods[] = '_getCurrentEndpoint';
		} else {
			$sourceMethods[] = '_extractResult';
		}
		$Source = $this->getMockBuilder('HttpTestSource')
				->setConstructorArgs(array(array('datasource' => 'HttpSource.Http/HttpSource') + $config, $Connection))
				->setMethods($sourceMethods)
				->getMock();
		if ($debug > 1) {
			$Source->expects($this->once())->method('logRequest');
		}
		$Source->expects($this->once())->method('swapTokens')->with($requestFull);
		$Source->expects($this->once())->method('beforeRequest')->with($requestFull, $requestMethod)->will($this->returnArgument(0));

		if ($debug < 2 && $connectionData['error']) {
			$Source->expects($this->once())->method('log')->with($log, LOG_ERR);
		}

		if (!$asModel) {
			$this->assertSame($responseResult, $Source->request(null, $request, $requestMethod));
		} else {
			$Source->expects($this->once())->method('afterRequest')->will($this->returnArgument(1));
			$Model = $this->getMockBuilder('Model')
					->setMethods(array(
						'onError'
					))
					->getMock();
			$Model->request = $request;
			if (!$responseResult || $connectionData['error']) {
				$Model->expects($this->once())->method('onError');
			}

			if ($responseResult && $Endpoint) {
				$Source->expects($this->any())->method('_getCurrentEndpoint')->will($this->returnValue($Endpoint));
			} elseif ($responseResult) {
				$Source->expects($this->once())->method('_extractResult')->with($Model, $responseResult, $requestMethod)->will($this->returnArgument(1));
			} else {
				$Source->expects($this->never())->method('_extractResult');
			}

			$this->assertSame($responseResult, $Source->request($Model, null, $requestMethod));
			$this->assertSame($responseResult, $Model->response);
			$this->assertSame($requestFull, $Model->request);
		}
		$this->assertSame($connectionData['error'], $Source->error);
		$this->assertSame($connectionData['took'], $Source->took);
		$this->assertSame($connectionData['query'], $Source->query);
		$this->assertSame($connectionData['affected'], $Source->affected);
		$this->assertSame($connectionData['numRows'], $Source->numRows);
	}

	/**
	 * Data provider for testSingleRequest
	 * 
	 * @return array
	 */
	public function singleRequestProvider() {
		$CF = HttpSourceConfigFactory::instance();
		return array(
			//set #0
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #1
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #2
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #3
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #4
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #5
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example.com',
						'port' => 7880,
						'path' => '/api',
						'scheme' => 'http'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #6
			array(
				//debug
				2,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #7
			array(
				//debug
				2,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #8
			array(
				//debug
				2,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'',
				//Endpoint
				null
			),
			//set #9
			array(
				//debug
				2,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #10
			array(
				//debug
				2,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #11
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
			),
			//set #12
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
			),
			//set #13
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly', 'Hi Jack!'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_READ,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 1
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
						->result($CF->result()
								->map(function($result) {
									return array_merge($result, array('Hi Jack!'));
								}))
			),
			//set #14
			array(
				//debug
				2,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
						->result($CF->result()
								->map(function($result) {
									return array_merge($result, array('Hi Jack!'));
								})
						)
			),
			//set #15
			array(
				//debug
				0,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
						->result($CF->result()
								->map(function($result) {
									return array_merge($result, array('Hi Jack!'));
								})
						)
			),
			//set #16
			array(
				//debug
				0,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
			//set #17
			array(
				//debug
				1,
				//request
				array(
					'lol'
				),
				//requestFull
				array(
					'lol'
				),
				//response
				array('hello dolly'),
				//responseResult
				array('hello dolly'),
				//asModel
				true,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(),
				//connectionData
				array(
					'error' => '',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
				),
				//log,
				'',
				//Endpoint
				$CF->endpoint()
						->result($CF->result()
								->map(function($result) {
									return array_merge($result, array('Hi Jack!'));
								})
						)
			),
			//set #18
			array(
				//debug
				1,
				//request
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//requestFull
				array(
					'lol',
					'uri' => array(
						'host' => 'example2.com',
						'port' => 2880,
						'path' => '/api2',
						'scheme' => 'https'
					)
				),
				//response
				array(),
				//responseResult
				array(),
				//asModel
				false,
				//requestMethod
				HttpSource::METHOD_CHECK,
				//config
				array(
					'path' => '/api',
					'scheme' => 'http',
					'port' => 7880,
					'host' => 'example.com'
				),
				//connectionData
				array(
					'error' => 'oh crap!',
					'took' => 10,
					'query' => 'GET somethong',
					'affected' => 1,
					'numRows' => 0
				),
				//log,
				'HttpSource: oh crap! Request: GET somethong',
				//Endpoint
				null
			),
		);
{'fraction_non_alphanumeric': 0.19458634758459903, 'fraction_numerical': 0.011537011005588507, 'mean_word_length': 2.2719165404677772, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 1104, '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': '5619457', 'n_tokens_mistral': 28015, 'n_tokens_neox': 19353, 'n_words': 3579}