v1.1.3
- Triggers (Admin > Wyzwalacze): event-driven rules that fire immediately on a ticket lifecycle event (created/updated/status/priority/assignee/team/ category changed, new reply), with AND-conditions and ordered actions (set status/priority/team/assignee, send e-mail). Ships its own dedicated, freely add/edit/delete-able e-mail templates, kept separate from the fixed system templates. - Ticket watching: operators can star/"Obserwuj" any ticket to follow it regardless of assignment/team. - Real-time notification bell (private per-user broadcast channel, 30s fallback poll) with an opt-in in-tab browser push notification. - Per-user notification preferences (/settings/notifications): scope (mine/unassigned/watched/all) and e-mail toggle per event category. - Admin > Integracje: new tab for LDAP/AD + BookStack config, split out of Konfiguracja. - Operator queue: Podkategoria/Zespół/Utworzono columns (off by default). - Obserwuj button moved next to the auto-refresh countdown; trigger condition builder shows subcategory/zgłaszający as name dropdowns instead of raw IDs; /settings/notifications got a back link, full-width push card, and a bordered table container; admin panel tab and operator queue view now persist across a plain page refresh. - Docs: README/ARCHITECTURE/wiki updated for all of the above. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
45
src/tests/Feature/TicketWatchingTest.php
Normal file
45
src/tests/Feature/TicketWatchingTest.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Operator\TicketShow as OperatorTicketShow;
|
||||
use App\Services\TicketService;
|
||||
use Livewire\Livewire;
|
||||
|
||||
test('an operator can watch and unwatch a ticket', function () {
|
||||
seedStatusesAndPriorities();
|
||||
$operator = operatorUser();
|
||||
$ticket = makeTicket();
|
||||
|
||||
expect($ticket->isWatchedBy($operator))->toBeFalse();
|
||||
|
||||
app(TicketService::class)->toggleWatch($ticket, $operator);
|
||||
expect($ticket->fresh()->isWatchedBy($operator))->toBeTrue()
|
||||
->and($operator->watchedTickets()->pluck('tickets.id'))->toContain($ticket->id);
|
||||
|
||||
app(TicketService::class)->toggleWatch($ticket, $operator);
|
||||
expect($ticket->fresh()->isWatchedBy($operator))->toBeFalse();
|
||||
});
|
||||
|
||||
test('the ticket-show watch button toggles watch state for the viewing operator', function () {
|
||||
seedStatusesAndPriorities();
|
||||
$operator = operatorUser();
|
||||
$ticket = makeTicket();
|
||||
|
||||
Livewire::actingAs($operator)->test(OperatorTicketShow::class, ['ticket' => $ticket])
|
||||
->assertSet('isWatching', false)
|
||||
->call('toggleWatch')
|
||||
->assertSet('isWatching', true);
|
||||
|
||||
expect($ticket->fresh()->isWatchedBy($operator))->toBeTrue();
|
||||
});
|
||||
|
||||
test('watching a ticket is per-operator, not shared', function () {
|
||||
seedStatusesAndPriorities();
|
||||
$watcher = operatorUser('watcher@example.com');
|
||||
$other = operatorUser('other@example.com');
|
||||
$ticket = makeTicket();
|
||||
|
||||
app(TicketService::class)->toggleWatch($ticket, $watcher);
|
||||
|
||||
expect($ticket->fresh()->isWatchedBy($watcher))->toBeTrue()
|
||||
->and($ticket->fresh()->isWatchedBy($other))->toBeFalse();
|
||||
});
|
||||
Reference in New Issue
Block a user