Behat with mink clean before each test - testing

I am trying to find a way to run cleanup (DB) before running on each test. How could I do if I am using behat with mink? My current FeatureContext.php looks like this:
class FeatureContext extends MinkContext
{
/**
* Initializes context.
* Every scenario gets its own context object.
*
* #param array $parameters context parameters (set them up through behat.yml)
*/
public function __construct(array $parameters)
{
// Initialize your context here
}
}

Use the hooks in your context, read docs for Behat 3 or Behat 2. Example from Behat 3:
// features/bootstrap/FeatureContext.php
use Behat\Behat\Context\Context;
use Behat\Testwork\Hook\Scope\BeforeSuiteScope;
use Behat\Behat\Hook\Scope\AfterScenarioScope;
class FeatureContext implements Context
{
/**
* #BeforeSuite
*/
public static function prepare(BeforeSuiteScope $scope)
{
// prepare system for test suite
// before it runs
}
/**
* #AfterScenario #database
*/
public function cleanDB(AfterScenarioScope $scope)
{
// clean database after scenarios,
// tagged with #database
}
}

Related

Phpstan is not recognizing my abstract class

I have a request with an authorize method that makes use of:
Illuminate\Http\Request::user()
And it gives me a phpstan error that says
phpstan: Cannot call method hasAnyRole() on App\Models\User|null.
And that makes sense.
So I made an abstract class that makes use of
Illuminate\Http\Request::user()
like this:
<?php
namespace App\Http\Requests;
use App\Models\User;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Http\FormRequest;
abstract class VbpRequest extends FormRequest
{
/**
* Get the user making the request.
*
* #param string|null $guard
* #return User
* #throws AuthenticationException
*/
public function user($guard = null): User
{
$user = parent::user($guard);
if ($user instanceof User) {
return $user;
}
throw new AuthenticationException('Trying to resolve a user, but no one is logged in.');
}
}
In theory this should only return an instance of the User model or an exception.
but when I use this new method it gives me the exact same phpstan warning.
phpstan: Cannot call method hasAnyRole() on App\Models\User|null.
Does anyone have an idea of what is going wrong or could be going wrong?
Here is the Request:
<?php
declare(strict_types=1);
namespace App\Http\Requests;
use App\Models\Role;
use App\Traits\RequestCast;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Validation\Rule;
class BelnotitieRequest extends VbpRequest
{
use RequestCast;
/**
* #throws AuthenticationException
*/
public function authorize(): bool
{
return $this->user()->hasAnyRole(Role::ADMIN_ID, Role::PROJECTMANAGER_ID, Role::ADMINISTRATIEF_MEDEWERKER_ID);
}
}
I'm using Laravel 9.24 and larastan 2.1.12

Laravel middleware is not called in feature test

I have a new middleware that works as expected in the browser. However, when I try to trigger the middleware via a feature test, the handle() is never called.
I understand I can write a unit test for this middleware, and should. But should my actual feature test be moved to a browser test?
# Kernel.php
protected $middlewareGroups = [
'web' => [
MyMiddleware::class,
...
# MyMiddleware.php
public function handle($request, Closure $next)
{
dd('I can see this in the browser, but not in the Feature test. Doing some 302 magic here.');
# Feature Test
/**
* #test
* #return void
*/
public function my_new_test(): void
{
$this->get('/test')
->assertStatus(302)
->assertRedirect($vanityDomain->getFallbackRedirectUrl('/non-matching-path'));
}
it's working for me, not sure why yours is not working.
middleware
class MyMiddleware
{
public function handle($request, Closure $next)
{
if ('test' === $request->path()) {
return redirect('/test1');
}
return $next($request);
}
}
feature test
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function testBasicTest()
{
$this->get('/test')->assertStatus(302)->assertRedirect('test1');
}
}
Btw, unit and feature tests just a way of grouping your tests. Does not matter where you put, they all behave the same.
On laravel 8 I had to run php artisan optimize to get it working. Seems the route cache somehow needed to be cleared.

Force running a codeception test before another

If i define an #depends annotation like below, the test cannot be run if the createObjectBase Test has not run successfully before.
Sometimes i don't want to run the whole suite, but only the createObjectGeo Test.
How can i define that if i run createObjectGeo, codeception runs createObjectBase before it?
/**
*
*/
public function createObjectBase (AcceptanceTester $I) {
}
/**
* #depends createObjectBase
*/
public function createObjectGeo(AcceptanceTester $I) {
}
you should looking for the #before/#after annotations for this functionality
/**
*
*/
public function createObjectBase (AcceptanceTester $I) {
}
/**
* #before createObjectBase
*/
public function createObjectGeo(AcceptanceTester $I) {
}
please take a look at the documentation http://codeception.com/docs/07-AdvancedUsage#BeforeAfter-Annotations
The tests will be executed in the same order they will be written in the Cest file.

Execute sql script when updating database schema Doctrine

Is it possible to append (or execute) a custom sql queries when executing:
app/console doctrine:schema:update --force
I have a script that create all my views and I want them to be updated whenever I update the database schema.
Sure, you can extend the UpdateSchemaCommand command and inject the EntityManager into by defining the command as a service.
The command:
// src/AppBundle/Command/CustomUpdateSchemaCommand.php
<?php
namespace AppBundle\Command;
use Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
class CustomUpdateSchemaCommand extends UpdateSchemaDoctrineCommand
{
/** #var EntityManagerInterface */
private $em;
/**
* #param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
/**
* {#inheritDoc}
*/
protected function configure()
{
parent::configure();
}
/**
* {#inheritDoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Hello world');
$conn = $this->em->getConnection();
$conn->exec(/* QUERY */);
return parent::execute($input, $output);
}
}
The service:
// app/config/services.yml
app.command.custom_schema_update_command:
class: App\SportBundle\Command\CustomUpdateSchemaCommand
arguments: ["#doctrine.orm.entity_manager"]
tags:
- { name: console.command }
Hope this helps.

TYPO3 - extending an extbase extension with new fields and using these in fluid templates

I'm trying to extend powermail (version 2) with the possibility to add a note for each input field. So far I have created a new extension using extension builder and with a few modifications to ext_tables.php the field show up in the backend. The new field is called 'note' and I thought I could just do something like {field.note} in the fluid template input.html, but that does not work. My model includes the setter and getter:
class Tx_Formnotes_Domain_Model_Powermailnotes extends Tx_Extbase_DomainObject_AbstractEntity {
/**
* note
*
* #var string
*/
protected $note;
/**
* Returns the note
*
* #return string $note
*/
public function getNote() {
return $this->note;
}
/**
* Sets the note
*
* #param string $note
* #return void
*/
public function setNote($note) {
$this->note = $note;
}
}
What else is needed?
Info: I'm using TYPO3 4.7
You could map the powermail model like
config.tx_extbase.persistence.classes {
Tx_Formnotes_Domain_Model_Powermailnotes {
mapping {
tableName = powermailTableName
columns {
exampleMedia.mapOnProperty = media
}
}
}
}
after that you should extend your TCA with these properties. At least you can write setter and getter for each property and use them in your fluid template.