Keep similar-ai from tripping the global circuit on a lone URL 502, clamp Qdrant search to 100, and add Server-Timing plus slow-request logging. Studio shared props, Academy S3 exists caching, heat chunking, and Redis/scheduler hygiene stay in this rollout.
120 lines
4.1 KiB
PHP
120 lines
4.1 KiB
PHP
<?php
|
|
|
|
use cPad\Plugins\Forum\Jobs\AnalyzeForumPostJob;
|
|
use cPad\Plugins\Forum\Jobs\BotActivityMonitor;
|
|
use cPad\Plugins\Forum\Jobs\FirewallActivityMonitor;
|
|
use cPad\Plugins\Forum\Models\ForumPost;
|
|
use cPad\Plugins\Forum\Services\ForumModerationService;
|
|
use cPad\Plugins\Forum\Services\Security\BotProtectionService;
|
|
use cPad\Plugins\Forum\Services\Security\ForumSecurityFirewallService;
|
|
use Illuminate\Support\Facades\Queue;
|
|
|
|
it('does not dispatch AnalyzeForumPostJob when AI queue dispatch is disabled', function () {
|
|
config(['skinbase_ai_moderation.queue.dispatch_enabled' => false]);
|
|
Queue::fake();
|
|
|
|
$post = new ForumPost();
|
|
$post->id = 42;
|
|
|
|
$queued = app(ForumModerationService::class)->dispatchAsyncScan($post);
|
|
|
|
expect($queued)->toBeFalse();
|
|
Queue::assertNotPushed(AnalyzeForumPostJob::class);
|
|
});
|
|
|
|
it('dispatches AnalyzeForumPostJob when AI queue dispatch is enabled', function () {
|
|
config(['skinbase_ai_moderation.queue.dispatch_enabled' => true]);
|
|
Queue::fake();
|
|
|
|
$post = new ForumPost();
|
|
$post->id = 43;
|
|
|
|
$queued = app(ForumModerationService::class)->dispatchAsyncScan($post);
|
|
|
|
expect($queued)->toBeTrue();
|
|
Queue::assertPushedOn(
|
|
(string) config('skinbase_ai_moderation.queue.name', 'forum-moderation'),
|
|
AnalyzeForumPostJob::class,
|
|
);
|
|
});
|
|
|
|
it('does not dispatch BotActivityMonitor when security queue dispatch is disabled', function () {
|
|
config(['forum_security.queues.dispatch_enabled' => false]);
|
|
Queue::fake();
|
|
|
|
$this->artisan('forum:bot-scan')->assertSuccessful();
|
|
|
|
Queue::assertNotPushed(BotActivityMonitor::class);
|
|
});
|
|
|
|
it('dispatches BotActivityMonitor when security queue dispatch is enabled', function () {
|
|
config(['forum_security.queues.dispatch_enabled' => true]);
|
|
Queue::fake();
|
|
|
|
$this->artisan('forum:bot-scan')->assertSuccessful();
|
|
|
|
Queue::assertPushed(BotActivityMonitor::class);
|
|
});
|
|
|
|
it('does not dispatch FirewallActivityMonitor when security queue dispatch is disabled', function () {
|
|
config(['forum_security.queues.dispatch_enabled' => false]);
|
|
Queue::fake();
|
|
|
|
$this->artisan('forum:firewall-scan')->assertSuccessful();
|
|
|
|
Queue::assertNotPushed(FirewallActivityMonitor::class);
|
|
});
|
|
|
|
it('dispatches FirewallActivityMonitor when security queue dispatch is enabled', function () {
|
|
config(['forum_security.queues.dispatch_enabled' => true]);
|
|
Queue::fake();
|
|
|
|
$this->artisan('forum:firewall-scan')->assertSuccessful();
|
|
|
|
Queue::assertPushed(FirewallActivityMonitor::class);
|
|
});
|
|
|
|
it('runs forum bot scan synchronously without queueing when --sync is passed', function () {
|
|
config(['forum_security.queues.dispatch_enabled' => false]);
|
|
Queue::fake();
|
|
|
|
$this->mock(BotProtectionService::class, function ($mock): void {
|
|
$mock->shouldReceive('scanRecentActivity')->once()->andReturn(['processed' => 0]);
|
|
});
|
|
|
|
$this->artisan('forum:bot-scan --sync')->assertSuccessful();
|
|
|
|
Queue::assertNothingPushed();
|
|
});
|
|
|
|
it('runs forum firewall scan synchronously without queueing when --sync is passed', function () {
|
|
config(['forum_security.queues.dispatch_enabled' => false]);
|
|
Queue::fake();
|
|
|
|
$this->mock(ForumSecurityFirewallService::class, function ($mock): void {
|
|
$mock->shouldReceive('scanRecentThreats')->once()->andReturn(['processed' => 0]);
|
|
});
|
|
|
|
$this->artisan('forum:firewall-scan --sync')->assertSuccessful();
|
|
|
|
Queue::assertNothingPushed();
|
|
});
|
|
|
|
it('does not enqueue AnalyzeForumPostJob from forum:ai-scan without --sync when dispatch is disabled', function () {
|
|
config(['skinbase_ai_moderation.queue.dispatch_enabled' => false]);
|
|
Queue::fake();
|
|
|
|
$this->artisan('forum:ai-scan')->assertSuccessful();
|
|
|
|
Queue::assertNotPushed(AnalyzeForumPostJob::class);
|
|
});
|
|
|
|
it('keeps synchronous forum:scan-posts on the schedule and omits async forum enqueue commands when dispatch is disabled', function () {
|
|
$this->artisan('schedule:list')
|
|
->expectsOutputToContain('forum:scan-posts')
|
|
->doesntExpectOutputToContain('forum:ai-scan')
|
|
->doesntExpectOutputToContain('forum:bot-scan')
|
|
->doesntExpectOutputToContain('forum:firewall-scan')
|
|
->assertSuccessful();
|
|
});
|