Testing Komposers and Komponents
Keep your code under control, otherwise it will control you 🧐

It is very easy to test Komposers using Laravel's already existing extensive testing tools. Here, we will give guidelines and examples on how to test your components every step of the way.

Browser tests

Laravel Dusk

Laravel Dusk provides a long list of methods for checking the existence of elements, manipulating input values and interacting with links and buttons - and they all work with Kompo Forms, Queries and Menus. We will take a look at an example for a Form.

First, start by installing Laravel Dusk and generate a first test template.

The Dusk selector

Kompo provides the `dusk` method that you can chain to components to add a dusk selector.

Button::form('Save')->dusk('my-form-btn')

This will add a `dusk` attribute to the button element:

<button dusk="my-form-btn">Save<button>

Then in your tests, you may easily point to this elements with the `@my-form-btn` selector.

public function testExample()
{
    $this->browse(function (Browser $browser) use($data) {
        $browser->visit('/') 
                ->click('@my-form-btn');
    });
}

Content assertions

Let's say we want to test that the form is displaying correctly on the home page. Our form has a title, a button and two required attributes: 'title' and 'published_at':

public function komponents()
{
    return [
        Title::form('Edit post'),
        Input::form('Title')->required(),
        Date::form('Published At')->required(),
        Button::form('Save')
            ->dusk('my-form-btn')
    ];
}

We may then create a Test that asserts seeing our Form's title. This test will pass and assures us that (part of) our Form is correctly displaying on the browser.

namespace Tests\Browser;

use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class HomeSimpleFormTest extends DuskTestCase
{
    public function testFormTitleDisplayed()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    //optional, pause for longer if necessary
                    //->pause(1000)
                    ->assertSee('Edit post');
        });
    }
}

Input validations

Now let's say we want to test that the form we are displaying on the home page does the proper input validations.

Check out Laravel's input filling methods to see all the methods you may use for interacting with Form elements.

namespace Tests\Browser;

use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class HomeSimpleFormTest extends DuskTestCase
{
    public function testPublishedAtValidation()
    {
        $data = [
            'title' => 'Edit post'
        ];

        $this->browse(function (Browser $browser) use($data) {
            $browser->visit('/')
                    ->type('title', $data['title'])
                    ->click('@simple-form-btn')
                    ->assertSee('The published at field is required'); //Validation error
        });
    }
}

This test proves that an empty `published_at` field will display an error message with the proper information.

HTTP tests

To test form submissions, query browsing and filtering, and other HTTP requests made directly to Komposers, we need to add a helper Trait to our Tests.

KompoTestRequestsTrait

Every request made to a Komposer contains important encrypted headers that uniquely identify the class targeted by the request as well as store and route paramters information used in the initial call.

In the prepare phase of the test, we need to call the Komposer - in this case a Form. Then in the assert phase, we may perform one of the requests from the Trait.

use Kompo\Tests\KompoTestRequestsTrait;

class MyFormTest extends EnvironmentBoot
{
   use KompoTestRequestsTrait; //we include the Kompo test helpers

   /** @test  */
   public function receive_valid_input_from_request()
   {
      //test content
   }

We may use any of the below methods to perform a well-defined Kompo action:

protected function getKomponents($komposer, $method)

protected function submit($komposer, $data = [])

protected function browse($komposer, $data = [], $sort = null, $page = null)

protected function searchOptions($komposer, $search, $method)

protected function selfGet($komposer, $method, $data = [])

protected function selfPost($komposer, $method, $data = [])

protected function selfPut($komposer, $method, $data = [])

protected function selfDelete($komposer, $method, $data = [])

protected function submitToRoute($form, $data = [])

protected function kompoAction($komposer, $action, $data, $headers = [], $method = 'POST')

Form submit example

Let's say we want to test that the validation is working correctly for a simple POST submit request from a Form with an Input component. In the prepare phase, we call our Form and instantiate a variable with the value that needs to be tested. Then we can make assertions on the response's content.

use Kompo\Tests\KompoTestRequestsTrait;

class MyFormTest extends EnvironmentBoot
{
   use KompoTestRequestsTrait; //This trait has the ->submit() method

   /** @test  */
   public function receive_valid_input_from_request()
   {
      //Prepare phase
      $testInput = 'valid-input';
      $form = new MyTestForm();

      //Assert phase
      $this->submit($form, [
         'input' => $testInput
      ])
      ->assertStatus(200) // or status 201, if the model is newly created
      ->assertJson([
         'input' => $testInput
      ]);
   }

Now let us write a test to make sure the submit is rejected when the input is too long.

/** @test  */
public function receive_invalid_input_from_request()
{
    //Prepare phase
    $form = new MyTestedForm();
    $testInput = 'invalid-long-sentence-input';

    //Assert phase
    $this->submit($form, [
           'input' => $testInput
        ])
        ->assertStatus(422) //we assert that we have a validation error response
        ->assertJson([ 'errors' => ['input' => []] ]) //and that the errors contains the input key;
}

Database tests

To perform database tests, you may use all the tools that Laravel offers by default for database testing and assertions. The same tools may be used for testing the results of Komponents on the database.

For information purposes, we will add some practical examples shortly.

Practical examples

Coming soon...