PHP code example of antonioprimera / laravel-test-scenarios

1. Go to this page and download the library: Download antonioprimera/laravel-test-scenarios library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

antonioprimera / laravel-test-scenarios example snippets


/** @test */
public function a_reader_can_only_read_published_posts()
{
    $scenario = new BlogScenario($this);
    $scenario->login($scenario->reader);
    
    $this->get(route('posts', ['slug' => $this->scenario->publishedPost->slug]))
        ->assertSuccessful();
    
    $this->get(route('posts', ['slug' => $this->scenario->unpublishedPost->slug]))
        ->assertStatus(404);
}

public function createPost(string $key, $author, $data = [])
{
    //allow the user to provide the author instance or its context key
    $authorInstance = $this->getInstance(User::class, $author, true);
    $post = $authorInstance->posts()->create($data);
    
    return $this->set($key, $post);
}

public function createComment(string $key, $parentPost, $author, $data = [])
{
    //allow the user to provide the post instance or its context key
    $postInstance = $this->getInstance(Post::class, $parentPost, true);
    
    //allow the user to provide the author instance or its context key
    $authorInstance = $this->getInstance(User::class, $author, true);
    
    $comment = $postInstance
        ->comments()
        ->create(array_merge($data, ['author_id' => $authorInstance->id]));
        
    return $this->set($key, $comment);
}

class SimpleBlogScenario extends TestScenario
{

    public function setup(mixed $data = null)
    {
        $context = $this->context;
        /* @var AppContext $context */
        
        //create all necessary models for this scenario
        $context->createUser('editor', ['role' => 'editor']);
        $context->createUser('reader', ['role' => 'reader']);
        $context->createPost('publishedPost', 'editor', ['published' => true]);
        $context->createPost('unpublishedPost', 'editor', ['published' => false]);
        $context->createComment('readerComment', 'publishedPost', 'reader', ['body' => 'Nice post']);
    }
    
    protected function createTestContext(TestCase $testCase): TestContext
    {
        //the test context created previously for your own project
        return new BlogContext($testCase);
    }
}

$scenario = new SimpleBlogScenario($this);

protected SimpleBlogScenario $scenario;

protected function setUp(): void
{
    parent::setUp();
    $this->scenario = new SimpleBlogScenario($this);  //then just use $this->scenario in your tests
}

namespace Tests;

use AntonioPrimera\TestScenarios\HasScenarios;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication,
        HasScenarios;               //1. add this trait

    protected function setUp(): void
    {
        parent::setUp();
        
        $this->setupScenarios();    //2. call this method to magically instantiate scenarios
        
        //... other setup stuff
    }
}

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Scenarios\SimpleBlogScenario;
use Tests\TestCase;

class PostTest extends TestCase
{
    use RefreshDatabase;

    protected SimpleBlogScenario $scenario;     //1. declare your scenarios with the proper type

    /** @test */
    public function a_moderator_can_edit_any_post()
    {
        $this->scenario->login('moderator');    //2. just use the scenario (it was magically set up)
        $this->patch(
            route('posts.update', ['post-id' => $this->scenario->post->id]),
            ['title' => 'Updated Title']
        );
        
        $this->assertEquals('Updated Title', $this->scenario->post->fresh()->title);
    }
}

/** @test */
public function a_reader_can_only_read_published_posts()
{
    $scenario = new BlogScenario($this);
    $scenario->login($scenario->reader);
    
    $this->get(route('posts', ['slug' => $this->scenario->publishedPost->slug]))
        ->assertSuccessful();
    
    $this->get(route('posts', ['slug' => $this->scenario->unpublishedPost->slug]))
        ->assertStatus(404);
}

$scenario->createPost('somePost', ['title' => 'Some Title', 'body' => 'Some Body']);
//is equivalent to
$scenario->context->createPost('somePost', ['title' => 'Some Title', 'body' => 'Some Body']);

//then, to access the post you can do:
$post = $scenario->somePost;                    //this is the magic version
//or
$post = $scenario->context->get('somePost');    //this actually happens under the hood

$scenario->login($scenario->reader);
//OR
$scenario->login('reader');