trypost/tests/Feature/Automation/Command/FireScheduleTriggersTest.php
Paulo Castellano a129b6b5cd Denormalize automation trigger_type into an indexed column
The scheduler command ran every minute and loaded all active automations,
then filtered by trigger_type in PHP because that value lived buried in the
nodes JSON array — effectively a full-table scan plus a JSON decode per row
each minute, discarding every non-schedule automation.

Derive trigger_type into a real, indexed column on save (recomputed in the
existing saving() hook so it can never drift from nodes) and filter on it in
SQL. Applies to both the schedule firer and the post-trigger dispatcher.
2026-06-13 15:26:54 -03:00

30 lines
1.2 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\Automation;
use App\Models\AutomationTriggerItem;
it('fires only schedule-trigger automations whose cron matches', function () {
$scheduleAutomation = Automation::factory()->active()->create([
'nodes' => [['id' => 't', 'type' => 'trigger', 'position' => ['x' => 0, 'y' => 0],
'data' => ['trigger_type' => 'schedule', 'cron' => '* * * * *']]],
]);
$rssAutomation = Automation::factory()->active()->withScheduleTrigger()->create();
$this->artisan('automation:fire-schedule')->assertSuccessful();
expect(AutomationTriggerItem::where('automation_id', $scheduleAutomation->id)->count())->toBe(1);
expect(AutomationTriggerItem::where('automation_id', $rssAutomation->id)->count())->toBe(0);
});
it('ignores automations whose trigger is not a schedule', function () {
$postAutomation = Automation::factory()->active()->create([
'nodes' => [['id' => 't', 'type' => 'trigger', 'position' => ['x' => 0, 'y' => 0],
'data' => ['trigger_type' => 'post_published']]],
]);
$this->artisan('automation:fire-schedule')->assertSuccessful();
expect(AutomationTriggerItem::where('automation_id', $postAutomation->id)->count())->toBe(0);
});