Laravel Cache testing issue - laravel

I'm trying to the the following piece of code:
public function remember(string $key, \Closure $callback, int $ttl = null): mixed
{
return \Cache::remember($key, $ttl, $callback);
}
with:
public function testRememberWhenTimeoutIsSet(): void
{
\Cache::shouldReceive('remember')
->once()
->with(\Mockery::on(function ($key, $ttl, $callback) {
return $key === 'key' && $ttl === 123 && is_callable($callback);
}))
->andReturn('any-thing');
$this->assertEquals(
'any-thing',
$this->service->remember('key', function () {}, 123)
);
}
But it keeps giving me the following error:
Mockery\Exception\NoMatchingExpectationException : No matching handler
found for Mockery_2_Illuminate_Cache_CacheManager::remember('key',
123, object(Closure)). Either the method was unexpected or its
arguments matched no expected argument list for this method
Objects: ( array ( 'Closure' => array (
'class' => 'Closure',
'identity' => '#3e713b47f2e6096de32a4437ee0381ff',
'properties' =>
array (
), ), ))
The error goes away if to completely remove with block. Any ideas?

You can consider the code below to work well:
Cache::shouldReceive('remember')
->once()
->with('key', 123, \Closure::class)
->andReturn('any-thing')
;
with method in your case doesn't need a CLOSURE matcher but only a list of expected arguments.

Related

How to use Enum on phpunit tests with Laravel 9?

I'm migrating a project from Lumen 8 to Laravel 9. I'm having problems using Enums; however, it worked in Lumen.
$router->patch('/orcamentos/{id}/situacao', [
'uses' => AlterarSituacaoOrcamentoController::class . '#executar',
'middleware' => ['pode:' . Permissao::VENDA_ORCAMENTOS_ALTERAR]
]);
Enum
namespace App\Models\helpers\Enums;
enum SituacaoOrcamento: string
{
case Orcado = 'Orçado';
case EnviadoAoCliente = 'Enviado ao cliente';
case AprovadoPeloCliente = 'Aprovado pelo cliente';
case RejeitadoPeloCliente = 'Rejeitado pelo cliente';
case RejeitadoPelaEmpresa = 'Rejeitado pela empresa';
case ConvertidoEmVenda = 'Convertido em venda';
}
Test
public function testaRetorno(): void
{
$retorno = $this->patch('/orcamentos/1/situacao', [
'situacao' => SituacaoOrcamento::AprovadoPeloCliente
]);
$retorno->assertStatus(Response::HTTP_OK);
}
The error when running the test:
Excepted a scalar, or an array as a 2nd argument to
"Symfony\Component\HttpFoundation\InputBag::set()",
"App\Models\helpers\Enums\SituacaoOrcamento" given.
The errors happen before even entering the controller. It occurs on the method set of class InputBag from Symfony/Component/HttpFoundation.
/**
* Sets an input by name.
*
* #param string|int|float|bool|array|null $value
*/
public function set(string $key, mixed $value)
{
if (null !== $value && !is_scalar($value) && !\is_array($value) && !$value instanceof \Stringable) {
throw new \InvalidArgumentException(sprintf('Excepted a scalar, or an array as a 2nd argument to "%s()", "%s" given.', __METHOD__, get_debug_type($value)));
}
$this->parameters[$key] = $value;
}
If I comment this if in the package file, it works. Maybe I'm doing something wrong that causes the issue.

Pass data from controller to View in Laravel

I have a query that I am not able to pass to the view.
$dias_usados = calendario::where('id_funcionario', '=', $userid)
->groupBy('id_funcionario')
->sum('contaferias');
dd outputs the correct expected value.
I tried to pass to the View as follows:
return view(
'ausencia',
compact('tabela'),
['itens' => $ferias],
['dias_usados' => $dias_usados]
);
I'm having problems with the last one dias_usados. The first two work normally.
<h3>{{$dias_usados}}</h3>
Causes the following error:
Undefined variable: "dias_usados"
I also leave the path I have on the route, but I don't see anything wrong
Route::get('Ausencia', [AusenciaController::class, 'index'])->name('ausencia.index');
This is the the definition of the view helper
function view($view = null, $data = [], $mergeData = []) { }
You are misusing the function by giving it three separate arrays expecting it to get them as $data.
Fixes
return view('ausencia', [
'tabela' => $tabela,
'itens' => $ferias,
'dias_usados' => $dias_usados,
]);
return view('ausencia')
->with(compact('tabela'))
->with(['itens' => $ferias])
->with(['dias_usados' => $dias_usados]);
return view(
'ausencia',
array_merge(
compact('tabela'),
['itens' => $ferias],
['dias_usados' => $dias_usados]
)
);

assertJson and assertSee show call to a null member error

I trying to develop a test for my APIs,
This is my code:
public function testFirstAPI()
{
$user = \User::find(1);
$r = $this
->actingAs($user)
->json('put', route('updateUser'),['lock' => 'true']);
$r->assertResponseStatus(200)->seeJson(['success' => true]);
}
this test will work and when I use $r->dump() I can found the success in the response.
but I don't know why seeJson show this error:
Symfony\Component\Debug\Exception\FatalErrorException]
Call to a member function assertJson() on null
This is because you are chaining assertResponseStatus() first and it does not return a fluent object.
A solution would be to put it as the last assertion in the chain:
public function testFirstAPI()
{
$user = \User::find(1);
$this->actingAs($user)
->json('put', route('updateUser'), ['lock' => 'true'])
->seeJson(['success' => true])
->assertResponseStatus(200)
}

add Symfony Assert in a Callback

I, i have to add an Assert to an atribute when other atribute is equal than something. Like this:
/**
* #Assert\Callback(methods={"isChildMinor",)
*/
class PatientData
{
/**
* #Assert\Date()
*/
public $birthday;
public $role;
public function isChildMinor(ExecutionContext $context)
{
if ($this->role == 3 && check #assert\isMinor() to $birtday) {
=>add violation
}
}
so, i want check if the patient is minor (with assert or somethings else) if the role is equal than 3. How do this?
There are several ways to do, what you want.
1) You could make it right in the form. Like that:
use Symfony\Component\Validator\Constraints as Assert;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$yourEntity = $builder->getData();
//here you start the field, you want to validate
$fieldOptions = [
'label' => 'Field Name',
'required' => true,
];
if ($yourEntity->getYourProperty != 'bla-bla-bla') {
$fieldOptions[] = 'constraints' => [
new Assert\NotBlank([
'message' => 'This is unforgivable! Fill the field with "bla-bla-bla" right now!',
]),
],
}
$builder->add('myField', TextType::class, $fieldOptions);
2) Other way - is to make your custom validation callback in your Entity and play with direct asserts there. It's possible, I think.
3) But the optimal way, from my point of view - is to use several asserts with validation groups. You need to specify Assert\isMinor(groups={"myCustomGroup"}) on birthday field. And then, in your form:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'validation_groups' => function (FormInterface $form) {
$yourEntity = $form->getData();
if ($yourEntity->role !== 3) {
return ['Default', 'myCustomGroup'];
}
return ['Default'];
},
Hope this'll be helpful for you.

parsing arguments with Codeigniter form_validation callback for file input

I have a upload input and am trying to parse an argument to callback function via the CI form_validation library.
$this->form_validation->set_rules('orderfile', 'Order Form'," trim|callback_upload_check[$account_id]");
This calls:
public function upload_check($str, $id)
{
$errors = $this->do_upload($id);
if(isset($errors['error']))
{
$this->form_validation->set_message('upload_check', $errors['error']);
return FALSE;
}else{
return TRUE;
}
}
The Codeigniter Userguide states that when calling the function, the first argument is parsed as the second argument inside the function.
Neither arguments are parsed through. I found this post on the Codeigniter Forum
This seems to explain what is happening (variables are stripped). If i change the to <input type="text" /> the params work...
Is there anyway of getting around this problem?
you need to edit your code like this :
$this->form_validation->set_rules('orderfile', 'Order Form'," trim|callback_upload_check[".$account_id."]");
i also noticed that in your form_validation->set_rules you are not passing any value for id so in your function you should do :
public function upload_check($str, $id=0){..}
You need to change the function to:
public function upload_check($orderfile)
{
$errors = $this->do_upload($orderfile);
if(isset($errors['error']))
{
$this->form_validation->set_message('upload_check', $errors['error']);
return FALSE;
}else{
return TRUE;
}
}
I know this is an old question, but I was having the same problem, I finally realized the second parameter comes back in quotes, so if you pass an $id with the value 1, it actually comes back as "1".
So, to the original question, you need to callback the function like so:
$this->form_validation->set_rules('orderfile', 'Order Form'," trim|callback_upload_check[".$account_id."]");
And in your call back function:
public function upload_check($str, $id){
$actual_id=str_replace('"', "", $id)
}
$config =array(
array(
"field" => "userEmail",
"label" => ":userEmail:",
"rules" => "required|valid_email",
),
array(
"field" => "userPassword",
"label" => ":userPassword:",
"rules" => "required|min_length[8]",
),
);
$error_messages = array(
"required" => "{field} the field is required.",
"min_length" => "{field} the field value is so short",
"valid_email" => "{field} please valid email",
);
$this->form_validation->set_message($error_messages);
$this->form_validation->set_rules($config);
if($this->form_validation->run() == FALSE) {
$alert =preg_replace("/(\n)+/m", ' ', strip_tags(validation_errors()));
$explode =explode(':', $alert);
$arr =array();
for($i=1; $i < count($explode); $i+=2){
$y=$i;
$j =++$y;
$arr[$explode[$i]] = $explode[$j];
}
print json_encode($arr);
} else {
//process
}

Resources