|
1 | 1 | use strict; |
2 | 2 | use warnings; |
3 | 3 |
|
| 4 | +use File::Spec; |
4 | 5 | use RT::Test tests => undef; |
5 | 6 |
|
6 | 7 | my $ticket = RT::Test->create_ticket( |
@@ -30,4 +31,109 @@ ok( $ret, 'Updated config' ); |
30 | 31 | $m->reload; |
31 | 32 | $m->content_contains('<img src="https://example.com/test.png">', 'Remote images are shown with ShowRemoteImages=1'); |
32 | 33 |
|
| 34 | +# Tests covering the inputs the client-side auto-contrast scanner relies on: |
| 35 | +# colors set on email HTML must survive scrubbing + CSS::Inliner, and the |
| 36 | +# history container must emit data-auto-contrast reflecting the config. |
| 37 | + |
| 38 | +diag "Inline color style survives into the rendered messagebody"; |
| 39 | +{ |
| 40 | + my $t = RT::Test->create_ticket( |
| 41 | + Queue => 'General', |
| 42 | + Subject => 'auto-contrast inline color', |
| 43 | + ContentType => 'text/html', |
| 44 | + Content => '<p style="color: #222222;">Dark text that is unreadable in dark mode</p>', |
| 45 | + ); |
| 46 | + $m->goto_ticket( $t->Id ); |
| 47 | + $m->content_contains( 'color: #222222', |
| 48 | + 'rendered messagebody retains inline color style' ); |
| 49 | +} |
| 50 | + |
| 51 | +diag "Stylesheet block gets inlined by CSS::Inliner"; |
| 52 | +{ |
| 53 | + my $t = RT::Test->create_ticket( |
| 54 | + Queue => 'General', |
| 55 | + Subject => 'auto-contrast style block', |
| 56 | + ContentType => 'text/html', |
| 57 | + Content => '<style>p { color: #333333; }</style><p>Stylesheet-driven dark text</p>', |
| 58 | + ); |
| 59 | + $m->goto_ticket( $t->Id ); |
| 60 | + $m->content_contains( 'color: #333333', |
| 61 | + 'CSS::Inliner pushed stylesheet color onto the element style attribute' ); |
| 62 | +} |
| 63 | + |
| 64 | +diag "An explicit inline background-color survives alongside a paired color"; |
| 65 | +{ |
| 66 | + my $t = RT::Test->create_ticket( |
| 67 | + Queue => 'General', |
| 68 | + Subject => 'auto-contrast own-bg', |
| 69 | + ContentType => 'text/html', |
| 70 | + Content => '<p style="color: #111111; background-color: #dddddd;">Both colors set inline</p>', |
| 71 | + ); |
| 72 | + $m->goto_ticket( $t->Id ); |
| 73 | + $m->content_contains( 'background-color: #dddddd', |
| 74 | + 'inline background-color is not scrubbed' ); |
| 75 | + $m->content_contains( 'color: #111111', |
| 76 | + 'paired inline color is not scrubbed' ); |
| 77 | +} |
| 78 | + |
| 79 | +diag "History container emits data-auto-contrast=1 by default"; |
| 80 | +{ |
| 81 | + $m->goto_ticket( $ticket->Id ); |
| 82 | + $m->content_contains( 'data-auto-contrast="1"', |
| 83 | + 'history-container has data-auto-contrast=1 by default' ); |
| 84 | +} |
| 85 | + |
| 86 | +diag "Real-world fixture: inline span color pattern from webmail senders"; |
| 87 | +{ |
| 88 | + my $path = RT::Test::get_relocatable_file( |
| 89 | + 'html-inline-span-colors', |
| 90 | + ( File::Spec->updir(), 'data', 'emails' ), |
| 91 | + ); |
| 92 | + my $mail = RT::Test->file_content($path); |
| 93 | + my ( $status, $id ) = RT::Test->send_via_mailgate($mail); |
| 94 | + is( $status >> 8, 0, 'mail gateway accepted the fixture' ); |
| 95 | + ok( $id, "created ticket $id from fixture" ); |
| 96 | + |
| 97 | + $m->goto_ticket($id); |
| 98 | + |
| 99 | + # Span-level colors on transparent bg — the pattern that triggers the |
| 100 | + # scanner in dark mode (but renders fine in light mode). |
| 101 | + $m->content_contains( 'color:#222222', |
| 102 | + 'span-on-transparent #222 color survives into rendered messagebody' ); |
| 103 | + $m->content_contains( 'color:#0000ff', |
| 104 | + 'span blue annotation color survives into rendered messagebody' ); |
| 105 | + |
| 106 | + # Span-level white background with dark text — should never trigger the |
| 107 | + # scanner regardless of theme because the inner bg/fg pair is high-contrast. |
| 108 | + $m->content_contains( 'background-color:#ffffff', |
| 109 | + 'span-level explicit white background survives scrubbing' ); |
| 110 | + $m->content_contains( 'color:#000000', |
| 111 | + 'span-level explicit black text color survives scrubbing' ); |
| 112 | + |
| 113 | + # The transparent-bg spans also need to keep their transparency so the |
| 114 | + # scanner walks up to the theme bg instead of stopping at the span. |
| 115 | + $m->content_contains( 'background-color:transparent', |
| 116 | + 'span-level transparent background survives scrubbing' ); |
| 117 | +} |
| 118 | + |
| 119 | +diag "Disabling \$TransactionAutoContrast flips the data attribute to 0"; |
| 120 | +{ |
| 121 | + my $cfg = RT::Configuration->new( RT->SystemUser ); |
| 122 | + my ( $r, $m2 ) = $cfg->Create( |
| 123 | + Name => 'TransactionAutoContrast', |
| 124 | + Content => 0, |
| 125 | + ); |
| 126 | + ok( $r, "Set TransactionAutoContrast=0: $m2" ); |
| 127 | + |
| 128 | + $m->reload; |
| 129 | + $m->goto_ticket( $ticket->Id ); |
| 130 | + $m->content_contains( 'data-auto-contrast="0"', |
| 131 | + 'history-container has data-auto-contrast=0 when disabled' ); |
| 132 | + |
| 133 | + # Leave config consistent for any further tests in the file. |
| 134 | + my $row = RT::Configuration->new( RT->SystemUser ); |
| 135 | + $row->LoadByCols( Name => 'TransactionAutoContrast' ); |
| 136 | + $row->Delete if $row->Id; |
| 137 | +} |
| 138 | + |
33 | 139 | done_testing; |
0 commit comments