Laravel Artisan command in controller ignores additional options - laravel

I'm trying to run an Artisan command from a controller with options to either run parallel or test a single test class:
$this->call('test', [
'--parallel',
'--filter' => 'FooTest',
]);
But it just ignores any options. If I run php artisan test --filter=FooTest or php artisan test --parallel in the command line this works just fine.
I've tried using Artisan::call( ... ), put the array in a variable, use array() instead of [] but nothing seems to work.
But when I run a seeder with options it works just fine
$this->call('db:seed', ['--class' => 'EssentialDatabaseSeeder']);

If you're attempting to pass a boolean value to the Artisan command, you need to do the following:
$this->call('test', [
'--parallel' => true, // Add true here
'--filter' => 'FooTest',
]);
From the documentation:
Passing Boolean Values
If you need to specify the value of an option that does not accept string values, such as the --force flag on the migrate:refresh command, you should pass true or false as the value of the option:

Related

Mews\Purifier\Purifier::__construct() must be an instance of Illuminate\Filesystem\Filesystem

I installed Mews-Purifier on laravel 5.1
I used Froala Editor.
https://stackoverflow.com/
<script>asdfasdfasdf</script>
<iframe>qwerqwerqwer</iframe>
I expect result.
<p>https://stackoverflow.com/</p>
<p>qwerqwerqwer</p>
but, I am not see it.
when save it,
$data['detail'] = app('purifier')->clean($data['detail']);
if use Purifier::clean($data['detail']), It send error message me.
Non-static method Mews\Purifier\Purifier::clean() should not be called statically
so, It changed.
$data['detail'] = (new \Mews\Purifier\Purifier)->clean($data['detail']);
send error message too.
Type error: Too few arguments to function Mews\Purifier\Purifier::__construct(),
so I do changed.
(new Mews\Purifier\Purifier($data['detail'], ['AutoFormat.DisplayLinkURI' => true] ))->clean($data['detail');
Type error: Argument 1 passed to Mews\Purifier\Purifier::__construct() must be an instance of Illuminate\Filesystem\Filesystem, string given, called in
what Filesystem? what file??
Let me know How should I use it?
If I wasn't good at installing, what would it be?
Oh the installation did the following.
terminal
composer require mews/purifier
/config/app.php
'providers' => [
// ...
Mews\Purifier\PurifierServiceProvider::class,
],
'aliases' => [
// ...
'Purifier' => Mews\Purifier\Facades\Purifier::class,
]
terminal
php artisan vendor:publish
check created file. /config/purifier.php
Thanks for watching
Please let me know if you know.

Unable to mock Cache::put() facade in Laravel

I'm trying to mock the Cache::put() facade. But it gives me an error. I have tried different ways but couldn't figure it out.
public function testGetAllFromDatabase()
{
$industry = new Industry();
Cache::shouldReceive('has')
->once()
->with('industries.all')
->andReturn(false);
Cache::shouldReceive('put')
->with('industries.all', '', 0)
->andReturn(true);
$this->industryMock
->shouldReceive('all')
->once()
->andReturn(array_reverse($this->industries));
$this->app->instance(Industry::class, $this->industryMock);
$industryRepository = new IndustryRepository();
$all = $industryRepository->all();
dd($all);
$this->assertContains( $this->industries[2], $all);
}
But when I execute it the following error is occurring.
$ vendor/bin/phpunit
PHPUnit 7.2.7 by Sebastian Bergmann and contributors.
...E 4 / 4 (100%)
Time: 3.76 seconds, Memory: 12.00MB
There was 1 error:
1) Tests\Unit\RepositoriesTests\IndustryRepositoryTest::testGetAllFromDatabase
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_1_Illuminate_Cache_CacheManager::put('industries.all', object(Illuminate\Database\Eloquent\Collection), '1440'). Either the method was unexpected or its arguments matched no expected argument list for this method
Objects: ( array (
'Illuminate\\Database\\Eloquent\\Collection' =>
array (
'class' => 'Illuminate\\Database\\Eloquent\\Collection',
'properties' =>
array (
),
),
))
F:\development\consulting.local\src\vendor\mockery\mockery\library\Mockery\ExpectationDirector.php:92
F:\development\consulting.local\src\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:223
F:\development\consulting.local\src\app\Repositories\IndustryRepository.php:30
F:\development\consulting.local\src\tests\Unit\RepositoriesTests\IndustryRepositoryTest.php:81
I have tried many ways but couldn't get it to fix. Thank you.
Since it may help others, Laravel's facade includes helper functions that allow swapping then with a Mockery test double
This means that when you use a shouldReceive you can chain it with any Mockery expectation for example in this case if you don't care about some parameters you can use:
Cache::shouldReceive('put')
->with('industries.all', \Mockery::any(), \Mockery::any())
->andReturn(true);
In case it helps others, it's good to point out that you may not want to mock Cache, but instead actually use the real Cache.
That's because it's a Cache for testing only:
When running tests via vendor/bin/phpunit, Laravel [....] automatically configures the session and cache to the array driver while testing, meaning no session or cache data will be persisted while testing.
https://laravel.com/docs/8.x/testing#environment
Note that unlike the OP's test, you may need to follow Laravel's guidance about your test class extending their TestCase to get the behavior, e.g.
use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase

Laravel, php artisan passport:install error

I was curious about setting up an API in Laravel using Passport so I followed their documentation here:
https://laravel.com/docs/5.6/passport
Once I run
php artisan passport:install
It gives me this error:
ErrorException : openssl_pkey_new(): private key length is too short; it needs to be at least 384 bits, not 0
at /Users/fantastisk/web/blog-laravel/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php:560
556| $config = array();
557| if (isset($this->configFile)) {
558| $config['config'] = $this->configFile;
559| }
> 560| $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config);
561| openssl_pkey_export($rsa, $privatekey, null, $config);
562| $publickey = openssl_pkey_get_details($rsa);
563| $publickey = $publickey['key'];
564|
Exception trace:
1 openssl_pkey_new(["4096", "/Users/fantastisk/web/blog-laravel/vendor/phpseclib/phpseclib/phpseclib/Crypt/../openssl.cnf"])
/Users/fantastisk/web/blog-laravel/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php:560
2 phpseclib\Crypt\RSA::createKey("4096")
/Users/fantastisk/web/blog-laravel/vendor/laravel/passport/src/Console/KeysCommand.php:35
This is what i have in the openssl.cnf file
# minimalist openssl.cnf file for use with phpseclib
HOME = .
RANDFILE = $ENV::HOME/.rnd
distinguished_name = req_distinguished_name
[ v3_ca ]
I'm running on a mac with php 7.1 (i tried building it from source with openssl too), SSL Version => LibreSSL/2.0.20.
I tried following the documentation using homestead too, which gives me the exact same error.
To me it seems like there's a problem with the phpseclib library, but I haven't been able to find anything on google regarding this error.
As a final note, I tried running this command to check if openssl_pkey_new works:
openssl_pkey_new(array("digest_alg" => "sha512","private_key_bits" => 4096,"private_key_type" => OPENSSL_KEYTYPE_RSA,));
That worked with no error.
Any help or point in the right direction will be very much appreciated.
Try passing the length option as you run the install command:
php artisan passport:install --length=256
If that doesn't work then try forcing the key generation:
php artisan passport:key --force
You may need to run composer update prior.

A Collection isn't Arrayable when testing

I'm making some HTTP Tests and I'm having an issue in one of them. Here's what happening:
Same endpoint
Same data on database
Same PHP version
Same headers
Different results
Here's the code:
1.
dd(
$interestResults instanceof Arrayable,
get_class($interestResults),
$interestResults[0] instanceof Arrayable,
get_class($interestResults[0]),
Arrayable::class,
phpversion()
);
2.
$typeBefore = gettype($interestResults);
$typeOfItemBefore = gettype($interestResults[0]);
$interestResults = $interestResults->toArray();
dd($typeBefore, $typeOfItemBefore, gettype($interestResults), gettype($interestResults[0]));
Here's what I get on Postman:
1.
true
"Illuminate\Database\Eloquent\Collection"
true
"App\Post"
"Illuminate\Contracts\Support\Arrayable"
"7.2.4"
2.
"object"
"object"
"array"
"array"
Here's what I get when testing:
1.
false
"Illuminate\Database\Eloquent\Collection"
true
"App\Post"
"Illuminate\Contracts\Support\Arrayable"
"7.2.4"
2.
"object"
"object"
"array"
"object"
TL;DR
If you use Laravel Valet, don't use your global phpunit. Use the project's local phpunit by running vendor/bin/phpunit.
Detailed version
While investigating this strange behavior I came to the conclusion that, since I know that class IS Illuminate\Database\Eloquent\Collection and it extends Illuminate\Support\Collection that implements Arrayable, it couldn't just "don't be" an instance of Arrayable.
So I've decided to check with Reflection what kind of Arrayable it was. That was my code:
$reflection = new \ReflectionClass(get_class($interestResults));
$implementedInterfacesList = array_keys($reflection->getInterfaces());
$isItArrayableByReflaction = in_array('Illuminate\Contracts\Support\Arrayable', $implementedInterfacesList);
$isItArrayableByInstanceOf = $interestResults instanceof \Illuminate\Contracts\Support\Arrayable;
dd($implementedInterfacesList, $isItArrayableByReflaction, $isItArrayableByInstanceOf);
And, for my surprise, those were the results:
Postman
array:8 [
0 => "JsonSerializable"
1 => "Illuminate\Contracts\Support\Jsonable"
2 => "Traversable"
3 => "IteratorAggregate"
4 => "Countable"
5 => "Illuminate\Contracts\Support\Arrayable"
6 => "ArrayAccess"
7 => "Illuminate\Contracts\Queue\QueueableCollection"
]
true
true
Terminal
array:8 [
0 => "JsonSerializable"
1 => "Tightenco\Collect\Contracts\Support\Jsonable"
2 => "Traversable"
3 => "IteratorAggregate"
4 => "Countable"
5 => "Tightenco\Collect\Contracts\Support\Arrayable"
6 => "ArrayAccess"
7 => "Illuminate\Contracts\Queue\QueueableCollection"
]
false
false
Interesting, Tightenco\Collect\Contracts\Support\Arrayable, but composer why tightenco\collect?
composer why tightenco/collect
[InvalidArgumentException]
Could not find package "tightenco/collect" in your project
So, the error isn't on my project neither on its dependencies. I've tried to run local local phpunit (vendor/bin/phpunit) and:
array:8 [
...
]
true
true
Great! Problem "fixed", but composer why was it happening?
composer global why tightenco/collect
Changed current directory to /Users/guilherme/.composer
laravel/valet v2.0.10 requires tightenco/collect (^5.3)
That's it! When running my global phpunit composer will use my global autoload and Laravel conflicts with tightenco/collect.
The solution?
Well, while I don't consider it a solution, I think this is the official one: Use the project's local phpunit by running vendor/bin/phpunit.
Also, you can skip tests that need Arrayable to be Illuminate\Contracts\Support\Arrayable:
use Illuminate\Contracts\Support\Arrayable;
...
if (!collect() instanceof Arrayable) {
$skipMessage = <<<'MESSAGE'
This test has conflicts with tightenco/collect and it seems you are using it.
If you are running the testsuite with your global phpunit, please try running 'vendor/bin/phpunit'.
MESSAGE;
$this->markTestSkipped($skipMessage);
}

Auth not working in Laravel Tinker

From within Tinker I am trying to:
>>> Auth::loginUsingId(12);
=> false
>>> Auth::user();
=> null
>>> Auth::attempt(['email' => 'my#email.com']);
=> false
I am guessing that since Auth typically uses session data, and maybe sessions don't work with tinker.
Is it possible to authenticate within tinker?
It's possible to login in Tinker. For example:
auth()->loginUsingId(1)
auth()->id()
Normally, the output of the auth()->id() will be 1.
If it doesn't work for you, make sure the storage directory is writable:
sudo chmod -R 755 storage
You're also doing it wrong when you're using the attempt() method. The correct syntax is:
attempt(['email' => 'my#email.com', 'password' => 'secret'])

Resources