Laravel 9.26, weekly updates, and 🔥 tip

Laravel 9.26

This week we got a new minor release with a fast-follow patch release bumping us to Laravel 9.26.1. Here are the highlights:

  • Add support for non-backed enums in #43728
  • Improve display of failures for assertDatabaseHas in #43736
  • Add Vite::asset() helper in #43702
  • Support additional where* methods to route groups in #43731
  • Add min_digits and max_digits validation rules in #43797
  • Add closure support to dispatch conditionals. in #43784
  • Add configurable paths to Vite in #43620

You may review the full branch diff on GitHub for a complete list of changes.

This version bump and update is automated for subscribers to a Shifty Plan. If you don't have one of those, be sure to bump your constraint and run composer update to get the latest features.

Weekly Journal

Last week I worked on another Human Shift. This time upgrading from Laravel 5.6 to Laravel 9.x. I also completed support for one from the previous week.

I spent Friday cleaning up anything I noticed while dogfooding Shift. I also reviewed some of the recent support emails for any additional improvements.

I spent most of yesterday backfilling tests to complete development for spawning new queue workers dynamically. I wanted to get this launched before today's release to test it in production.

So today, with the tag of Laravel 9.26 (and 9.26.1), additional queue workers were dynamically created and removed within an hour of each release. This was pretty cool! I shared some screenshots and a follow-up video on Twitter. I also plan on writing a blog post which will focus more on the business decisions. I'll share that on Twitter once it's published, and in next week's newsletter.

With the rest of this week I'll do another Wednesday live stream, as well as continue to tweak Shifts and likely the dynamic workers too.

🔥 Tip

While testing the dynamic workers I stumbled upon a little gotcha when testing Laravel. Despite the implementation being correct, the following test failed.

public function it_dispatches_job_to_destroy_worker()
{
Queue::fake();
Http::preventStrayRequests()
->fake(['https://api.digitalocean.com/v2/droplets/54321' => Http::response('...');
 
CheckWorker::dispatch(54321);
 
Queue::assertPushed(
DestroyWorker::class,
fn ($job) => $job->id === 54321 && $job->name === 'shift-worker-02'
);
}

Those that write a lot of Laravel tests or are very familiar with fakes may notice the reason right away. But it took me a little rubber ducking.

When writing tests in Laravel, it's easy to write a query or fire an event or dispatch a job the same way you would within your application code. However, if you're faking one of Laravel's core components, it's possible that may no longer work.

In this case, because I was faking the queue and then dispatching a job to the queue, the job itself never executed. It was simply recorded as being dispatched for testing purposes.

To get around this, I wrote a simple helper method to dispatch the job manually.

private function dispatchJob(int $id)
{
(new CheckWorker($id))->handle();
}

While I still prefer to use Laravel helpers in tests, for complex tests like this one (where jobs dispatch jobs), manually calling your code is an alternative.