Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically Registered Event Listeners assertListening Fails #41771

Closed
gofish543 opened this issue Apr 1, 2022 · 6 comments
Closed

Dynamically Registered Event Listeners assertListening Fails #41771

gofish543 opened this issue Apr 1, 2022 · 6 comments

Comments

@gofish543
Copy link

  • Laravel Version: 9.5.1
  • PHP Version: 8.1.0
  • Database Driver & Version:

Description:

A dynamically registered event listener using the EventServiceProvider@shouldDiscoverEvents => returns true registers the listener in the dispatcher as a string value.

This is fine, and the listener fires correctly. However, if a call is made to the EventFake@assertListening(...), it will fail because the $actualListener variable is a string class@method syntax not matching any of the equals statements found.

Steps To Reproduce:

  1. Create a UserLogin Listener REGISTERED DYNAMICALLY
<?php

namespace App\Listeners\Auth;

use Illuminate\Auth\Events\Login;
use Illuminate\Http\Request;

class LoginListener
{
    /**
     * Create the event listener.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    public function __construct(
        protected Request $request
    ) {
        //
    }

    /**
     * Handle the event.
     *
     * @param  \Illuminate\Auth\Events\Login  $event
     * @return void
     */
    public function handle(Login $event)
    {
        $event->user->logins()->create([
            'source_ip' => $this->request->ip(),
        ]);
    }
}

and the EventServiceProvider...

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array<string, string[]>
     */
    protected $listen = [
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     *
     * @return bool
     */
    public function shouldDiscoverEvents(): bool
    {
        return true;
    }
}
  1. Create a test case to test the registration using assertListening
<?php

namespace Tests\Unit\Listeners\Auth;

use App\Listeners\Auth\LoginListener;
use App\Models\User;
use Illuminate\Auth\Events\Login as LoginEvent;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;

class LoginListenerTest extends TestCase
{
    /**
     * @return void
     */
    protected function setUp(): void
    {
        parent::setUp();

        Event::fake([
            LoginEvent::class
        ]);
    }

    /**
     * @small
     */
    public function testListenerRegistered()
    {
        Event::assertListening(LoginEvent::class, LoginListener::class);
    }

    /**
     * @medium
     */
    public function testRecordsLoginEvent()
    {
        Event::fake();

        $user = User::factory()->create([
            'password' => 'testing543',
        ]);

        $this->post(route('login'), [
            'email' => $user->email,
            'password' => 'testing543',
        ]);

        Event::assertDispatched(LoginEvent::class);
    }
}
  1. Observe the test case failing
    image

  2. Navigate to the file throwing the error Illuminate/Support/Testing/Fakes/EventFake.php line 58

  3. Dump the $actualListener and $expectedListener variables (We can assume a string is never an instance of Closure or Closure::class so we need the $actualListener === $expectedListener to work)
    image

@driesvints driesvints changed the title [9.5.1] Dynamically Registered Event Listeners assertListening Fails Dynamically Registered Event Listeners assertListening Fails Apr 1, 2022
@driesvints
Copy link
Member

Heya, thanks for reporting.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as separate commits on the main/master branch and share the repository here? Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Please do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

@driesvints
Copy link
Member

Hey @gofish543. Feel free to provide that repo and I'll re-open.

@gofish543
Copy link
Author

Hey @gofish543. Feel free to provide that repo and I'll re-open.

I'll get something up late tonight or tomorrow. You'll have it Monday.

@gofish543
Copy link
Author

gofish543 commented Apr 1, 2022

Hey @gofish543. Feel free to provide that repo and I'll re-open.

I'll get something up late tonight or tomorrow. You'll have it Monday.

@driesvints Scratch that...

https://github.com/gofish543/bug-report

@driesvints
Copy link
Member

Thanks @gofish543. I managed to reproduce this. I've sent in a PR for this: #41820

@gofish543
Copy link
Author

@driesvints Lovely! Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants