Open FzSalehi opened 2 years ago
same question
@FzSalehi , @sinamiandashti I had the same problem today. Here my solution for it. Not pretty, but does the work. :stuck_out_tongue_winking_eye:
Some explanation:
You can not get the captcha value, because it is hashed after the creation and only the hash is obtained. See: https://github.com/mewebstudio/captcha/blob/master/src/Captcha.php#L343
The comparison is done via hashing and comparing the provided value with existing hash. See: https://github.com/mewebstudio/captcha/blob/master/src/Captcha.php#L478
The good thing is, that the author used dependency injection and all the properties and methods are public or protected, so you can easily override necessary parts and replace the base class. :thumbsup:
Here my simple Fake Class solution:
<?php
namespace Tests;
use Mews\Captcha\Captcha;
class CaptchaFake extends Captcha
{
public static string $expectedValue = '';
public static function fake(string $value = ''): void
{
self::$expectedValue = $value;
app()->bind('captcha', function ($app) {
return new CaptchaFake(
$app['Illuminate\Filesystem\Filesystem'],
$app['Illuminate\Contracts\Config\Repository'],
$app['Intervention\Image\ImageManager'],
$app['Illuminate\Session\Store'],
$app['Illuminate\Hashing\BcryptHasher'],
$app['Illuminate\Support\Str']
);
});
}
public function check(string $value): bool
{
return self::$expectedValue === $value;
}
}
I have added a static expected value property, so I can easily simulate success and failure. Just call the fake method at the beginning of your test method:
CaptchaFake::fake('123456');
I did not wanted to mock a lot so I just copied the creation of the original Captcha Class from the provider. See: https://github.com/mewebstudio/captcha/blob/master/src/CaptchaServiceProvider.php#L73
If you use the check_api method, you can fake it as well. https://github.com/mewebstudio/captcha/blob/master/src/Captcha.php#L505
Hope it helps you as well. Enjoy :wink:
Oohh man, @Sergej-Tihonov. Thank so much. It's work!
@sinamiandashti thank you for your help .. I have also a solution which is not so pretty too 😜 but it is simpler
you can modify laravel request validations .. right ?
so just put a simple condition like so:
// in some controller
public function store(Request $request)
{
//here we decide which inputs required
$requiredInputs = $this->getInputRequired();
//then do the validation ...
$validatedData = $request->validate($requiredInputs );
// The blog post is valid...
}
private function getInputRequired(){
// this is golden condition
if(env('debug')){
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'captcha' => 'required',
];
}
}
in this way .. you will never need to pass captcha input from your test requests.
But anyways I suggest to @mewebstudio to do something about the testing environment.
I think @Sergej-Tihonov 's solution could be implemented in this package.
expectedValue
it's a very bad practice, never mix test and production code.
Hi You can use it like below
If used API
Captcha::shouldReceive('check_api')->andReturn(true);
If did not use API
Captcha::shouldReceive('check')->andReturn(true);
@sinamiandashti @FzSalehi
Hi You can use it like below
If used API
Captcha::shouldReceive('check_api')->andReturn(true);
If did not use API
Captcha::shouldReceive('check')->andReturn(true);
@sinamiandashti @FzSalehi
thank you, this work for me, I use FormRequest validation and it's working
Hi , im using this captcha in a form and i want to do some tests .. how to get correct code and insert it in form to submit the form?