Files
servicedesk/src/tests/Feature/EmailLayoutTest.php
Kacper ab90abcaa3 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>
2026-07-22 23:43:01 +02:00

95 lines
3.8 KiB
PHP

<?php
use App\Livewire\Admin\Panel;
use App\Models\EmailTemplate;
use App\Notifications\TicketNotification;
use App\Support\Settings;
use Livewire\Livewire;
test('Settings::renderEmailLayout always wraps content in the fixed box layout, ignoring any stored override', function () {
// The box is no longer admin-editable — a leftover/stale stored value
// (e.g. from before this UI was removed) must not be used.
Settings::set('email_layout_html', '<div class="should-be-ignored">{tresc}</div>');
Settings::set('email_footer', 'Pozdrawiamy, Wsparcie');
Settings::set('company_name', 'Acme');
$html = Settings::renderEmailLayout('<p>Treść zgłoszenia</p>');
expect($html)->not->toContain('should-be-ignored')
->and($html)->toBe(strtr(Settings::default('email_layout_html'), [
'{tresc}' => '<p>Treść zgłoszenia</p>',
'{stopka}' => 'Pozdrawiamy, Wsparcie',
'{firma}' => 'Acme',
]));
});
test('the default footer is not empty and its own {firma} placeholder resolves through the layout', function () {
Settings::set('company_name', 'Acme');
$html = Settings::renderEmailLayout('<p>Treść</p>');
expect(Settings::default('email_footer'))->not->toBeEmpty()
->and($html)->toContain('Acme')
->and($html)->not->toContain('{firma}');
});
test('admin can reset the email footer back to its default, remounting the editor with a fresh key', function () {
$admin = adminUser();
$component = Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'email')
->call('saveEmailFooter', 'Coś innego')
->assertSet('emailFooterVersion', 0);
$component->call('resetEmailFooter')
->assertOk()
->assertSet('emailFooterHtml', Settings::default('email_footer'))
->assertSet('emailFooterVersion', 1)
->assertSee('email-footer-1', escape: false);
expect(Settings::get('email_footer'))->toBe(Settings::default('email_footer'));
});
test('admin can save the email footer from the E-MAIL tab', function () {
$admin = adminUser();
Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'email')
->call('saveEmailFooter', '<p>Pozdrawiamy, Zespół Wsparcia</p>')
->assertOk()
->assertSet('emailFooterHtml', '<p>Pozdrawiamy, Zespół Wsparcia</p>');
expect(Settings::get('email_footer'))->toBe('<p>Pozdrawiamy, Zespół Wsparcia</p>');
});
test('the live example preview reflects the currently saved footer', function () {
$admin = adminUser();
$component = Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'email')
->call('saveEmailFooter', 'Stopka na żywo');
expect($component->instance()->emailPreviewHtml)->toContain('Stopka na żywo')
->and($component->instance()->emailPreviewHtml)->toContain('#1234');
});
test('there is no more editor for the box layout itself, only for its footer', function () {
expect(method_exists(Panel::class, 'saveEmailLayout'))->toBeFalse()
->and(method_exists(Panel::class, 'resetEmailLayout'))->toBeFalse();
});
test('a rendered ticket notification embeds its template body inside the fixed box layout', function () {
seedStatusesAndPriorities();
$template = EmailTemplate::query()->create([
'key' => 'tpl-layout-test', 'name' => 'x', 'trigger_label' => 'x',
'subject' => 'S', 'body' => '<p>Zgłoszenie #{numer} zostało utworzone.</p>',
]);
$ticket = makeTicket();
$mail = (new TicketNotification($ticket, $template->id))->toMail((object) ['routes' => ['mail' => $ticket->email]]);
expect($mail->viewData['html'])->toBe(Settings::renderEmailLayout('<p>Zgłoszenie #'.$ticket->number.' zostało utworzone.</p>'))
->and($mail->view)->toBe('emails.ticket-notification');
});