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
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
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.
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.
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.
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.