Testovanie
Reports::fake() nasadí zaznamenávajúci fake za fasádu aj do kontajnera, takže naň dopadne fasáda, vložený ReportsManager, buildery, reports:prune, $report->changeStatusTo() aj trait GivesReports. Meniace volania sa zaznamenajú a nič sa nezapíše: create() vráti neuložené hlásenie v stave Pending, moderate()->open() neuložený ApprovalRequest a prune() vráti 0. Čítanie dôvodov funguje naozaj:
use RoundlyConsulting\Reports\Facades\Reports;
$fake = Reports::fake();
$user->report($post)->for('spam')->create();
Reports::resolve($report, by: $admin, note: 'Removed.');
$fake->assertReported($post, $user, 'spam');
$fake->assertResolved($report, $admin, 'Removed.');
$fake->assertNothingPruned();Všetky asercie
| Asercia | Negatívna | Prejde, keď |
|---|---|---|
assertReported($subject, ?$by, Reason|string|null $reason) | assertNothingReported() | Podalo sa hlásenie o subjekte (od $by, s dôvodom $reason, ak ich zadáte). |
assertModerated($report) | assertNothingModerated() | Prebehlo moderate($report)->…->open(). |
assertResolved($report, ?$by, ?$note) | assertNothingResolved() | Hlásenie bolo vyriešené (kým a s poznámkou, ak ich zadáte). |
assertRejected($report, ?$by, ?$note) | assertNothingRejected() | To isté pre zamietnutia. |
assertStatusChanged($report, ?Status $to) | assertNothingStatusChanged() | changeStatus(), review(), close() alebo changeStatusTo() ho presunuli (na $to). |
assertPruned(?int $days, ?bool $force) | assertNothingPruned() | Prebehlo prune() (s daným oknom a príznakom, ak ich zadáte). |
use RoundlyConsulting\Reports\Enums\Status;
use RoundlyConsulting\Reports\Facades\Reports;
it('routes a report through moderation', function () {
$fake = Reports::fake();
$this->actingAs($admin)->post(route('admin.reports.escalate', $report))->assertOk();
$fake->assertModerated($report); // moderate($report)->…->open() ran
$fake->assertStatusChanged($report, Status::InReview); // review() / changeStatus() / changeStatusTo()
$fake->assertNothingResolved();
$fake->assertNothingRejected();
$fake->assertNothingReported();
});
it('rejects and prunes from the console', function () {
$fake = Reports::fake();
Reports::reject($report, by: $admin, note: 'Not a violation.');
$this->artisan('reports:prune', ['--days' => 30])->assertSuccessful();
$fake->assertRejected($report, $admin, 'Not a violation.');
$fake->assertPruned(30, force: false);
$fake->assertNothingModerated();
$fake->assertNothingStatusChanged();
});Stavy factory
Report má factory so stavom pre každú fázu životného cyklu:
use RoundlyConsulting\Reports\Enums\Reason;
use RoundlyConsulting\Reports\Models\Report;
Report::factory()->create(); // Pending, reason 'spam'
Report::factory()->forReporter($user)->against($post)->create();
Report::factory()->reason(Reason::Harassment)->create(); // Reason case or slug
Report::factory()->inReview()->create();
Report::factory()->resolved($moderator)->create(); // sets resolver + resolved_at
Report::factory()->rejected()->create();
Report::factory()->closed()->create();
Report::factory()->guest('guest-hash')->create(); // null reporter, guest identifierHlásenia z factory sa zapisujú priamo, takže validácia dôvodu, kontrola duplicít ani prah sa neuplatnia — ReportCreated sa však spustí. Ak chcete bez fake skutočný priebeh, podávajte hlásenia cez fasádu:
use Illuminate\Support\Facades\Event;
use RoundlyConsulting\Reports\Enums\Reason;
use RoundlyConsulting\Reports\Enums\Status;
use RoundlyConsulting\Reports\Events\ReportResolved;
use RoundlyConsulting\Reports\Events\ReportThresholdReached;
use RoundlyConsulting\Reports\Exceptions\DuplicateReportException;
use RoundlyConsulting\Reports\Facades\Reports;
it('files, deduplicates and resolves a report', function () {
Event::fake([ReportResolved::class]);
$user = User::factory()->create();
$moderator = User::factory()->create();
$post = Post::factory()->create();
$report = Reports::report($post)->by($user)->for(Reason::Spam)->create();
expect($report->status)->toBe(Status::Pending)
->and($post->isReportedBy($user))->toBeTrue();
expect(fn () => Reports::report($post)->by($user)->for(Reason::Spam)->create())
->toThrow(DuplicateReportException::class);
Reports::resolve($report, by: $moderator, note: 'Removed.');
expect($report->fresh()->status)->toBe(Status::Resolved);
Event::assertDispatched(ReportResolved::class);
});
it('escalates once the threshold is reached', function () {
config()->set('reports.threshold', 3);
Event::fake([ReportThresholdReached::class]);
$post = Post::factory()->create();
foreach (User::factory()->count(3)->create() as $user) {
Reports::report($post)->by($user)->for(Reason::Spam)->create();
}
Event::assertDispatchedTimes(ReportThresholdReached::class, 1);
});Testy spúšťajte s publikovanými migráciami reports a approvals (RefreshDatabase) — vybavenie alebo zamietnutie hlásenia číta approval_requests, aj keď moderáciu netestujete.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.