diff options
Diffstat (limited to 't/app')
-rw-r--r-- | t/app/controller/alert_new.t | 43 | ||||
-rw-r--r-- | t/app/controller/my.t | 23 | ||||
-rw-r--r-- | t/app/controller/questionnaire.t | 9 | ||||
-rw-r--r-- | t/app/controller/report_updates.t | 87 |
4 files changed, 153 insertions, 9 deletions
diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index d968b56b1..31d8c52ed 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -866,4 +866,47 @@ subtest 'check setting include dates in new updates cobrand option' => sub { $include_date_in_alert_override->restore(); }; +subtest 'check staff updates can include sanitized HTML' => sub { + my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User'); + my $user2 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $body); + my $user3 = $mech->create_user_ok('updater@example.com', name => 'Another User'); + + my $dt = DateTime->now->add( minutes => -30 ); + my $r_dt = $dt->clone->add( minutes => 20 ); + + my ($report) = $mech->create_problems_for_body(1, $body->id, 'Testing', { + user => $user1, + }); + + my $update1 = $mech->create_comment_for_problem($report, $user2, 'Staff User', '<p>This is some update text with <strong>HTML</strong> and *italics*.</p> <ul><li>Even a list</li><li>Which might work</li><li>In the <a href="https://www.fixmystreet.com/">text</a> part</li></ul> <script>not allowed</script>', 't', 'confirmed', undef, { confirmed => $r_dt->clone->add( minutes => 8 ) }); + $update1->set_extra_metadata(is_body_user => $user2->from_body->id); + $update1->update; + + $mech->create_comment_for_problem($report, $user3, 'Updater User', 'Public users <i>cannot</i> use HTML. <script>not allowed</script>', 't', 'confirmed', undef, { confirmed => $r_dt->clone->add( minutes => 9 ) }); + + my $alert_user1 = FixMyStreet::DB->resultset('Alert')->create( { + user => $user1, + alert_type => 'new_updates', + parameter => $report->id, + confirmed => 1, + whensubscribed => $dt, + } ); + ok $alert_user1, "alert created"; + + FixMyStreet::DB->resultset('AlertType')->email_alerts(); + my $email = $mech->get_email; + my $plain = $mech->get_text_body_from_email($email); + like $plain, qr/This is some update text with \*HTML\* and \*italics\*\.\r\n\r\n\* Even a list\r\n\r\n\* Which might work\r\n\r\n\* In the text \[https:\/\/www.fixmystreet.com\/\] part/, 'plain text part contains no HTML tags from staff update'; + like $plain, qr/Public users <i>cannot<\/i> use HTML\./, 'plain text part contains exactly what was entered'; + + my $html = $mech->get_html_body_from_email($email); + like $html, qr{This is some update text with <strong>HTML</strong> and <i>italics</i>\.}, 'HTML part contains HTML tags'; + unlike $html, qr/<script>/, 'HTML part contains no script tags'; + + $mech->delete_user( $user1 ); + $mech->delete_user( $user2 ); + $mech->delete_user( $user3 ); +}; + + done_testing(); diff --git a/t/app/controller/my.t b/t/app/controller/my.t index 673addf0c..85902ae1a 100644 --- a/t/app/controller/my.t +++ b/t/app/controller/my.t @@ -14,17 +14,12 @@ my $other_user = FixMyStreet::DB->resultset('User')->find_or_create({ email => ' my @other = $mech->create_problems_for_body(1, 1234, 'Another Title', { user => $other_user }); my $user = $mech->log_in_ok( 'test@example.com' ); -$mech->get_ok('/my'); -is $mech->uri->path, '/my', "stayed on '/my' page"; - -$mech->content_contains('Test Title'); -$mech->content_lacks('Another Title'); - my @update; my $i = 0; +my $staff_text = '<p>this is <script>how did this happen</script> <strong>an update</strong></p><ul><li>With</li><li>A</li><li>List</li></ul>'; foreach ($user, $user, $other_user) { $update[$i] = FixMyStreet::DB->resultset('Comment')->create({ - text => 'this is an update', + text => $staff_text, user => $_, state => 'confirmed', problem => $problems[0], @@ -35,6 +30,20 @@ foreach ($user, $user, $other_user) { $i++; } +subtest 'Check loading of /my page' => sub { + $mech->get_ok('/my'); + is $mech->uri->path, '/my', "stayed on '/my' page"; + + $mech->content_contains('Test Title'); + $mech->content_lacks('Another Title'); + $mech->content_contains('<p>this is'); + $mech->content_lacks('<p>this is <strong>an update</strong></p><ul><li>With'); + + $update[0]->update({ extra => { is_superuser => 1 } }); + $mech->get_ok('/my'); + $mech->content_contains('<p>this is <strong>an update</strong></p><ul><li>With'); +}; + foreach ( { type => 'problem', id => 0, result => 404, desc => 'nothing' }, { type => 'problem', obj => $problems[0], result => 200, desc => 'own report' }, diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index b561b271a..592507288 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -351,7 +351,7 @@ my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create( user_id => $user->id, name => 'A User', mark_fixed => 'false', - text => 'This is some update text', + text => 'This is some <strong>update</strong> text', state => 'confirmed', confirmed => $sent_time, anonymous => 'f', @@ -360,7 +360,12 @@ my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create( subtest 'Check updates are shown correctly on questionnaire page' => sub { $mech->get_ok("/Q/" . $token->token); $mech->content_contains( 'Show all updates' ); - $mech->content_contains( 'This is some update text' ); + $mech->content_contains( 'This is some <strong>update</strong> text' ); +}; +subtest 'Check staff update is shown correctly on questionnaire page' => sub { + $comment->update({ extra => { is_superuser => 1 } }); + $mech->get_ok("/Q/" . $token->token); + $mech->content_contains( 'This is some <strong>update</strong> text' ); }; for my $test ( diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t index 760a5a45b..2b60867b8 100644 --- a/t/app/controller/report_updates.t +++ b/t/app/controller/report_updates.t @@ -2218,4 +2218,91 @@ subtest 'check disabling of updates per category' => sub { $mech->content_lacks('Provide an update'); }; +subtest 'check that only staff can display HTML in updates' => sub { + $report->comments->delete; + $user->update({ from_body => undef, is_superuser => 0 }); + + my @lines = ( + "This update contains:", + "1. <strong>some staff-allowed HTML</strong>", + "2. *some Markdown-style italics*", + "3. <script>some disallowed HTML</script>", + "4. An automatic link: https://myfancylink.fixmystreet.com/", + "5. A block-level element: <p>This is its own para</p>", + "" + ); + my $comment = FixMyStreet::DB->resultset('Comment')->create( + { + user => $user, + problem_id => $report->id, + text => join("\n\n", @lines), + confirmed => DateTime->now( time_zone => 'local'), + problem_state => 'confirmed', + anonymous => 0, + mark_open => 0, + mark_fixed => 0, + state => 'confirmed', + } + ); + + # First check that comments from a public user don't receive special treatment + $mech->get_ok( "/report/" . $report->id ); + + $mech->content_contains("1. <strong>some staff-allowed HTML</strong>"); + $mech->content_lacks("<strong>some staff-allowed HTML</strong>"); + + $mech->content_contains("2. *some Markdown-style italics*"); + $mech->content_lacks("<i>some Markdown-style italics</i>"); + $mech->content_lacks("<i>some Markdown-style italics</i>"); + + $mech->content_contains("3. <script>some disallowed HTML</script>"); + $mech->content_lacks("<script>some disallowed HTML</script>"); + + $mech->content_contains('4. An automatic link: <a href="https://myfancylink.fixmystreet.com/">https://myfancylink.fixmystreet.com/</a>') or diag $mech->content; + + $mech->content_contains("5. A block-level element: <p>This is its own para</p>"); + $mech->content_lacks("5. A block-level element: <p>This is its own para</p>"); + + # Now check that comments from a member of staff user do allow HTML/italic markup + $comment->set_extra_metadata(is_body_user => $body->id); + $comment->update; + $mech->get_ok( "/report/" . $report->id ); + + $mech->content_contains("1. <strong>some staff-allowed HTML</strong>"); + $mech->content_lacks("<strong>some staff-allowed HTML</strong>"); + + $mech->content_contains("2. <i>some Markdown-style italics</i>"); + $mech->content_lacks("*some Markdown-style italics*"); + $mech->content_lacks("<i>some Markdown-style italics</i>"); + + $mech->content_lacks("some disallowed HTML"); + + $mech->content_contains('4. An automatic link: <a href="https://myfancylink.fixmystreet.com/">https://myfancylink.fixmystreet.com/</a>'); + + $mech->content_contains("5. A block-level element: <p>This is its own para</p>"); + $mech->content_lacks("<p>\n5. A block-level element: <p>This is its own para</p></p>"); + + # and the same for superusers + $comment->unset_extra_metadata('is_body_user'); + $comment->set_extra_metadata(is_superuser => 1); + $comment->update; + $mech->get_ok( "/report/" . $report->id ); + + $mech->content_contains("1. <strong>some staff-allowed HTML</strong>"); + $mech->content_lacks("<strong>some staff-allowed HTML</strong>"); + + $mech->content_contains("2. <i>some Markdown-style italics</i>"); + $mech->content_lacks("*some Markdown-style italics*"); + $mech->content_lacks("<i>some Markdown-style italics</i>"); + + $mech->content_lacks("some disallowed HTML"); + + $mech->content_contains('4. An automatic link: <a href="https://myfancylink.fixmystreet.com/">https://myfancylink.fixmystreet.com/</a>'); + + $mech->content_contains("5. A block-level element: <p>This is its own para</p>"); + $mech->content_lacks("<p>\n5. A block-level element: <p>This is its own para</p></p>"); + +}; + + done_testing(); |