Unit testing in Laravel5 - Error - php

According to:
/**
* Call the given URI and return the Response.
*
* #param string $method
* #param string $uri
* #param array $parameters
* #param array $files
* #param array $server
* #param string $content
* #param bool $changeHistory
* #return \Illuminate\Http\Response
*/
public function call()
In order to pass headers, I set them in the $server parameter, which I'm doing like so:
public function testCreateLocation(){
$response = $this->call('POST', '/api/v1/token', $this->test_token_request);
$tokenObject = json_decode($response->getContent());
/** Run the test */
$response = $this->call('POST', '/api/v1/location', $this->test_1_create_tag,
[], ['Authorization' => 'Bearer '.$tokenObject->token]);
/** Read the response */
$this->assertResponseOk();
}
However, when I run the unit test, I get the following error:
vagrant#homestead:~/Code$ php phpunit.phar tests/LocationModelTest.php
PHPUnit 4.6.2 by Sebastian Bergmann and contributors.
Configuration read from /home/vagrant/Code/phpunit.xml.dist
EFF
Time: 3.75 seconds, Memory: 35.75Mb
There was 1 error:
1) LocationModelTest::testCreateLocation
InvalidArgumentException: An uploaded file must be an array or an instance of UploadedFile.
I've tried passing in null and an empty array as it states, but the error is never resolved. Anyone have any ideas?

I ran into this problem on Laravel 5.1 as well. Once I checked the up to date documentation on the call() method I saw the issue though:
call(string $method, string $uri, array $parameters = array(), **array $cookies = array(),** array $files = array(), array $server = array(), string $content = null)
Somewhere along the way an extra parameter (cookies) got added to the method.
So add an extra empty array and you should be good:
$response = $this->call('POST', '/api/v1/location', $this->test_1_create_tag, [], [], ['Authorization' => 'Bearer '.$tokenObject->token]);

Related

Google Search Console API UrlInspectionIndex, inspect function

I want to use this function function like this.
class UrlInspectionIndex extends \Google\Service\Resource
{
/**
* Index inspection. (index.inspect)
*
* #param InspectUrlIndexRequest $postBody
* #param array $optParams Optional parameters.
* #return InspectUrlIndexResponse
*/
public function inspect(InspectUrlIndexRequest $postBody, $optParams = [])
{
$params = ['postBody' => $postBody];
$params = array_merge($params, $optParams);
return $this->call('inspect', [$params], InspectUrlIndexResponse::class);
}
}
This is how I use
$service= new SearchConsole($client);
$postBody=[
'inspectionUrl'=>'myinspectionUrl',
'siteUrl'=>env('APP_URL')
];
$result=$service->urlInspection_index->inspect($postBody);
The error I got
TypeError
Google\Service\SearchConsole\Resource\UrlInspectionIndex::inspect(): Argument #1 ($postBody) must be of type Google\Service\SearchConsole\InspectUrlIndexRequest, array given, called in /var/www/vhosts/habertema.com/httpdocs/app/Http/Controllers/IntegratedController.php on line 648
what is the type InspectUrlIndexRequest ?

how the Laravel "Storage::download()" method works under the hood?

I can't see this method in facade and in related to this facade class. Can anyone tell me how this "magic" actually works or at least provide some links with explanation?
As per laravel source code that method comes from Symfony component and it creates a streamed download response for a given file.
/**
* Create a streamed download response for a given file.
*
* #param string $path
* #param string|null $name
* #param array|null $headers
* #return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function download($path, $name = null, array $headers = [])
{
return $this->response($path, $name, $headers, 'attachment');
}
ref:https://github.com/laravel/framework/blob/5398fbbbf81ed842cf0430b278f07eb0f869cf8f/src/Illuminate/Filesystem/FilesystemAdapter.php#L205

cURL error 7: Failed to connect to logging.googleapis.com port 443: Connection timed out

We are currently experiencing some connection issues when trying to log to the Google Stackdriver via our Laravel 6 application.
We use the official google/cloud-logging package within a custom Laravel logging channel for the logging with the following setup, which enables us to use the Laravel's native log methods (Log::info('...')):
// Within the `channels` array in `logging.php`
'googlelog' => [
'driver' => 'custom',
'via' => CreateStackdriverLogger::class,
'logName' => 'api',
'loggingClientOptions' => [
'keyFilePath' => resource_path('google-service-account-prod.json'),
],
'level' => env('LOG_LEVEL', 'info'),
'username' => 'Logger'
],
use Monolog\Logger;
class CreateStackdriverLogger {
/**
* Create a custom Monolog instance.
*
* #param array $config
* #return Logger
*/
public function __invoke(array $config) {
$projectId = $config['logName'] ?? '';
$loggingClientOptions = $config['loggingClientOptions'] ?? [];
$loggerOptions = $config['loggerOptions'] ?? [];
$entryOptionsWrapper = $config['entryOptionsWrapper'] ?? 'stackdriver';
$lineFormat = $config['lineFormat'] ?? '%message%';
$level = $config['level'] ?? Logger::DEBUG;
$bubble = $config['bubble'] ?? true;
$stackdriverHandler = new StackdriverLogger($projectId, $loggingClientOptions, $loggerOptions, $entryOptionsWrapper, $lineFormat, $level, $bubble);
return new Logger('stackdriver', [$stackdriverHandler]);
}
}
use Google\Cloud\Logging\LoggingClient;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
class StackdriverLogger extends AbstractProcessingHandler {
/**
* The Stackdriver logger
*
* #var \Google\Cloud\Logging\Logger
*/
private $logger;
/**
* A context array key used to take log entry options from
*
* #var string
*/
private $entryOptionsWrapper;
/**
* Log entry options (all but severity) as supported by Google\Cloud\Logging\Logger::entry
*
* #var array Entry options.
*/
private $entryOptions = [
'resource',
'httpRequest',
'labels',
'operation',
'insertId',
'timestamp',
];
/**
* #param string $logName Name of your log
* #param array $loggingClientOptions Google\Cloud\Logging\LoggingClient valid options
* #param array $loggerOptions Google\Cloud\Logging\LoggingClient::logger valid options
* #param string $entryOptionsWrapper Array key used in the context array to take Google\Cloud\Logging\Entry options from
* #param string $lineFormat Monolog\Formatter\LineFormatter format
* #param int $level The minimum logging level at which this handler will be triggered
* #param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
*/
public function __construct($logName, $loggingClientOptions, $loggerOptions = [], $entryOptionsWrapper = 'stackdriver', $lineFormat = '%message%', $level = Logger::DEBUG,
$bubble = true) {
parent::__construct($level, $bubble);
$this->logger = (new LoggingClient($loggingClientOptions))->logger($logName, $loggerOptions);
$this->formatter = new LineFormatter($lineFormat);
$this->entryOptionsWrapper = $entryOptionsWrapper;
}
/**
* Writes the record down to the log
*
* #param array $record
* #return void
*/
protected function write(array $record): void {
$options = $this->getOptionsFromRecord($record);
$data = [
'message' => $record['formatted'],
'data' => $record['context']
];
$entry = $this->logger->entry($data, $options);
$this->logger->write($entry);
}
/**
* Get the Google\Cloud\Logging\Entry options
*
* #param array $record by reference
* #return array $options
*/
private function getOptionsFromRecord(array &$record) {
$options = [
'severity' => $record['level_name']
];
if (isset($record['context'][$this->entryOptionsWrapper])) {
foreach ($this->entryOptions as $entryOption) {
if ($record['context'][$this->entryOptionsWrapper][$entryOption] ?? false) {
$options[$entryOption] = $record['context'][$this->entryOptionsWrapper][$entryOption];
}
}
unset($record['context'][$this->entryOptionsWrapper]);
}
return $options;
}
}
So the logging via this setup seems to work in the most cases, but sometimes we receive the following different errors at irregular intervals all in the context of the logging process :
cURL error 7: Failed to connect to logging.googleapis.com port 443:
Connection timed out (see
http://curl.haxx.se/libcurl/c/libcurl-errors.html)
cURL error 7: Failed to connect to oauth2.googleapis.com port 443:
Connection timed out (see
http://curl.haxx.se/libcurl/c/libcurl-errors.html)
cURL error 35: Unknown SSL protocol error in connection to
oauth2.googleapis.com:443 (see
http://curl.haxx.se/libcurl/c/libcurl-errors.html)
Here's an example for a full stacktrace: https://sentry.io/share/issue/7a25c0a3575e4e2684ad5220cd89b86a/
We already checked, if we are running against any rate limits of Google but that doesn't seem to be the case.
Is there anything else that can cause these kind of connection issues?

Php Slim framework unittest mock Router

I have created a wrapper for the Slim request in my application to have the ability to create some custom methods on the Request object.
class Request extends SlimRequest
{
/**
* Get authorization token.
*
* #return null|string
*/
public function getAuthToken(): ?string
{
return $this->getHeaderLine('FOOBAR-TOKEN');
}
/**
* Retrieves a route parameter.
*
* #param string $name
* #return string|null
*/
public function getRouteParam(string $name): ?string
{
return $this->getRoute()->getArgument($name);
}
/**
* Retrieves the route instance.
*
* #return Route
*/
public function getRoute(): Route
{
return $this->getAttribute('route');
}
}
My problem comes when trying to create unit test for this class. The way I have been testing requests is by using Slims build in environment mocks. The first function I added a header to the request which can be seen below, but I can't figure out how to add a Route object to the request
$request = Request::createFromEnvironment(Environment::mock());
$request = $request->withHeader('FOOBAR-TOKEN', 'superSafeExampleToken');
I tried creating the request with a request options but $this->getAttribute('route'); returns null
$requestOptions = [
'REQUEST_METHOD' => 'POST,
'REQUEST_URI' => '/foo/bar',
'QUERY_STRING' => http_build_query($requestParameters),
];
$environment = Environment::mock($requestOptions);
Okay so the solution was the following
public function testGetRouteParam()
{
$route = $route = new Route('GET', '/foo/{bar}', []);
$route->setArguments(['bar' => 1]);
$request = Request::createFromEnvironment(Environment::mock());
$request = $request->withAttribute('route', $route);
$this->assertEquals(1, $request->getRouteParam('bar'));
$this->assertNull($request->getRouteParam('baz'));
}

Laravel - unit testing

Hi i am trying to set a a test to test my database calls. I want to pass a variables in url but cant seem to get it to work.
I wanted to do this
public function testDb()
{
$response = $this->call('GET', '/searchAvailability?keyword=test product');
$content = $response->getContent();
$this->assertEquals('[{"name":"test product"}]',$content );
}
But i keep getting "Undefined variable : keyword" when i try. It works in the browser just not when i run phpunit. Anyone got any ideas on why this is not working thanks.
The answer here is you need to specify the parameters differently in your call method:
$this->call('GET', '/searchAvailability', array('keyword' => 'test product'));
Below is the implementation of Illuminate\Foundation\Testing\TestCase::call method:
/**
* Call the given URI and return the Response.
*
* #param string $method
* #param string $uri
* #param array $parameters
* #param array $files
* #param array $server
* #param string $content
* #param bool $changeHistory
* #return \Illuminate\Http\Response
*/
public function call()
{
call_user_func_array(array($this->client, 'request'), func_get_args());
return $this->client->getResponse();
}

Categories