public function testFindAllWithGetParamsQueryConditions() { $this->setupIndividualTest($this->getTestOptions()); extract($this->getTestOptions()); $conditions = ConditionFactory::build(); $conditions->addCondition('name', '=', 'John Doe'); $conditions->addCondition('email', '=', '*****@*****.**'); $conditions->addCondition('id', '>=', 100); $this->assertEquals(http_build_query($conditions->toArray()), $conditions->toQueryString(), "Expected query string to look different"); $this->setExpectedException('InvalidArgumentException'); $conditions->setLogicalOperator('invalid-operator'); $conditions->setLogicalOperator($conditions->getLogicalOperatorAnd()); $this->assertEquals(Config::get('query_condition.and_operator'), $conditions->getLogicalOperatorAnd()); $this->assertEquals(Config::get('query_condition.or_operator'), $conditions->getLogicalOperatorOr()); $found = User::all($conditions); //get objects to assert on $history = $this->getHttpClientHistory(); $request = $history->getLastRequest(); $response = $history->getLastResponse(); $this->makeGuzzleAssertions('GET', $base_uri, $uri, $conditions->toArray()); //assert that the HTTP RESPONSE is what is expected $this->assertTrue($response->isSuccessful()); $this->assertEquals($response_body, $response->getBody(true)); $this->assertTrue($found instanceof Collection); $this->assertEquals(5, $found->size(), "expected count is wrong"); $this->assertEquals(1234, $found->first()->id); $this->assertEquals('John Doe', $found->first()->name); }
/** * Function to find an instance of an Entity record * * @param Trucker\Resource\Model $model Model to use for URL generation etc. * @param int $id The primary identifier value for the record * @param array $getParams Array of GET parameters to pass * @return Trucker\Resource\Model An instance of the entity requested */ public function fetch($model, $id, $getParams = array()) { $instance = null; //get a request object $request = RequestFactory::build(); //init the request $request->createRequest(Config::get('request.base_uri'), UrlGenerator::getInstanceUri($model, [':' . $model->getIdentityProperty() => $id]), 'GET'); //add auth if it is needed if ($auth = AuthFactory::build()) { $request->authenticate($auth); } //set any get parameters on the request $request->setGetParameters($getParams); //actually send the request $response = $request->sendRequest(); if (!ResponseInterpreterFactory::build()->success($response)) { return null; } //kraft the response into an object to return $data = $response->parseResponseToData(); $instance = new $model($data); //inflate the ID property that should be guarded $id = $instance->getIdentityProperty(); if (array_key_exists($id, $data)) { $instance->{$id} = $data[$id]; } return $instance; }
/** * Function to fetch a collection of Trucker\Resource\Model object * from the remote API. * * @param Model $model Instance of entity type being fetched * @param QueryConditionInterface $condition Query conditions for the request * @param QueryResultOrderInterface $resultOrder Result ordering requirements for the request * @param array $getParams Additional GET parameters to send w/ request * @return Trucker\Responses\Collection */ public function fetch(Model $model, QueryConditionInterface $condition = null, QueryResultOrderInterface $resultOrder = null, array $getParams = []) { //get a request object $request = RequestFactory::build(); //init the request $request->createRequest(Config::get('request.base_uri'), UrlGenerator::getCollectionUri($model), 'GET'); //add auth if it is needed if ($auth = AuthFactory::build()) { $request->authenticate($auth); } //add query conditions if needed if ($condition) { $request->addQueryCondition($condition); } //add result ordering if needed if ($resultOrder) { $request->addQueryResultOrder($resultOrder); } //set any get parameters on the request $request->setGetParameters($getParams); //actually send the request $response = $request->sendRequest(); //get api response $data = $response->parseResponseToData(); //make an array to hold results $records = array(); //figure out wether a collection key is used $collection_key = Config::get('resource.collection_key'); //if collection key is a CLosure, call the closure if ($collection_key instanceof \Closure) { $collection_key = $collection_key($model); } //set records array appropriatley if (isset($collection_key)) { $recordCollection = $data[$collection_key]; } else { $recordCollection = $data; } //create an array of popuplated results foreach ($recordCollection as $values) { $instance = new $model($values); //inflate the ID property that should be guarded $id = $instance->getIdentityProperty(); if (array_key_exists($id, $values)) { $instance->{$id} = $values[$id]; } //add the instance to the records array $records[] = $instance; } //end foreach //create a collection object to return $collection = new Collection($records); // if there was a collection_key, put any extra data that was returned // outside the collection key in the metaData attribute if (isset($collection_key)) { $collection->metaData = array_diff_key($data, array_flip((array) array($collection_key))); } return $collection; }
public function testCreateInvalidQueryConditionDriver() { $this->swapConfig(['trucker::query_condition.driver' => 'invalid']); Config::setApp($this->app); $this->setExpectedException('ReflectionException'); $this->setExpectedException('InvalidArgumentException'); $foo = ConditionFactory::build(); }
public function testCreateInvalidRequest() { $this->swapConfig(['trucker::request.driver' => 'invalid']); Config::setApp($this->app); $this->setExpectedException('ReflectionException'); $this->setExpectedException('InvalidArgumentException'); $foo = RequestFactory::build(); }
public function testCreateInvalidTransporter() { $this->swapConfig(['trucker::error_handler.driver' => 'invalid']); Config::setApp($this->app); $this->setExpectedException('ReflectionException'); $this->setExpectedException('InvalidArgumentException'); $foo = ErrorHandlerFactory::build(); }
public function testSetsAuthOnRequest() { $this->swapConfig(['trucker::auth.driver' => 'basic', 'trucker::auth.basic.username' => 'myUsername', 'trucker::auth.basic.password' => 'myPassword']); Config::setApp($this->app); $request = m::mock('Guzzle\\Http\\Message\\Request'); $request->shouldReceive('setAuth')->with('myUsername', 'myPassword')->once(); $auth = new BasicAuthenticator($this->app); $auth->authenticateRequest($request); }
/** * Function to take the response object and return * an array of errors * * @param Trucker\Responses\Response $response - response object * @return array - array of string error messages */ public function parseErrors(\Trucker\Responses\Response $response) { $result = $response->parseResponseStringToObject(); $error_key = Config::get('error_handler.errors_key'); if (property_exists($result, $error_key)) { return $result->errors; } else { throw new \InvalidArgumentException("Error key [{$error_key}] does not exist in response"); } }
public function testGetOption() { $config = m::mock('Illuminate\\Config\\Repository'); $config->shouldIgnoreMissing(); $config->shouldReceive('get')->with('trucker::transporter.driver')->andReturn('json'); $app = m::mock('Illuminate\\Container\\Container'); $app->shouldIgnoreMissing(); $app->shouldReceive('offsetGet')->with('config')->andReturn($config); $transporter = Config::get('transporter.driver'); $this->assertEquals('json', $transporter); }
/** * Function to execute a raw request on the base URI with the given uri path * and params * * @param string $uri uri to hit (i.e. /users) * @param string $method Request method (GET, PUT, POST, PATCH, DELETE, etc.) * @param array $params PUT or POST parameters to send * @param array $getParams Querystring parameters to send * @param array $files PUT or POST files to send (key = name, value = path) * @param array $headers Optional headers to use * @return \Trucker\Responses\RawResponse */ public function rawRequest($uri, $method, $params = array(), $getParams = array(), $files = array(), $headers = array()) { $this->request = self::createRequest(Config::get('request.base_uri'), $uri, $method); $this->setPostParameters($params); $this->setGetParameters($getParams); $this->setFileParameters($files); $this->setHeaders($headers); //encode the request body /** @var \Trucker\Transporters\TransporterInterface $transporter */ $transporter = TransporterFactory::build(); $transporter->setRequestBody($this, $params); // Trucker\Response $response = $this->sendRequest(); //handle clean response with errors if (ResponseInterpreterFactory::build()->invalid($response)) { //get the errors and set them to our local collection $errors = (array) ErrorHandlerFactory::build()->parseErrors($response); return new RawResponse(false, $response, $errors); } //end if return new RawResponse(true, $response); }
/** * Swap the current config * * @param array $config * * @return void */ protected function swapConfig($config) { $this->app['config'] = $this->getConfig($config); Config::setApp($this->app); }
/** * Function to add the necessary authentication * to the request * * @param Guzzle\Http\Message\Request $request Request passed by reference * @return void */ public function authenticateRequest(&$request) { $username = Config::get('auth.basic.username'); $password = Config::get('auth.basic.password'); $request->setAuth($username, $password); }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('result_order.driver'); }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('response.driver'); }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('auth.driver'); }
/** * Function to convert the conditions and * logical operator represented in this class * to an array, this is useful for testing * * @return array */ public function toArray() { $conatiner = Config::get('query_condition.get_array_params.container_parameter'); $property = Config::get('query_condition.get_array_params.property'); $operator = Config::get('query_condition.get_array_params.operator'); $value = Config::get('query_condition.get_array_params.value'); $params = []; $x = 0; foreach ($this->conditions as $condition) { $params["{$conatiner}[{$x}][{$property}]"] = $condition[self::PROPERTY]; $params["{$conatiner}[{$x}][{$operator}]"] = $condition[self::OPERATOR]; $params["{$conatiner}[{$x}][{$value}]"] = $condition[self::VALUE]; $x++; } //end foreach $findConditions if (isset($this->logicalOperator)) { $params[Config::get('query_condition.get_array_params.logical_operator')] = $this->logicalOperator; } return $params; }
/** * Function to return a boolean value indicating whether * the provided status is matched by the configured setting. * * Currently supports: * * @param $option * @param $status * * @return bool */ protected function matchesStatus($option, $status) { $configValue = Config::get($option); if (is_array($configValue)) { return Config::contains($option, $status); } return Str::is($configValue, $status); }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('query_condition.driver'); }
/** * Function to return the name of the URI to hit based on * the interpreted name of the class in question. For example * a Person class would resolve to /people * * @param Trucker\Resource\Model * @return string The URI to hit */ public function getURI($model) { if ($uri = $model->getURI()) { return $uri; } $uri = Inflector::pluralize(Inflector::tableize($model->getResourceName())); $uriResult = []; if (!empty($model->nestedUnder)) { $nesting = array_map(function ($item) { return explode(':', trim($item)); }, explode(',', $model->nestedUnder)); $modelAttr = $model->attributes(); foreach ($nesting as $nest) { list($klass, $entityIdSegment) = $nest; if (!is_numeric($entityIdSegment)) { // @TODO - allow a custom 'isIdNumber' Closure function to be entered in config file. if (array_key_exists($entityIdSegment, $modelAttr)) { $entityIdSegment = $modelAttr[$entityIdSegment]; } else { $entityIdSegment = ":{$entityIdSegment}"; } } $entityTypeSegment = Inflector::pluralize(Inflector::tableize($klass)); $uriResult[] = $entityTypeSegment; $uriResult[] = $entityIdSegment; } $uri = implode("/", $uriResult) . "/{$uri}"; } $prefix = Config::get('request.path_prefix', '/'); return "{$prefix}{$uri}"; }
/** * Function to return the name of the URI to hit based on * the interpreted name of the class in question. For example * a Person class would resolve to /people * * @param Trucker\Resource\Model * @return string The URI to hit */ public function getURI($model) { if ($uri = $model->getURI()) { return $uri; } $uri = $model->pluralize(); $uriResult = []; if (!empty($model->nestedUnder)) { $nesting = array_map(function ($item) { return explode(':', trim($item)); }, explode(',', $model->nestedUnder)); foreach ($nesting as $nest) { list($klass, $entityIdSegment) = $nest; if (!is_numeric($entityIdSegment)) { $entityIdSegment = ":{$entityIdSegment}"; } $entityTypeSegment = Inflector::pluralize(Inflector::tableize($klass)); $uriResult[] = $entityTypeSegment; $uriResult[] = $entityIdSegment; } $uri = implode("/", $uriResult) . "/{$uri}"; } $prefix = Config::get('request.path_prefix', '/'); return "{$prefix}{$uri}"; }
/** * Function to delete an existing entity * * @return Boolean Success of the delete operation */ public function destroy() { //get a request object $request = RequestFactory::build(); //init the request $request->createRequest(Config::get('request.base_uri'), UrlGenerator::getDeleteUri($this, [':' . $this->getIdentityProperty() => $this->getId()]), 'DELETE', [], Config::get('request.http_method_param')); //add auth if it is needed if ($auth = AuthFactory::build()) { $request->authenticate($auth); } //actually send the request $response = $request->sendRequest(); //clean up anything no longer needed $this->doPostRequestCleanUp(); $interpreter = ResponseInterpreterFactory::build(); //handle clean response with errors if ($interpreter->success($response)) { return true; } else { if ($interpreter->invalid($response)) { //get the errors and set them to our local collection $this->errors = ErrorHandlerFactory::build()->parseErrors($response); } } //end if-else return false; }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('error_handler.driver'); }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('request.driver'); }
/** * Function to return the string representation of the driver * itslef based on a value fetched from the config file. This * function will itself access the config, and return the driver * setting * * @return string */ public function getDriverConfigValue() { return Config::get('transporter.driver'); }
/** * Function to convert the directives represented in this class * to an array, this is useful for testing * * @return array */ public function toArray() { $order_by = Config::get('result_order.get_params.order_by'); $order_dir = Config::get('result_order.get_params.order_dir'); $params = []; $params[$order_by] = $this->orderByField; $params[$order_dir] = $this->orderDirection; return $params; }
/** * Helper function to test various aspects of a Guzzle * request / response * * @param string $method HTTP method expected * @param string $baseUri Base URL expected in request * @param string $uri URI expected for request * @param array $queryParams Assoc array of querystring params expected * @param array $postParams Assoc array of post params expected * @param array $fileParams Assoc array (name => path) of files expected * @return void */ protected function makeGuzzleAssertions($method, $baseUri, $uri, $queryParams = [], $postParams = [], $fileParams = []) { //get objects to assert on $history = $this->getHttpClientHistory(); $request = $history->getLastRequest(); $response = $history->getLastResponse(); //assert the HTTP REQUEST is manufactured as it should be $this->assertEquals(last(explode('/', $baseUri)), $request->getHost(), "The request host is wrong"); $this->assertEquals($uri, $request->getPath(), "The request path is wrong"); $this->assertTrue($this->arraysAreSimilar($queryParams, $request->getQuery()->toArray()), "The query parameters didn't match as expected"); //if request can have post / files if (!in_array($method, ['GET', 'HEAD', 'TRACE', 'OPTIONS'])) { //test the post parameters $this->assertEquals($postParams, $request->getPostFields()->getAll(), "The post params are wrong"); //test the files $files = $request->getPostFiles(); $this->assertCount(count($fileParams), $files, "The file upload count is wrong"); $this->assertEquals(array_keys($fileParams), array_keys($files), "The file upload fields are wrong"); foreach ($fileParams as $field => $path) { $this->assertArrayHasKey($field, $files, "The file upload fields appear to be missing: {$field}"); if (array_key_exists($field, $files)) { $postFileObj = $files[$field][0]; $this->assertEquals($path, $post->getFilename(), "The filename is wrong for the '{$field}' file"); } } } //end if request can have post / files $this->assertEquals($method, $request->getMethod(), "The HTTP method is wrong"); $this->assertEquals(Config::get('transporter.driver'), last(explode('/', $request->getHeader('Accept'))), "The transport language is wrong"); }
public function testDestroyShouldFailWithoutErrorsKey() { $invalid_status = Config::get('response.http_status.invalid'); //setup our creation mocks, expected results etc $this->setupIndividualTest($this->getSaveErrorTestOptions(), [], $invalid_status); $u = new User(); $u->id = 1; $result = $u->destroy(); //get objects to assert on $history = $this->getHttpClientHistory(); $request = $history->getLastRequest(); $response = $history->getLastResponse(); $this->assertFalse($result, 'Expected destroy() to return false'); $this->assertEquals($invalid_status, $response->getStatusCode(), "Expected different response code"); $this->assertCount(2, $u->errors(), 'Expected 2 errors'); }
/** * Create a request to use with the specified request type & any additional text after the url * @param $requestType (GET/POST/DELETE/PATCH/PUT) * @param string $urlSuffix (anything else to add after the url) */ protected function createRequest($requestType, $urlSuffix = '') { //get a request object $request = RequestFactory::build(); // find the method to use for url generation based on the request type $methodToFnMap = ['POST' => 'getCreateUri', 'GET' => 'getInstanceUri', 'DELETE' => 'getDeleteUri', 'PUT' => 'getUpdateUri']; if (!isset($methodToFnMap[strtoupper($requestType)])) { throw new Exception('Request type "' . $requestType . '" not supported'); } $fnName = $methodToFnMap[strtoupper($requestType)]; // put together the url options to pass in $urlOptions = []; if ($this->getId()) { $urlOptions[':' . $this->getIdentityProperty()] = $this->getId(); } // get the url to use $url = call_user_func([UrlGenerator::class, $fnName], $this, $urlOptions) . $urlSuffix; //init the request $request->createRequest(Config::get('request.base_uri'), $url, $requestType, [], Config::get('request.http_method_param')); return $request; }