summaryrefslogtreecommitdiff
path: root/rt/t/web
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2012-04-24 11:35:56 -0700
committerIvan Kohler <ivan@freeside.biz>2012-04-24 11:35:56 -0700
commit6587f6ba7d047ddc1686c080090afe7d53365bd4 (patch)
treeec77342668e8865aca669c9b4736e84e3077b523 /rt/t/web
parent47153aae5c2fc00316654e7277fccd45f72ff611 (diff)
first pass RT4 merge, RT#13852
Diffstat (limited to 'rt/t/web')
-rw-r--r--rt/t/web/admin_groups.t59
-rw-r--r--rt/t/web/admin_user.t21
-rw-r--r--rt/t/web/articles-links.t52
-rw-r--r--rt/t/web/attachment-with-name-0.t23
-rw-r--r--rt/t/web/attachment_encoding.t15
-rw-r--r--rt/t/web/attachments.t46
-rw-r--r--rt/t/web/basic.t35
-rw-r--r--rt/t/web/case-sensitivity.t85
-rw-r--r--rt/t/web/cf_access.t129
-rw-r--r--rt/t/web/cf_date.t187
-rw-r--r--rt/t/web/cf_datetime.t235
-rw-r--r--rt/t/web/cf_onqueue.t24
-rw-r--r--rt/t/web/cf_render_type.t50
-rw-r--r--rt/t/web/cf_select_one.t81
-rw-r--r--rt/t/web/charting.t25
-rw-r--r--rt/t/web/class_create.t75
-rw-r--r--rt/t/web/clickjacking-preventions.t30
-rw-r--r--rt/t/web/command_line.t65
-rw-r--r--rt/t/web/command_line_with_unknown_field.t11
-rw-r--r--rt/t/web/compilation_errors.t38
-rw-r--r--rt/t/web/config_tab_right.t8
-rw-r--r--rt/t/web/crypt-gnupg.t77
-rw-r--r--rt/t/web/custom_frontpage.t39
-rw-r--r--rt/t/web/custom_search.t6
-rw-r--r--rt/t/web/dashboards-basics.t268
-rw-r--r--rt/t/web/dashboards-deleted-saved-search.t89
-rw-r--r--rt/t/web/dashboards-groups.t139
-rw-r--r--rt/t/web/dashboards-permissions.t10
-rw-r--r--rt/t/web/dashboards-search-cache.t73
-rw-r--r--rt/t/web/gnupg-headers.t53
-rw-r--r--rt/t/web/gnupg-select-keys-on-create.t183
-rw-r--r--rt/t/web/gnupg-select-keys-on-update.t197
-rw-r--r--rt/t/web/gnupg-tickyboxes.t84
-rw-r--r--rt/t/web/googleish_search.t219
-rw-r--r--rt/t/web/group_create.t75
-rw-r--r--rt/t/web/html/Callbacks/logout.t/NoAuth/Logout.html/Default6
-rw-r--r--rt/t/web/html/NoAuth/js/not-by-default.js3
-rw-r--r--rt/t/web/html/delete-article-name-method.html15
-rw-r--r--rt/t/web/html_template.t12
-rw-r--r--rt/t/web/logout.t39
-rw-r--r--rt/t/web/offline.t78
-rw-r--r--rt/t/web/offline_messages_utf8.t3
-rw-r--r--rt/t/web/offline_utf8.t15
-rw-r--r--rt/t/web/passthrough-jsmin5
-rw-r--r--rt/t/web/path-traversal.t12
-rw-r--r--rt/t/web/private-components.t6
-rw-r--r--rt/t/web/query_builder.t100
-rw-r--r--rt/t/web/query_log.t20
-rw-r--r--rt/t/web/queue_caching.t90
-rw-r--r--rt/t/web/queue_create.t75
-rw-r--r--rt/t/web/quickcreate.t37
-rw-r--r--rt/t/web/quicksearch.t6
-rw-r--r--rt/t/web/redirect-after-login.t26
-rw-r--r--rt/t/web/redirect.t106
-rw-r--r--rt/t/web/reminders.t88
-rw-r--r--rt/t/web/remote_user.t36
-rw-r--r--rt/t/web/requestor_groups_edit_link.t56
-rw-r--r--rt/t/web/requestor_groups_limit.t36
-rw-r--r--rt/t/web/rest-non-ascii-subject.t6
-rw-r--r--rt/t/web/rest-sort.t46
-rw-r--r--rt/t/web/rest.t4
-rw-r--r--rt/t/web/richtext-autohandler.t10
-rw-r--r--rt/t/web/rights.t38
-rw-r--r--rt/t/web/rights1.t33
-rw-r--r--rt/t/web/saved_search_chart.t82
-rw-r--r--rt/t/web/saved_search_context.t69
-rw-r--r--rt/t/web/saved_search_permissions.t6
-rw-r--r--rt/t/web/saved_search_update.t2
-rw-r--r--rt/t/web/scrips.t105
-rw-r--r--rt/t/web/scrub.t46
-rw-r--r--rt/t/web/search_bulk_update_links.t24
-rw-r--r--rt/t/web/search_cf_quotes.t53
-rw-r--r--rt/t/web/search_rss.t11
-rw-r--r--rt/t/web/search_simple.t22
-rw-r--r--rt/t/web/search_tabs.t86
-rw-r--r--rt/t/web/self_service.t19
-rw-r--r--rt/t/web/squish.t78
-rw-r--r--rt/t/web/template.t62
-rw-r--r--rt/t/web/ticket-create-utf8.t18
-rw-r--r--rt/t/web/ticket_display.t63
-rw-r--r--rt/t/web/ticket_forward.t232
-rw-r--r--rt/t/web/ticket_links.t110
-rw-r--r--rt/t/web/ticket_modify_all.t44
-rw-r--r--rt/t/web/ticket_modify_people.t113
-rw-r--r--rt/t/web/ticket_owner.t147
-rw-r--r--rt/t/web/ticket_owner_autocomplete.t185
-rw-r--r--rt/t/web/ticket_owner_issues_16656.t63
-rw-r--r--rt/t/web/ticket_seen.t24
-rw-r--r--rt/t/web/ticket_txn_content.t71
-rw-r--r--rt/t/web/ticket_update_without_content.t14
-rw-r--r--rt/t/web/transaction_batch.t55
-rw-r--r--rt/t/web/unlimited_search.t13
-rw-r--r--rt/t/web/user_update.t32
-rw-r--r--rt/t/web/walk.t92
94 files changed, 4977 insertions, 777 deletions
diff --git a/rt/t/web/admin_groups.t b/rt/t/web/admin_groups.t
new file mode 100644
index 000000000..783b5ad44
--- /dev/null
+++ b/rt/t/web/admin_groups.t
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test tests => 26;
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login(), 'logged in' );
+
+{
+ diag "test creating a group" if $ENV{TEST_VERBOSE};
+ $m->get_ok( $url . '/Admin/Groups/Modify.html?Create=1' );
+ $m->content_contains('Create a new group', 'found title');
+ $m->submit_form_ok({
+ form_number => 3,
+ fields => { Name => 'test group' },
+ });
+ $m->content_contains('Group created', 'found results');
+ $m->content_contains('Modify the group test group', 'found title');
+}
+
+{
+ diag "test creating another group" if $ENV{TEST_VERBOSE};
+ $m->get_ok( $url . '/Admin/Groups/Modify.html?Create=1' );
+ $m->content_contains('Create a new group', 'found title');
+ $m->submit_form_ok({
+ form_number => 3,
+ fields => { Name => 'test group2' },
+ });
+ $m->content_contains('Group created', 'found results');
+ $m->content_contains('Modify the group test group2', 'found title');
+}
+
+{
+ diag "test creating an overlapping group" if $ENV{TEST_VERBOSE};
+ $m->get_ok( $url . '/Admin/Groups/Modify.html?Create=1' );
+ $m->content_contains('Create a new group', 'found title');
+ $m->submit_form_ok({
+ form_number => 3,
+ fields => { Name => 'test group' },
+ });
+ $m->content_contains('Group could not be created', 'found results');
+ $m->content_like(qr/Group name .+? is already in use/, 'found message');
+}
+
+{
+ diag "test updating a group name to overlap" if $ENV{TEST_VERBOSE};
+ $m->get_ok( $url . '/Admin/Groups/' );
+ $m->follow_link_ok({text => 'test group2'}, 'found title');
+ $m->content_contains('Modify the group test group2');
+ $m->submit_form_ok({
+ form_number => 3,
+ fields => { Name => 'test group' },
+ });
+ $m->content_lacks('Name changed', "name not changed");
+ $m->content_contains('Illegal value for Name', 'found error message');
+ $m->content_contains('test group', 'did not find new name');
+}
+
diff --git a/rt/t/web/admin_user.t b/rt/t/web/admin_user.t
new file mode 100644
index 000000000..fde075f4d
--- /dev/null
+++ b/rt/t/web/admin_user.t
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 7;
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login(), 'logged in' );
+
+my $root = RT::User->new( $RT::SystemUser );
+$root->Load('root');
+ok( $root->id, 'loaded root' );
+
+
+diag "test the history page" if $ENV{TEST_VERBOSE};
+$m->get_ok( $url . '/Admin/Users/History.html?id=' . $root->id );
+$m->content_contains('User created', 'has User created entry');
+
+# TODO more /Admin/Users tests
+
diff --git a/rt/t/web/articles-links.t b/rt/t/web/articles-links.t
new file mode 100644
index 000000000..713dc05e4
--- /dev/null
+++ b/rt/t/web/articles-links.t
@@ -0,0 +1,52 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 18;
+
+RT->Config->Set( MasonLocalComponentRoot => RT::Test::get_abs_relocatable_dir('html') );
+
+my ($baseurl, $m) = RT::Test->started_ok;
+
+my $queue = RT::Queue->new(RT->SystemUser);
+$queue->Load('General');
+
+my $class = RT::Class->new(RT->SystemUser);
+my ($ok, $msg) = $class->Create(Name => "issues");
+ok($ok, "created class: $msg");
+
+($ok, $msg) = $class->AddToObject($queue);
+ok($ok, "applied class to General: $msg");
+
+my $article = RT::Article->new(RT->SystemUser);
+($ok, $msg) = $article->Create(Name => "instance of ticket #17421", Class => $class->id);
+ok($ok, "created article: $msg");
+
+ok($m->login, "logged in");
+
+my $ticket = RT::Test->create_ticket(Queue => $queue->Id, Subject => 'oh wow! an AUTOLOAD bug');
+
+$m->goto_ticket($ticket->id);
+$m->follow_link_ok({text => 'Reply'});
+
+$m->form_name('TicketUpdate');
+$m->field('Articles-Include-Article-Named' => $article->Name);
+$m->submit;
+
+$m->content_contains('instance of ticket #17421', 'got the name of the article in the ticket');
+
+# delete RT::Article's Name method on the server so we'll need to AUTOLOAD it
+my $clone = $m->clone;
+$clone->get_ok('/delete-article-name-method.html');
+like($clone->content, qr/{deleted}/);
+
+$m->form_name('TicketUpdate');
+$m->click('SubmitTicket');
+
+$m->follow_link_ok({text => 'Links'});
+
+$m->text_contains('Article ' . $article->id . ': instance of ticket #17421', 'Article appears with its name in the links table');
+
+my $refers_to = $ticket->RefersTo;
+is($refers_to->Count, 1, 'the ticket has a refers-to link');
+is($refers_to->First->TargetURI->URI, 'fsck.com-article://example.com/article/' . $article->Id, 'when we included the article it created a refers-to');
+
diff --git a/rt/t/web/attachment-with-name-0.t b/rt/t/web/attachment-with-name-0.t
new file mode 100644
index 000000000..12a8dd548
--- /dev/null
+++ b/rt/t/web/attachment-with-name-0.t
@@ -0,0 +1,23 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 8;
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+
+use File::Spec;
+
+my $file = File::Spec->catfile( RT::Test->temp_directory, 0 );
+open my $fh, '>', $file or die $!;
+print $fh 'foobar';
+close $fh;
+
+$m->get_ok( '/Ticket/Create.html?Queue=1' );
+
+$m->submit_form(
+ form_number => 3,
+ fields => { Subject => 'test att 0', Content => 'test', Attach => $file },
+);
+$m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+$m->follow_link_ok( { text => 'Download 0' } );
+$m->content_contains( 'foobar', 'file content' );
diff --git a/rt/t/web/attachment_encoding.t b/rt/t/web/attachment_encoding.t
index 9ba567746..bfbf24590 100644
--- a/rt/t/web/attachment_encoding.t
+++ b/rt/t/web/attachment_encoding.t
@@ -3,13 +3,11 @@
use strict;
use warnings;
-use RT::Test tests => 28;
+use RT::Test tests => 32;
use Encode;
my ( $baseurl, $m ) = RT::Test->started_ok;
ok $m->login, 'logged in as root';
-$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
-
use utf8;
use File::Spec;
@@ -19,7 +17,7 @@ diag 'test without attachments' if $ENV{TEST_VERBOSE};
{
$m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
- $m->form_number(3);
+ $m->form_name('TicketModify');
$m->submit_form(
form_number => 3,
fields => { Subject => '标题', Content => '测试' },
@@ -47,7 +45,7 @@ diag 'test with attachemnts' if $ENV{TEST_VERBOSE};
{
my $file =
- File::Spec->catfile( File::Spec->tmpdir, 'rt_attachemnt_abcde.txt' );
+ File::Spec->catfile( RT::Test->temp_directory, encode_utf8 '附件.txt' );
open( my $fh, '>', $file ) or die $!;
binmode $fh, ':utf8';
print $fh '附件';
@@ -55,12 +53,14 @@ diag 'test with attachemnts' if $ENV{TEST_VERBOSE};
$m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
- $m->form_number(3);
+ $m->form_name('TicketModify');
$m->submit_form(
form_number => 3,
fields => { Subject => '标题', Content => '测试', Attach => $file },
);
$m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+ $m->content_contains( '附件.txt', 'attached filename' );
+ $m->content_lacks( encode_utf8 '附件.txt', 'no double encoded attached filename' );
$m->follow_link_ok( { text => 'with headers' },
'-> /Ticket/Attachment/WithHeaders/...' );
@@ -82,7 +82,7 @@ diag 'test with attachemnts' if $ENV{TEST_VERBOSE};
$m->back;
$m->back;
- $m->follow_link_ok( { text_regex => qr/by Enoch Root/ },
+ $m->follow_link_ok( { text => 'Download 附件.txt' },
'-> /Ticket/Attachment/...' );
$m->content_contains( '附件', 'has content 附件' );
@@ -100,4 +100,3 @@ diag 'test with attachemnts' if $ENV{TEST_VERBOSE};
unlink $file;
}
-
diff --git a/rt/t/web/attachments.t b/rt/t/web/attachments.t
index e827b2f02..8c75f6caf 100644
--- a/rt/t/web/attachments.t
+++ b/rt/t/web/attachments.t
@@ -1,15 +1,15 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 14;
+use RT::Test tests => 25;
-use constant LogoFile => $RT::MasonComponentRoot .'/NoAuth/images/bplogo.gif';
+use constant LogoFile => $RT::MasonComponentRoot .'/NoAuth/images/bpslogo.png';
use constant FaviconFile => $RT::MasonComponentRoot .'/NoAuth/images/favicon.png';
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in';
-my $queue = RT::Queue->new($RT::Nobody);
+my $queue = RT::Queue->new(RT->Nobody);
my $qid = $queue->Load('General');
ok( $qid, "Loaded General queue" );
@@ -17,7 +17,7 @@ $m->form_name('CreateTicketInQueue');
$m->field('Queue', $qid);
$m->submit;
is($m->status, 200, "request successful");
-$m->content_like(qr/Create a new ticket/, 'ticket create page');
+$m->content_contains("Create a new ticket", 'ticket create page');
$m->form_name('TicketCreate');
$m->field('Subject', 'Attachments test');
@@ -26,9 +26,9 @@ $m->field('Content', 'Some content');
$m->submit;
is($m->status, 200, "request successful");
-$m->content_like(qr/Attachments test/, 'we have subject on the page');
-$m->content_like(qr/Some content/, 'and content');
-$m->content_like(qr/Download bplogo\.gif/, 'page has file name');
+$m->content_contains('Attachments test', 'we have subject on the page');
+$m->content_contains('Some content', 'and content');
+$m->content_contains('Download bpslogo.png', 'page has file name');
$m->follow_link_ok({text => 'Reply'}, "reply to the ticket");
$m->form_name('TicketUpdate');
@@ -42,6 +42,34 @@ $m->field('UpdateContent', 'Message');
$m->click('SubmitTicket');
is($m->status, 200, "request successful");
-$m->content_like(qr/Download bplogo\.gif/, 'page has file name');
-$m->content_like(qr/Download favicon\.png/, 'page has file name');
+$m->content_contains('Download bpslogo.png', 'page has file name');
+$m->content_contains('Download favicon.png', 'page has file name');
+
+diag "test mobile ui";
+$m->get_ok( $baseurl . '/m/ticket/create?Queue=' . $qid );
+
+$m->form_name('TicketCreate');
+$m->field('Subject', 'Attachments test');
+$m->field('Attach', LogoFile);
+$m->field('Content', 'Some content');
+$m->submit;
+is($m->status, 200, "request successful");
+
+$m->content_contains('Attachments test', 'we have subject on the page');
+$m->content_contains('bpslogo.png', 'page has file name');
+
+$m->follow_link_ok({text => 'Reply'}, "reply to the ticket");
+$m->form_name('TicketUpdate');
+$m->field('Attach', LogoFile);
+$m->click('AddMoreAttach');
+is($m->status, 200, "request successful");
+
+$m->form_name('TicketUpdate');
+$m->field('Attach', FaviconFile);
+$m->field('UpdateContent', 'Message');
+$m->click('SubmitTicket');
+is($m->status, 200, "request successful");
+
+$m->content_contains('bpslogo.png', 'page has file name');
+$m->content_contains('favicon.png', 'page has file name');
diff --git a/rt/t/web/basic.t b/rt/t/web/basic.t
index 3f94e732f..31e28c406 100644
--- a/rt/t/web/basic.t
+++ b/rt/t/web/basic.t
@@ -4,37 +4,35 @@ use strict;
use warnings;
use Encode;
-use RT::Test tests => 21;
-$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
+use RT::Test tests => 23;
my ($baseurl, $agent) = RT::Test->started_ok;
my $url = $agent->rt_base_url;
-diag $url if $ENV{TEST_VERBOSE};
# get the top page
{
$agent->get($url);
- is ($agent->{'status'}, 200, "Loaded a page");
+ is ($agent->status, 200, "Loaded a page");
}
# test a login
{
$agent->login('root' => 'password');
# the field isn't named, so we have to click link 0
- is( $agent->{'status'}, 200, "Fetched the page ok");
- ok( $agent->{'content'} =~ /Logout/i, "Found a logout link");
+ is( $agent->status, 200, "Fetched the page ok");
+ $agent->content_contains("Logout", "Found a logout link");
}
{
- $agent->get($url."Ticket/Create.html?Queue=1");
- is ($agent->{'status'}, 200, "Loaded Create.html");
- $agent->form_number(3);
+ $agent->goto_create_ticket(1);
+ is ($agent->status, 200, "Loaded Create.html");
+ $agent->form_name('TicketCreate');
my $string = Encode::decode_utf8("I18N Web Testing æøå");
$agent->field('Subject' => "Ticket with utf8 body");
$agent->field('Content' => $string);
ok($agent->submit, "Created new ticket with $string as Content");
- $agent->content_like( qr{$string} , "Found the content");
+ $agent->content_contains($string, "Found the content");
ok($agent->{redirected_uri}, "Did redirection");
{
@@ -48,15 +46,15 @@ diag $url if $ENV{TEST_VERBOSE};
}
{
- $agent->get($url."Ticket/Create.html?Queue=1");
- is ($agent->{'status'}, 200, "Loaded Create.html");
- $agent->form_number(3);
+ $agent->goto_create_ticket(1);
+ is ($agent->status, 200, "Loaded Create.html");
+ $agent->form_name('TicketCreate');
my $string = Encode::decode_utf8("I18N Web Testing æøå");
$agent->field('Subject' => $string);
$agent->field('Content' => "Ticket with utf8 subject");
ok($agent->submit, "Created new ticket with $string as Content");
- $agent->content_like( qr{$string} , "Found the content");
+ $agent->content_contains($string, "Found the content");
ok($agent->{redirected_uri}, "Did redirection");
{
@@ -71,14 +69,13 @@ diag $url if $ENV{TEST_VERBOSE};
# Update time worked in hours
{
$agent->follow_link( text_regex => qr/Basics/ );
- $agent->submit_form( form_number => 3,
+ $agent->submit_form( form_name => 'TicketModify',
fields => { TimeWorked => 5, 'TimeWorked-TimeUnits' => "hours" }
);
- like ($agent->{'content'}, qr/to &#39;300&#39;/, "5 hours is 300 minutes");
+ $agent->content_contains("to &#39;300&#39;", "5 hours is 300 minutes");
}
-# {{{ test an image
TODO: {
todo_skip("Need to handle mason trying to compile images",1);
@@ -94,9 +91,7 @@ is(
"got a file of the correct size ($file)",
);
}
-# }}}
-# {{{ Query Builder tests
#
# XXX: hey-ho, we have these tests in t/web/query-builder
# TODO: move everything about QB there
@@ -135,5 +130,3 @@ $query =~ s/\s+/ /g;
is ($query, "Subject LIKE 'aaa' AND Subject LIKE 'bbb'");
-
-1;
diff --git a/rt/t/web/case-sensitivity.t b/rt/t/web/case-sensitivity.t
new file mode 100644
index 000000000..276b7615a
--- /dev/null
+++ b/rt/t/web/case-sensitivity.t
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 18;
+
+my $q = RT::Test->load_or_create_queue( Name => 'General' );
+ok $q && $q->id, 'loaded or created queue';
+
+my ($root, $root_id);
+{
+ $root = RT::User->new( RT->SystemUser );
+ $root->Load('root');
+ ok $root_id = $root->id, 'found root';
+}
+
+my ($baseurl, $m) = RT::Test->started_ok;
+$m->login;
+
+# test users auto completer
+{
+ $m->get_ok('/Helpers/Autocomplete/Users?term=eNo');
+ require JSON;
+ is_deeply(
+ JSON::from_json( $m->content ),
+ [{"value" => "root\@localhost","label" => "Enoch Root"}]
+ );
+}
+
+# test ticket's People page
+{
+ my $ticket = RT::Test->create_ticket( Queue => $q->id );
+ ok $ticket && $ticket->id, "created ticket";
+
+ $m->goto_ticket( $ticket->id );
+ $m->follow_link_ok( {text => 'People'} );
+ $m->form_number(3);
+ $m->select( UserField => 'RealName' );
+ $m->field( UserString => 'eNo' );
+ $m->click('OnlySearchForPeople');
+
+ my $form = $m->form_number(3);
+ my $input = $form->find_input('Ticket-AddWatcher-Principal-'. $root->id );
+ ok $input, 'input is there';
+}
+
+# test users' admin UI
+{
+ $m->get_ok('/Admin/Users/');
+
+ $m->form_number(4);
+ $m->select( UserField => 'RealName' );
+ $m->field( UserString => 'eNo' );
+ $m->submit;
+
+ like $m->uri, qr{\QAdmin/Users/Modify.html?id=$root_id\E};
+}
+
+# create a cf for testing
+my $cf;
+{
+ $cf = RT::CustomField->new(RT->SystemUser);
+ my ($id,$msg) = $cf->Create(
+ Name => 'Test',
+ Type => 'Select',
+ MaxValues => '1',
+ Queue => $q->id,
+ );
+ ok($id,$msg);
+
+ ($id,$msg) = $cf->AddValue(Name => 'Enoch', Description => 'Root');
+ ok($id,$msg);
+}
+
+# test custom field values auto completer
+{
+ $m->get_ok('/Helpers/Autocomplete/CustomFieldValues?term=eNo&Object---CustomField-'. $cf->id .'-Value');
+ require JSON;
+ is_deeply(
+ JSON::from_json( $m->content ),
+ [{"value" => "Enoch","label" => "Enoch (Root)"}]
+ );
+}
+
diff --git a/rt/t/web/cf_access.t b/rt/t/web/cf_access.t
index 183597b4a..73b7765c1 100644
--- a/rt/t/web/cf_access.t
+++ b/rt/t/web/cf_access.t
@@ -1,23 +1,54 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 26;
-$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
+use RT::Test tests => 32;
my ($baseurl, $m) = RT::Test->started_ok;
-use constant ImageFile => $RT::MasonComponentRoot .'/NoAuth/images/bplogo.gif';
+use constant ImageFile => $RT::MasonComponentRoot .'/NoAuth/images/bpslogo.png';
use constant ImageFileContent => RT::Test->file_content(ImageFile);
ok $m->login, 'logged in';
-diag "Create a CF" if $ENV{'TEST_VERBOSE'};
+diag "Create a CF";
{
- $m->follow_link( text => 'Configuration' );
- $m->title_is(q/RT Administration/, 'admin screen');
- $m->follow_link( text => 'Custom Fields' );
- $m->title_is(q/Select a Custom Field/, 'admin-cf screen');
- $m->follow_link( text => 'Create' );
+ $m->follow_link( id => 'tools-config-custom-fields-create');
+
+ # Test form validation
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => {
+ TypeComposite => 'Image-0',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Name => '',
+ Description => 'img',
+ },
+ );
+ $m->text_contains('Invalid value for Name');
+
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => {
+ TypeComposite => 'Image-0',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Name => '0',
+ Description => 'img',
+ },
+ );
+ $m->text_contains('Invalid value for Name');
+
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => {
+ TypeComposite => 'Image-0',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Name => '1',
+ Description => 'img',
+ },
+ );
+ $m->text_contains('Invalid value for Name');
+
+ # The real submission
$m->submit_form(
form_name => "ModifyCustomField",
fields => {
@@ -27,19 +58,47 @@ diag "Create a CF" if $ENV{'TEST_VERBOSE'};
Description => 'img',
},
);
+ $m->text_contains('Object created');
+
+ # Validation on update
+ $m->form_name("ModifyCustomField");
+ $m->set_fields(
+ TypeComposite => 'Image-0',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Name => '',
+ Description => 'img',
+ );
+ $m->click('Update');
+ $m->text_contains('Illegal value for Name');
+ $m->form_name("ModifyCustomField");
+ $m->set_fields(
+ TypeComposite => 'Image-0',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Name => '0',
+ Description => 'img',
+ );
+ $m->click('Update');
+ $m->text_contains('Illegal value for Name');
+ $m->form_name("ModifyCustomField");
+ $m->set_fields(
+ TypeComposite => 'Image-0',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Name => '1',
+ Description => 'img',
+ );
+ $m->click('Update');
+ $m->text_contains('Illegal value for Name');
}
-diag "apply the CF to General queue" if $ENV{'TEST_VERBOSE'};
+diag "apply the CF to General queue";
my ( $cf, $cfid, $tid );
{
- $m->title_is(q/Created CustomField img/, 'admin-cf created');
- $m->follow_link( text => 'Queues' );
- $m->title_is(q/Admin queues/, 'admin-queues screen');
+ $m->title_is(q/Editing CustomField img/, 'admin-cf created');
+ $m->follow_link( id => 'tools-config-queues');
$m->follow_link( text => 'General' );
- $m->title_is(q/Editing Configuration for queue General/, 'admin-queue: general');
- $m->follow_link( text => 'Ticket Custom Fields' );
-
- $m->title_is(q/Edit Custom Fields for General/, 'admin-queue: general cfid');
+ $m->title_is(q/Configuration for queue General/, 'admin-queue: general');
+ $m->follow_link( id => 'page-ticket-custom-fields');
+ $m->title_is(q/Custom Fields for queue General/, 'admin-queue: general cfid');
$m->form_name('EditCustomFields');
# Sort by numeric IDs in names
@@ -52,7 +111,7 @@ my ( $cf, $cfid, $tid );
$m->tick( AddCustomField => $_ => 0 ) for @names; # ...and not any other. ;-)
$m->click('UpdateCFs');
- $m->content_like( qr/Object created/, 'TCF added to the queue' );
+ $m->content_contains('Object created', 'TCF added to the queue' );
}
my $tester = RT::Test->load_or_create_user( Name => 'tester', Password => '123456' );
@@ -61,17 +120,16 @@ RT::Test->set_rights(
Right => [qw(SeeQueue ShowTicket CreateTicket)],
},
);
-ok $m->login( $tester->Name, 123456), 'logged in';
+ok $m->login( $tester->Name, 123456, logout => 1), 'logged in';
diag "check that we have no the CF on the create"
- ." ticket page when user has no SeeCustomField right"
- if $ENV{'TEST_VERBOSE'};
+ ." ticket page when user has no SeeCustomField right";
{
$m->submit_form(
form_name => "CreateTicketInQueue",
fields => { Queue => 'General' },
);
- $m->content_unlike(qr/Upload multiple images/, 'has no upload image field');
+ $m->content_lacks('Upload multiple images', 'has no upload image field');
my $form = $m->form_name("TicketCreate");
my $upload_field = "Object-RT::Ticket--CustomField-$cfid-Upload";
@@ -83,9 +141,9 @@ diag "check that we have no the CF on the create"
);
$m->content_like(qr/Ticket \d+ created/, "a ticket is created succesfully");
- $m->content_unlike(qr/img:/, 'has no img field on the page');
+ $m->content_lacks('img:', 'has no img field on the page');
$m->follow_link( text => 'Custom Fields');
- $m->content_unlike(qr/Upload multiple images/, 'has no upload image field');
+ $m->content_lacks('Upload multiple images', 'has no upload image field');
}
RT::Test->set_rights(
@@ -95,14 +153,13 @@ RT::Test->set_rights(
);
diag "check that we have no the CF on the create"
- ." ticket page when user has no ModifyCustomField right"
- if $ENV{'TEST_VERBOSE'};
+ ." ticket page when user has no ModifyCustomField right";
{
$m->submit_form(
form_name => "CreateTicketInQueue",
fields => { Queue => 'General' },
);
- $m->content_unlike(qr/Upload multiple images/, 'has no upload image field');
+ $m->content_lacks('Upload multiple images', 'has no upload image field');
my $form = $m->form_name("TicketCreate");
my $upload_field = "Object-RT::Ticket--CustomField-$cfid-Upload";
@@ -115,9 +172,9 @@ diag "check that we have no the CF on the create"
$tid = $1 if $m->content =~ /Ticket (\d+) created/i;
ok $tid, "a ticket is created succesfully";
- $m->follow_link( text => 'Custom Fields' );
- $m->content_unlike(qr/Upload multiple images/, 'has no upload image field');
- $form = $m->form_number(3);
+ $m->follow_link( id => 'page-basics');
+ $m->content_lacks('Upload multiple images', 'has no upload image field');
+ $form = $m->form_name('TicketModify');
$upload_field = "Object-RT::Ticket-$tid-CustomField-$cfid-Upload";
ok !$form->find_input( $upload_field ), 'no form field on the page';
}
@@ -128,13 +185,13 @@ RT::Test->set_rights(
},
);
-diag "create a ticket with an image" if $ENV{'TEST_VERBOSE'};
+diag "create a ticket with an image";
{
$m->submit_form(
form_name => "CreateTicketInQueue",
fields => { Queue => 'General' },
);
- $m->content_like(qr/Upload multiple images/, 'has a upload image field');
+ $m->content_contains('Upload multiple images', 'has a upload image field');
$cf =~ /(\d+)$/ or die "Hey this is impossible dude";
my $upload_field = "Object-RT::Ticket--CustomField-$1-Upload";
@@ -153,14 +210,12 @@ diag "create a ticket with an image" if $ENV{'TEST_VERBOSE'};
$m->title_like(qr/testing img cf creation/, "its title is the Subject");
- $m->follow_link( text => 'bplogo.gif' );
+ $m->follow_link( text => 'bpslogo.png' );
$m->content_is(ImageFileContent, "it links to the uploaded image");
}
$m->get( $m->rt_base_url );
-$m->follow_link( text => 'Tickets' );
-$m->follow_link( text => 'New Query' );
-
+$m->follow_link( id => 'search-new');
$m->title_is(q/Query Builder/, 'Query building');
$m->submit_form(
form_name => "BuildQuery",
@@ -182,7 +237,7 @@ $m->click('AddCol');
$m->form_name('BuildQuery');
$m->click('DoSearch');
-$m->follow_link( text_regex => qr/bplogo\.gif/ );
+$m->follow_link( text_regex => qr/bpslogo\.png/ );
$m->content_is(ImageFileContent, "it links to the uploaded image");
__END__
diff --git a/rt/t/web/cf_date.t b/rt/t/web/cf_date.t
new file mode 100644
index 000000000..887aa4220
--- /dev/null
+++ b/rt/t/web/cf_date.t
@@ -0,0 +1,187 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 35;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+my $root = RT::User->new(RT->SystemUser);
+ok( $root->Load('root'), 'load root user' );
+
+my $cf_name = 'test cf date';
+
+my $cfid;
+diag "Create a CF";
+{
+ $m->follow_link( id => 'tools-config-custom-fields-create');
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => {
+ Name => $cf_name,
+ TypeComposite => 'Date-1',
+ LookupType => 'RT::Queue-RT::Ticket',
+ },
+ );
+ $m->content_contains('Object created', 'created CF sucessfully' );
+ $cfid = $m->form_name('ModifyCustomField')->value('id');
+ ok $cfid, "found id of the CF in the form, it's #$cfid";
+}
+
+diag "apply the CF to General queue";
+my $queue = RT::Test->load_or_create_queue( Name => 'General' );
+ok $queue && $queue->id, 'loaded or created queue';
+
+{
+ $m->follow_link( id => 'tools-config-queues-select');
+ $m->title_is( q/Admin queues/, 'admin-queues screen' );
+ $m->follow_link( text => 'General' );
+ $m->title_is( q/Configuration for queue General/,
+ 'admin-queue: general' );
+ $m->follow_link( text => 'Ticket Custom Fields' );
+ $m->title_is( q/Custom Fields for queue General/,
+ 'admin-queue: general cfid' );
+
+ $m->form_name('EditCustomFields');
+ $m->tick( "AddCustomField" => $cfid );
+ $m->click('UpdateCFs');
+
+ $m->content_contains('Object created', 'TCF added to the queue' );
+}
+
+diag 'check valid inputs with various timezones in ticket create page';
+{
+ my ( $ticket, $id );
+
+ $m->submit_form(
+ form_name => "CreateTicketInQueue",
+ fields => { Queue => 'General' },
+ );
+ $m->content_contains('Select date', 'has cf field' );
+
+ $m->submit_form(
+ form_name => "TicketCreate",
+ fields => {
+ Subject => 'test 2010-05-04',
+ Content => 'test',
+ "Object-RT::Ticket--CustomField-$cfid-Values" => '2010-05-04',
+ },
+ );
+ ok( ($id) = $m->content =~ /Ticket (\d+) created/, "created ticket $id" );
+
+ $ticket = RT::Ticket->new(RT->SystemUser);
+ $ticket->Load($id);
+ is( $ticket->CustomFieldValues($cfid)->First->Content,
+ '2010-05-04', 'date in db' );
+
+ $m->content_contains('test cf date:', 'has no cf date field on the page' );
+ $m->content_contains('Tue May 04 2010',
+ 'has cf date value on the page' );
+}
+
+diag 'check search build page';
+{
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+
+ $m->form_name('BuildQuery');
+ my ($cf_op) =
+ $m->find_all_inputs( type => 'option', name_regex => qr/test cf date/ );
+ is_deeply(
+ [ $cf_op->possible_values ],
+ [ '<', '=', '>' ],
+ 'right oprators'
+ );
+
+ my ($cf_field) =
+ $m->find_all_inputs( type => 'text', name_regex => qr/test cf date/ );
+ $m->submit_form(
+ fields => {
+ $cf_op->name => '=',
+ $cf_field->name => '2010-05-04'
+ },
+ button => 'DoSearch',
+ );
+
+ $m->content_contains( 'Found 1 ticket', 'Found 1 ticket' );
+ $m->content_contains( '2010-05-04', 'got the right ticket' );
+ $m->content_lacks( '2010-05-06', 'did not get the wrong ticket' );
+
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+ $m->form_name('BuildQuery');
+ $m->submit_form(
+ fields => {
+ $cf_op->name => '<',
+ $cf_field->name => '2010-05-05'
+ },
+ button => 'DoSearch',
+ );
+ $m->content_contains( 'Found 1 ticket', 'Found 1 ticket' );
+
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+ $m->form_name('BuildQuery');
+ $m->submit_form(
+ fields => {
+ $cf_op->name => '>',
+ $cf_field->name => '2010-05-03',
+ },
+ button => 'DoSearch',
+ );
+ $m->content_contains( 'Found 1 ticket', 'Found 1 ticket' );
+
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+ $m->form_name('BuildQuery');
+ $m->submit_form(
+ fields => {
+ $cf_op->name => '=',
+ $cf_field->name => '2010-05-05',
+ },
+ button => 'DoSearch',
+ );
+ $m->content_contains( 'Found 0 tickets', 'Found 0 tickets' );
+
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+ $m->form_name('BuildQuery');
+ $m->submit_form(
+ fields => {
+ $cf_op->name => '<',
+ $cf_field->name => '2010-05-03',
+ },
+ button => 'DoSearch',
+ );
+ $m->content_contains( 'Found 0 tickets', 'Found 0 tickets' );
+
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+ $m->form_name('BuildQuery');
+ $m->submit_form(
+ fields => {
+ $cf_op->name => '>',
+ $cf_field->name => '2010-05-05',
+ },
+ button => 'DoSearch',
+ );
+ $m->content_contains( 'Found 0 tickets', 'Found 0 tickets' );
+}
+
+diag 'check invalid inputs';
+{
+ $m->submit_form(
+ form_name => "CreateTicketInQueue",
+ fields => { Queue => 'General' },
+ );
+ my $form = $m->form_name("TicketCreate");
+
+ $m->submit_form(
+ form_name => "TicketCreate",
+ fields => {
+ Subject => 'test',
+ Content => 'test',
+ "Object-RT::Ticket--CustomField-$cfid-Values" => 'foodate',
+ },
+ );
+ $m->content_like( qr/Ticket \d+ created/,
+ "a ticket is created succesfully" );
+
+ $m->content_contains('test cf date:', 'has no cf date field on the page' );
+ $m->content_lacks('foodate', 'invalid dates not set' );
+}
diff --git a/rt/t/web/cf_datetime.t b/rt/t/web/cf_datetime.t
new file mode 100644
index 000000000..9781c5e2e
--- /dev/null
+++ b/rt/t/web/cf_datetime.t
@@ -0,0 +1,235 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 51;
+
+RT->Config->Set( 'Timezone' => 'EST5EDT' ); # -04:00
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+my $root = RT::User->new( RT->SystemUser );
+ok( $root->Load('root'), 'load root user' );
+
+my $cf_name = 'test cf datetime';
+
+my $why;
+
+if ( ( $ENV{RT_TEST_WEB_HANDLER} || '' ) =~ /^apache(\+mod_perl)?$/
+ && RT::Test::Apache->apache_mpm_type =~ /^(?:worker|event)$/ )
+{
+ $why =
+'localizing $ENV{TZ} does *not* work with mod_perl+mpm_event or mod_perl+mpm_worker';
+}
+
+my $cfid;
+diag "Create a CF";
+{
+ $m->follow_link( id => 'tools-config-custom-fields-create');
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => {
+ Name => $cf_name,
+ TypeComposite => 'DateTime-1',
+ LookupType => 'RT::Queue-RT::Ticket',
+ },
+ );
+ $m->content_contains('Object created', 'created CF sucessfully' );
+ $cfid = $m->form_name('ModifyCustomField')->value('id');
+ ok $cfid, "found id of the CF in the form, it's #$cfid";
+}
+
+diag "apply the CF to General queue";
+my $queue = RT::Test->load_or_create_queue( Name => 'General' );
+ok $queue && $queue->id, 'loaded or created queue';
+
+{
+ $m->follow_link( text => 'Queues' );
+ $m->title_is(q/Admin queues/, 'admin-queues screen');
+ $m->follow_link( text => 'General' );
+ $m->title_is(q/Configuration for queue General/, 'admin-queue: general');
+ $m->follow_link( text => 'Ticket Custom Fields' );
+ $m->title_is(q/Custom Fields for queue General/, 'admin-queue: general cfid');
+
+ $m->form_name('EditCustomFields');
+ $m->tick( "AddCustomField" => $cfid );
+ $m->click('UpdateCFs');
+
+ $m->content_contains('Object created', 'TCF added to the queue' );
+}
+
+diag 'check valid inputs with various timezones in ticket create page';
+{
+ my ( $ticket, $id );
+
+ $m->submit_form(
+ form_name => "CreateTicketInQueue",
+ fields => { Queue => 'General' },
+ );
+ $m->content_contains('Select datetime', 'has cf field');
+
+ $m->submit_form(
+ form_name => "TicketCreate",
+ fields => {
+ Subject => 'test 2010-05-04 13:00:01',
+ Content => 'test',
+ "Object-RT::Ticket--CustomField-$cfid-Values" => '2010-05-04 13:00:01',
+ },
+ );
+ ok( ($id) = $m->content =~ /Ticket (\d+) created/,
+ "created ticket $id" );
+
+ $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load($id);
+ TODO: {
+ local $TODO = $why;
+ is(
+ $ticket->CustomFieldValues($cfid)->First->Content,
+ '2010-05-04 17:00:01',
+ 'date in db is in UTC'
+ );
+ }
+
+ $m->content_contains('test cf datetime:', 'has cf datetime field on the page');
+ $m->content_contains('Tue May 04 13:00:01 2010', 'has cf datetime value on the page');
+
+ $root->SetTimezone( 'Asia/Shanghai' );
+ # interesting that $m->reload doesn't work
+ $m->get_ok( $m->uri );
+
+ TODO: {
+ local $TODO = $why;
+ $m->content_contains( 'Wed May 05 01:00:01 2010',
+ 'cf datetime value respects user timezone' );
+ }
+
+ $m->submit_form(
+ form_name => "CreateTicketInQueue",
+ fields => { Queue => 'General' },
+ );
+ $m->submit_form(
+ form_name => "TicketCreate",
+ fields => {
+ Subject => 'test 2010-05-06 07:00:01',
+ Content => 'test',
+ "Object-RT::Ticket--CustomField-$cfid-Values" => '2010-05-06 07:00:01',
+ },
+ );
+ ok( ($id) = $m->content =~ /Ticket (\d+) created/,
+ "created ticket $id" );
+ $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load($id);
+ TODO: {
+ local $TODO = $why;
+ is(
+ $ticket->CustomFieldValues($cfid)->First->Content,
+ '2010-05-05 23:00:01',
+ 'date in db is in UTC'
+ );
+ }
+
+ $m->content_contains('test cf datetime:', 'has cf datetime field on the page');
+ $m->content_contains( 'Thu May 06 07:00:01 2010',
+ 'cf datetime input respects user timezone' );
+ $root->SetTimezone( 'EST5EDT' ); # back to -04:00
+ $m->get_ok( $m->uri );
+
+ TODO: {
+ local $TODO = $why;
+ $m->content_contains( 'Wed May 05 19:00:01 2010',
+ 'cf datetime value respects user timezone' );
+ }
+}
+
+
+diag 'check search build page';
+{
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+
+ $m->form_name('BuildQuery');
+ my ($cf_op) =
+ $m->find_all_inputs( type => 'option', name_regex => qr/test cf datetime/ );
+ is_deeply(
+ [ $cf_op->possible_values ],
+ [ '<', '=', '>' ],
+ 'right oprators'
+ );
+
+ my ($cf_field) =
+ $m->find_all_inputs( type => 'text', name_regex => qr/test cf datetime/ );
+
+ is_results_number( { $cf_op->name => '=', $cf_field->name => '2010-05-04', }, 1 );
+ $m->content_contains( '2010-05-04', 'got the right ticket' );
+ $m->content_lacks( '2010-05-06', 'did not get the wrong ticket' );
+
+ my $shanghai = RT::Test->load_or_create_user(
+ Name => 'shanghai',
+ Password => 'password',
+ Timezone => 'Asia/Shanghai',
+ );
+ ok( $shanghai->PrincipalObj->GrantRight(
+ Right => 'SuperUser',
+ Object => $RT::System,
+ ));
+ $m->login( 'shanghai', 'password', logout => 1 );
+
+ is_results_number( { $cf_op->name => '<', $cf_field->name => '2010-05-07', }, 2 );
+ is_results_number( { $cf_op->name => '>', $cf_field->name => '2010-05-04', }, 2 );
+
+ TODO: {
+ local $TODO = $why;
+ is_results_number( { $cf_op->name => '=', $cf_field->name => '2010-05-05', }, 1 );
+ is_results_number( { $cf_op->name => '=', $cf_field->name => '2010-05-05 01:00:01', }, 1 );
+ }
+
+ is_results_number(
+ { $cf_op->name => '=', $cf_field->name => '2010-05-05 02:00:01', }, 0 );
+
+ is_results_number( { $cf_op->name => '=', $cf_field->name => '2010-05-06', }, 1 );
+ is_results_number( { $cf_op->name => '=', $cf_field->name => '2010-05-06 07:00:01', }, 1 );
+ is_results_number( { $cf_op->name => '=', $cf_field->name => '2010-05-06 08:00:01', }, 0 );
+}
+
+diag 'check invalid inputs';
+{
+ $m->submit_form(
+ form_name => "CreateTicketInQueue",
+ fields => { Queue => 'General' },
+ );
+ my $form = $m->form_name("TicketCreate");
+
+ $m->submit_form(
+ form_name => "TicketCreate",
+ fields => {
+ Subject => 'test',
+ Content => 'test',
+ "Object-RT::Ticket--CustomField-$cfid-Values" => 'foodate',
+ },
+ );
+ $m->content_like(qr/Ticket \d+ created/, "a ticket is created succesfully");
+
+ $m->content_contains('test cf datetime:', 'has cf datetime field on the page');
+ $m->content_lacks('foodate', 'invalid dates not set');
+}
+
+sub is_results_number {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my $fields = shift;
+ my $number = shift;
+ my $operator = shift;
+ my $value = shift;
+ {
+ local $TODO;
+ $m->get_ok( $baseurl . '/Search/Build.html?Query=Queue=1' );
+ }
+ $m->form_name('BuildQuery');
+ $m->submit_form(
+ fields => $fields,
+ button => 'DoSearch',
+ );
+ $m->content_contains( "Found $number ticket", "Found $number ticket" );
+}
+
+# to make $m->DESTROY happy
+undef $m;
+
diff --git a/rt/t/web/cf_onqueue.t b/rt/t/web/cf_onqueue.t
index bed4dd188..422eeff60 100644
--- a/rt/t/web/cf_onqueue.t
+++ b/rt/t/web/cf_onqueue.t
@@ -6,13 +6,9 @@ my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in';
-diag "Create a queue CF" if $ENV{'TEST_VERBOSE'};
+diag "Create a queue CF";
{
- $m->follow_link( text => 'Configuration' );
- $m->title_is(q/RT Administration/, 'admin screen');
- $m->follow_link( text => 'Custom Fields' );
- $m->title_is(q/Select a Custom Field/, 'admin-cf screen');
- $m->follow_link( text => 'Create' );
+ $m->follow_link( id => 'tools-config-custom-fields-create');
$m->submit_form(
form_name => "ModifyCustomField",
fields => {
@@ -22,10 +18,10 @@ diag "Create a queue CF" if $ENV{'TEST_VERBOSE'};
Description => 'QueueCFTest',
},
);
- $m->content_like( qr/Object created/, 'CF QueueCFTest created' );
+ $m->content_contains('Object created', 'CF QueueCFTest created' );
}
-diag "Apply the new CF globally" if $ENV{'TEST_VERBOSE'};
+diag "Apply the new CF globally";
{
$m->follow_link( text => 'Global' );
$m->title_is(q!Admin/Global configuration!, 'global configuration screen');
@@ -33,22 +29,22 @@ diag "Apply the new CF globally" if $ENV{'TEST_VERBOSE'};
$m->title_is(q/Global custom field configuration/, 'global custom field configuration screen');
$m->follow_link( url => 'Queues.html' );
$m->title_is(q/Edit Custom Fields for all queues/, 'global custom field for all queues configuration screen');
- $m->content_like( qr/QueueCFTest/, 'CF QueueCFTest displayed on page' );
+ $m->content_contains('QueueCFTest', 'CF QueueCFTest displayed on page' );
$m->form_name('EditCustomFields');
$m->tick( AddCustomField => 1 );
$m->click('UpdateCFs');
- $m->content_like( qr/Object created/, 'CF QueueCFTest enabled globally' );
+ $m->content_contains('Object created', 'CF QueueCFTest enabled globally' );
}
-diag "Edit the CF value for default queue" if $ENV{'TEST_VERBOSE'};
+diag "Edit the CF value for default queue";
{
$m->follow_link( url => '/Admin/Queues/' );
$m->title_is(q/Admin queues/, 'queues configuration screen');
$m->follow_link( text => "1" );
- $m->title_is(q/Editing Configuration for queue General/, 'default queue configuration screen');
- $m->content_like( qr/QueueCFTest/, 'CF QueueCFTest displayed on default queue' );
+ $m->title_is(q/Configuration for queue General/, 'default queue configuration screen');
+ $m->content_contains('QueueCFTest', 'CF QueueCFTest displayed on default queue' );
$m->submit_form(
form_number => 3,
# The following doesn't want to works :(
@@ -57,7 +53,7 @@ diag "Edit the CF value for default queue" if $ENV{'TEST_VERBOSE'};
'Object-RT::Queue-1-CustomField-1-Value' => 'QueueCFTest content',
},
);
- $m->content_like( qr/QueueCFTest QueueCFTest content added/, 'Content filed in CF QueueCFTest for default queue' );
+ $m->content_contains('QueueCFTest QueueCFTest content added', 'Content filed in CF QueueCFTest for default queue' );
}
diff --git a/rt/t/web/cf_render_type.t b/rt/t/web/cf_render_type.t
new file mode 100644
index 000000000..8d8efa897
--- /dev/null
+++ b/rt/t/web/cf_render_type.t
@@ -0,0 +1,50 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 8;
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+
+my $cf_name = 'test render type';
+
+my $cfid;
+diag "Create a CF";
+{
+ $m->follow_link( id => 'tools-config-custom-fields-create');
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => {
+ Name => $cf_name,
+ TypeComposite => 'Freeform-1',
+ LookupType => 'RT::Queue-RT::Ticket',
+ },
+ );
+ $m->content_contains('Object created', 'created Freeform-1' );
+ $cfid = $m->form_name('ModifyCustomField')->value('id');
+ ok $cfid, "found id of the CF in the form, it's #$cfid";
+}
+
+diag "change to Select type";
+{
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ fields => { TypeComposite => 'Select-1', },
+ button => 'Update',
+ );
+ $m->content_contains(
+ "Type changed from &#39;Enter one value&#39; to &#39;Select one value&#39;",
+ 'changed to Select-1' );
+}
+
+diag "let's save it again";
+{
+ $m->submit_form(
+ form_name => "ModifyCustomField",
+ button => 'Update',
+ );
+ $m->content_lacks( "Render Type changed from &#39;1&#39; to &#39;Select box&#39;",
+ 'no buggy RenderType change msg' );
+}
+
+
diff --git a/rt/t/web/cf_select_one.t b/rt/t/web/cf_select_one.t
index 26c1fcf65..15fe416b4 100644
--- a/rt/t/web/cf_select_one.t
+++ b/rt/t/web/cf_select_one.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 46;
+use RT::Test tests => 45;
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in as root';
@@ -11,13 +11,9 @@ ok $m->login, 'logged in as root';
my $cf_name = 'test select one value';
my $cfid;
-diag "Create a CF" if $ENV{'TEST_VERBOSE'};
+diag "Create a CF";
{
- $m->follow_link( text => 'Configuration' );
- $m->title_is(q/RT Administration/, 'admin screen');
- $m->follow_link( text => 'Custom Fields' );
- $m->title_is(q/Select a Custom Field/, 'admin-cf screen');
- $m->follow_link( text => 'Create' );
+ $m->follow_link( id => 'tools-config-custom-fields-create');
$m->submit_form(
form_name => "ModifyCustomField",
fields => {
@@ -26,12 +22,12 @@ diag "Create a CF" if $ENV{'TEST_VERBOSE'};
LookupType => 'RT::Queue-RT::Ticket',
},
);
- $m->content_like( qr/Object created/, 'created CF sucessfully' );
+ $m->content_contains('Object created', 'created CF sucessfully' );
$cfid = $m->form_name('ModifyCustomField')->value('id');
ok $cfid, "found id of the CF in the form, it's #$cfid";
}
-diag "add 'qwe', 'ASD', '0' and ' foo ' as values to the CF" if $ENV{'TEST_VERBOSE'};
+diag "add 'qwe', 'ASD', '0' and ' foo ' as values to the CF";
{
foreach my $value(qw(qwe ASD 0), 'foo ') {
$m->submit_form(
@@ -41,38 +37,36 @@ diag "add 'qwe', 'ASD', '0' and ' foo ' as values to the CF" if $ENV{'TEST_VERBO
},
button => 'Update',
);
- $m->content_like( qr/Object created/, 'added a value to the CF' ); # or diag $m->content;
+ $m->content_contains('Object created', 'added a value to the CF' ); # or diag $m->content;
my $v = $value;
$v =~ s/^\s+$//;
$v =~ s/\s+$//;
- $m->content_like( qr/value="$v"/, 'the added value is right' );
+ $m->content_contains("value=\"$v\"", 'the added value is right' );
}
}
my $queue = RT::Test->load_or_create_queue( Name => 'General' );
ok $queue && $queue->id, 'loaded or created queue';
-diag "apply the CF to General queue" if $ENV{'TEST_VERBOSE'};
+diag "apply the CF to General queue";
{
- $m->follow_link( text => 'Queues' );
- $m->title_is(q/Admin queues/, 'admin-queues screen');
+ $m->follow_link( id => 'tools-config-queues');
$m->follow_link( text => 'General' );
- $m->title_is(q/Editing Configuration for queue General/, 'admin-queue: general');
- $m->follow_link( text => 'Ticket Custom Fields' );
- $m->title_is(q/Edit Custom Fields for General/, 'admin-queue: general cfid');
+ $m->title_is(q/Configuration for queue General/, 'admin-queue: general');
+ $m->follow_link( id => 'page-ticket-custom-fields');
+ $m->title_is(q/Custom Fields for queue General/, 'admin-queue: general cfid');
$m->form_name('EditCustomFields');
$m->tick( "AddCustomField" => $cfid );
$m->click('UpdateCFs');
- $m->content_like( qr/Object created/, 'TCF added to the queue' );
+ $m->content_contains('Object created', 'TCF added to the queue' );
}
my $tid;
-diag "create a ticket using API with 'asd'(not 'ASD') as value of the CF"
- if $ENV{'TEST_VERBOSE'};
+diag "create a ticket using API with 'asd'(not 'ASD') as value of the CF";
{
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
my ($txnid, $msg);
($tid, $txnid, $msg) = $ticket->Create(
Subject => 'test',
@@ -80,7 +74,7 @@ diag "create a ticket using API with 'asd'(not 'ASD') as value of the CF"
"CustomField-$cfid" => 'asd',
);
ok $tid, "created ticket";
- diag $msg if $msg && $ENV{'TEST_VERBOSE'};
+ diag $msg if $msg;
# we use lc as we really don't care about case
# so if later we'll add canonicalization of value
@@ -89,72 +83,69 @@ diag "create a ticket using API with 'asd'(not 'ASD') as value of the CF"
'asd', 'assigned value of the CF';
}
-diag "check that values of the CF are case insensetive(asd vs. ASD)"
- if $ENV{'TEST_VERBOSE'};
+diag "check that values of the CF are case insensetive(asd vs. ASD)";
{
ok $m->goto_ticket( $tid ), "opened ticket's page";
- $m->follow_link( text => 'Custom Fields' );
+ $m->follow_link( id => 'page-basics');
$m->title_like(qr/Modify ticket/i, 'modify ticket');
- $m->content_like(qr/\Q$cf_name/, 'CF on the page');
+ $m->content_contains($cf_name, 'CF on the page');
- my $value = $m->form_number(3)->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
+ my $value = $m->form_name('TicketModify')->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
is lc $value, 'asd', 'correct value is selected';
$m->submit;
$m->content_unlike(qr/\Q$cf_name\E.*?changed/mi, 'field is not changed');
- $value = $m->form_number(3)->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
+ $value = $m->form_name('TicketModify')->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
is lc $value, 'asd', 'the same value is still selected';
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $tid );
ok $ticket->id, 'loaded the ticket';
is lc $ticket->FirstCustomFieldValue( $cf_name ),
'asd', 'value is still the same';
}
-diag "check that 0 is ok value of the CF"
- if $ENV{'TEST_VERBOSE'};
+diag "check that 0 is ok value of the CF";
{
ok $m->goto_ticket( $tid ), "opened ticket's page";
- $m->follow_link( text => 'Custom Fields' );
+ $m->follow_link( id => 'page-basics');
$m->title_like(qr/Modify ticket/i, 'modify ticket');
- $m->content_like(qr/\Q$cf_name/, 'CF on the page');
+ $m->content_contains($cf_name, 'CF on the page');
- my $value = $m->form_number(3)->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
+ my $value = $m->form_name('TicketModify')->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
is lc $value, 'asd', 'correct value is selected';
$m->select("Object-RT::Ticket-$tid-CustomField-$cfid-Values" => 0 );
$m->submit;
$m->content_like(qr/\Q$cf_name\E.*?changed/mi, 'field is changed');
- $m->content_unlike(qr/0 is no longer a value for custom field/mi, 'no bad message in results');
+ $m->content_lacks('0 is no longer a value for custom field', 'no bad message in results');
- $value = $m->form_number(3)->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
+ $value = $m->form_name('TicketModify')->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
is lc $value, '0', 'new value is selected';
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $tid );
ok $ticket->id, 'loaded the ticket';
is lc $ticket->FirstCustomFieldValue( $cf_name ),
'0', 'API returns correct value';
}
-diag "check that we can set empty value when the current is 0"
- if $ENV{'TEST_VERBOSE'};
+diag "check that we can set empty value when the current is 0";
{
ok $m->goto_ticket( $tid ), "opened ticket's page";
- $m->follow_link( text => 'Custom Fields' );
+ $m->follow_link( id => 'page-basics');
$m->title_like(qr/Modify ticket/i, 'modify ticket');
- $m->content_like(qr/\Q$cf_name/, 'CF on the page');
+ $m->content_contains($cf_name, 'CF on the page');
- my $value = $m->form_number(3)->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
+ my $value = $m->form_name('TicketModify')->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
is lc $value, '0', 'correct value is selected';
$m->select("Object-RT::Ticket-$tid-CustomField-$cfid-Values" => '' );
$m->submit;
- $m->content_like(qr/0 is no longer a value for custom field/mi, '0 is no longer a value');
+ $m->content_contains('0 is no longer a value for custom field', '0 is no longer a value');
- $value = $m->form_number(3)->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
+ $value = $m->form_name('TicketModify')->value("Object-RT::Ticket-$tid-CustomField-$cfid-Values");
is $value, '', '(no value) is selected';
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $tid );
ok $ticket->id, 'loaded the ticket';
is $ticket->FirstCustomFieldValue( $cf_name ),
diff --git a/rt/t/web/charting.t b/rt/t/web/charting.t
index 7c11f9c92..32d95d99b 100644
--- a/rt/t/web/charting.t
+++ b/rt/t/web/charting.t
@@ -1,7 +1,16 @@
use strict;
use warnings;
-use RT::Test no_plan => 1;
+BEGIN {
+ require RT::Test;
+
+ if (eval { require GD; 1 }) {
+ RT::Test->import(plan => 'no_plan');
+ }
+ else {
+ RT::Test->import(skip_all => 'GD required.');
+ }
+}
for my $n (1..7) {
my $ticket = RT::Ticket->new( RT->SystemUser );
@@ -26,8 +35,8 @@ ok( $m->login, "Logged in" );
# Test that defaults work
$m->get_ok( "/Search/Chart.html?Query=id>0" );
-$m->content_like(qr{<th[^>]*>\s*Queue\s*</th>\s*<th[^>]*>\s*Tickets\s*</th>}, "Grouped by queue");
-$m->content_like(qr{General</a>\s*</td>\s*<td[^>]*>\s*7}, "Found results in table");
+$m->content_like(qr{<th[^>]*>Queue\s*</th>\s*<th[^>]*>Tickets\s*</th>}, "Grouped by queue");
+$m->content_like(qr{General</a>\s*</td>\s*<td[^>]*>\s*<a[^>]*>7</a>}, "Found results in table");
$m->content_like(qr{<img src="/Search/Chart\?}, "Found image");
$m->get_ok( "/Search/Chart?Query=id>0" );
@@ -37,8 +46,8 @@ ok( length($m->content), "Has content" );
# Group by Queue
$m->get_ok( "/Search/Chart.html?Query=id>0&PrimaryGroupBy=Queue" );
-$m->content_like(qr{<th[^>]*>\s*Queue\s*</th>\s*<th[^>]*>\s*Tickets\s*</th>}, "Grouped by queue");
-$m->content_like(qr{General</a>\s*</td>\s*<td[^>]*>\s*7}, "Found results in table");
+$m->content_like(qr{<th[^>]*>Queue\s*</th>\s*<th[^>]*>Tickets\s*</th>}, "Grouped by queue");
+$m->content_like(qr{General</a>\s*</td>\s*<td[^>]*>\s*<a[^>]*>7</a>}, "Found results in table");
$m->content_like(qr{<img src="/Search/Chart\?}, "Found image");
$m->get_ok( "/Search/Chart?Query=id>0&PrimaryGroupBy=Queue" );
@@ -48,9 +57,9 @@ ok( length($m->content), "Has content" );
# Group by Requestor email
$m->get_ok( "/Search/Chart.html?Query=id>0&PrimaryGroupBy=Requestor.EmailAddress" );
-$m->content_like(qr{<th[^>]*>\s*Requestor\.EmailAddress\s*</th>\s*<th[^>]*>\s*Tickets\s*</th>},
+$m->content_like(qr{<th[^>]*>Requestor\.EmailAddress\s*</th>\s*<th[^>]*>Tickets\s*</th>},
"Grouped by requestor");
-$m->content_like(qr{root0\@localhost</a>\s*</td>\s*<td[^>]*>\s*3}, "Found results in table");
+$m->content_like(qr{root0\@localhost</a>\s*</td>\s*<td[^>]*>\s*<a[^>]*>3</a>}, "Found results in table");
$m->content_like(qr{<img src="/Search/Chart\?}, "Found image");
$m->get_ok( "/Search/Chart?Query=id>0&PrimaryGroupBy=Requestor.Email" );
@@ -60,7 +69,7 @@ ok( length($m->content), "Has content" );
# Group by Requestor phone -- which is bogus, and falls back to queue
$m->get_ok( "/Search/Chart.html?Query=id>0&PrimaryGroupBy=Requestor.Phone" );
-$m->content_like(qr{General</a>\s*</td>\s*<td[^>]*>\s*7},
+$m->content_like(qr{General</a>\s*</td>\s*<td[^>]*>\s*<a[^>]*>7</a>},
"Found queue results in table, as a default");
$m->content_like(qr{<img src="/Search/Chart\?}, "Found image");
diff --git a/rt/t/web/class_create.t b/rt/t/web/class_create.t
new file mode 100644
index 000000000..cec41a8aa
--- /dev/null
+++ b/rt/t/web/class_create.t
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 13;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+my $root = RT::User->new(RT->SystemUser);
+ok( $root->Load('root'), 'load root user' );
+
+my $class_name = 'test class';
+
+my $class_id;
+diag "Create a class";
+{
+ $m->follow_link( id => 'tools-config-articles-classes-create');
+
+ # Test class form validation
+ $m->submit_form(
+ form_name => 'ModifyClass',
+ fields => {
+ Name => '',
+ },
+ );
+ $m->text_contains('Invalid value for Name');
+ $m->submit_form(
+ form_name => 'ModifyClass',
+ fields => {
+ Name => '0',
+ },
+ );
+ $m->text_contains('Invalid value for Name');
+ $m->submit_form(
+ form_name => 'ModifyClass',
+ fields => {
+ Name => '1',
+ },
+ );
+ $m->text_contains('Invalid value for Name');
+ $m->submit_form(
+ form_name => 'ModifyClass',
+ fields => {
+ Name => $class_name,
+ },
+ );
+ $m->content_contains('Object created', 'created class sucessfully' );
+
+ # Test validation on updae
+ $m->form_name('ModifyClass');
+ $m->set_fields(
+ Name => '',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->text_contains('Illegal value for Name');
+
+ $m->form_name('ModifyClass');
+ $m->set_fields(
+ Name => '0',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->text_contains('Illegal value for Name');
+
+ $m->form_name('ModifyClass');
+ $m->set_fields(
+ Name => '1',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->text_contains('Illegal value for Name');
+
+ $class_id = $m->form_name('ModifyClass')->value('id');
+ ok $class_id, "found id of the class in the form, it's #$class_id";
+}
+
diff --git a/rt/t/web/clickjacking-preventions.t b/rt/t/web/clickjacking-preventions.t
new file mode 100644
index 000000000..dde82952b
--- /dev/null
+++ b/rt/t/web/clickjacking-preventions.t
@@ -0,0 +1,30 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test tests => 11;
+
+my ($url, $m);
+
+# Enabled by default
+{
+ ok(RT->Config->Get('Framebusting'), "Framebusting enabled by default");
+
+ ($url, $m) = RT::Test->started_ok;
+ $m->get_ok($url);
+ $m->content_contains('if (window.top !== window.self) {', "Found the framekiller javascript");
+ is $m->response->header('X-Frame-Options'), 'DENY', "X-Frame-Options is set to DENY";
+
+ RT::Test->stop_server;
+}
+
+# Disabled
+{
+ RT->Config->Set('Framebusting', 0);
+
+ ($url, $m) = RT::Test->started_ok;
+ $m->get_ok($url);
+ $m->content_lacks('if (window.top !== window.self) {', "Didn't find the framekiller javascript");
+ is $m->response->header('X-Frame-Options'), undef, "X-Frame-Options is not present";
+}
+
diff --git a/rt/t/web/command_line.t b/rt/t/web/command_line.t
index 884b064e6..1fed8e69e 100644
--- a/rt/t/web/command_line.t
+++ b/rt/t/web/command_line.t
@@ -3,7 +3,7 @@
use strict;
use File::Spec ();
use Test::Expect;
-use RT::Test tests => 295;
+use RT::Test tests => 303, actual_server => 1;
my ($baseurl, $m) = RT::Test->started_ok;
use RT::User;
@@ -11,7 +11,6 @@ use RT::Queue;
my $rt_tool_path = "$RT::BinPath/rt";
-# {{{ test configuration options
# config directives:
# (in $CWD/.rtrc)
@@ -38,14 +37,13 @@ $ENV{'RTSERVER'} =RT->Config->Get('WebBaseURL') ;
$ENV{'RTDEBUG'} = '1';
# - RTCONFIG Specifies a name other than ".rtrc" for the
# configuration file.
+$ENV{'RTCONFIG'} = '/dev/null';
#
# - RTQUERY Default RT Query for rt list
# - RTORDERBY Default order for rt list
-# }}}
-# {{{ test ticket manipulation
# create a ticket
expect_run(
@@ -54,6 +52,7 @@ expect_run(
quit => 'quit',
);
expect_send(q{create -t ticket set subject='new ticket' add cc=foo@example.com}, "Creating a ticket...");
+
expect_like(qr/Ticket \d+ created/, "Created the ticket");
expect_handle->before() =~ /Ticket (\d+) created/;
my $ticket_id = $1;
@@ -65,7 +64,6 @@ expect_like(qr/Ticket \d+ created/, "Created the ticket");
expect_send(q{rt create -t ticket set subject='rt ticket'}, "Creating a ticket with 'rt create'...");
expect_like(qr/Ticket \d+ created/, "Created the ticket");
-# {{{ test queue manipulation
# creating queues
expect_send("create -t queue set Name='NewQueue$$'", 'Creating a queue...');
@@ -85,19 +83,18 @@ TODO: {
expect_like(qr/$queue_id: EditedQueue$$/, 'Found the queue');
}
-# }}}
# Set up a custom field for editing tests
-my $cf = RT::CustomField->new($RT::SystemUser);
+my $cf = RT::CustomField->new(RT->SystemUser);
my ($val,$msg) = $cf->Create(Name => 'MyCF'.$$, Type => 'FreeformSingle', Queue => $queue_id);
ok($val,$msg);
-my $othercf = RT::CustomField->new($RT::SystemUser);
+my $othercf = RT::CustomField->new(RT->SystemUser);
($val,$msg) = $othercf->Create(Name => 'My CF'.$$, Type => 'FreeformSingle', Queue => $queue_id);
ok($val,$msg);
-my $multiple_cf = RT::CustomField->new($RT::SystemUser);
+my $multiple_cf = RT::CustomField->new(RT->SystemUser);
($val,$msg) = $multiple_cf->Create(Name => 'MultipleCF'.$$, Type =>
'FreeformMultiple', Queue => $queue_id);
ok($val,$msg);
@@ -118,7 +115,7 @@ ok($val,$msg);
# text attachment
check_attachment($test_email);
# binary attachment
- check_attachment($RT::MasonComponentRoot.'/NoAuth/images/bplogo.gif');
+ check_attachment($RT::MasonComponentRoot.'/NoAuth/images/bpslogo.png');
# change a ticket's Owner
expect_send("edit ticket/$ticket_id set owner=root", 'Changing owner...');
@@ -130,6 +127,11 @@ expect_send("edit ticket/$ticket_id set requestors=foo\@example.com", 'Changing
expect_like(qr/Ticket $ticket_id updated/, 'Changed Requestor');
expect_send("show ticket/$ticket_id -f requestors", 'Verifying change...');
expect_like(qr/Requestors: foo\@example.com/, 'Verified change');
+# set multiple Requestors
+expect_send("edit ticket/$ticket_id set requestors=foo\@example.com,bar\@example.com", 'Changing Requestor...');
+expect_like(qr/Ticket $ticket_id updated/, 'Changed Requestor');
+expect_send("show ticket/$ticket_id -f requestors", 'Verifying change...');
+expect_like(qr/Requestors: bar\@example.com, foo\@example.com/, 'Verified change');
# change a ticket's Cc
expect_send("edit ticket/$ticket_id set cc=bar\@example.com", 'Changing Cc...');
expect_like(qr/Ticket $ticket_id updated/, 'Changed Cc');
@@ -269,17 +271,19 @@ expect_send("show ticket/$ticket_id -f status", 'Verifying change...');
expect_like(qr/Status: resolved/, 'Verified change');
# try to set status to an illegal value
expect_send("edit ticket/$ticket_id set status=quux", 'Changing status to an illegal value...');
-expect_like(qr/illegal value/i, 'Errored out');
+expect_like(qr/isn't a valid status/i, 'Errored out');
expect_send("show ticket/$ticket_id -f status", 'Verifying lack of change...');
expect_like(qr/Status: resolved/, 'Verified change');
-# }}}
-# {{{ display
# show ticket list
expect_send("ls -s -t ticket -o +id \"Status='resolved'\"", 'Listing resolved tickets...');
expect_like(qr/$ticket_id: new ticket/, 'Found our ticket');
+
+expect_send("ls -s -t ticket -f Requestors $ticket_id", 'getting Requestors');
+expect_like(qr/$ticket_id\s+bar\@example.com,\s+foo\@example.com/, 'got Requestors');
+
# show ticket list verbosely
expect_send("ls -l -t ticket -o +id \"Status='resolved'\"", 'Listing resolved tickets verbosely...');
expect_like(qr/id: ticket\/$ticket_id/, 'Found our ticket');
@@ -307,9 +311,7 @@ ok($attachment_id, "Got attachment id=$attachment_id $attachment_type");
expect_send("show -s ticket/$ticket_id/attachments/$attachment_id", "Showing attachment $attachment_id...");
expect_like(qr/ContentType: $attachment_type/, 'Got the attachment');
-# }}}
-# {{{ test user manipulation
# creating users
expect_send("create -t user set Name='NewUser$$' EmailAddress='fbar$$\@example.com'", 'Creating a user...');
@@ -329,9 +331,7 @@ TODO: {
expect_like(qr/$user_id: EditedUser$$/, 'Found the user');
}
-# }}}
-# {{{ test group manipulation
TODO: {
todo_skip "Group manipulation doesn't work right now", 8;
@@ -354,11 +354,9 @@ TODO: {
}
}
-# }}}
TODO: {
todo_skip "Custom field manipulation not yet implemented", 8;
-# {{{ test custom field manipulation
# creating custom fields
expect_send("create -t custom_field set Name='NewCF$$'", 'Creating a custom field...');
@@ -379,9 +377,7 @@ TODO: {
}
}
-# }}}
-# {{{ test merging tickets
expect_send("create -t ticket set subject='CLIMergeTest1-$$'", 'Creating first ticket to merge...');
expect_like(qr/Ticket \d+ created/, 'Created first ticket');
expect_handle->before() =~ /Ticket (\d+) created/;
@@ -395,30 +391,23 @@ ok($merge_ticket_B, "Got second ticket to merge id=$merge_ticket_B");
expect_send("merge $merge_ticket_B $merge_ticket_A", 'Merging the tickets...');
expect_like(qr/Merge completed/, 'Merged the tickets');
-TODO: {
- local $TODO = "we generate a spurious warning here";
- $m->no_warnings_ok;
-}
-
expect_send("show ticket/$merge_ticket_A/history", 'Checking merge on first ticket');
expect_like(qr/Merged into ticket #$merge_ticket_A by root/, 'Merge recorded in first ticket');
expect_send("show ticket/$merge_ticket_B/history", 'Checking merge on second ticket');
expect_like(qr/Merged into ticket #$merge_ticket_A by root/, 'Merge recorded in second ticket');
-# }}}
-# {{{ test taking/stealing tickets
{
# create a user; give them privileges to take and steal
### TODO: implement 'grant' in the CLI tool; use that here instead.
### this breaks the abstraction barrier, like, a lot.
- my $steal_user = RT::User->new($RT::SystemUser);
+ my $steal_user = RT::User->new(RT->SystemUser);
my ($steal_user_id, $msg) = $steal_user->Create( Name => "fooser$$",
EmailAddress => "fooser$$\@localhost",
Privileged => 1,
Password => 'foobar',
);
ok($steal_user_id, "Created the user? $msg");
- my $steal_queue = RT::Queue->new($RT::SystemUser);
+ my $steal_queue = RT::Queue->new(RT->SystemUser);
my $steal_queue_id;
($steal_queue_id, $msg) = $steal_queue->Create( Name => "Steal$$" );
ok($steal_queue_id, "Got the queue? $msg");
@@ -476,9 +465,7 @@ expect_like(qr/Merged into ticket #$merge_ticket_A by root/, 'Merge recorded in
expect_send("steal $steal_ticket_id", 'root steals the ticket back...');
expect_like(qr/Owner changed from fooser$$ to root/, '...and succeeds.');
}
-# }}}
-# {{{ test ticket linking
my @link_relns = ( 'DependsOn', 'DependedOnBy', 'RefersTo', 'ReferredToBy',
'MemberOf', 'HasMember', );
my %display_relns = map { $_ => $_ } @link_relns;
@@ -502,7 +489,6 @@ expect_like(qr/Merged into ticket #$merge_ticket_A by root/, 'Merge recorded in
#expect_unlike(qr/\Q$reln: \E[\w\d\.]+\Q://\E[w\d\.]+\/ticket\/$link2_id/, "Removed link $reln");
}
-# }}}
expect_quit(); # We need to do this ourselves, so that we quit
# *before* we tear down the webserver.
@@ -536,9 +522,16 @@ sub check_attachment {
my $attachment_content = do { local($/); <$fh> };
close $fh;
chomp $attachment_content;
- expect_is($attachment_content,"Attachment contains original text");
+ TODO: {
+ local $TODO = "Binary PNG content is getting mangled somewhere along the way"
+ if $attachment_path =~ /\.png$/;
+ expect_is($attachment_content,"Attachment contains original text");
+ }
}
+# you may encounter warning like Use of uninitialized value $ampm
+# ... in Time::ParseDate
+my @warnings = grep { $_ !~ /\$ampm/ } $m->get_warnings;
+is( scalar @warnings, 0, 'no extra warnings' );
-
-1;
+1; # needed to avoid a weird exit value from expect_quit
diff --git a/rt/t/web/command_line_with_unknown_field.t b/rt/t/web/command_line_with_unknown_field.t
index 9a7ec7acd..736be4d1c 100644
--- a/rt/t/web/command_line_with_unknown_field.t
+++ b/rt/t/web/command_line_with_unknown_field.t
@@ -3,7 +3,7 @@
use strict;
use File::Spec ();
use Test::Expect;
-use RT::Test tests => 10;
+use RT::Test tests => 14, actual_server => 1;
my ($baseurl, $m) = RT::Test->started_ok;
my $rt_tool_path = "$RT::BinPath/rt";
@@ -12,6 +12,7 @@ $ENV{'RTPASSWD'} = 'password';
$RT::Logger->debug("Connecting to server at ".RT->Config->Get('WebBaseURL'));
$ENV{'RTSERVER'} =RT->Config->Get('WebBaseURL') ;
$ENV{'RTDEBUG'} = '1';
+$ENV{'RTCONFIG'} = '/dev/null';
expect_run(
command => "$rt_tool_path shell",
@@ -19,6 +20,7 @@ expect_run(
quit => 'quit',
);
expect_send(q{create -t ticket set subject='new ticket' add cc=foo@example.com}, "Creating a ticket...");
+
expect_like(qr/Ticket \d+ created/, "Created the ticket");
expect_handle->before() =~ /Ticket (\d+) created/;
my $ticket_id = $1;
@@ -32,3 +34,10 @@ expect_like(qr/homer: Unknown field/, 'homer is unknown field');
expect_like(qr/homer: simpson/, 'the value we set for homer is shown too');
expect_quit();
+
+# you may encounter warning like Use of uninitialized value $ampm
+# ... in Time::ParseDate
+my @warnings = grep { $_ !~ /\$ampm/ } $m->get_warnings;
+is( scalar @warnings, 0, 'no extra warnings' );
+
+1; # needed to avoid a weird exit value from expect_quit
diff --git a/rt/t/web/compilation_errors.t b/rt/t/web/compilation_errors.t
index 36a006890..1f82ab91f 100644
--- a/rt/t/web/compilation_errors.t
+++ b/rt/t/web/compilation_errors.t
@@ -7,7 +7,7 @@ BEGIN {
sub wanted {
-f && /\.html$/ && $_ !~ /Logout.html$/ && $File::Find::dir !~ /RichText/;
}
- my $tests = 4;
+ my $tests = 8;
find( sub { wanted() and $tests += 4 }, 'share/html/' );
plan tests => $tests;
}
@@ -28,33 +28,37 @@ $agent->cookie_jar($cookie_jar);
# get the top page
my $url = $agent->rt_base_url;
-diag "Base URL is '$url'" if $ENV{TEST_VERBOSE};
$agent->get($url);
-is ($agent->{'status'}, 200, "Loaded a page");
-
-# {{{ test a login
+is($agent->status, 200, "Loaded a page");
# follow the link marked "Login"
$agent->login(root => 'password');
-is($agent->{'status'}, 200, "Fetched the page ok");
-like( $agent->{'content'} , qr/Logout/i, "Found a logout link");
+is($agent->status, 200, "Fetched the page ok");
+$agent->content_contains('Logout', "Found a logout link");
+
+find ( sub { wanted() and test_get($agent, $File::Find::name) } , 'share/html/');
-find ( sub { wanted() and test_get($File::Find::name) } , 'share/html/');
+TODO: {
+ local $TODO = "we spew *lots* of undef warnings";
+ $agent->no_warnings_ok;
+};
sub test_get {
+ my $agent = shift;
my $file = shift;
$file =~ s#^share/html/##;
- diag( "testing $url/$file" ) if $ENV{TEST_VERBOSE};
- ok ($agent->get("$url/$file", "GET $url/$file"), "Can Get $url/$file");
- is ($agent->{'status'}, 200, "Loaded $file");
-# ok( $agent->{'content'} =~ /Logout/i, "Found a logout link on $file ");
- ok( $agent->{'content'} !~ /Not logged in/i, "Still logged in for $file");
- ok( $agent->{'content'} !~ /raw error/i, "Didn't get a Mason compilation error on $file");
+ diag( "testing $url/$file" );
+
+ $agent->get_ok("$url/$file");
+ is($agent->status, 200, "Loaded $file");
+ $agent->content_lacks('Not logged in', "Still logged in for $file");
+ $agent->content_lacks('raw error', "Didn't get a Mason compilation error on $file") or do {
+ if (my ($error) = $agent->content =~ /<pre>(.*?line.*?)$/s) {
+ diag "$file: $error";
+ }
+ };
}
-# }}}
-
-1;
diff --git a/rt/t/web/config_tab_right.t b/rt/t/web/config_tab_right.t
index 4dc9ec082..361506c10 100644
--- a/rt/t/web/config_tab_right.t
+++ b/rt/t/web/config_tab_right.t
@@ -2,11 +2,11 @@
use strict;
use warnings;
-use RT::Test tests => 8;
+use RT::Test nodata => 1, tests => 10;
my ($uname, $upass, $user) = ('tester', 'tester');
{
- $user = RT::User->new($RT::SystemUser);
+ $user = RT::User->new(RT->SystemUser);
my ($status, $msg) = $user->Create(
Name => $uname,
Password => $upass,
@@ -20,7 +20,7 @@ my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login($uname, $upass), "logged in";
{
- $m->content_unlike(qr/Configuration/, 'no configuration');
+ $m->content_lacks('Configuration', 'no configuration tab');
$m->get('/Admin/');
is $m->status, 403, 'no access to /Admin/';
}
@@ -33,7 +33,7 @@ RT::Test->set_rights(
{
$m->get('/');
- $m->content_like(qr/Configuration/, 'configuration is there');
+ $m->content_contains('Configuration', 'configuration tab is there');
$m->follow_link_ok({text => 'Configuration'});
is $m->status, 200, 'user has access to /Admin/';
diff --git a/rt/t/web/crypt-gnupg.t b/rt/t/web/crypt-gnupg.t
index fb28c887c..6bdefdac7 100644
--- a/rt/t/web/crypt-gnupg.t
+++ b/rt/t/web/crypt-gnupg.t
@@ -1,20 +1,16 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 94;
-
-plan skip_all => 'GnuPG required.'
- unless eval 'use GnuPG::Interface; 1';
-plan skip_all => 'gpg executable is required.'
- unless RT::Test->find_executable('gpg');
-
+use RT::Test::GnuPG
+ tests => 102,
+ gnupg_options => {
+ passphrase => 'recipient',
+ 'trust-model' => 'always',
+};
+use Test::Warn;
use RT::Action::SendEmail;
-eval 'use GnuPG::Interface; 1' or plan skip_all => 'GnuPG required.';
-
-RT::Test->set_mail_catcher;
-
RT->Config->Set( CommentAddress => 'general@example.com');
RT->Config->Set( CorrespondAddress => 'general@example.com');
RT->Config->Set( DefaultSearchResultFormat => qq{
@@ -26,23 +22,6 @@ RT->Config->Set( DefaultSearchResultFormat => qq{
'KR-__KeyRequestors__-K',
Status});
-use File::Spec ();
-use Cwd;
-use File::Temp qw(tempdir);
-my $homedir = tempdir( CLEANUP => 1 );
-
-use_ok('RT::Crypt::GnuPG');
-
-RT->Config->Set( 'GnuPG',
- Enable => 1,
- OutgoingMessagesFormat => 'RFC' );
-
-RT->Config->Set( 'GnuPGOptions',
- homedir => $homedir,
- passphrase => 'recipient',
- 'no-permission-warning' => undef,
- 'trust-model' => 'always');
-RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
RT::Test->import_gnupg_key('recipient@example.com', 'public');
RT::Test->import_gnupg_key('recipient@example.com', 'secret');
@@ -51,7 +30,7 @@ RT::Test->import_gnupg_key('general@example.com', 'secret');
RT::Test->import_gnupg_key('general@example.com.2', 'public');
RT::Test->import_gnupg_key('general@example.com.2', 'secret');
-ok(my $user = RT::User->new($RT::SystemUser));
+ok(my $user = RT::User->new(RT->SystemUser));
ok($user->Load('root'), "Loaded user 'root'");
$user->SetEmailAddress('recipient@example.com');
@@ -62,11 +41,6 @@ my $queue = RT::Test->load_or_create_queue(
ok $queue && $queue->id, 'loaded or created queue';
my $qid = $queue->id;
-RT::Test->set_rights(
- Principal => 'Everyone',
- Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ModifyTicket'],
-);
-
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in';
@@ -113,7 +87,7 @@ MAIL
is ($status >> 8, 0, "The mail gateway exited normally");
ok ($id, "got id of a newly created ticket - $id");
- my $tick = RT::Ticket->new( $RT::SystemUser );
+ my $tick = RT::Ticket->new( RT->SystemUser );
$tick->Load( $id );
ok ($tick->id, "loaded ticket #$id");
@@ -181,7 +155,7 @@ MAIL
is ($status >> 8, 0, "The mail gateway exited normally");
ok ($id, "got id of a newly created ticket - $id");
- my $tick = RT::Ticket->new( $RT::SystemUser );
+ my $tick = RT::Ticket->new( RT->SystemUser );
$tick->Load( $id );
ok ($tick->id, "loaded ticket #$id");
@@ -253,7 +227,7 @@ MAIL
is ($status >> 8, 0, "The mail gateway exited normally");
ok ($id, "got id of a newly created ticket - $id");
- my $tick = RT::Ticket->new( $RT::SystemUser );
+ my $tick = RT::Ticket->new( RT->SystemUser );
$tick->Load( $id );
ok ($tick->id, "loaded ticket #$id");
@@ -319,7 +293,7 @@ MAIL
is ($status >> 8, 0, "The mail gateway exited normally");
ok ($id, "got id of a newly created ticket - $id");
- my $tick = RT::Ticket->new( $RT::SystemUser );
+ my $tick = RT::Ticket->new( RT->SystemUser );
$tick->Load( $id );
ok ($tick->id, "loaded ticket #$id");
@@ -361,12 +335,12 @@ my $nokey = RT::Test->load_or_create_user(Name => 'nokey', EmailAddress => 'noke
$nokey->PrincipalObj->GrantRight(Right => 'CreateTicket');
$nokey->PrincipalObj->GrantRight(Right => 'OwnTicket');
-my $tick = RT::Ticket->new( $RT::SystemUser );
+my $tick = RT::Ticket->new( RT->SystemUser );
$tick->Create(Subject => 'owner lacks pubkey', Queue => 'general',
Owner => $nokey);
ok(my $id = $tick->id, 'created ticket for owner-without-pubkey');
-$tick = RT::Ticket->new( $RT::SystemUser );
+$tick = RT::Ticket->new( RT->SystemUser );
$tick->Create(Subject => 'owner has pubkey', Queue => 'general',
Owner => 'root');
ok($id = $tick->id, 'created ticket for owner-with-pubkey');
@@ -379,11 +353,18 @@ To: general\@example.com
hello
MAIL
-((my $status), $id) = RT::Test->send_via_mailgate($mail);
+my $status;
+warning_like {
+ ($status, $id) = RT::Test->send_via_mailgate($mail);
+} [
+ qr/nokey\@example.com: skipped: public key not found/,
+ qr/Recipient 'nokey\@example.com' is unusable/,
+];
+
is ($status >> 8, 0, "The mail gateway exited normally");
ok ($id, "got id of a newly created ticket - $id");
-$tick = RT::Ticket->new( $RT::SystemUser );
+$tick = RT::Ticket->new( RT->SystemUser );
$tick->Load( $id );
ok ($tick->id, "loaded ticket #$id");
@@ -396,7 +377,7 @@ is ($tick->Subject,
my $key1 = "EC1E81E7DC3DB42788FB0E4E9FA662C06DE22FC2";
my $key2 = "75E156271DCCF02DDD4A7A8CDF651FA0632C4F50";
-ok($user = RT::User->new($RT::SystemUser));
+ok($user = RT::User->new(RT->SystemUser));
ok($user->Load('root'), "Loaded user 'root'");
is($user->PreferredKey, $key1, "preferred key is set correctly");
$m->get("$baseurl/Prefs/Other.html");
@@ -407,11 +388,11 @@ like($m->content, qr/$key1/, "first key shows up in preferences");
like($m->content, qr/$key2/, "second key shows up in preferences");
like($m->content, qr/$key1.*?$key2/s, "first key shows up before the second");
-$m->form_number(3);
+$m->form_name('ModifyPreferences');
$m->select("PreferredKey" => $key2);
$m->submit;
-ok($user = RT::User->new($RT::SystemUser));
+ok($user = RT::User->new(RT->SystemUser));
ok($user->Load('root'), "Loaded user 'root'");
is($user->PreferredKey, $key2, "preferred key is set correctly to the new value");
@@ -423,6 +404,8 @@ like($m->content, qr/$key2/, "second key shows up in preferences");
like($m->content, qr/$key1/, "first key shows up in preferences");
like($m->content, qr/$key2.*?$key1/s, "second key (now preferred) shows up before the first");
+$m->no_warnings_ok;
+
# test that the new fields work
$m->get("$baseurl/Search/Simple.html?q=General");
my $content = $m->content;
@@ -441,6 +424,10 @@ like($content, qr/KO-nokey \(no pubkey!\)-K/, "KeyOwnerName issues no-pubkey war
like($content, qr/KO-Nobody \(no pubkey!\)-K/, "KeyOwnerName issues no-pubkey warning for nobody");
like($content, qr/KR-recipient\@example.com-K/, "KeyRequestors does not issue no-pubkey warning for recipient\@example.com");
+
like($content, qr/KR-general\@example.com-K/, "KeyRequestors does not issue no-pubkey warning for general\@example.com");
like($content, qr/KR-nokey\@example.com \(no pubkey!\)-K/, "KeyRequestors DOES issue no-pubkey warning for nokey\@example.com");
+$m->next_warning_like(qr/public key not found/);
+$m->next_warning_like(qr/public key not found/);
+$m->no_leftover_warnings_ok;
diff --git a/rt/t/web/custom_frontpage.t b/rt/t/web/custom_frontpage.t
index 79ea56629..43c5f6e33 100644
--- a/rt/t/web/custom_frontpage.t
+++ b/rt/t/web/custom_frontpage.t
@@ -1,12 +1,12 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 7;
+use RT::Test tests => 12;
my ($baseurl, $m) = RT::Test->started_ok;
my $url = $m->rt_base_url;
-my $user_obj = RT::User->new($RT::SystemUser);
+my $user_obj = RT::User->new(RT->SystemUser);
my ($ret, $msg) = $user_obj->LoadOrCreateByEmail('customer@example.com');
ok($ret, 'ACL test user creation');
$user_obj->SetName('customer');
@@ -29,9 +29,9 @@ $m->field ( "SavedSearchDescription" => 'stupid tickets');
$m->click_button (name => 'SavedSearchSave');
$m->get ( $url.'Prefs/MyRT.html' );
-$m->content_like (qr/stupid tickets/, 'saved search listed in rt at a glance items');
+$m->content_contains('stupid tickets', 'saved search listed in rt at a glance items');
-ok $m->login, 'we did log in as root';
+ok $m->login('root', 'password', logout => 1), 'we did log in as root';
$m->get ( $url.'Prefs/MyRT.html' );
$m->form_name ('SelectionBox-body');
@@ -58,4 +58,33 @@ $m->click_button (name => 'movedown');
$m->form_name ('SelectionBox-body');
#$m->click_button (name => 'body-Save');
$m->get ( $url );
-$m->content_like (qr'highest priority tickets', 'adds them back');
+$m->content_contains('highest priority tickets', 'adds them back');
+
+
+#create a saved search with special chars
+$m->get( $url . "Search/Build.html" );
+$m->form_name('BuildQuery');
+$m->field( "ValueOfAttachment" => 'stupid' );
+$m->field( "SavedSearchDescription" => 'special chars [test] [_1] ~[_1~]' );
+$m->click_button( name => 'SavedSearchSave' );
+my ($name) = $m->content =~ /value="(RT::User-\d+-SavedSearch-\d+)"/;
+ok( $name, 'saved search name' );
+$m->get( $url . 'Prefs/MyRT.html' );
+$m->content_contains( 'special chars [test] [_1] ~[_1~]',
+ 'saved search listed in rt at a glance items' );
+
+$m->get( $url . 'Prefs/MyRT.html' );
+$m->form_name('SelectionBox-body');
+$m->field(
+ 'body-Available' => [
+ 'component-QuickCreate',
+ 'system-Unowned Tickets',
+ 'system-My Tickets',
+ 'saved-' . $name,
+ ]
+);
+$m->click_button( name => 'add' );
+
+$m->get($url);
+$m->content_like( qr/special chars \[test\] \d+ \[_1\]/,
+ 'special chars in titlebox' );
diff --git a/rt/t/web/custom_search.t b/rt/t/web/custom_search.t
index 05cfdab60..f8fde2500 100644
--- a/rt/t/web/custom_search.t
+++ b/rt/t/web/custom_search.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 11;
+use RT::Test tests => 13;
my ($baseurl, $m) = RT::Test->started_ok;
my $url = $m->rt_base_url;
@@ -9,7 +9,7 @@ my $url = $m->rt_base_url;
-my $t = RT::Ticket->new($RT::SystemUser);
+my $t = RT::Ticket->new(RT->SystemUser);
$t->Create(Subject => 'for custom search'.$$, Queue => 'general',
Owner => 'root', Requestor => 'customsearch@localhost');
ok(my $id = $t->id, 'created ticket for custom search');
@@ -24,7 +24,7 @@ $m->get ( $url.'Prefs/MyRT.html' );
my $cus_hp = $m->find_link( text => "My Tickets" );
my $cus_qs = $m->find_link( text => "Quick search" );
$m->get ($cus_hp);
-$m->content_like (qr'highest priority tickets');
+$m->content_contains('highest priority tickets');
# add Requestor to the fields
$m->form_name ('BuildQuery');
diff --git a/rt/t/web/dashboards-basics.t b/rt/t/web/dashboards-basics.t
new file mode 100644
index 000000000..1d56da5be
--- /dev/null
+++ b/rt/t/web/dashboards-basics.t
@@ -0,0 +1,268 @@
+#!/usr/bin/perl -w
+use strict;
+
+use RT::Test tests => 122;
+my ($baseurl, $m) = RT::Test->started_ok;
+
+my $url = $m->rt_base_url;
+
+my $user_obj = RT::User->new(RT->SystemUser);
+my ($ret, $msg) = $user_obj->LoadOrCreateByEmail('customer@example.com');
+ok($ret, 'ACL test user creation');
+$user_obj->SetName('customer');
+$user_obj->SetPrivileged(1);
+($ret, $msg) = $user_obj->SetPassword('customer');
+$user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
+my $currentuser = RT::CurrentUser->new($user_obj);
+
+my $onlooker = RT::User->new(RT->SystemUser);
+($ret, $msg) = $onlooker->LoadOrCreateByEmail('onlooker@example.com');
+ok($ret, 'ACL test user creation');
+$onlooker->SetName('onlooker');
+$onlooker->SetPrivileged(1);
+($ret, $msg) = $onlooker->SetPassword('onlooker');
+
+my $queue = RT::Queue->new(RT->SystemUser);
+$queue->Create(Name => 'SearchQueue'.$$);
+
+for my $user ($user_obj, $onlooker) {
+ $user->PrincipalObj->GrantRight(Right => 'ModifySelf');
+ for my $right (qw/SeeQueue ShowTicket OwnTicket/) {
+ $user->PrincipalObj->GrantRight(Right => $right, Object => $queue);
+ }
+}
+
+ok $m->login(customer => 'customer'), "logged in";
+
+$m->get_ok($url."Dashboards/index.html");
+$m->content_lacks('<a href="/Dashboards/Modify.html?Create=1">New</a>',
+ "No 'new dashboard' link because we have no CreateOwnDashboard");
+
+$m->no_warnings_ok;
+
+$m->get_ok($url."Dashboards/Modify.html?Create=1");
+$m->content_contains("Permission denied");
+$m->content_lacks("Save Changes");
+
+$m->warning_like(qr/Permission denied/, "got a permission denied warning");
+
+$user_obj->PrincipalObj->GrantRight(Right => 'ModifyOwnDashboard', Object => $RT::System);
+
+# Modify itself is no longer good enough, you need Create
+$m->get_ok($url."Dashboards/Modify.html?Create=1");
+$m->content_contains("Permission denied");
+$m->content_lacks("Save Changes");
+
+$m->warning_like(qr/Permission denied/, "got a permission denied warning");
+
+$user_obj->PrincipalObj->GrantRight(Right => 'CreateOwnDashboard', Object => $RT::System);
+
+$m->get_ok($url."Dashboards/Modify.html?Create=1");
+$m->content_lacks("Permission denied");
+$m->content_contains("Create");
+
+$m->get_ok($url."Dashboards/index.html");
+$m->content_contains("New", "'New' link because we now have ModifyOwnDashboard");
+$m->follow_link_ok({ id => 'home-dashboard_create'});
+$m->form_name('ModifyDashboard');
+$m->field("Name" => 'different dashboard');
+$m->content_lacks('Delete', "Delete button hidden because we are creating");
+$m->click_button(value => 'Create');
+$m->content_contains("Saved dashboard different dashboard");
+$user_obj->PrincipalObj->GrantRight(Right => 'SeeOwnDashboard', Object => $RT::System);
+$m->get($url."Dashboards/index.html");
+$m->follow_link_ok({ text => 'different dashboard'});
+$m->content_lacks("Permission denied", "we now have SeeOwnDashboard");
+$m->content_lacks('Delete', "Delete button hidden because we lack DeleteOwnDashboard");
+
+$m->get_ok($url."Dashboards/index.html");
+$m->content_contains("different dashboard", "we now have SeeOwnDashboard");
+$m->content_lacks("Permission denied");
+
+$m->follow_link_ok({text => "different dashboard"});
+$m->content_contains("Basics");
+$m->content_contains("Content");
+$m->content_lacks("Subscription", "we don't have the SubscribeDashboard right");
+
+$m->follow_link_ok({text => "Basics"});
+$m->content_contains("Modify the dashboard different dashboard");
+
+$m->follow_link_ok({text => "Content"});
+$m->content_contains("Modify the content of dashboard different dashboard");
+my $form = $m->form_name('Dashboard-Searches-body');
+my @input = $form->find_input('Searches-body-Available');
+my ($unowned) =
+ map { ( $_->possible_values )[1] }
+ grep { ( $_->value_names )[1] =~ /Saved Search: Unowned Tickets/ } @input;
+$form->value('Searches-body-Available' => $unowned );
+$m->click_button(name => 'add');
+$m->content_contains("Dashboard updated");
+
+my $dashboard = RT::Dashboard->new($currentuser);
+my ($id) = $m->content =~ /name="id" value="(\d+)"/;
+ok($id, "got an ID, $id");
+$dashboard->LoadById($id);
+is($dashboard->Name, "different dashboard");
+
+is($dashboard->Privacy, 'RT::User-' . $user_obj->Id, "correct privacy");
+is($dashboard->PossibleHiddenSearches, 0, "all searches are visible");
+
+my @searches = $dashboard->Searches;
+is(@searches, 1, "one saved search in the dashboard");
+like($searches[0]->Name, qr/newest unowned tickets/, "correct search name");
+
+$form = $m->form_name('Dashboard-Searches-body');
+@input = $form->find_input('Searches-body-Available');
+my ($my_tickets) =
+ map { ( $_->possible_values )[1] }
+ grep { ( $_->value_names )[1] =~ /Saved Search: My Tickets/ } @input;
+$form->value('Searches-body-Available' => $my_tickets );
+$m->click_button(name => 'add');
+$m->content_contains("Dashboard updated");
+
+RT::Record->FlushCache if RT::Record->can('FlushCache');
+$dashboard = RT::Dashboard->new($currentuser);
+$dashboard->LoadById($id);
+
+@searches = $dashboard->Searches;
+is(@searches, 2, "two saved searches in the dashboard");
+like($searches[0]->Name, qr/newest unowned tickets/, "correct existing search name");
+like($searches[1]->Name, qr/highest priority tickets I own/, "correct new search name");
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+$ticket->Create(
+ Queue => $queue->Id,
+ Requestor => [ $user_obj->Name ],
+ Owner => $user_obj,
+ Subject => 'dashboard test',
+);
+
+$m->follow_link_ok({id => 'page-show'});
+$m->content_contains("50 highest priority tickets I own");
+$m->content_contains("50 newest unowned tickets");
+$m->content_unlike( qr/Bookmarked Tickets.*Bookmarked Tickets/s,
+ 'only dashboard queries show up' );
+$m->content_contains("dashboard test", "ticket subject");
+
+$m->get_ok("/Dashboards/$id/This fragment left intentionally blank");
+$m->content_contains("50 highest priority tickets I own");
+$m->content_contains("50 newest unowned tickets");
+$m->content_unlike( qr/Bookmarked Tickets.*Bookmarked Tickets/s,
+ 'only dashboard queries show up' );
+$m->content_contains("dashboard test", "ticket subject");
+
+$m->get_ok("/Dashboards/Subscription.html?id=$id");
+$m->form_name('SubscribeDashboard');
+$m->click_button(name => 'Save');
+$m->content_contains("Permission denied");
+$m->warning_like(qr/Unable to subscribe to dashboard.*Permission denied/, "got a permission denied warning when trying to subscribe to a dashboard");
+
+$user_obj->Attributes->RedoSearch;
+is($user_obj->Attributes->Named('Subscription'), 0, "no subscriptions");
+
+$user_obj->PrincipalObj->GrantRight(Right => 'SubscribeDashboard', Object => $RT::System);
+
+$m->get_ok("/Dashboards/Modify.html?id=$id");
+$m->follow_link_ok({text => "Subscription"});
+$m->content_contains("Subscribe to dashboard different dashboard");
+$m->content_contains("Unowned Tickets");
+$m->content_contains("My Tickets");
+$m->content_unlike( qr/Bookmarked Tickets.*Bookmarked Tickets/s,
+ 'only dashboard queries show up' );
+
+$m->form_name('SubscribeDashboard');
+$m->click_button(name => 'Save');
+$m->content_lacks("Permission denied");
+$m->content_contains("Subscribed to dashboard different dashboard");
+
+$user_obj->Attributes->RedoSearch;
+is($user_obj->Attributes->Named('Subscription'), 1, "we have a subscription");
+
+$m->get_ok("/Dashboards/Modify.html?id=$id");
+$m->follow_link_ok({text => "Subscription"});
+$m->content_contains("Modify the subscription to dashboard different dashboard");
+
+$m->get_ok("/Dashboards/Modify.html?id=$id&Delete=1");
+$m->content_contains("Permission denied", "unable to delete dashboard because we lack DeleteOwnDashboard");
+
+$m->warning_like(qr/Couldn't delete dashboard.*Permission denied/, "got a permission denied warning when trying to delete the dashboard");
+
+$user_obj->PrincipalObj->GrantRight(Right => 'DeleteOwnDashboard', Object => $RT::System);
+
+$m->get_ok("/Dashboards/Modify.html?id=$id");
+$m->content_contains('Delete', "Delete button shows because we have DeleteOwnDashboard");
+
+$m->form_name('ModifyDashboard');
+$m->click_button(name => 'Delete');
+$m->content_contains("Deleted dashboard");
+
+$m->get("/Dashboards/Modify.html?id=$id");
+$m->content_lacks("different dashboard", "dashboard was deleted");
+$m->content_contains("Failed to load dashboard $id");
+
+$m->warning_like(qr/Failed to load dashboard.*Couldn't find row/, "the dashboard was deleted");
+
+$user_obj->PrincipalObj->GrantRight(Right => "SuperUser", Object => $RT::System);
+
+# now test that we warn about searches others can't see
+# first create a personal saved search...
+$m->get_ok($url."Search/Build.html");
+$m->follow_link_ok({text => 'Advanced'});
+$m->form_with_fields('Query');
+$m->field(Query => "id > 0");
+$m->submit;
+
+$m->form_with_fields('SavedSearchDescription');
+$m->field(SavedSearchDescription => "personal search");
+$m->click_button(name => "SavedSearchSave");
+
+# then the system-wide dashboard
+$m->get_ok($url."Dashboards/Modify.html?Create=1");
+
+$m->form_name('ModifyDashboard');
+$m->field("Name" => 'system dashboard');
+$m->field("Privacy" => 'RT::System-1');
+$m->content_lacks('Delete', "Delete button hidden because we are creating");
+$m->click_button(value => 'Create');
+$m->content_lacks("No permission to create dashboards");
+$m->content_contains("Saved dashboard system dashboard");
+
+$m->follow_link_ok({id => 'page-content'});
+
+$form = $m->form_name('Dashboard-Searches-body');
+@input = $form->find_input('Searches-body-Available');
+my ($personal) =
+ map { ( $_->possible_values )[1] }
+ grep { ( $_->value_names )[1] =~ /Saved Search: personal search/ } @input;
+$form->value('Searches-body-Available' => $personal );
+$m->click_button(name => 'add');
+$m->content_contains("Dashboard updated");
+
+$m->content_contains("The following queries may not be visible to all users who can see this dashboard.");
+
+$m->follow_link_ok({id => 'page-show'});
+$m->content_contains("personal search", "saved search shows up");
+$m->content_contains("dashboard test", "matched ticket shows up");
+
+# make sure the onlooker can't see the search...
+$onlooker->PrincipalObj->GrantRight(Right => 'SeeDashboard', Object => $RT::System);
+
+my $omech = RT::Test::Web->new;
+ok $omech->login(onlooker => 'onlooker'), "logged in";
+$omech->get_ok("/Dashboards");
+
+$omech->follow_link_ok({text => 'system dashboard'});
+$omech->content_lacks("personal search", "saved search doesn't show up");
+$omech->content_lacks("dashboard test", "matched ticket doesn't show up");
+
+$omech->warning_like(qr/User .* tried to load container user /, "can't see other users' personal searches");
+
+# make sure that navigating to dashboard pages with bad IDs throws an error
+my ($bad_id) = $personal =~ /^search-(\d+)/;
+
+for my $page (qw/Modify Queries Render Subscription/) {
+ $m->get("/Dashboards/$page.html?id=$bad_id");
+ $m->content_like(qr/Couldn.+t load dashboard $bad_id: Invalid object type/);
+ $m->warning_like(qr/Couldn't load dashboard $bad_id: Invalid object type/);
+}
+
diff --git a/rt/t/web/dashboards-deleted-saved-search.t b/rt/t/web/dashboards-deleted-saved-search.t
new file mode 100644
index 000000000..4cd7fea1f
--- /dev/null
+++ b/rt/t/web/dashboards-deleted-saved-search.t
@@ -0,0 +1,89 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test tests => 20;
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login, 'logged in' );
+
+# create a saved search
+$m->get_ok( $url . "/Search/Build.html?Query=" . 'id=1' );
+
+$m->submit_form(
+ form_name => 'BuildQuery',
+ fields => { SavedSearchDescription => 'foo', },
+ button => 'SavedSearchSave',
+);
+
+my ( $search_uri, $user_id, $search_id ) =
+ $m->content =~ /value="(RT::User-(\d+)-SavedSearch-(\d+))"/;
+$m->submit_form(
+ form_name => 'BuildQuery',
+ fields => { SavedSearchLoad => $search_uri },
+ button => 'SavedSearchSave',
+);
+
+$m->content_like( qr/name="SavedSearchDelete"\s+value="Delete"/,
+ 'found Delete button' );
+$m->content_like(
+ qr/name="SavedSearchDescription"\s+value="foo"/,
+ 'found Description input with the value filled'
+);
+
+# create a dashboard with the created search
+
+$m->get_ok( $url . "/Dashboards/Modify.html?Create=1" );
+$m->submit_form(
+ form_name => 'ModifyDashboard',
+ fields => { Name => 'bar' },
+);
+
+$m->content_contains('Saved dashboard bar', 'dashboard saved' );
+my $dashboard_queries_link = $m->find_link( text_regex => qr/Content/ );
+my ( $dashboard_id ) = $dashboard_queries_link->url =~ /id=(\d+)/;
+
+$m->get_ok( $url . "/Dashboards/Queries.html?id=$dashboard_id" );
+
+$m->content_lacks( 'value="Update"', 'no update button' );
+
+$m->submit_form(
+ form_name => 'Dashboard-Searches-body',
+ fields =>
+ { 'Searches-body-Available' => "search-$search_id-RT::User-$user_id" },
+ button => 'add',
+);
+
+$m->content_contains('Dashboard updated', 'added search foo to dashboard bar' );
+
+# delete the created search
+
+$m->get_ok( $url . "/Search/Build.html?Query=" . 'id=1' );
+$m->submit_form(
+ form_name => 'BuildQuery',
+ fields => { SavedSearchLoad => $search_uri },
+);
+$m->submit_form(
+ form_name => 'BuildQuery',
+ button => 'SavedSearchDelete',
+);
+
+$m->content_lacks( $search_uri, 'deleted search foo' );
+
+# here is what we really want to test
+
+$m->get_ok( $url . "/Dashboards/Queries.html?id=$dashboard_id" );
+$m->content_contains('Deleted queries', 'found deleted message' );
+
+# Update button shows so we can update the deleted search easily
+$m->content_contains( 'value="Update"', 'found update button' );
+
+$m->submit_form(
+ form_name => 'Dashboard-Searches-body',
+ button => 'update',
+);
+
+$m->content_lacks('Deleted queries', 'deleted message is gone' );
+$m->content_lacks( 'value="Update"', 'update button is gone too' );
+
+$m->get_warnings; # we'll get a lot of warnings because the deleted search
+
diff --git a/rt/t/web/dashboards-groups.t b/rt/t/web/dashboards-groups.t
index cbf1d6a9f..ac2a5aca0 100644
--- a/rt/t/web/dashboards-groups.t
+++ b/rt/t/web/dashboards-groups.t
@@ -1,13 +1,13 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 40;
+use RT::Test nodata => 1, tests => 64;
my ($baseurl, $m) = RT::Test->started_ok;
my $url = $m->rt_base_url;
-# create user and queue {{{
-my $user_obj = RT::User->new($RT::SystemUser);
+# create user and queue
+my $user_obj = RT::User->new(RT->SystemUser);
my ($ok, $msg) = $user_obj->LoadOrCreateByEmail('customer@example.com');
ok($ok, 'ACL test user creation');
$user_obj->SetName('customer');
@@ -16,7 +16,7 @@ $user_obj->SetPrivileged(1);
$user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
my $currentuser = RT::CurrentUser->new($user_obj);
-my $queue = RT::Queue->new($RT::SystemUser);
+my $queue = RT::Queue->new(RT->SystemUser);
$queue->Create(Name => 'SearchQueue'.$$);
$user_obj->PrincipalObj->GrantRight(Right => $_, Object => $queue)
@@ -26,13 +26,12 @@ $user_obj->PrincipalObj->GrantRight(Right => $_, Object => $queue)
# are checked and not these as well
$user_obj->PrincipalObj->GrantRight(Right => $_, Object => $RT::System)
for qw/SubscribeDashboard CreateOwnDashboard SeeOwnDashboard ModifyOwnDashboard DeleteOwnDashboard/;
-# }}}
-# create and test groups (outer < inner < user) {{{
-my $inner_group = RT::Group->new($RT::SystemUser);
+# create and test groups (outer < inner < user)
+my $inner_group = RT::Group->new(RT->SystemUser);
($ok, $msg) = $inner_group->CreateUserDefinedGroup(Name => "inner", Description => "inner group");
ok($ok, "created inner group: $msg");
-my $outer_group = RT::Group->new($RT::SystemUser);
+my $outer_group = RT::Group->new(RT->SystemUser);
($ok, $msg) = $outer_group->CreateUserDefinedGroup(Name => "outer", Description => "outer group");
ok($ok, "created outer group: $msg");
@@ -51,28 +50,36 @@ ok(!$inner_group->HasMember($outer_group->PrincipalId), "inner doesn't have oute
ok($inner_group->HasMember($user_obj->PrincipalId), "inner has user");
ok(!$inner_group->HasMemberRecursively($outer_group->PrincipalId), "inner doesn't have outer, even recursively");
ok($inner_group->HasMemberRecursively($user_obj->PrincipalId), "inner has user recursively");
-# }}}
ok $m->login(customer => 'customer'), "logged in";
-$m->get_ok("$url/Dashboards");
-$m->follow_link_ok({text => "New"});
+$m->follow_link_ok({ id => 'home-dashboard_create'});
$m->form_name('ModifyDashboard');
is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id], "the only selectable privacy is user");
$m->content_lacks('Delete', "Delete button hidden because we are creating");
$user_obj->PrincipalObj->GrantRight(Right => 'CreateGroupDashboard', Object => $inner_group);
-$m->follow_link_ok({text => "New"});
+$m->follow_link_ok({ id => 'home-dashboard_create'});
$m->form_name('ModifyDashboard');
is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id, "RT::Group-" . $inner_group->Id], "the only selectable privacies are user and inner group (not outer group)");
-$m->field("Name" => 'inner dashboard');
+$m->field("Name" => 'broken dashboard');
$m->field("Privacy" => "RT::Group-" . $inner_group->Id);
$m->content_lacks('Delete', "Delete button hidden because we are creating");
+$m->click_button(value => 'Create');
+$m->content_contains("saved", "we lack SeeGroupDashboard, so we end up back at the index.");
+$user_obj->PrincipalObj->GrantRight(
+ Right => 'SeeGroupDashboard',
+ Object => $inner_group,
+);
+$m->follow_link_ok({ id => 'home-dashboard_create'});
+$m->form_name('ModifyDashboard');
+$m->field("Name" => 'inner dashboard');
+$m->field("Privacy" => "RT::Group-" . $inner_group->Id);
$m->click_button(value => 'Create');
-$m->content_lacks("No permission to create dashboards");
+$m->content_lacks("Permission denied", "we now have SeeGroupDashboard");
$m->content_contains("Saved dashboard inner dashboard");
$m->content_lacks('Delete', "Delete button hidden because we lack DeleteDashboard");
@@ -85,18 +92,104 @@ is($dashboard->Name, "inner dashboard");
is($dashboard->Privacy, 'RT::Group-' . $inner_group->Id, "correct privacy");
is($dashboard->PossibleHiddenSearches, 0, "all searches are visible");
-$m->no_warnings_ok;
-
-$m->get_ok("/Dashboards/Modify.html?id=$id");
-$m->content_lacks("inner dashboard", "no SeeGroupDashboard right");
-$m->content_contains("Permission denied");
-
-$m->warning_like(qr/Permission denied/, "got a permission denied warning");
-$user_obj->PrincipalObj->GrantRight(Right => 'SeeGroupDashboard', Object => $inner_group);
$m->get_ok("/Dashboards/Modify.html?id=$id");
$m->content_contains("inner dashboard", "we now have SeeGroupDashboard right");
$m->content_lacks("Permission denied");
-
$m->content_contains('Subscription', "Subscription link not hidden because we have SubscribeDashboard");
+
+$m->get_ok("/Dashboards/index.html");
+$m->content_contains("inner dashboard", "We can see the inner dashboard from the UI");
+
+$m->get_ok("/index.html");
+$m->content_contains("inner dashboard", "We can see the inner dashboard from the menu drop-down");
+
+my ($group) = grep {$_->isa("RT::Group") and $_->Id == $inner_group->Id}
+ RT::Dashboard->new($currentuser)->_PrivacyObjects;
+ok($group, "Found the group in the privacy objects list");
+
+my @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id],
+ "We can load from ourselves (SeeOwnDashboard) and a group we are with SeeGroupDashboard"
+);
+
+# If you are granted SeeGroupDashboard globally, you can only see
+# dashboards in groups you are in.
+$user_obj->PrincipalObj->RevokeRight(
+ Right => 'SeeGroupDashboard',
+ Object => $inner_group,
+);
+$user_obj->PrincipalObj->GrantRight(
+ Right => 'SeeGroupDashboard',
+ Object => RT->System,
+);
+$m->get_ok("/Dashboards/index.html");
+$m->content_contains("inner dashboard", "Having SeeGroupDashboard gobally is fine for groups you are in");
+@loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id],
+ "SeeGroupDashboard globally still works for groups you are in"
+);
+
+$inner_group->DeleteMember($user_obj->PrincipalObj->Id);
+ok(!$outer_group->HasMemberRecursively($user_obj->PrincipalId), "outer no longer has user recursively");
+ok(!$inner_group->HasMemberRecursively($user_obj->PrincipalId), "inner no longer has user recursively");
+$m->get_ok("/Dashboards/index.html");
+$m->content_lacks("inner dashboard", "But global SeeGroupDashboard isn't enough for other groups");
+$m->no_warnings_ok;
+@loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id],
+ "We only have our SeeOwnDashboard right, as we are no longer in inner"
+);
+
+# Similarly, if you're a SuperUser, you still only see dashboards for
+# groups you belong to
+$user_obj->PrincipalObj->RevokeRight(
+ Right => 'SeeGroupDashboard',
+ Object => RT->System,
+);
+$user_obj->PrincipalObj->GrantRight(
+ Right => 'SuperUser',
+ Object => RT->System,
+);
+$m->get_ok("/Dashboards/index.html");
+$m->content_lacks("inner dashboard", "Superuser can't see dashboards in groups they're not in");
+@loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id, "RT::System-1"],
+ "We pick up the system-level SeeDashboard right from superuser"
+);
+@loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading(IncludeSuperuserGroups => 0);
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id, "RT::System-1"],
+ "IncludeSuperusers only cuts out _group_ dashboard objects for loading, not user and system ones"
+);
+
+$inner_group->AddMember($user_obj->PrincipalId);
+$m->get_ok("/Dashboards/index.html");
+$m->content_contains("inner dashboard", "Superuser can see dashboards in groups they are in");
+@loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id, "RT::System-1"],
+ "Becoming a member of the group makes it a possibility"
+);
+@loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading(IncludeSuperuserGroups => 0);
+is_deeply(
+ \@loading,
+ ["RT::User-".$user_obj->Id, "RT::System-1"],
+ "But only via superuser"
+);
+
+$m->get_ok("/Dashboards/index.html");
+$m->content_contains("inner dashboard", "The dashboards list includes superuser rights");
+$m->get_ok("/index.html");
+$m->content_lacks("inner dashboard", "But the menu skips them");
diff --git a/rt/t/web/dashboards-permissions.t b/rt/t/web/dashboards-permissions.t
index 172404289..f2e59e5cc 100644
--- a/rt/t/web/dashboards-permissions.t
+++ b/rt/t/web/dashboards-permissions.t
@@ -2,13 +2,13 @@
use strict;
use warnings;
-use RT::Test tests => 7;
+use RT::Test nodata => 1, tests => 8;
my ($baseurl, $m) = RT::Test->started_ok;
my $url = $m->rt_base_url;
# create user and queue {{{
-my $user_obj = RT::User->new($RT::SystemUser);
+my $user_obj = RT::User->new(RT->SystemUser);
my ($ok, $msg) = $user_obj->LoadOrCreateByEmail('customer@example.com');
ok($ok, 'ACL test user creation');
$user_obj->SetName('customer');
@@ -17,7 +17,7 @@ $user_obj->SetPrivileged(1);
$user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
my $currentuser = RT::CurrentUser->new($user_obj);
-my $queue = RT::Queue->new($RT::SystemUser);
+my $queue = RT::Queue->new(RT->SystemUser);
$queue->Create(Name => 'SearchQueue'.$$);
$user_obj->PrincipalObj->GrantRight(Right => $_, Object => $queue)
@@ -25,13 +25,11 @@ $user_obj->PrincipalObj->GrantRight(Right => $_, Object => $queue)
$user_obj->PrincipalObj->GrantRight(Right => $_, Object => $RT::System)
for qw/SubscribeDashboard CreateOwnDashboard SeeOwnDashboard ModifyOwnDashboard DeleteOwnDashboard/;
-# }}}
ok $m->login(customer => 'customer'), "logged in";
-$m->get_ok("$url/Dashboards");
-$m->follow_link_ok({text => "New"});
+$m->follow_link_ok( {id => 'home-dashboard_create'});
$m->form_name('ModifyDashboard');
is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id], "the only selectable privacy is user");
$m->content_lacks('Delete', "Delete button hidden because we are creating");
diff --git a/rt/t/web/dashboards-search-cache.t b/rt/t/web/dashboards-search-cache.t
new file mode 100644
index 000000000..ad2a96969
--- /dev/null
+++ b/rt/t/web/dashboards-search-cache.t
@@ -0,0 +1,73 @@
+#!/usr/bin/perl -w
+use strict;
+
+use RT::Test tests => 20;
+my ($baseurl, $m) = RT::Test->started_ok;
+
+my $url = $m->rt_base_url;
+
+ok($m->login, 'logged in');
+
+# create a search
+$m->follow_link_ok({text => 'Tickets'}, 'to query builder');
+$m->form_name('BuildQuery');
+
+$m->field(ValueOfid => 10 );
+$m->click('AddClause');
+$m->text_contains( 'id < 10', 'added new clause');
+
+$m->form_name('BuildQuery');
+$m->field(SavedSearchDescription => 'Original Name');
+$m->click('SavedSearchSave');
+
+# create a dashboard
+$m->get_ok("$url/Dashboards/Modify.html?Create=1");
+$m->form_name('ModifyDashboard');
+$m->field('Name' => 'cachey dashboard');
+$m->click_button(value => 'Create');
+$m->text_contains('Saved dashboard cachey dashboard');
+
+my ($dashboard_id) = $m->content =~ /name="id" value="(\d+)"/;
+ok($dashboard_id, "got an ID, $dashboard_id");
+
+# add the search to the dashboard
+$m->follow_link_ok({text => 'Content'});
+my $form = $m->form_name('Dashboard-Searches-body');
+my @input = $form->find_input('Searches-body-Available');
+my ($search) =
+ map { ( $_->possible_values )[1] }
+ grep { ( $_->value_names )[1] =~ /Saved Search: Original Name/ } @input;
+$form->value('Searches-body-Available' => $search );
+$m->click_button(name => 'add');
+$m->text_contains('Dashboard updated');
+
+# subscribe to the dashboard
+$m->follow_link_ok({text => 'Subscription'});
+$m->text_contains('Saved Search: Original Name');
+$m->form_name('SubscribeDashboard');
+$m->click_button(name => 'Save');
+$m->text_contains('Subscribed to dashboard cachey dashboard');
+
+# rename the search
+$m->follow_link_ok({text => 'Tickets'}, 'to query builder');
+$form = $m->form_name('BuildQuery');
+@input = $form->find_input('SavedSearchLoad');
+($search) =
+ map { ( $_->possible_values )[1] }
+ grep { ( $_->value_names )[1] =~ /Original Name/ } @input;
+$form->value('SavedSearchLoad' => $search );
+$m->click_button(value => 'Load');
+$m->text_contains('Loaded saved search "Original Name"');
+
+$m->form_name('BuildQuery');
+$m->field('SavedSearchDescription' => 'New Name');
+$m->click_button(value => 'Update');
+$m->text_contains('Updated saved search "New Name"');
+
+# check subscription page again
+$m->get_ok("/Dashboards/Subscription.html?id=$dashboard_id");
+TODO: {
+ local $TODO = 'we cache search names too aggressively';
+ $m->text_contains('Saved Search: New Name');
+ $m->text_unlike(qr/Saved Search: Original Name/); # t-w-m lacks text_lacks
+}
diff --git a/rt/t/web/gnupg-headers.t b/rt/t/web/gnupg-headers.t
new file mode 100644
index 000000000..88b3ab9c2
--- /dev/null
+++ b/rt/t/web/gnupg-headers.t
@@ -0,0 +1,53 @@
+#!/usr/bin/perl -w
+use strict;
+
+use RT::Test::GnuPG
+ tests => 15,
+ gnupg_options => {
+ passphrase => 'recipient',
+ 'trust-model' => 'always',
+ };
+
+RT::Test->import_gnupg_key( 'recipient@example.com', 'public' );
+RT::Test->import_gnupg_key( 'general@example.com', 'secret' );
+
+ok( my $user = RT::User->new( RT->SystemUser ) );
+ok( $user->Load('root'), "Loaded user 'root'" );
+$user->SetEmailAddress('recipient@example.com');
+
+my $queue = RT::Test->load_or_create_queue(
+ Name => 'General',
+ CorrespondAddress => 'general@example.com',
+);
+ok $queue && $queue->id, 'loaded or created queue';
+my $qid = $queue->id;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in';
+
+diag "test with Encrypt and Sign disabled";
+
+$m->goto_create_ticket($queue);
+$m->form_name('TicketCreate');
+$m->field( 'Subject', 'Signing test' );
+$m->field( 'Content', 'Some other content' );
+$m->submit;
+$m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+$m->follow_link_ok( { text => 'with headers' } );
+$m->content_contains('X-RT-Encrypt: 0');
+$m->content_contains('X-RT-Sign: 0');
+
+diag "test with Encrypt and Sign enabled";
+
+$m->goto_create_ticket($queue);
+$m->form_name('TicketCreate');
+$m->field( 'Subject', 'Signing test' );
+$m->field( 'Content', 'Some other content' );
+$m->tick( 'Encrypt', 1 );
+$m->tick( 'Sign', 1 );
+$m->submit;
+$m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+$m->follow_link_ok( { text => 'with headers' } );
+$m->content_contains('X-RT-Encrypt: 1');
+$m->content_contains('X-RT-Sign: 1');
+
diff --git a/rt/t/web/gnupg-select-keys-on-create.t b/rt/t/web/gnupg-select-keys-on-create.t
index deee6b291..cf27e48a7 100644
--- a/rt/t/web/gnupg-select-keys-on-create.t
+++ b/rt/t/web/gnupg-select-keys-on-create.t
@@ -2,34 +2,8 @@
use strict;
use warnings;
-use RT::Test tests => 60;
-
-plan skip_all => 'GnuPG required.'
- unless eval 'use GnuPG::Interface; 1';
-plan skip_all => 'gpg executable is required.'
- unless RT::Test->find_executable('gpg');
-
-
+use RT::Test::GnuPG tests => 79, gnupg_options => { passphrase => 'rt-test' };
use RT::Action::SendEmail;
-use File::Temp qw(tempdir);
-
-RT::Test->set_mail_catcher;
-
-use_ok('RT::Crypt::GnuPG');
-
-RT->Config->Set( GnuPG =>
- Enable => 1,
- OutgoingMessagesFormat => 'RFC',
-);
-
-RT->Config->Set( GnuPGOptions =>
- homedir => scalar tempdir( CLEANUP => 0 ),
- passphrase => 'rt-test',
- 'no-permission-warning' => undef,
-);
-diag "GnuPG --homedir ". RT->Config->Get('GnuPGOptions')->{'homedir'} if $ENV{TEST_VERBOSE};
-
-RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
my $queue = RT::Test->load_or_create_queue(
Name => 'Regression',
@@ -38,28 +12,24 @@ my $queue = RT::Test->load_or_create_queue(
);
ok $queue && $queue->id, 'loaded or created queue';
-RT::Test->set_rights(
- Principal => 'Everyone',
- Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ReplyToTicket', 'ModifyTicket'],
-);
-
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in';
-diag "check that signing doesn't work if there is no key" if $ENV{TEST_VERBOSE};
+diag "check that signing doesn't work if there is no key";
{
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Sign => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->submit;
- $m->content_like(
- qr/unable to sign outgoing email messages/i,
+ $m->content_contains(
+ 'unable to sign outgoing email messages',
'problems with passphrase'
);
+ $m->warning_like(qr/signing failed: secret key not available/);
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
@@ -72,33 +42,36 @@ diag "check that signing doesn't work if there is no key" if $ENV{TEST_VERBOSE};
is $res{'info'}[0]{'TrustTerse'}, 'ultimate', 'ultimately trusted key';
}
-diag "check that things don't work if there is no key" if $ENV{TEST_VERBOSE};
+diag "check that things don't work if there is no key";
{
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Encrypt => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There is no key suitable for encryption/i,
+ $m->content_contains(
+ 'There is no key suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketCreate');
ok !$form->find_input( 'UseKey-rt-test@example.com' ), 'no key selector';
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->next_warning_like(qr/public key not found/) for 1 .. 4;
+ $m->no_leftover_warnings_ok;
}
-diag "import first key of rt-test\@example.com" if $ENV{TEST_VERBOSE};
+diag "import first key of rt-test\@example.com";
my $fpr1 = '';
{
RT::Test->import_gnupg_key('rt-test@example.com', 'public');
@@ -107,45 +80,47 @@ my $fpr1 = '';
$fpr1 = $res{'info'}[0]{'Fingerprint'};
}
-diag "check that things still doesn't work if key is not trusted" if $ENV{TEST_VERBOSE};
+diag "check that things still doesn't work if key is not trusted";
{
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Encrypt => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There is one suitable key, but trust level is not set/i,
+ $m->content_contains(
+ 'There is one suitable key, but trust level is not set',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketCreate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 1, 'one option';
$m->select( 'UseKey-rt-test@example.com' => $fpr1 );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/Selected key either is not trusted/i,
+ $m->content_contains(
+ 'Selected key either is not trusted',
'problems with keys'
);
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->no_warnings_ok;
}
-diag "import a second key of rt-test\@example.com" if $ENV{TEST_VERBOSE};
+diag "import a second key of rt-test\@example.com";
my $fpr2 = '';
{
RT::Test->import_gnupg_key('rt-test@example.com.2', 'public');
@@ -154,42 +129,44 @@ my $fpr2 = '';
$fpr2 = $res{'info'}[2]{'Fingerprint'};
}
-diag "check that things still doesn't work if two keys are not trusted" if $ENV{TEST_VERBOSE};
+diag "check that things still doesn't work if two keys are not trusted";
{
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Encrypt => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketCreate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
$m->select( 'UseKey-rt-test@example.com' => $fpr1 );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/Selected key either is not trusted/i,
+ $m->content_contains(
+ 'Selected key either is not trusted',
'problems with keys'
);
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->no_warnings_ok;
}
{
@@ -204,26 +181,28 @@ diag "check that we see key selector even if only one key is trusted but there a
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Encrypt => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketCreate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->no_warnings_ok;
}
diag "check that key selector works and we can select trusted key";
@@ -231,21 +210,21 @@ diag "check that key selector works and we can select trusted key";
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Encrypt => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketCreate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
@@ -256,6 +235,8 @@ diag "check that key selector works and we can select trusted key";
my @mail = RT::Test->fetch_caught_mails;
ok @mail, 'there are some emails';
check_text_emails( { Encrypt => 1 }, @mail );
+
+ $m->no_warnings_ok;
}
diag "check encrypting of attachments";
@@ -263,22 +244,22 @@ diag "check encrypting of attachments";
RT::Test->clean_caught_mails;
ok $m->goto_create_ticket( $queue ), "UI -> create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->tick( Encrypt => 1 );
$m->field( Requestors => 'rt-test@example.com' );
$m->field( Content => 'Some content' );
$m->field( Attach => $0 );
$m->submit;
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketCreate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
@@ -289,37 +270,7 @@ diag "check encrypting of attachments";
my @mail = RT::Test->fetch_caught_mails;
ok @mail, 'there are some emails';
check_text_emails( { Encrypt => 1, Attachment => 1 }, @mail );
-}
-sub check_text_emails {
- my %args = %{ shift @_ };
- my @mail = @_;
-
- ok scalar @mail, "got some mail";
- for my $mail (@mail) {
- for my $type ('email', 'attachment') {
- next if $type eq 'attachment' && !$args{'Attachment'};
-
- my $content = $type eq 'email'
- ? "Some content"
- : "Attachment content";
-
- if ( $args{'Encrypt'} ) {
- unlike $mail, qr/$content/, "outgoing $type was encrypted";
- } else {
- like $mail, qr/$content/, "outgoing $type was not encrypted";
- }
-
- next unless $type eq 'email';
-
- if ( $args{'Sign'} && $args{'Encrypt'} ) {
- like $mail, qr/BEGIN PGP MESSAGE/, 'outgoing email was signed';
- } elsif ( $args{'Sign'} ) {
- like $mail, qr/SIGNATURE/, 'outgoing email was signed';
- } else {
- unlike $mail, qr/SIGNATURE/, 'outgoing email was not signed';
- }
- }
- }
+ $m->no_warnings_ok;
}
diff --git a/rt/t/web/gnupg-select-keys-on-update.t b/rt/t/web/gnupg-select-keys-on-update.t
index 76817ddf2..4842dcd54 100644
--- a/rt/t/web/gnupg-select-keys-on-update.t
+++ b/rt/t/web/gnupg-select-keys-on-update.t
@@ -2,34 +2,9 @@
use strict;
use warnings;
-use RT::Test tests => 68;
-
-plan skip_all => 'GnuPG required.'
- unless eval 'use GnuPG::Interface; 1';
-plan skip_all => 'gpg executable is required.'
- unless RT::Test->find_executable('gpg');
-
+use RT::Test::GnuPG tests => 86, gnupg_options => { passphrase => 'rt-test' };
use RT::Action::SendEmail;
-use File::Temp qw(tempdir);
-
-RT::Test->set_mail_catcher;
-
-use_ok('RT::Crypt::GnuPG');
-
-RT->Config->Set( GnuPG =>
- Enable => 1,
- OutgoingMessagesFormat => 'RFC',
-);
-
-RT->Config->Set( GnuPGOptions =>
- homedir => scalar tempdir( CLEANUP => 0 ),
- passphrase => 'rt-test',
- 'no-permission-warning' => undef,
-);
-diag "GnuPG --homedir ". RT->Config->Get('GnuPGOptions')->{'homedir'} if $ENV{TEST_VERBOSE};
-
-RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
my $queue = RT::Test->load_or_create_queue(
Name => 'Regression',
@@ -38,18 +13,13 @@ my $queue = RT::Test->load_or_create_queue(
);
ok $queue && $queue->id, 'loaded or created queue';
-RT::Test->set_rights(
- Principal => 'Everyone',
- Right => ['CreateTicket', 'ShowTicket', 'SeeQueue', 'ReplyToTicket', 'ModifyTicket'],
-);
-
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in';
my $tid;
{
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
($tid) = $ticket->Create(
Subject => 'test',
Queue => $queue->id,
@@ -57,24 +27,27 @@ my $tid;
ok $tid, 'ticket created';
}
-diag "check that signing doesn't work if there is no key" if $ENV{TEST_VERBOSE};
+diag "check that signing doesn't work if there is no key";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Sign => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->click('SubmitTicket');
- $m->content_like(
- qr/unable to sign outgoing email messages/i,
+ $m->content_contains(
+ 'unable to sign outgoing email messages',
'problems with passphrase'
);
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->next_warning_like(qr/secret key not available/);
+ $m->no_leftover_warnings_ok;
}
{
@@ -84,35 +57,38 @@ diag "check that signing doesn't work if there is no key" if $ENV{TEST_VERBOSE};
is $res{'info'}[0]{'TrustTerse'}, 'ultimate', 'ultimately trusted key';
}
-diag "check that things don't work if there is no key" if $ENV{TEST_VERBOSE};
+diag "check that things don't work if there is no key";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Encrypt => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There is no key suitable for encryption/i,
+ $m->content_contains(
+ 'There is no key suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketUpdate');
ok !$form->find_input( 'UseKey-rt-test@example.com' ), 'no key selector';
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->next_warning_like(qr/public key not found/) for 1 .. 2;
+ $m->no_leftover_warnings_ok;
}
-diag "import first key of rt-test\@example.com" if $ENV{TEST_VERBOSE};
+diag "import first key of rt-test\@example.com";
my $fpr1 = '';
{
RT::Test->import_gnupg_key('rt-test@example.com', 'public');
@@ -121,46 +97,48 @@ my $fpr1 = '';
$fpr1 = $res{'info'}[0]{'Fingerprint'};
}
-diag "check that things still doesn't work if key is not trusted" if $ENV{TEST_VERBOSE};
+diag "check that things still doesn't work if key is not trusted";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Encrypt => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There is one suitable key, but trust level is not set/i,
+ $m->content_contains(
+ 'There is one suitable key, but trust level is not set',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketUpdate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 1, 'one option';
$m->select( 'UseKey-rt-test@example.com' => $fpr1 );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/Selected key either is not trusted/i,
+ $m->content_contains(
+ 'Selected key either is not trusted',
'problems with keys'
);
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->no_warnings_ok;
}
-diag "import a second key of rt-test\@example.com" if $ENV{TEST_VERBOSE};
+diag "import a second key of rt-test\@example.com";
my $fpr2 = '';
{
RT::Test->import_gnupg_key('rt-test@example.com.2', 'public');
@@ -169,43 +147,45 @@ my $fpr2 = '';
$fpr2 = $res{'info'}[2]{'Fingerprint'};
}
-diag "check that things still doesn't work if two keys are not trusted" if $ENV{TEST_VERBOSE};
+diag "check that things still doesn't work if two keys are not trusted";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Encrypt => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketUpdate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
$m->select( 'UseKey-rt-test@example.com' => $fpr1 );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/Selected key either is not trusted/i,
+ $m->content_contains(
+ 'Selected key either is not trusted',
'problems with keys'
);
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->no_warnings_ok;
}
{
@@ -215,130 +195,103 @@ diag "check that things still doesn't work if two keys are not trusted" if $ENV{
is $res{'info'}[1]{'TrustLevel'}, 0, 'is not trusted key';
}
-diag "check that we see key selector even if only one key is trusted but there are more keys" if $ENV{TEST_VERBOSE};
+diag "check that we see key selector even if only one key is trusted but there are more keys";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Encrypt => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketUpdate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
my @mail = RT::Test->fetch_caught_mails;
ok !@mail, 'there are no outgoing emails';
+
+ $m->no_warnings_ok;
}
-diag "check that key selector works and we can select trusted key" if $ENV{TEST_VERBOSE};
+diag "check that key selector works and we can select trusted key";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Encrypt => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketUpdate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
$m->select( 'UseKey-rt-test@example.com' => $fpr1 );
$m->click('SubmitTicket');
- $m->content_like( qr/Message recorded/i, 'Message recorded' );
+ $m->content_contains('Message recorded', 'Message recorded' );
my @mail = RT::Test->fetch_caught_mails;
ok @mail, 'there are some emails';
check_text_emails( { Encrypt => 1 }, @mail );
+
+ $m->no_warnings_ok;
}
-diag "check encrypting of attachments" if $ENV{TEST_VERBOSE};
+diag "check encrypting of attachments";
{
RT::Test->clean_caught_mails;
ok $m->goto_ticket( $tid ), "UI -> ticket #$tid";
$m->follow_link_ok( { text => 'Reply' }, 'ticket -> reply' );
- $m->form_number(3);
+ $m->form_name('TicketUpdate');
$m->tick( Encrypt => 1 );
$m->field( UpdateCc => 'rt-test@example.com' );
$m->field( UpdateContent => 'Some content' );
$m->field( Attach => $0 );
$m->click('SubmitTicket');
- $m->content_like(
- qr/You are going to encrypt outgoing email messages/i,
+ $m->content_contains(
+ 'You are going to encrypt outgoing email messages',
'problems with keys'
);
- $m->content_like(
- qr/There are several keys suitable for encryption/i,
+ $m->content_contains(
+ 'There are several keys suitable for encryption',
'problems with keys'
);
- my $form = $m->form_number(3);
+ my $form = $m->form_name('TicketUpdate');
ok my $input = $form->find_input( 'UseKey-rt-test@example.com' ), 'found key selector';
is scalar $input->possible_values, 2, 'two options';
$m->select( 'UseKey-rt-test@example.com' => $fpr1 );
$m->click('SubmitTicket');
- $m->content_like( qr/Message recorded/i, 'Message recorded' );
+ $m->content_contains('Message recorded', 'Message recorded' );
my @mail = RT::Test->fetch_caught_mails;
ok @mail, 'there are some emails';
check_text_emails( { Encrypt => 1, Attachment => 1 }, @mail );
-}
-sub check_text_emails {
- my %args = %{ shift @_ };
- my @mail = @_;
-
- ok scalar @mail, "got some mail";
- for my $mail (@mail) {
- for my $type ('email', 'attachment') {
- next if $type eq 'attachment' && !$args{'Attachment'};
-
- my $content = $type eq 'email'
- ? "Some content"
- : "Attachment content";
-
- if ( $args{'Encrypt'} ) {
- unlike $mail, qr/$content/, "outgoing $type was encrypted";
- } else {
- like $mail, qr/$content/, "outgoing $type was not encrypted";
- }
-
- next unless $type eq 'email';
-
- if ( $args{'Sign'} && $args{'Encrypt'} ) {
- like $mail, qr/BEGIN PGP MESSAGE/, 'outgoing email was signed';
- } elsif ( $args{'Sign'} ) {
- like $mail, qr/SIGNATURE/, 'outgoing email was signed';
- } else {
- unlike $mail, qr/SIGNATURE/, 'outgoing email was not signed';
- }
- }
- }
+ $m->no_warnings_ok;
}
-
diff --git a/rt/t/web/gnupg-tickyboxes.t b/rt/t/web/gnupg-tickyboxes.t
new file mode 100644
index 000000000..944539758
--- /dev/null
+++ b/rt/t/web/gnupg-tickyboxes.t
@@ -0,0 +1,84 @@
+#!/usr/bin/perl -w
+use strict;
+use warnings;
+
+use RT::Test::GnuPG tests => 22, gnupg_options => { passphrase => 'rt-test' };
+
+use RT::Action::SendEmail;
+
+RT::Test->import_gnupg_key('rt-recipient@example.com');
+RT::Test->import_gnupg_key('rt-test@example.com', 'public');
+
+my $queue = RT::Test->load_or_create_queue(
+ Name => 'Regression',
+ CorrespondAddress => 'rt-recipient@example.com',
+ CommentAddress => 'rt-recipient@example.com',
+);
+ok $queue && $queue->id, 'loaded or created queue';
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in';
+
+my @variants = (
+ {},
+ { Sign => 1 },
+ { Encrypt => 1 },
+ { Sign => 1, Encrypt => 1 },
+);
+
+# collect emails
+my %mail = (
+ plain => [],
+ signed => [],
+ encrypted => [],
+ signed_encrypted => [],
+);
+
+diag "check in read-only mode that queue's props influence create/update ticket pages";
+{
+ foreach my $variant ( @variants ) {
+ set_queue_crypt_options( $queue => %$variant );
+ $m->goto_create_ticket( $queue );
+ $m->form_name('TicketCreate');
+ if ( $variant->{'Encrypt'} ) {
+ ok $m->value('Encrypt', 2), "encrypt tick box is checked";
+ } else {
+ ok !$m->value('Encrypt', 2), "encrypt tick box is unchecked";
+ }
+ if ( $variant->{'Sign'} ) {
+ ok $m->value('Sign', 2), "sign tick box is checked";
+ } else {
+ ok !$m->value('Sign', 2), "sign tick box is unchecked";
+ }
+ }
+
+ # to avoid encryption/signing during create
+ set_queue_crypt_options($queue);
+
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ my ($id) = $ticket->Create(
+ Subject => 'test',
+ Queue => $queue->id,
+ Requestor => 'rt-test@example.com',
+ );
+ ok $id, 'ticket created';
+
+ foreach my $variant ( @variants ) {
+ set_queue_crypt_options( $queue => %$variant );
+ $m->get( $m->rt_base_url . "/Ticket/Update.html?Action=Respond&id=$id" );
+ $m->form_name('TicketUpdate');
+ if ( $variant->{'Encrypt'} ) {
+ ok $m->value('Encrypt', 2), "encrypt tick box is checked";
+ } else {
+ ok !$m->value('Encrypt', 2), "encrypt tick box is unchecked";
+ }
+ if ( $variant->{'Sign'} ) {
+ ok $m->value('Sign', 2), "sign tick box is checked";
+ } else {
+ ok !$m->value('Sign', 2), "sign tick box is unchecked";
+ }
+ }
+}
+
+
+
diff --git a/rt/t/web/googleish_search.t b/rt/t/web/googleish_search.t
new file mode 100644
index 000000000..e2a4e9116
--- /dev/null
+++ b/rt/t/web/googleish_search.t
@@ -0,0 +1,219 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test tests => 96, config => 'Set( %FullTextSearch, Enable => 1, Indexed => 0 );';
+my ($baseurl, $m) = RT::Test->started_ok;
+my $url = $m->rt_base_url;
+
+my $queue = RT::Queue->new($RT::SystemUser);
+$queue->Create( Name => 'other' );
+ok( $queue->id, 'created queue other');
+
+my $two_words_queue = RT::Test->load_or_create_queue(
+ Name => 'Two Words',
+);
+ok $two_words_queue && $two_words_queue->id, 'loaded or created a queue';
+
+
+{
+ my $tickets = RT::Tickets->new( RT->SystemUser );
+ my $active = "( ".join( " OR ", map "Status = '$_'", RT::Queue->ActiveStatusArray())." )";
+ my $inactive = "( ".join( " OR ", map "Status = '$_'", RT::Queue->InactiveStatusArray())." )";
+
+ require RT::Search::Googleish;
+ my $parser = RT::Search::Googleish->new(
+ TicketsObj => $tickets,
+ Argument => '',
+ );
+ is $parser->QueryToSQL("foo"), "$active AND ( Subject LIKE 'foo' )", "correct parsing";
+ is $parser->QueryToSQL("1"), "( Id = 1 )", "correct parsing";
+ is $parser->QueryToSQL("#1"), "( Id = 1 )", "correct parsing";
+ is $parser->QueryToSQL("'1'"), "$active AND ( Subject LIKE '1' )", "correct parsing";
+
+ is $parser->QueryToSQL("foo bar"),
+ "$active AND ( Subject LIKE 'foo' AND Subject LIKE 'bar' )",
+ "correct parsing";
+ is $parser->QueryToSQL("'foo bar'"),
+ "$active AND ( Subject LIKE 'foo bar' )",
+ "correct parsing";
+
+ is $parser->QueryToSQL("'foo \\' bar'"),
+ "$active AND ( Subject LIKE 'foo \\' bar' )",
+ "correct parsing";
+ is $parser->QueryToSQL('"foo \' bar"'),
+ "$active AND ( Subject LIKE 'foo \\' bar' )",
+ "correct parsing";
+ is $parser->QueryToSQL('"\f\o\o"'),
+ "$active AND ( Subject LIKE '\\\\f\\\\o\\\\o' )",
+ "correct parsing";
+
+ is $parser->QueryToSQL("General"), "( Queue = 'General' ) AND $active", "correct parsing";
+ is $parser->QueryToSQL("'Two Words'"), "$active AND ( Subject LIKE 'Two Words' )", "correct parsing";
+ is $parser->QueryToSQL("queue:'Two Words'"), "( Queue = 'Two Words' ) AND $active", "correct parsing";
+ is $parser->QueryToSQL("subject:'Two Words'"), "$active AND ( Subject LIKE 'Two Words' )", "correct parsing";
+
+ is $parser->QueryToSQL("me"), "( Owner.id = '__CurrentUser__' ) AND $active", "correct parsing";
+ is $parser->QueryToSQL("'me'"), "$active AND ( Subject LIKE 'me' )", "correct parsing";
+ is $parser->QueryToSQL("owner:me"), "( Owner.id = '__CurrentUser__' ) AND $active", "correct parsing";
+ is $parser->QueryToSQL("owner:'me'"), "( Owner = 'me' ) AND $active", "correct parsing";
+
+ is $parser->QueryToSQL("resolved me"), "( Owner.id = '__CurrentUser__' ) AND ( Status = 'resolved' )", "correct parsing";
+ is $parser->QueryToSQL("resolved active me"), "( Owner.id = '__CurrentUser__' ) AND ( Status = 'resolved' OR Status = 'new' OR Status = 'open' OR Status = 'stalled' )", "correct parsing";
+ is $parser->QueryToSQL("status:active"), $active, "Explicit active search";
+ is $parser->QueryToSQL("status:'active'"), "( Status = 'active' )", "Quoting active makes it the actual word";
+ is $parser->QueryToSQL("inactive me"), "( Owner.id = '__CurrentUser__' ) AND $inactive", "correct parsing";
+
+ is $parser->QueryToSQL("cf.Foo:bar"), "( 'CF.{Foo}' LIKE 'bar' ) AND $active", "correct parsing of CFs";
+ is $parser->QueryToSQL(q{cf."don't foo?":'bar n\\' baz'}), qq/( 'CF.{don\\'t foo?}' LIKE 'bar n\\' baz' ) AND $active/, "correct parsing of CFs with quotes";
+}
+
+my $ticket_found_1 = RT::Ticket->new($RT::SystemUser);
+my $ticket_found_2 = RT::Ticket->new($RT::SystemUser);
+my $ticket_not_found = RT::Ticket->new($RT::SystemUser);
+
+$ticket_found_1->Create(
+ Subject => 'base ticket 1'.$$,
+ Queue => 'general',
+ Owner => 'root',
+ Requestor => 'customsearch@localhost',
+ Content => 'this is base ticket 1',
+);
+ok( $ticket_found_1->id, 'created ticket for custom search');
+
+
+$ticket_found_2->Create(
+ Subject => 'base ticket 2'.$$,
+ Queue => 'general',
+ Owner => 'root',
+ Requestor => 'customsearch@localhost',
+ Content => 'this is base ticket 2',
+);
+ok( $ticket_found_2->id, 'created ticket for custom search');
+
+$ticket_not_found = RT::Ticket->new($RT::SystemUser);
+$ticket_not_found->Create(
+ Subject => 'not found subject' . $$,
+ Queue => 'other',
+ Owner => 'nobody',
+ Requestor => 'notfound@localhost',
+ Content => 'this is not found content',
+);
+ok( $ticket_not_found->id, 'created ticket for custom search');
+
+ok($m->login, 'logged in');
+
+my @queries = (
+ 'base ticket', 'root',
+ 'customsearch@localhost', 'requestor:customsearch',
+ 'subject:base', 'subject:"base ticket"',
+ 'queue:general', 'owner:root',
+);
+
+for my $q (@queries) {
+ $m->form_with_fields('q');
+ $m->field( q => $q );
+ $m->submit;
+ $m->content_contains( 'base ticket 1', 'base ticket 1 is found' );
+ $m->content_contains( 'base ticket 2', 'base ticket 2 is found' );
+ $m->content_lacks( 'not found subject', 'not found ticket is not found' );
+}
+
+$ticket_not_found->SetStatus('open');
+is( $ticket_not_found->Status, 'open', 'status of not found ticket is open' );
+@queries = qw/new status:new/;
+for my $q (@queries) {
+ $m->form_with_fields('q');
+ $m->field( q => $q );
+ $m->submit;
+ $m->content_contains( 'base ticket 1', 'base ticket 1 is found' );
+ $m->content_contains( 'base ticket 2', 'base ticket 2 is found' );
+ $m->content_lacks( 'not found subject', 'not found ticket is not found' );
+}
+
+@queries = ( 'fulltext:"base ticket 1"', "'base ticket 1'" );
+for my $q (@queries) {
+ $m->form_with_fields('q');
+ $m->field( q => $q );
+ $m->submit;
+ $m->content_contains( 'base ticket 1', 'base ticket 1 is found' );
+ $m->content_lacks( 'base ticket 2', 'base ticket 2 is not found' );
+ $m->content_lacks( 'not found subject', 'not found ticket is not found' );
+}
+
+# now let's test with ' or "
+for my $quote ( q{'}, q{"} ) {
+ my $user = RT::User->new($RT::SystemUser);
+ is( ref($user), 'RT::User' );
+ my ( $id, $msg ) = $user->Create(
+ Name => qq!foo${quote}bar!,
+ EmailAddress => qq!foo${quote}bar$$\@example.com !,
+ Privileged => 1,
+ );
+ ok ($id, "Creating user - " . $msg );
+
+ my ( $grantid, $grantmsg ) =
+ $user->PrincipalObj->GrantRight( Right => 'OwnTicket' );
+ ok( $grantid, $grantmsg );
+
+
+
+ my $ticket_quote = RT::Ticket->new($RT::SystemUser);
+ $ticket_quote->Create(
+ Subject => qq!base${quote}ticket $$!,
+ Queue => 'general',
+ Owner => $user->Name,
+ Requestor => qq!custom${quote}search\@localhost!,
+ Content => qq!this is base${quote}ticket with quote inside!,
+ );
+ ok( $ticket_quote->id, 'created ticket with quote for custom search' );
+
+ @queries = (
+ qq!fulltext:base${quote}ticket!,
+ "base${quote}ticket",
+ "owner:foo${quote}bar",
+ "foo${quote}bar",
+
+ # email doesn't allow " character
+ $quote eq q{'}
+ ? (
+ "requestor:custom${quote}search\@localhost",
+ "custom${quote}search\@localhost",
+ )
+ : (),
+ );
+ for my $q (@queries) {
+ $m->form_with_fields('q');
+ $m->field( q => $q );
+ $m->submit;
+ my $escape_quote = $quote;
+ RT::Interface::Web::EscapeUTF8(\$escape_quote);
+ $m->content_contains( "base${escape_quote}ticket",
+ "base${quote}ticket is found" );
+ }
+}
+
+# Create a CF
+{
+ my $cf = RT::CustomField->new(RT->SystemUser);
+ ok( $cf->Create(Name => 'Foo', Type => 'Freeform', MaxValues => '1', Queue => 0) );
+ ok $cf->Id;
+
+ $ticket_found_1->AddCustomFieldValue( Field => 'Foo', Value => 'bar' );
+ $ticket_found_2->AddCustomFieldValue( Field => 'Foo', Value => 'bar' );
+ $ticket_not_found->AddCustomFieldValue( Field => 'Foo', Value => 'baz' );
+ is( $ticket_found_1->FirstCustomFieldValue('Foo'), 'bar', 'cf value is ok' );
+ is( $ticket_found_2->FirstCustomFieldValue('Foo'), 'bar', 'cf value is ok' );
+ is( $ticket_not_found->FirstCustomFieldValue('Foo'), 'baz', 'cf value is ok' );
+
+ @queries = qw/cf.Foo:bar/;
+ for my $q (@queries) {
+ $m->form_with_fields('q');
+ $m->field( q => $q );
+ $m->submit;
+ $m->content_contains( 'base ticket 1', 'base ticket 1 is found' );
+ $m->content_contains( 'base ticket 2', 'base ticket 2 is found' );
+ $m->content_lacks( 'not found subject', 'not found ticket is not found' );
+ }
+}
+
diff --git a/rt/t/web/group_create.t b/rt/t/web/group_create.t
new file mode 100644
index 000000000..26da59268
--- /dev/null
+++ b/rt/t/web/group_create.t
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 13;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+my $root = RT::User->new(RT->SystemUser);
+ok( $root->Load('root'), 'load root user' );
+
+my $group_name = 'test group';
+
+my $group_id;
+diag "Create a group";
+{
+ $m->follow_link( id => 'tools-config-groups-create');
+
+ # Test group form validation
+ $m->submit_form(
+ form_name => 'ModifyGroup',
+ fields => {
+ Name => '',
+ },
+ );
+ $m->text_contains('Name is required');
+ $m->submit_form(
+ form_name => 'ModifyGroup',
+ fields => {
+ Name => '0',
+ },
+ );
+ $m->text_contains('Could not create group');
+ $m->submit_form(
+ form_name => 'ModifyGroup',
+ fields => {
+ Name => '1',
+ },
+ );
+ $m->text_contains('Could not create group');
+ $m->submit_form(
+ form_name => 'ModifyGroup',
+ fields => {
+ Name => $group_name,
+ },
+ );
+ $m->content_contains('Group created', 'created group sucessfully' );
+
+ # Test validation on updae
+ $m->form_name('ModifyGroup');
+ $m->set_fields(
+ Name => '',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->text_contains('Illegal value for Name');
+
+ $m->form_name('ModifyGroup');
+ $m->set_fields(
+ Name => '0',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->text_contains('Illegal value for Name');
+
+ $m->form_name('ModifyGroup');
+ $m->set_fields(
+ Name => '1',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->text_contains('Illegal value for Name');
+
+ $group_id = $m->form_name('ModifyGroup')->value('id');
+ ok $group_id, "found id of the group in the form, it's #$group_id";
+}
+
diff --git a/rt/t/web/html/Callbacks/logout.t/NoAuth/Logout.html/Default b/rt/t/web/html/Callbacks/logout.t/NoAuth/Logout.html/Default
new file mode 100644
index 000000000..90278ae49
--- /dev/null
+++ b/rt/t/web/html/Callbacks/logout.t/NoAuth/Logout.html/Default
@@ -0,0 +1,6 @@
+<%args>
+$URL
+</%args>
+<%init>
+$$URL = 'http://bestpractical.com/rt';
+</%init>
diff --git a/rt/t/web/html/NoAuth/js/not-by-default.js b/rt/t/web/html/NoAuth/js/not-by-default.js
new file mode 100644
index 000000000..568f670ee
--- /dev/null
+++ b/rt/t/web/html/NoAuth/js/not-by-default.js
@@ -0,0 +1,3 @@
+function just_testing() {
+ alert("hi");
+}
diff --git a/rt/t/web/html/delete-article-name-method.html b/rt/t/web/html/delete-article-name-method.html
new file mode 100644
index 000000000..27592c1d0
--- /dev/null
+++ b/rt/t/web/html/delete-article-name-method.html
@@ -0,0 +1,15 @@
+<%INIT>
+# This is used by t/web/articles-links.t. Since we fork off a server
+# under most test configurations, and we need a way to run code in the
+# middle of the test script, we have to play at shenanigans to delete
+# RT::Article's Name method. Other options were a Plack::Middleware that
+# eval'd code given by paths like /__perl/(.+) (is scary), a signal
+# handler (fails under apache), and only running articles-links.t for
+# inline tests (fails under apache and standalone)
+
+delete $RT::Article::{Name};
+
+</%INIT>
+
+<% RT::Article->can('Name') ? '{exists}' : '{deleted}' %>
+
diff --git a/rt/t/web/html_template.t b/rt/t/web/html_template.t
index a2461dc97..662a26bbd 100644
--- a/rt/t/web/html_template.t
+++ b/rt/t/web/html_template.t
@@ -8,22 +8,17 @@ use Encode;
my ( $baseurl, $m ) = RT::Test->started_ok;
ok $m->login, 'logged in as root';
-$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
-RT::Test->set_mail_catcher;
-
use utf8;
diag('make Autoreply template a html one and add utf8 chars')
if $ENV{TEST_VERBOSE};
{
- $m->follow_link_ok( { text => 'Configuration' }, '-> Configuration' );
- $m->follow_link_ok( { text => 'Global' }, '-> Global' );
- $m->follow_link_ok( { text => 'Templates' }, '-> Templates' );
+ $m->follow_link_ok( { id => 'tools-config-global-templates' }, '-> Templates' );
$m->follow_link_ok( { text => 'Autoreply' }, '-> Autoreply' );
- $m->form_number(3);
$m->submit_form(
+ form_name => 'ModifyTemplate',
fields => {
Content => <<'EOF',
Subject: AutoReply: {$Ticket->Subject}
@@ -46,9 +41,8 @@ diag('create a ticket to see the autoreply mail') if $ENV{TEST_VERBOSE};
{
$m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
- $m->form_number(3);
$m->submit_form(
- form_number => 3,
+ form_name => 'TicketCreate',
fields => { Subject => '标题', Content => '<h1>测试</h1>',
ContentType => 'text/html' },
);
diff --git a/rt/t/web/logout.t b/rt/t/web/logout.t
new file mode 100644
index 000000000..889e5fc18
--- /dev/null
+++ b/rt/t/web/logout.t
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test tests => 12;
+
+my ($baseurl, $agent) = RT::Test->started_ok;
+
+my $url = $agent->rt_base_url;
+diag $url if $ENV{TEST_VERBOSE};
+
+# test that logout would actually redirects to the correct URL
+{
+ ok $agent->login, "logged in";
+ $agent->follow_link_ok({ text => 'Logout' });
+ like $agent->uri, qr'/Logout\.html$', "right url";
+ $agent->content_contains('<meta http-equiv="refresh" content="1;URL=/"', "found the expected meta-refresh");
+}
+
+# Stop server and set MasonLocalComponentRoot
+RT::Test->stop_server;
+
+RT->Config->Set(MasonLocalComponentRoot => RT::Test::get_abs_relocatable_dir('html'));
+
+($baseurl, $agent) = RT::Test->started_ok;
+
+$url = $agent->rt_base_url;
+diag $url if $ENV{TEST_VERBOSE};
+
+# test that logout would actually redirects to URL from the callback
+{
+ ok $agent->login, "logged in";
+ $agent->follow_link_ok({ text => 'Logout' });
+ like $agent->uri, qr'/Logout\.html$', "right url";
+ $agent->content_contains('<meta http-equiv="refresh" content="1;URL=http://bestpractical.com/rt"', "found the expected meta-refresh");
+}
+
+
+1;
diff --git a/rt/t/web/offline.t b/rt/t/web/offline.t
new file mode 100644
index 000000000..b3762fc20
--- /dev/null
+++ b/rt/t/web/offline.t
@@ -0,0 +1,78 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test tests => 20;
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login, 'logged in' );
+
+{
+ my $template = <<EOF;
+===Create-Ticket: ticket1
+Queue: General
+Subject: test
+Status: new
+EOF
+ my $ticket = create_ticket_offline( $m, $template );
+ ok $ticket->id, 'created a ticket with offline tool';
+ is $ticket->QueueObj->Name, 'General', 'correct value';
+ is $ticket->Subject, 'test', 'correct value';
+ is $ticket->Status, 'new', 'correct value';
+}
+
+{
+ my $template = <<'EOF';
+===Create-Ticket: ticket1
+Queue: General
+Subject: test
+Status: new
+Requestor: test@example.com
+EOF
+ my $ticket = create_ticket_offline( $m, $template );
+ ok $ticket->id, 'created a ticket with offline tool';
+ is $ticket->RequestorAddresses, 'test@example.com', 'correct value';
+}
+
+{
+ my $group = RT::Group->new(RT->SystemUser);
+ my ($id, $msg) = $group->CreateUserDefinedGroup( Name => 'test' );
+ ok $id, "created a user defined group";
+
+ my $template = <<'EOF';
+===Create-Ticket: ticket1
+Queue: General
+Subject: test
+Status: new
+Requestor: test@example.com
+RequestorGroup: test
+EOF
+ my $ticket = create_ticket_offline( $m, $template );
+ ok $ticket->id, 'created a ticket with offline tool';
+ ok grep(
+ { $_->MemberId eq $group->id }
+ @{ $ticket->Requestors->MembersObj->ItemsArrayRef }
+ ), 'correct value' ;
+ is $ticket->RequestorAddresses, 'test@example.com', 'correct value';
+}
+
+sub create_ticket_offline {
+ my ($m, $template) = @_;
+
+ $m->get_ok( $url . '/Tools/Offline.html' );
+
+ $m->submit_form(
+ form_name => 'TicketUpdate',
+ fields => { string => $template },
+ button => 'UpdateTickets',
+ );
+
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ $m->content_like( qr/Ticket \d+ created/, 'found ticket created message' )
+ or return $ticket;
+
+ $ticket->Load( $m->content =~ /Ticket (\d+) created/ );
+ return $ticket;
+}
+
+
diff --git a/rt/t/web/offline_messages_utf8.t b/rt/t/web/offline_messages_utf8.t
index 9901b4555..bf9cf39fa 100644
--- a/rt/t/web/offline_messages_utf8.t
+++ b/rt/t/web/offline_messages_utf8.t
@@ -2,8 +2,7 @@
use strict;
use warnings;
-use RT::Test tests => 6;
-use File::Temp qw/tempfile/;
+use RT::Test tests => 8;
use Encode;
use RT::Ticket;
diff --git a/rt/t/web/offline_utf8.t b/rt/t/web/offline_utf8.t
index 2a3e64d3c..24795c0d3 100644
--- a/rt/t/web/offline_utf8.t
+++ b/rt/t/web/offline_utf8.t
@@ -2,11 +2,14 @@
use strict;
use warnings;
-use RT::Test tests => 8;
-use File::Temp qw/tempfile/;
+use RT::Test tests => 9;
+use utf8;
+
use Encode;
+
use RT::Ticket;
-my ( $fh, $file ) = tempfile;
+my $file = File::Spec->catfile( RT::Test->temp_directory, 'template' );
+open my $fh, '>', $file or die $!;
my $template = <<EOF;
===Create-Ticket: ticket1
Queue: General
@@ -38,17 +41,17 @@ $m->submit_form(
button => 'UpdateTickets',
# mimic what browsers do: they seems decoded $template
- fields => { string => decode( 'utf8', $template ), },
+ fields => { string => $template },
);
$m->content_like( qr/Ticket \d+ created/, 'found ticket created message' );
my ( $ticket_id ) = $m->content =~ /Ticket (\d+) created/;
-my $ticket = RT::Ticket->new( $RT::SystemUser );
+my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $ticket_id );
is( $ticket->Subject, '标题', 'subject in $ticket is right' );
-$m->get_ok( $url . "/Ticket/Display.html?id=$ticket_id" );
+$m->goto_ticket($ticket_id);
$m->content_contains( '这是正文',
'content is right in ticket display page' );
diff --git a/rt/t/web/passthrough-jsmin b/rt/t/web/passthrough-jsmin
new file mode 100644
index 000000000..3d9bf0129
--- /dev/null
+++ b/rt/t/web/passthrough-jsmin
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo "// passthrough-jsmin added this";
+
+exec cat;
diff --git a/rt/t/web/path-traversal.t b/rt/t/web/path-traversal.t
index 8d2f5cc88..5d5c954a1 100644
--- a/rt/t/web/path-traversal.t
+++ b/rt/t/web/path-traversal.t
@@ -1,7 +1,7 @@
use strict;
use warnings;
-use RT::Test tests => 20;
+use RT::Test tests => 22;
my ($baseurl, $agent) = RT::Test->started_ok;
@@ -19,11 +19,17 @@ $agent->warning_like(qr/Invalid request.*aborting/,);
$agent->get("$baseurl/NoAuth/../../../etc/RT_Config.pm");
is($agent->status, 400);
-$agent->warning_like(qr/Invalid request.*aborting/,);
+SKIP: {
+ skip "Apache rejects busting up above / for us", 2 if $ENV{RT_TEST_WEB_HANDLER} =~ /^apache/;
+ $agent->warning_like(qr/Invalid request.*aborting/,);
+};
$agent->get("$baseurl/NoAuth/css/web2/images/../../../../../../etc/RT_Config.pm");
is($agent->status, 400);
-$agent->warning_like(qr/Invalid request.*aborting/,);
+SKIP: {
+ skip "Apache rejects busting up above / for us", 2 if $ENV{RT_TEST_WEB_HANDLER} =~ /^apache/;
+ $agent->warning_like(qr/Invalid request.*aborting/,);
+};
# do not reject these URLs, even though they contain /. outside the path
$agent->get("$baseurl/index.html?ignored=%2F%2E");
diff --git a/rt/t/web/private-components.t b/rt/t/web/private-components.t
index 30e145f34..ceb2b34af 100644
--- a/rt/t/web/private-components.t
+++ b/rt/t/web/private-components.t
@@ -1,6 +1,6 @@
use strict;
-use RT::Test tests => 20;
+use RT::Test tests => 24;
my ($baseurl, $agent) = RT::Test->started_ok;
ok $agent->login, 'logged in';
@@ -18,6 +18,10 @@ $agent->get("/Widgets/TitleBox?title=private");
is($agent->status, 403);
$agent->content_lacks("private");
+$agent->get("/m/_elements/header?title=private");
+is($agent->status, 403);
+$agent->content_lacks("private");
+
$agent->get("/autohandler");
is($agent->status, 403);
$agent->content_lacks("comp called without component");
diff --git a/rt/t/web/query_builder.t b/rt/t/web/query_builder.t
index 25d6ec5a3..0abbfaca8 100644
--- a/rt/t/web/query_builder.t
+++ b/rt/t/web/query_builder.t
@@ -5,7 +5,7 @@ use HTTP::Request::Common;
use HTTP::Cookies;
use LWP;
use Encode;
-use RT::Test tests => 50;
+use RT::Test tests => 56;
my $cookie_jar = HTTP::Cookies->new;
my ($baseurl, $agent) = RT::Test->started_ok;
@@ -22,12 +22,12 @@ ok $queue && $queue->id, 'loaded or created queue';
my $url = $agent->rt_base_url;
ok $agent->login, "logged in";
-# {{{ Query Builder tests
my $response = $agent->get($url."Search/Build.html");
ok $response->is_success, "Fetched ". $url ."Search/Build.html";
sub getQueryFromForm {
+ my $agent = shift;
$agent->form_name('BuildQuery');
# This pulls out the "hidden input" query from the page
my $q = $agent->current_form->find_input("Query")->value;
@@ -38,117 +38,117 @@ sub getQueryFromForm {
}
sub selectedClauses {
+ my $agent = shift;
my @clauses = grep { defined } map { $_->value } $agent->current_form->find_input("clauses");
return [ @clauses ];
}
-diag "add the first condition" if $ENV{'TEST_VERBOSE'};
+diag "add the first condition";
{
ok $agent->form_name('BuildQuery'), "found the form once";
$agent->field("ActorField", "Owner");
$agent->field("ActorOp", "=");
$agent->field("ValueOfActor", "Nobody");
$agent->submit;
- is getQueryFromForm, "Owner = 'Nobody'", 'correct query';
+ is getQueryFromForm($agent), "Owner = 'Nobody'", 'correct query';
}
-diag "set the next condition" if $ENV{'TEST_VERBOSE'};
+diag "set the next condition";
{
ok($agent->form_name('BuildQuery'), "found the form again");
$agent->field("QueueOp", "!=");
$agent->field("ValueOfQueue", "Regression");
$agent->submit;
- is getQueryFromForm, "Owner = 'Nobody' AND Queue != 'Regression'",
+ is getQueryFromForm($agent), "Owner = 'Nobody' AND Queue != 'Regression'",
'correct query';
}
-diag "We're going to delete the owner" if $ENV{'TEST_VERBOSE'};
+diag "We're going to delete the owner";
{
$agent->select("clauses", ["0"] );
$agent->click("DeleteClause");
ok $agent->form_name('BuildQuery'), "found the form";
- is getQueryFromForm, "Queue != 'Regression'", 'correct query';
+ is getQueryFromForm($agent), "Queue != 'Regression'", 'correct query';
}
-diag "add a cond with OR and se number by the way" if $ENV{'TEST_VERBOSE'};
+diag "add a cond with OR and se number by the way";
{
$agent->field("AndOr", "OR");
$agent->select("idOp", ">");
$agent->field("ValueOfid" => "1234");
$agent->click("AddClause");
ok $agent->form_name('BuildQuery'), "found the form again";
- is getQueryFromForm, "Queue != 'Regression' OR id > 1234",
+ is getQueryFromForm($agent), "Queue != 'Regression' OR id > 1234",
"added something as OR, and number not quoted";
- is_deeply selectedClauses, ["1"], 'the id that we just entered is still selected';
+ is_deeply selectedClauses($agent), ["1"], 'the id that we just entered is still selected';
}
-diag "Move the second one up a level" if $ENV{'TEST_VERBOSE'};
+diag "Move the second one up a level";
{
$agent->click("Up");
ok $agent->form_name('BuildQuery'), "found the form again";
- is getQueryFromForm, "id > 1234 OR Queue != 'Regression'", "moved up one";
- is_deeply selectedClauses, ["0"], 'the one we moved up is selected';
+ is getQueryFromForm($agent), "id > 1234 OR Queue != 'Regression'", "moved up one";
+ is_deeply selectedClauses($agent), ["0"], 'the one we moved up is selected';
}
-diag "Move the second one right" if $ENV{'TEST_VERBOSE'};
+diag "Move the second one right";
{
$agent->click("Right");
ok $agent->form_name('BuildQuery'), "found the form again";
- is getQueryFromForm, "Queue != 'Regression' OR ( id > 1234 )",
+ is getQueryFromForm($agent), "Queue != 'Regression' OR ( id > 1234 )",
"moved over to the right (and down)";
- is_deeply selectedClauses, ["2"], 'the one we moved right is selected';
+ is_deeply selectedClauses($agent), ["2"], 'the one we moved right is selected';
}
-diag "Move the block up" if $ENV{'TEST_VERBOSE'};
+diag "Move the block up";
{
$agent->select("clauses", ["1"]);
$agent->click("Up");
ok $agent->form_name('BuildQuery'), "found the form again";
- is getQueryFromForm, "( id > 1234 ) OR Queue != 'Regression'", "moved up";
- is_deeply selectedClauses, ["0"], 'the one we moved up is selected';
+ is getQueryFromForm($agent), "( id > 1234 ) OR Queue != 'Regression'", "moved up";
+ is_deeply selectedClauses($agent), ["0"], 'the one we moved up is selected';
}
-diag "Can not move up the top most clause" if $ENV{'TEST_VERBOSE'};
+diag "Can not move up the top most clause";
{
$agent->select("clauses", ["0"]);
$agent->click("Up");
ok $agent->form_name('BuildQuery'), "found the form again";
- $agent->content_like(qr/error: can\S+t move up/, "i shouldn't have been able to hit up");
- is_deeply selectedClauses, ["0"], 'the one we tried to move is selected';
+ $agent->content_contains("error: can&#39;t move up", "i shouldn't have been able to hit up");
+ is_deeply selectedClauses($agent), ["0"], 'the one we tried to move is selected';
}
-diag "Can not move left the left most clause" if $ENV{'TEST_VERBOSE'};
+diag "Can not move left the left most clause";
{
$agent->click("Left");
ok($agent->form_name('BuildQuery'), "found the form again");
- $agent->content_like(qr/error: can\S+t move left/, "i shouldn't have been able to hit left");
- is_deeply selectedClauses, ["0"], 'the one we tried to move is selected';
+ $agent->content_contains("error: can&#39;t move left", "i shouldn't have been able to hit left");
+ is_deeply selectedClauses($agent), ["0"], 'the one we tried to move is selected';
}
-diag "Add a condition into a nested block" if $ENV{'TEST_VERBOSE'};
+diag "Add a condition into a nested block";
{
$agent->select("clauses", ["1"]);
$agent->select("ValueOfStatus" => "stalled");
$agent->submit;
ok $agent->form_name('BuildQuery'), "found the form again";
- is_deeply selectedClauses, ["2"], 'the one we added is only selected';
- is getQueryFromForm,
+ is_deeply selectedClauses($agent), ["2"], 'the one we added is only selected';
+ is getQueryFromForm($agent),
"( id > 1234 AND Status = 'stalled' ) OR Queue != 'Regression'",
"added new one";
}
-diag "click advanced, enter 'C1 OR ( C2 AND C3 )', apply, aggregators should stay the same."
- if $ENV{'TEST_VERBOSE'};
+diag "click advanced, enter 'C1 OR ( C2 AND C3 )', apply, aggregators should stay the same.";
{
my $response = $agent->get($url."Search/Edit.html");
ok( $response->is_success, "Fetched /Search/Edit.html" );
- ok($agent->form_number(3), "found the form");
+ ok($agent->form_name('BuildQueryAdvanced'), "found the form");
$agent->field("Query", "Status = 'new' OR ( Status = 'open' AND Subject LIKE 'office' )");
$agent->submit;
- is( getQueryFromForm,
+ is( getQueryFromForm($agent),
"Status = 'new' OR ( Status = 'open' AND Subject LIKE 'office' )",
"no aggregators change"
);
@@ -194,11 +194,10 @@ diag "click advanced, enter 'C1 OR ( C2 AND C3 )', apply, aggregators should sta
# - clears entire query
# - clears it from the session, too
-# }}}
# create a custom field with nonascii name and try to add a condition
{
- my $cf = RT::CustomField->new( $RT::SystemUser );
+ my $cf = RT::CustomField->new( RT->SystemUser );
$cf->LoadByName( Name => "\x{442}", Queue => 0 );
if ( $cf->id ) {
is($cf->Type, 'Freeform', 'loaded and type is correct');
@@ -217,22 +216,21 @@ diag "click advanced, enter 'C1 OR ( C2 AND C3 )', apply, aggregators should sta
ok($agent->form_name('BuildQuery'), "found the form once");
$agent->field("ValueOf'CF.{\x{442}}'", "\x{441}");
$agent->submit();
- is( getQueryFromForm,
+ is( getQueryFromForm($agent),
"'CF.{\x{442}}' LIKE '\x{441}'",
"no changes, no duplicate condition with badly encoded text"
);
}
-diag "input a condition, select (several conditions), click delete"
- if $ENV{'TEST_VERBOSE'};
+diag "input a condition, select (several conditions), click delete";
{
my $response = $agent->get( $url."Search/Edit.html" );
ok $response->is_success, "Fetched /Search/Edit.html";
- ok $agent->form_number(3), "found the form";
+ ok $agent->form_name('BuildQueryAdvanced'), "found the form";
$agent->field("Query", "( Status = 'new' OR Status = 'open' )");
$agent->submit;
- is( getQueryFromForm,
+ is( getQueryFromForm($agent),
"( Status = 'new' OR Status = 'open' )",
"query is the same"
);
@@ -240,7 +238,7 @@ diag "input a condition, select (several conditions), click delete"
$agent->field( ValueOfid => 10 );
$agent->click("DeleteClause");
- is( getQueryFromForm,
+ is( getQueryFromForm($agent),
"id < 10",
"replaced query successfuly"
);
@@ -251,7 +249,7 @@ diag "send query with not quoted negative number";
my $response = $agent->get($url."Search/Build.html?Query=Priority%20>%20-2");
ok( $response->is_success, "Fetched " . $url."Search/Build.html" );
- is( getQueryFromForm,
+ is( getQueryFromForm($agent),
"Priority > -2",
"query is the same"
);
@@ -261,7 +259,7 @@ diag "click advanced, enter an invalid SQL IS restriction, apply and check that
{
my $response = $agent->get($url."Search/Edit.html");
ok( $response->is_success, "Fetched /Search/Edit.html" );
- ok($agent->form_number(3), "found the form");
+ ok($agent->form_name('BuildQueryAdvanced'), "found the form");
$agent->field("Query", "Requestor.EmailAddress IS 'FOOBAR'");
$agent->submit;
is( getQueryFromForm($agent),
@@ -274,7 +272,7 @@ diag "click advanced, enter an invalid SQL IS NOT restriction, apply and check t
{
my $response = $agent->get($url."Search/Edit.html");
ok( $response->is_success, "Fetched /Search/Edit.html" );
- ok($agent->form_number(3), "found the form");
+ ok($agent->form_name('BuildQueryAdvanced'), "found the form");
$agent->field("Query", "Requestor.EmailAddress IS NOT 'FOOBAR'");
$agent->submit;
is( getQueryFromForm($agent),
@@ -283,3 +281,17 @@ diag "click advanced, enter an invalid SQL IS NOT restriction, apply and check t
);
}
+diag "click advanced, enter a valid SQL, but the field is lower cased";
+{
+ my $response = $agent->get($url."Search/Edit.html");
+ ok( $response->is_success, "Fetched /Search/Edit.html" );
+ ok($agent->form_name('BuildQueryAdvanced'), "found the form");
+ $agent->field("Query", "status = 'new'");
+ $agent->submit;
+ $agent->content_lacks( 'Unknown field:', 'no "unknown field" warning' );
+ is( getQueryFromForm($agent),
+ "Status = 'new'",
+ "field's case is corrected"
+ );
+}
+
diff --git a/rt/t/web/query_log.t b/rt/t/web/query_log.t
new file mode 100644
index 000000000..e19f44dc6
--- /dev/null
+++ b/rt/t/web/query_log.t
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test tests => 9;
+
+RT->Config->Set(StatementLog => 1);
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in';
+
+my $root = RT::User->new($RT::SystemUser);
+$root->LoadByEmail('root@localhost');
+
+$m->get_ok("/Admin/Tools/Queries.html");
+$m->text_contains("/index.html", "we include info about a page we hit while logging in");
+$m->text_contains("Stack:", "stack traces");
+$m->text_like(qr{share/html/autohandler:\d+}, "stack trace includes mason components");
+$m->text_contains("SELECT * FROM Principals WHERE id = '".$root->id."'", "we interpolate bind params");
+
diff --git a/rt/t/web/queue_caching.t b/rt/t/web/queue_caching.t
new file mode 100644
index 000000000..d90aacbdf
--- /dev/null
+++ b/rt/t/web/queue_caching.t
@@ -0,0 +1,90 @@
+use strict;
+use warnings;
+use RT::Test tests => 36;
+
+# make an initial queue, so we have more than 1
+my $original_test_queue = new_queue("Test$$");
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in';
+
+diag("Check for 2 existing queues being visible");
+{
+ check_queues($m);
+}
+
+diag("Add a new queue, which won't show up until we fix the cache");
+{
+ new_queue("New Test $$");
+ check_queues($m);
+}
+
+diag("Disable an existing queue, it should stop appearing in the list");
+{
+ ok($original_test_queue->SetDisabled(1));
+ check_queues($m);
+}
+
+diag("Bring back a disabled queue");
+{
+ ok($original_test_queue->SetDisabled(0));
+ check_queues($m);
+}
+
+diag("Test a user who has more limited rights Queues");
+{
+
+my $user_a = RT::Test->load_or_create_user(
+ Name => 'user_a', Password => 'password',
+);
+ok $user_a && $user_a->id, 'loaded or created user';
+
+ok( RT::Test->set_rights(
+ { Principal => $user_a, Right => [qw(SeeQueue CreateTicket)], Object => $original_test_queue },
+), 'Allow user a to see the testing queue');
+
+my $a_m = RT::Test::Web->new;
+ok $a_m->login('user_a', 'password'), 'logged in as user A';
+
+# check that they see a single queue
+check_queues($a_m,[$original_test_queue->Id]);
+
+ok( RT::Test->add_rights(
+ { Principal => $user_a, Right => [qw(SeeQueue CreateTicket)] },
+), 'add global queue viewing rights');
+
+check_queues($a_m);
+
+}
+
+sub new_queue {
+ my $name = shift;
+ my $new_queue = RT::Queue->new(RT->SystemUser);
+ ok($new_queue->Create( Name => $name, Description => "Testing for $name queue" ), "Created queue ".$new_queue->Name);
+ return $new_queue;
+}
+
+sub internal_queues {
+ my $internal_queues = RT::Queues->new(RT->SystemUser);
+ $internal_queues->Limit(FIELD => 'Disabled', VALUE => 0);
+ my $queuelist;
+ while ( my $q = $internal_queues->Next ) {
+ $queuelist->{$q->Id} = $q->Name;
+ }
+ return $queuelist;
+}
+
+
+# takes a WWW::Mech object and an optional arrayref of queue ids
+# compares the list of ids to the dropdown of Queues for the New Ticket In form
+sub check_queues {
+ my $browser = shift;
+ my $queue_list = shift;
+ $browser->get_ok($baseurl,"Navigated to homepage");
+ ok(my $form = $browser->form_name('CreateTicketInQueue'), "Found New Ticket In form");
+ ok(my $queuelist = $form->find_input('Queue','option'), "Found queue select");
+ my @queues = $queuelist->possible_values;
+
+ $queue_list = [keys %{internal_queues()}] unless $queue_list;
+ is_deeply([sort @queues],[sort @$queue_list], "Queue list contains the expected queues");
+}
diff --git a/rt/t/web/queue_create.t b/rt/t/web/queue_create.t
new file mode 100644
index 000000000..3d2cd04d0
--- /dev/null
+++ b/rt/t/web/queue_create.t
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 13;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+my $root = RT::User->new(RT->SystemUser);
+ok( $root->Load('root'), 'load root user' );
+
+my $queue_name = 'test queue';
+
+my $queue_id;
+diag "Create a queue";
+{
+ $m->follow_link( id => 'tools-config-queues-create');
+
+ # Test queue form validation
+ $m->submit_form(
+ form_name => 'ModifyQueue',
+ fields => {
+ Name => '',
+ },
+ );
+ $m->text_contains('Queue name is required');
+ $m->submit_form(
+ form_name => 'ModifyQueue',
+ fields => {
+ Name => '0',
+ },
+ );
+ $m->text_contains("'0' is not a valid name");
+ $m->submit_form(
+ form_name => 'ModifyQueue',
+ fields => {
+ Name => '1',
+ },
+ );
+ $m->text_contains("'1' is not a valid name");
+ $m->submit_form(
+ form_name => 'ModifyQueue',
+ fields => {
+ Name => $queue_name,
+ },
+ );
+ $m->content_contains('Queue created', 'created queue sucessfully' );
+
+ # Test validation on update
+ $m->form_name('ModifyQueue');
+ $m->set_fields(
+ Name => '',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->content_contains('Illegal value for Name');
+
+ $m->form_name('ModifyQueue');
+ $m->set_fields(
+ Name => '0',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->content_contains('Illegal value for Name');
+
+ $m->form_name('ModifyQueue');
+ $m->set_fields(
+ Name => '1',
+ );
+ $m->click_button(value => 'Save Changes');
+ $m->content_contains('Illegal value for Name');
+
+ $queue_id = $m->form_name('ModifyQueue')->value('id');
+ ok $queue_id, "found id of the queue in the form, it's #$queue_id";
+}
+
diff --git a/rt/t/web/quickcreate.t b/rt/t/web/quickcreate.t
new file mode 100644
index 000000000..b257f9ddd
--- /dev/null
+++ b/rt/t/web/quickcreate.t
@@ -0,0 +1,37 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test tests => 11;
+
+RT->Config->Set('DisplayTicketAfterQuickCreate' => 0);
+
+my ($baseurl, $m) = RT::Test->started_ok;
+
+ok($m->login, 'logged in');
+
+$m->form_with_fields('Subject', 'Content');
+$m->field(Subject => 'from quick create');
+$m->submit;
+
+$m->content_like(qr/Ticket \d+ created in queue/, 'created ticket');
+like( $m->uri, qr{^\Q$baseurl\E/(?:index\.html)?\?results=}, 'still in homepage' );
+unlike( $m->uri, qr{Ticket/Display.html}, 'not on ticket display page' );
+
+$m->get_ok($baseurl . '/Prefs/Other.html');
+$m->submit_form(
+ form_name => 'ModifyPreferences',
+ fields => { 'DisplayTicketAfterQuickCreate' => 1, },
+ button => 'Update',
+);
+
+$m->content_contains( 'Preferences saved',
+ 'enabled DisplayTicketAfterQuickCreate' );
+$m->get($baseurl);
+
+$m->form_with_fields('Subject', 'Content');
+$m->field(Subject => 'from quick create');
+$m->submit;
+
+$m->content_like(qr/Ticket \d+ created in queue/, 'created ticket');
+like( $m->uri, qr!/Ticket/Display.html!, 'still in homepage' );
diff --git a/rt/t/web/quicksearch.t b/rt/t/web/quicksearch.t
index cd9a8e76c..8cc084ce5 100644
--- a/rt/t/web/quicksearch.t
+++ b/rt/t/web/quicksearch.t
@@ -2,12 +2,12 @@
use strict;
use warnings;
-use RT::Test tests => 7;
+use RT::Test tests => 9;
my ($baseurl, $m) = RT::Test->started_ok;
my $url = $m->rt_base_url;
# merged tickets still show up in search
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
$t1->Create(
Subject => 'base ticket'.$$,
Queue => 'general',
@@ -22,7 +22,7 @@ $t1->Create(
);
ok(my $id1 = $t1->id, 'created ticket for custom search');
-my $t2 = RT::Ticket->new($RT::SystemUser);
+my $t2 = RT::Ticket->new(RT->SystemUser);
$t2->Create(
Subject => 'merged away'.$$,
Queue => 'general',
diff --git a/rt/t/web/redirect-after-login.t b/rt/t/web/redirect-after-login.t
index d39bb58c8..d429d30d1 100644
--- a/rt/t/web/redirect-after-login.t
+++ b/rt/t/web/redirect-after-login.t
@@ -3,7 +3,9 @@
use strict;
use warnings;
-use RT::Test tests => 120;
+use RT::Test tests => 122;
+
+RT->Config->Set( GnuPG => Enable => 0 );
my ($baseurl, $agent) = RT::Test->started_ok;
@@ -51,11 +53,9 @@ diag $url if $ENV{TEST_VERBOSE};
ok( $agent->content =~ /Your username or password is incorrect/i, "Found the error message");
like( $agent->uri, qr{/NoAuth/Login\.html$}, "now on /NoAuth/Login.html" );
- $agent->logout();
-
- # Handle the warning after we're done with the page, since this leaves us
- # with a completely different $mech
$agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
+
+ $agent->logout();
}
# test a login from a non-front page, both with a double leading slash and without
@@ -116,6 +116,7 @@ for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
ok( $agent->content =~ /Your username or password is incorrect/i, "Found the error message");
like( $agent->uri, qr{/NoAuth/Login\.html$}, "still on /NoAuth/Login.html" );
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
# try to login again
ok($agent->current_form->find_input('user'));
@@ -136,10 +137,6 @@ for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
is( $agent->uri, $requested, "right URL" );
like( $agent->{redirected_uri}, qr{/NoAuth/Login\.html}, "We redirected from login");
$agent->logout();
-
- # Handle the warning after we're done with the page, since this leaves us
- # with a completely different $mech
- $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
}
# test a login from the main page with query params
@@ -163,9 +160,6 @@ for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
ok($agent->current_form->find_input('user'));
ok($agent->current_form->find_input('pass'));
like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
-
- # Handle the warning after we're done with the page, since this leaves us
- # with a completely different $mech
$agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
}
@@ -183,6 +177,7 @@ for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
ok($agent->current_form->find_input('next'));
like($agent->value('next'), qr/^[a-z0-9]{32}$/i, "next page argument is a hash");
like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
# Try to login again
ok($agent->content =~ /username:/i);
@@ -197,10 +192,6 @@ for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
is( $agent->uri, $requested, "right URL" );
like( $agent->{redirected_uri}, qr{/NoAuth/Login\.html}, "We redirected from login");
$agent->logout();
-
- # Handle the warning after we're done with the page, since this leaves us
- # with a completely different $mech
- $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
}
# test REST login response
@@ -221,9 +212,6 @@ for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
is($agent->uri, $requested, "didn't redirect to /NoAuth/Login.html for REST");
like($agent->content, qr/401 Credentials required/i, "got error status");
like($agent->content, qr/Your username or password is incorrect/, "got error message");
-
- # Handle the warning after we're done with the page, since this leaves us
- # with a completely different $mech
$agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
}
diff --git a/rt/t/web/redirect.t b/rt/t/web/redirect.t
new file mode 100644
index 000000000..d92386bb8
--- /dev/null
+++ b/rt/t/web/redirect.t
@@ -0,0 +1,106 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 13;
+
+my $r = $HTML::Mason::Commands::r = bless {}, 'R';
+my $m = $HTML::Mason::Commands::m = bless {}, 'M';
+
+set_config(
+ CanonicalizeRedirectURLs => 0,
+ WebDomain => 'localhost',
+ WebPort => 80,
+ WebPath => '',
+);
+is( RT->Config->Get('WebBaseURL'), 'http://localhost' );
+is( RT->Config->Get('WebURL'), 'http://localhost/' );
+
+redirect_ok(
+ 'http://localhost/Ticket/', 'http://localhost/Ticket/',
+ { SERVER_NAME => 'localhost', SERVER_PORT => 80 },
+);
+redirect_ok(
+ '/Ticket/', 'http://localhost/Ticket/',
+ { SERVER_NAME => 'localhost', SERVER_PORT => 80 },
+);
+redirect_ok(
+ 'http://localhost/Ticket/', 'http://example.com/Ticket/',
+ { SERVER_NAME => 'example.com', SERVER_PORT => 80 },
+);
+
+set_config(
+ CanonicalizeRedirectURLs => 0,
+ WebDomain => 'localhost',
+ WebPort => 443,
+ WebPath => '',
+);
+is( RT->Config->Get('WebBaseURL'), 'https://localhost' );
+is( RT->Config->Get('WebURL'), 'https://localhost/' );
+
+redirect_ok(
+ 'https://localhost/Ticket/', 'https://localhost/Ticket/',
+ { SERVER_NAME => 'localhost', SERVER_PORT => 443, HTTPS => 'on' },
+);
+redirect_ok(
+ '/Ticket/', 'https://localhost/Ticket/',
+ { SERVER_NAME => 'localhost', SERVER_PORT => 443, HTTPS => 'on' },
+);
+redirect_ok(
+ 'https://localhost/Ticket/', 'http://localhost/Ticket/',
+ { SERVER_NAME => 'localhost', SERVER_PORT => 80 },
+);
+redirect_ok(
+ '/Ticket/', 'http://localhost/Ticket/',
+ { SERVER_NAME => 'localhost', SERVER_PORT => 80 },
+);
+redirect_ok(
+ 'https://localhost/Ticket/', 'http://example.com/Ticket/',
+ { SERVER_NAME => 'example.com', SERVER_PORT => 80 },
+);
+redirect_ok(
+ 'https://localhost/Ticket/', 'https://example.com/Ticket/',
+ { SERVER_NAME => 'example.com', SERVER_PORT => 443, HTTPS => 'on' },
+);
+
+sub set_config {
+ my %values = @_;
+ while ( my ($k, $v) = each %values ) {
+ RT->Config->Set( $k => $v );
+ }
+
+ unless ( $values{'WebBaseURL'} ) {
+ my $port = RT->Config->Get('WebPort');
+ RT->Config->Set(
+ WebBaseURL =>
+ ($port == 443? 'https': 'http') .'://'
+ . RT->Config->Get('WebDomain')
+ . ($port != 80 && $port != 443? ":$port" : '')
+ );
+ }
+ unless ( $values{'WebURL'} ) {
+ RT->Config->Set(
+ WebURL => RT->Config->Get('WebBaseURL') . RT->Config->Get('WebPath') . "/"
+ );
+ }
+}
+
+sub redirect_ok {
+ my ($to, $expected, $env, $details) = @_;
+
+ local %ENV = %ENV;
+ while ( my ($k, $v) = each %{ $env || {} } ) {
+ $ENV{ $k } = $v;
+ }
+ RT::Interface::Web::Redirect( $to );
+ is($m->redirect, $expected, $details || "correct for '$to'");
+}
+
+package R;
+sub status {};
+
+package M;
+sub redirect { $_[0]{'last'} = $_[1] if @_ > 1; return $_[0]{'last'} }
+sub abort {}
+
diff --git a/rt/t/web/reminders.t b/rt/t/web/reminders.t
new file mode 100644
index 000000000..32e130c47
--- /dev/null
+++ b/rt/t/web/reminders.t
@@ -0,0 +1,88 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use RT::Test tests => 35;
+
+my ($baseurl, $m) = RT::Test->started_ok;
+
+ok($m->login, 'logged in');
+my $user = RT::CurrentUser->new('root');
+
+my $ticket = RT::Ticket->new($user);
+$ticket->Create(Subject => 'testing reminders!', Queue => 'General');
+ok($ticket->id, 'created a ticket');
+
+$m->goto_ticket($ticket->id);
+$m->text_contains('New reminder:', 'can create a new reminder');
+$m->content_unlike(qr{Check box to complete}, "we don't display this text when there are no reminders");
+$m->content_unlike(qr{<th[^>]*>Reminders?</th>}, "no reminder titlebar");
+
+$m->follow_link_ok({id => 'page-reminders'});
+$m->title_is("Reminders for ticket #" . $ticket->id);
+$m->text_contains('New reminder:', 'can create a new reminder');
+$m->content_unlike(qr{Check box to complete}, "we don't display this text when there are no reminders");
+$m->content_unlike(qr{<th[^>]*>Reminders?</th>}, "no reminder titlebar");
+
+$m->goto_ticket($ticket->id);
+$m->form_name('UpdateReminders');
+$m->field( 'NewReminder-Subject' => "baby's first reminder" );
+$m->submit;
+
+my $reminders = RT::Reminders->new($user);
+$reminders->Ticket($ticket->id);
+my $col = $reminders->Collection;
+is($col->Count, 1, 'got a reminder');
+my $reminder = $col->First;
+is($reminder->Subject, "baby's first reminder");
+my $reminder_id = $reminder->id;
+is($reminder->Status, 'new');
+
+$m->text_contains('New reminder:', 'can create a new reminder');
+$m->text_contains('Check box to complete', "we DO display this text when there are reminders");
+$m->content_like(qr{<th[^>]*>Reminders?</th>}, "now we have a reminder titlebar");
+$m->text_contains("baby's first reminder", "display the reminder's subject");
+
+$m->follow_link_ok({id => 'page-reminders'});
+$m->title_is("Reminders for ticket #" . $ticket->id);
+$m->form_name('UpdateReminders');
+$m->field("Reminder-Subject-$reminder_id" => "changed the subject");
+$m->submit;
+
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+$reminder = RT::Ticket->new($user);
+$reminder->Load($reminder_id);
+is($reminder->Subject, 'changed the subject');
+is($reminder->Status, 'new');
+
+$m->goto_ticket($ticket->id);
+$m->form_name('UpdateReminders');
+$m->tick("Complete-Reminder-$reminder_id" => 1);
+$m->submit;
+
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+$reminder = RT::Ticket->new($user);
+$reminder->Load($reminder_id);
+is($reminder->Status, 'resolved');
+
+$m->text_contains('New reminder:', 'can create a new reminder');
+$m->content_unlike(qr{Check box to complete}, "we don't display this text when there are open reminders");
+$m->content_unlike(qr{<th[^>]*>Reminders?</th>}, "no reminder titlebar");
+$m->content_unlike(qr{baby's first reminder}, "we don't display resolved reminders");
+
+$m->follow_link_ok({id => 'page-reminders'});
+$m->title_is("Reminders for ticket #" . $ticket->id);
+$m->text_contains('New reminder:', 'can create a new reminder');
+$m->text_contains('Check box to complete', "we DO display this text when there are reminders");
+$m->content_contains("changed the subject", "display the resolved reminder's subject");
+
+# make sure that when we submit the form, it doesn't accidentally reopen
+# resolved reminders
+$m->goto_ticket($ticket->id);
+$m->form_name('UpdateReminders');
+$m->submit;
+
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+$reminder = RT::Ticket->new($user);
+$reminder->Load($reminder_id);
+is($reminder->Status, 'resolved');
+
diff --git a/rt/t/web/remote_user.t b/rt/t/web/remote_user.t
new file mode 100644
index 000000000..edad6ef95
--- /dev/null
+++ b/rt/t/web/remote_user.t
@@ -0,0 +1,36 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test tests => 9;
+use MIME::Base64 qw//;
+
+RT->Config->Set( DevelMode => 0 );
+RT->Config->Set( WebExternalAuth => 1 );
+
+sub auth {
+ return Authorization => "Basic " .
+ MIME::Base64::encode( join(":", @_) );
+}
+
+my ( $url, $m ) = RT::Test->started_ok( basic_auth => 1 );
+$m->get($url);
+is($m->status, 401, "Initial request with no creds gets 401");
+
+$m->get($url, auth( root => "wrong" ));
+is($m->status, 401, "Request with wrong creds gets 401");
+
+$m->get($url, auth( root => "password" ));
+is($m->status, 200, "Request with right creds gets 200");
+
+$m->content_like(
+ qr{<span class="current-user">\Qroot\E</span>}i,
+ "Has user on the page"
+);
+$m->content_unlike(qr/Logout/i, "Has no logout button, no WebFallbackToInternalAuth");
+
+$m->get($url);
+is($m->status, 401, "Subsequent requests without credentials aren't still logged in");
+
+
+# Put the credentials back for the warnings check at the end
+$m->default_header( auth( root => "password" ));
diff --git a/rt/t/web/requestor_groups_edit_link.t b/rt/t/web/requestor_groups_edit_link.t
new file mode 100644
index 000000000..9d1fefd5c
--- /dev/null
+++ b/rt/t/web/requestor_groups_edit_link.t
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 11;
+
+RT->Config->Set( ShowMoreAboutPrivilegedUsers => 1 );
+
+my ( $url, $m ) = RT::Test->started_ok;
+my $user_a = RT::Test->load_or_create_user(
+ Name => 'user_a',
+ Password => 'password',
+);
+ok( $user_a, 'created user user_a' );
+ok(
+ RT::Test->set_rights(
+ {
+ Principal => $user_a,
+ Right => [ qw/SeeQueue ShowTicket CreateTicket/ ]
+ },
+ ),
+ 'set rights for user_a'
+);
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+my ($id) = $ticket->Create(
+ Subject => 'groups limit',
+ Queue => 'General',
+ Requestor => $user_a->id,
+);
+ok( $id, 'created ticket' );
+
+
+ok( $m->login( user_a => 'password' ), 'logged in as user_a' );
+
+$m->goto_ticket($id);
+
+ok(
+ !$m->find_link( text => 'Edit' ), 'no Edit link without AdminUsers permission'
+);
+
+ok(
+ RT::Test->add_rights(
+ {
+ Principal => $user_a,
+ Right => [ qw/AdminUsers ShowConfigTab/ ]
+ },
+ ),
+ 'add AdminUsers and ShowConfigTab rights for user_a'
+);
+
+$m->goto_ticket($id);
+$m->follow_link_ok( { text => 'Edit' }, 'follow the Edit link' );
+is( $m->uri, $url . "/Admin/Users/Memberships.html?id=" . $user_a->id, 'url is right' );
+
diff --git a/rt/t/web/requestor_groups_limit.t b/rt/t/web/requestor_groups_limit.t
new file mode 100644
index 000000000..7987a136c
--- /dev/null
+++ b/rt/t/web/requestor_groups_limit.t
@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 11;
+
+diag "set groups limit to 1";
+RT->Config->Set( ShowMoreAboutPrivilegedUsers => 1 );
+RT->Config->Set( MoreAboutRequestorGroupsLimit => 1 );
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+my ($id) = $ticket->Create(
+ Subject => 'groups limit',
+ Queue => 'General',
+ Requestor => 'root@localhost',
+);
+ok( $id, 'created ticket' );
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login(), 'logged in as root' );
+$m->goto_ticket($id);
+$m->content_like( qr/Everyone|Privileged/, 'got one group' );
+$m->content_unlike( qr/Everyone.*?Privileged/, 'not 2 groups' );
+
+RT::Test->stop_server;
+
+diag "set groups limit to 2";
+
+RT->Config->Set( MoreAboutRequestorGroupsLimit => 2 );
+( $url, $m ) = RT::Test->started_ok;
+ok( $m->login(), 'logged in as root' );
+$m->goto_ticket($id);
+$m->content_contains( 'Everyone', 'got the first group' );
+$m->content_contains( 'Privileged', 'got the second group' );
+
diff --git a/rt/t/web/rest-non-ascii-subject.t b/rt/t/web/rest-non-ascii-subject.t
index 371b2ffc0..d7a89af5e 100644
--- a/rt/t/web/rest-non-ascii-subject.t
+++ b/rt/t/web/rest-non-ascii-subject.t
@@ -2,9 +2,7 @@
# Test ticket creation with REST using non ascii subject
use strict;
use warnings;
-use RT::Test tests => 7;
-
-local $RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
+use RT::Test tests => 9;
use Encode;
# \x{XX} where XX is less than 255 is not treated as unicode code point
@@ -42,7 +40,7 @@ $m->post("$baseurl/REST/1.0/ticket/new", [
my ($id) = $m->content =~ /Ticket (\d+) created/;
ok($id, "got ticket #$id");
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
$ticket->Load($id);
is($ticket->Id, $id, "loaded the REST-created ticket");
is($ticket->Subject, $subject, "ticket subject successfully set");
diff --git a/rt/t/web/rest-sort.t b/rt/t/web/rest-sort.t
new file mode 100644
index 000000000..6b4d35169
--- /dev/null
+++ b/rt/t/web/rest-sort.t
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use RT::Test tests => 25;
+
+my ($baseurl, $m) = RT::Test->started_ok;
+
+RT::Test->create_tickets(
+ { },
+ { Subject => 'uno' },
+ { Subject => 'dos' },
+ { Subject => 'tres' },
+);
+
+ok($m->login, 'logged in');
+
+sorted_tickets_ok('Subject', ['2: dos', '3: tres', '1: uno']);
+sorted_tickets_ok('+Subject', ['2: dos', '3: tres', '1: uno']);
+sorted_tickets_ok('-Subject', ['1: uno', '3: tres', '2: dos']);
+
+sorted_tickets_ok('id', ['1: uno', '2: dos', '3: tres']);
+sorted_tickets_ok('+id', ['1: uno', '2: dos', '3: tres']);
+sorted_tickets_ok('-id', ['3: tres', '2: dos', '1: uno']);
+
+undef $m;
+
+sub sorted_tickets_ok {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my $order = shift;
+ my $expected = shift;
+
+ my $query = 'id > 0';
+
+ my $uri = URI->new("$baseurl/REST/1.0/search/ticket");
+ $uri->query_form(
+ query => $query,
+ orderby => $order,
+ );
+ $m->get_ok($uri);
+
+ my @lines = split /\n/, $m->content;
+ shift @lines; # header
+ shift @lines; # empty line
+
+ is_deeply(\@lines, $expected, "sorted results by '$order'");
+}
diff --git a/rt/t/web/rest.t b/rt/t/web/rest.t
index b3a7c558b..5e7194c95 100644
--- a/rt/t/web/rest.t
+++ b/rt/t/web/rest.t
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use strict;
use warnings;
-use RT::Test tests => 16;
+use RT::Test tests => 18;
my ($baseurl, $m) = RT::Test->started_ok;
@@ -46,7 +46,7 @@ $m->post("$baseurl/REST/1.0/ticket/edit", [
my ($id) = $m->content =~ /Ticket (\d+) created/;
ok($id, "got ticket #$id");
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
$ticket->Load($id);
is($ticket->Id, $id, "loaded the REST-created ticket");
is($ticket->Subject, "REST interface", "subject successfully set");
diff --git a/rt/t/web/richtext-autohandler.t b/rt/t/web/richtext-autohandler.t
index 56617b2fb..734426fc3 100644
--- a/rt/t/web/richtext-autohandler.t
+++ b/rt/t/web/richtext-autohandler.t
@@ -1,13 +1,13 @@
use strict;
-use RT::Test tests => 7;
+use RT::Test tests => 9;
my ($baseurl, $agent) = RT::Test->started_ok;
-$agent->get("$baseurl/NoAuth/RichText/FCKeditor/license.txt");
+$agent->get("$baseurl/NoAuth/RichText/ckeditor/config.js");
is($agent->status, 403);
-$agent->content_lacks("It is not the purpose of this section to induce");
+$agent->content_lacks("config.disableNativeSpellChecker");
-$agent->get_ok("/NoAuth/RichText/license.txt");
-$agent->content_contains("It is not the purpose of this section to induce");
+$agent->get_ok("/NoAuth/RichText/config.js");
+$agent->content_contains("config.disableNativeSpellChecker");
$agent->warning_like(qr/Invalid request directly to the rich text editor/,);
diff --git a/rt/t/web/rights.t b/rt/t/web/rights.t
index b47ba99af..9a5f358e2 100644
--- a/rt/t/web/rights.t
+++ b/rt/t/web/rights.t
@@ -7,34 +7,32 @@ use RT::Test tests => 14;
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, "logged in";
-$m->follow_link_ok({ text => 'Configuration' });
-$m->follow_link_ok({ text => 'Global' });
-$m->follow_link_ok({ text => 'Group Rights' });
+$m->follow_link_ok({ id => 'tools-config-global-group-rights'});
sub get_rights {
my $agent = shift;
my $principal_id = shift;
my $object = shift;
- $agent->form_number(3);
- my @inputs = $agent->current_form->find_input("RevokeRight-$principal_id-$object");
- my @rights = sort grep $_, map $_->possible_values, grep $_, @inputs;
+ $agent->form_name('ModifyGroupRights');
+ my @inputs = $agent->current_form->find_input("SetRights-$principal_id-$object");
+ my @rights = sort grep $_, map $_->possible_values, grep $_ && $_->value, @inputs;
return @rights;
};
-diag "load Everyone group" if $ENV{'TEST_VERBOSE'};
+diag "load Everyone group";
my ($everyone, $everyone_gid);
{
- $everyone = RT::Group->new( $RT::SystemUser );
+ $everyone = RT::Group->new( RT->SystemUser );
$everyone->LoadSystemInternalGroup('Everyone');
ok($everyone_gid = $everyone->id, "loaded 'everyone' group");
}
-diag "revoke all global rights from Everyone group" if $ENV{'TEST_VERBOSE'};
+diag "revoke all global rights from Everyone group";
my @has = get_rights( $m, $everyone_gid, 'RT::System-1' );
if ( @has ) {
- $m->form_number(3);
- $m->tick("RevokeRight-$everyone_gid-RT::System-1", $_) foreach @has;
+ $m->form_name('ModifyGroupRights');
+ $m->untick("SetRights-$everyone_gid-RT::System-1", $_) foreach @has;
$m->submit;
is_deeply([get_rights( $m, $everyone_gid, 'RT::System-1' )], [], 'deleted all rights' );
@@ -42,10 +40,10 @@ if ( @has ) {
ok(1, 'the group has no global rights');
}
-diag "grant SuperUser right to everyone" if $ENV{'TEST_VERBOSE'};
+diag "grant SuperUser right to everyone";
{
- $m->form_number(3);
- $m->select("GrantRight-$everyone_gid-RT::System-1", ['SuperUser']);
+ $m->form_name('ModifyGroupRights');
+ $m->tick("SetRights-$everyone_gid-RT::System-1", 'SuperUser');
$m->submit;
$m->content_contains('Right Granted', 'got message');
@@ -54,10 +52,10 @@ diag "grant SuperUser right to everyone" if $ENV{'TEST_VERBOSE'};
is_deeply( [get_rights( $m, $everyone_gid, 'RT::System-1' )], ['SuperUser'], 'granted SuperUser right' );
}
-diag "revoke the right" if $ENV{'TEST_VERBOSE'};
+diag "revoke the right";
{
- $m->form_number(3);
- $m->tick("RevokeRight-$everyone_gid-RT::System-1", 'SuperUser');
+ $m->form_name('ModifyGroupRights');
+ $m->untick("SetRights-$everyone_gid-RT::System-1", 'SuperUser');
$m->submit;
$m->content_contains('Right revoked', 'got message');
@@ -67,10 +65,10 @@ diag "revoke the right" if $ENV{'TEST_VERBOSE'};
}
-diag "return rights the group had in the beginning" if $ENV{'TEST_VERBOSE'};
+diag "return rights the group had in the beginning";
if ( @has ) {
- $m->form_number(3);
- $m->select("GrantRight-$everyone_gid-RT::System-1", \@has);
+ $m->form_name('ModifyGroupRights');
+ $m->tick("SetRights-$everyone_gid-RT::System-1", $_) for @has;
$m->submit;
$m->content_contains('Right Granted', 'got message');
diff --git a/rt/t/web/rights1.t b/rt/t/web/rights1.t
index c8892f2fe..24e5c3448 100644
--- a/rt/t/web/rights1.t
+++ b/rt/t/web/rights1.t
@@ -2,11 +2,11 @@
use strict;
use HTTP::Cookies;
-use RT::Test tests => 29;
+use RT::Test nodata => 1, tests => 31;
my ($baseurl, $agent) = RT::Test->started_ok;
# Create a user with basically no rights, to start.
-my $user_obj = RT::User->new($RT::SystemUser);
+my $user_obj = RT::User->new(RT->SystemUser);
my ($ret, $msg) = $user_obj->LoadOrCreateByEmail('customer-'.$$.'@example.com');
ok($ret, 'ACL test user creation');
$user_obj->SetName('customer-'.$$);
@@ -24,7 +24,6 @@ my $cookie_jar = HTTP::Cookies->new;
$agent->cookie_jar($cookie_jar);
-no warnings 'once';
# get the top page
$agent->login( $user_obj->Name, 'customer');
@@ -36,13 +35,13 @@ ok(!$agent->find_link( url => "$RT::WebPath/User/Prefs.html",
# Now test for their presence, one at a time. Sleep for a bit after
# ACL changes, thanks to the 10s ACL cache.
-my ($grantid,$grantmsg) =$user_obj->PrincipalObj->GrantRight(Right => 'ShowConfigTab', Object => $RT::System);
+my ($grantid,$grantmsg) =$user_obj->PrincipalObj->GrantRight(Right => 'ShowConfigTab', Object => RT->System);
ok($grantid,$grantmsg);
$agent->reload;
-like($agent->{'content'} , qr/Logout/i, "Reloaded page successfully");
+$agent->content_contains('Logout', "Reloaded page successfully");
ok($agent->find_link( url => "$RT::WebPath/Admin/",
text => 'Configuration'), "Found config tab" );
my ($revokeid,$revokemsg) =$user_obj->PrincipalObj->RevokeRight(Right => 'ShowConfigTab');
@@ -50,41 +49,40 @@ ok ($revokeid,$revokemsg);
($grantid,$grantmsg) =$user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
ok ($grantid,$grantmsg);
$agent->reload();
-like($agent->{'content'} , qr/Logout/i, "Reloaded page successfully");
+$agent->content_contains('Logout', "Reloaded page successfully");
ok($agent->find_link(
- text => 'Preferences'), "Found prefs pane" );
+ id => 'preferences-settings' ), "Found prefs pane" );
($revokeid,$revokemsg) = $user_obj->PrincipalObj->RevokeRight(Right => 'ModifySelf');
ok ($revokeid,$revokemsg);
# Good. Now load the search page and test Load/Save Search.
$agent->follow_link( url => "$RT::WebPath/Search/Build.html",
text => 'Tickets');
-is($agent->{'status'}, 200, "Fetched search builder page");
-ok($agent->{'content'} !~ /Load saved search/i, "No search loading box");
-ok($agent->{'content'} !~ /Saved searches/i, "No saved searches box");
+is($agent->status, 200, "Fetched search builder page");
+$agent->content_lacks("Load saved search", "No search loading box");
+$agent->content_lacks("Saved searches", "No saved searches box");
($grantid,$grantmsg) = $user_obj->PrincipalObj->GrantRight(Right => 'LoadSavedSearch');
ok($grantid,$grantmsg);
$agent->reload();
-like($agent->{'content'} , qr/Load saved search/i, "Search loading box exists");
-ok($agent->{'content'} !~ /input\s+type=['"]submit['"][^>]+name=['"]SavedSearchSave['"]/i,
+$agent->content_contains("Load saved search", "Search loading box exists");
+$agent->content_unlike(qr/input\s+type=['"]submit['"][^>]+name=['"]SavedSearchSave['"]/i,
"Still no saved searches box");
($grantid,$grantmsg) =$user_obj->PrincipalObj->GrantRight(Right => 'CreateSavedSearch');
ok ($grantid,$grantmsg);
$agent->reload();
-like($agent->{'content'} , qr/Load saved search/i,
- "Search loading box still exists");
-like($agent->{'content'} , qr/input\s+type=['"]submit['"][^>]+name=['"]SavedSearchSave['"]/i,
+$agent->content_contains("Load saved search", "Search loading box still exists");
+$agent->content_like(qr/input\s+type=['"]submit['"][^>]+name=['"]SavedSearchSave['"]/i,
"Saved searches box exists");
# Create a group, and a queue, so we can test limited user visibility
# via SelectOwner.
-my $queue_obj = RT::Queue->new($RT::SystemUser);
+my $queue_obj = RT::Queue->new(RT->SystemUser);
($ret, $msg) = $queue_obj->Create(Name => 'CustomerQueue-'.$$,
Description => 'queue for SelectOwner testing');
ok($ret, "SelectOwner test queue creation. $msg");
-my $group_obj = RT::Group->new($RT::SystemUser);
+my $group_obj = RT::Group->new(RT->SystemUser);
($ret, $msg) = $group_obj->CreateUserDefinedGroup(Name => 'CustomerGroup-'.$$,
Description => 'group for SelectOwner testing');
ok($ret, "SelectOwner test group creation. $msg");
@@ -107,4 +105,3 @@ ok($agent->form_name('BuildQuery'), "Yep, form is still there");
my $input = $agent->current_form->find_input('ValueOfActor');
ok(grep(/customer-$$/, $input->value_names()), "Found self in the actor listing");
-1;
diff --git a/rt/t/web/saved_search_chart.t b/rt/t/web/saved_search_chart.t
index 105166233..f84307162 100644
--- a/rt/t/web/saved_search_chart.t
+++ b/rt/t/web/saved_search_chart.t
@@ -2,11 +2,12 @@
use strict;
use warnings;
-use RT::Test tests => 19;
+use RT::Test no_plan => 1;
my ( $url, $m ) = RT::Test->started_ok;
use RT::Attribute;
-my $search = RT::Attribute->new($RT::SystemUser);
-my $ticket = RT::Ticket->new($RT::SystemUser);
+
+my $search = RT::Attribute->new(RT->SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my ( $ret, $msg ) = $ticket->Create(
Subject => 'base ticket' . $$,
Queue => 'general',
@@ -35,7 +36,7 @@ $m->submit_form(
button => 'SavedSearchSave',
);
-$m->content_like( qr/Chart first chart saved/, 'saved first chart' );
+$m->content_contains("Chart first chart saved", 'saved first chart' );
my ( $search_uri, $id ) = $m->content =~ /value="(RT::User-\d+-SavedSearch-(\d+))"/;
$m->submit_form(
@@ -64,8 +65,8 @@ $m->submit_form(
button => 'SavedSearchSave',
);
-$m->content_like( qr/Chart first chart updated/, 'found updated message' );
-$m->content_like( qr/id=2/, 'Query is updated' );
+$m->content_contains("Chart first chart updated", 'found updated message' );
+$m->content_contains("id=2", 'Query is updated' );
$m->content_like( qr/value="Status"\s+selected="selected"/,
'PrimaryGroupBy is updated' );
$m->content_like( qr/value="pie"\s+selected="selected"/,
@@ -81,6 +82,73 @@ $m->submit_form(
form_name => 'SaveSearch',
button => 'SavedSearchDelete',
);
-$m->content_like( qr/Chart first chart deleted/, 'found deleted message' );
+$m->content_contains("Chart first chart deleted", 'found deleted message' );
$m->content_unlike( qr/value="RT::User-\d+-SavedSearch-\d+"/,
'no saved search' );
+
+for ('A' .. 'F') {
+ $ticket->Create(
+ Subject => $$ . $_,
+ );
+}
+
+for ([A => 'subject="'.$$.'A"'], [BorC => 'subject="'.$$.'B" OR subject="'.$$.'C"']) {
+ $m->get_ok('/Search/Edit.html');
+ $m->form_name('BuildQueryAdvanced');
+ $m->field('Query', $_->[1]);
+ $m->submit;
+
+ # Save the search
+ $m->follow_link_ok({id => 'page-chart'});
+ $m->form_name('SaveSearch');
+ $m->field(SavedSearchDescription => $_->[0]);
+ $m->click_ok('SavedSearchSave');
+ $m->text_contains('Chart ' . $_->[0] . ' saved.');
+
+}
+
+$m->form_name('SaveSearch');
+my @saved_search_ids =
+ $m->current_form->find_input('SavedSearchLoad')->possible_values;
+shift @saved_search_ids; # first value is blank
+
+cmp_ok(@saved_search_ids, '==', 2, 'Two saved charts were made');
+
+# TODO get find_link('page-chart')->URI->params to work...
+sub page_chart_link_has {
+ my ($m, $id, $msg) = @_;
+
+ $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ (my $dec_id = $id) =~ s/:/%3A/g;
+
+ my $chart_url = $m->find_link(id => 'page-chart')->url;
+ like(
+ $chart_url, qr{SavedChartSearchId=\Q$dec_id\E},
+ $msg || 'Page chart link matches the pattern we expected'
+ );
+}
+
+# load the first chart
+$m->field('SavedSearchLoad' => $saved_search_ids[0]);
+$m->click('SavedSearchLoadSubmit');
+
+page_chart_link_has($m, $saved_search_ids[0]);
+
+$m->form_name('SaveSearch');
+is($m->form_number(3)->value('SavedChartSearchId'), $saved_search_ids[0]);
+
+$m->form_name('SaveSearch');
+
+# now load the second chart
+$m->field('SavedSearchLoad' => $saved_search_ids[1]);
+$m->click('SavedSearchLoadSubmit');
+
+page_chart_link_has($m, $saved_search_ids[1]);
+
+is(
+ $m->form_number(3)->value('SavedChartSearchId'), $saved_search_ids[1],
+ 'Second form is seen as a hidden field'
+);
+
+page_chart_link_has($m, $saved_search_ids[1]);
diff --git a/rt/t/web/saved_search_context.t b/rt/t/web/saved_search_context.t
new file mode 100644
index 000000000..fe9c51ead
--- /dev/null
+++ b/rt/t/web/saved_search_context.t
@@ -0,0 +1,69 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test no_plan => 1;
+my ( $url, $m ) = RT::Test->started_ok;
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+for (['x', 50], ['y', 40], ['z', 30]) {
+ $ticket->Create(
+ Subject => $_->[0],
+ Queue => 'general',
+ Owner => 'root',
+ Priority => $_->[1],
+ Requestor => 'root@localhost',
+ );
+}
+
+ok( $m->login, 'logged in' );
+
+$m->get($url . '/Search/Build.html?NewQuery=1');
+$m->form_name('BuildQuery');
+$m->field(ValueOfPriority => 45);
+$m->click('DoSearch');
+#RT->Logger->error($m->uri); sleep 100;
+#{ open my $fh, '>', 'm.html'; print $fh $m->content; close $fh; }; die;
+$m->text_contains('Found 2 tickets');
+
+$m->follow_link(id => 'page-edit_search');
+$m->form_name('BuildQuery');
+$m->field(ValueOfAttachment => 'z');
+$m->click('DoSearch');
+
+$m->text_contains('Found 1 ticket');
+
+$m->follow_link(id => 'page-bulk');
+
+$m->form_name('BulkUpdate');
+ok(!$m->value('UpdateTicket2'), "There is no Ticket #2 in the search's bulk update");
+
+sub edit_search_link_has {
+ my ($m, $id, $msg) = @_;
+
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ (my $dec_id = $id) =~ s/:/%3A/g;
+
+ my $chart_url = $m->find_link(id => 'page-edit_search')->url;
+ like(
+ $chart_url, qr{SavedSearchId=\Q$dec_id\E},
+ $msg || 'Search link matches the pattern we expected'
+ );
+}
+
+diag("Test search context");
+{
+ $m->get_ok($url . '/Search/Build.html');
+ $m->form_name('BuildQuery');
+ $m->field(ValueOfPriority => 45);
+ $m->click('AddClause');
+ $m->form_name('BuildQuery');
+ $m->set_fields(
+ SavedSearchDescription => 'my saved search',
+ );
+ $m->click('SavedSearchSave');
+
+ my $saved_search_id = $m->form_name('BuildQuery')->value('SavedSearchId');
+ edit_search_link_has($m, $saved_search_id);
+}
diff --git a/rt/t/web/saved_search_permissions.t b/rt/t/web/saved_search_permissions.t
index f91ca13c6..5cae30b28 100644
--- a/rt/t/web/saved_search_permissions.t
+++ b/rt/t/web/saved_search_permissions.t
@@ -2,8 +2,8 @@
use strict;
use warnings;
-use RT::Test tests => 10;
-my $user = RT::User->new($RT::SystemUser);
+use RT::Test tests => 12;
+my $user = RT::User->new(RT->SystemUser);
ok(
$user->Create(
Name => 'foo',
@@ -23,7 +23,7 @@ $m->submit_form(
$m->content_contains( q{name="SavedSearchDescription" value="test"},
'saved test search' );
my ($id) = $m->content =~ /value="(RT::User-\d+-SavedSearch-\d+)"/;
-ok( $m->login( 'foo', 'foobar' ), 'logged in' );
+ok( $m->login( 'foo', 'foobar', logout => 1 ), 'logged in' );
$m->get_ok( $url . "/Search/Build.html?SavedSearchLoad=$id" );
my $message = qq{Can not load saved search "$id"};
diff --git a/rt/t/web/saved_search_update.t b/rt/t/web/saved_search_update.t
index 9b2724e82..dfb18d49c 100644
--- a/rt/t/web/saved_search_update.t
+++ b/rt/t/web/saved_search_update.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 16;
+use RT::Test tests => 18;
my $root = RT::User->new( $RT::SystemUser );
$root->Load('root');
diff --git a/rt/t/web/scrips.t b/rt/t/web/scrips.t
new file mode 100644
index 000000000..def20eca7
--- /dev/null
+++ b/rt/t/web/scrips.t
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 14;
+
+# TODO:
+# Test the rest of the conditions.
+# Test actions.
+# Test templates?
+# Test cleanup scripts.
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, "logged in";
+
+$m->follow_link_ok({id => 'tools-config-global-scrips-create'});
+
+sub prepare_code_with_value {
+ my $value = shift;
+
+ # changing the ticket is an easy scrip check for a test
+ return
+ '$self->TicketObj->SetSubject(' .
+ '$self->TicketObj->Subject . ' .
+ '"|" . ' . $value .
+ ')';
+}
+
+{
+ # preserve order for checking the subject string later
+ my @values_for_actions;
+
+ my $conds = RT::ScripConditions->new(RT->SystemUser);
+ foreach my $cond_value ('On Forward', 'On Forward Ticket', 'On Forward Transaction') {
+ $conds->Limit(
+ FIELD => 'name',
+ VALUE => $cond_value,
+ ENTRYAGGREGATOR => 'OR',
+ );
+ }
+
+ while (my $rec = $conds->Next) {
+ push @values_for_actions, [$rec->Id, '"' . $rec->Name . '"'];
+ }
+
+ @values_for_actions = sort { $a->[0] cmp $b->[0] } @values_for_actions;
+
+ foreach my $data (@values_for_actions) {
+ my ($condition, $prepare_code_value) = @$data;
+ diag "Create Scrip (Cond #$condition)" if $ENV{TEST_VERBOSE};
+ $m->follow_link_ok({id => 'tools-config-global-scrips-create'});
+ my $prepare_code = prepare_code_with_value($prepare_code_value);
+ $m->form_name('ModifyScrip');
+ $m->set_fields(
+ 'Scrip-new-ScripCondition' => $condition,
+ 'Scrip-new-ScripAction' => 15, # User Defined
+ 'Scrip-new-Template' => 1, # Blank
+ 'Scrip-new-CustomPrepareCode' => $prepare_code,
+ );
+ $m->submit;
+ }
+
+ my $ticket_obj = RT::Test->create_ticket(
+ Subject => 'subject',
+ Content => 'stuff',
+ Queue => 1,
+ );
+ my $ticket = $ticket_obj->id;
+ $m->goto_ticket($ticket);
+
+ $m->follow_link_ok(
+ { id => 'page-actions-forward' },
+ 'follow 1st Forward to forward ticket'
+ );
+
+ diag "Forward Ticket" if $ENV{TEST_VERBOSE};
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test, rt-to@example.com',
+ },
+ button => 'ForwardAndReturn'
+ );
+
+ $m->text_contains("#${ticket}: subject|On Forward|On Forward Ticket");
+
+ diag "Forward Transaction" if $ENV{TEST_VERBOSE};
+ # get the first transaction on the ticket
+ my ($transaction) = $ticket_obj->Transactions->First->id;
+ $m->get(
+ "$baseurl/Ticket/Forward.html?id=1&QuoteTransaction=$transaction"
+ );
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test, rt-to@example.com',
+ },
+ button => 'ForwardAndReturn'
+ );
+
+ $m->text_contains("#${ticket}: subject|On Forward|On Forward Ticket|On Forward|On Forward Transaction");
+
+ RT::Test->clean_caught_mails;
+}
diff --git a/rt/t/web/scrub.t b/rt/t/web/scrub.t
new file mode 100644
index 000000000..6483a7500
--- /dev/null
+++ b/rt/t/web/scrub.t
@@ -0,0 +1,46 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test nodb => 1, tests => 6;
+use RT::Interface::Web; # This gets us HTML::Mason::Commands
+use Test::LongString;
+
+{
+ my $html = 'This is a test of <span style="color: rgb(255, 0, 0); ">color</span> and <span style="font-size: 18px; "><span style="font-family: Georgia, serif; ">font</span></span> and <em><u><strike><strong>boldness</strong></strike></u></em>.';
+ is_string(scrub_html($html), $html, "CKEditor produced HTML sails through");
+}
+
+{
+ my $html = '<p style="text-align: right; ">
+ And <span style="color: rgb(255, 0, 0); "><span style="font-size: 16px; "><span style="font-family: Georgia, serif; ">alignment with color</span></span></span>?</p>';
+ is_string(scrub_html($html), $html, "CKEditor produced HTML sails through");
+}
+
+{
+ my $html = 'This is a test of <span style="color: rgb(255, 0, 0); content: url(/Nasty/URL);">color</span> and <span style="font-size: 18px; "><span style="font-family: Georgia, serif; ">font</span></span> and <em><u><strike><strong>boldness</strong></strike></u></em>.';
+ my $expected = 'This is a test of <span>color</span> and <span style="font-size: 18px; "><span style="font-family: Georgia, serif; ">font</span></span> and <em><u><strike><strong>boldness</strong></strike></u></em>.';
+ is_string(scrub_html($html), $expected, "nasty CSS not allowed through");
+}
+
+{
+ my $html = 'Let\'s add some <span style="color: blue; font-family: Georgia">color</span> up in <span style="color: #DEADBE">here</span>.';
+ is_string(scrub_html($html), $html, "multiple props and color specs allowed");
+}
+
+{
+ my $html = q[<span lang=EN-US style='font-family:"Century Gothic","sans-serif";'>oh hai I'm some text</span>];
+ my $expected = q[<span style="font-family:&quot;Century Gothic&quot;,&quot;sans-serif&quot;;">oh hai I'm some text</span>];
+ is_string(scrub_html($html), $expected, "font lists");
+}
+
+{
+ my $html = q[<span lang=EN-US style='font-size:7.5pt;font-family:"Century Gothic","sans-serif";color:#666666;mso-fareast-language:IT'>oh hai I'm some text</span>];
+ my $expected = q[<span style="font-size:7.5pt;font-family:&quot;Century Gothic&quot;,&quot;sans-serif&quot;;color:#666666;mso-fareast-language:IT">oh hai I'm some text</span>];
+ is_string(scrub_html($html), $expected, "outlook html");
+}
+
+sub scrub_html {
+ return HTML::Mason::Commands::ScrubHTML(shift);
+}
+
diff --git a/rt/t/web/search_bulk_update_links.t b/rt/t/web/search_bulk_update_links.t
index d6bfdfd3c..7d150a699 100644
--- a/rt/t/web/search_bulk_update_links.t
+++ b/rt/t/web/search_bulk_update_links.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
-use RT::Test tests => 28;
+use RT::Test tests => 47;
my ( $url, $m ) = RT::Test->started_ok;
ok( $m->login, 'logged in' );
@@ -13,7 +13,7 @@ use RT::Ticket;
my ( @link_tickets, @search_tickets );
for ( 1 .. 3 ) {
- my $link_ticket = RT::Ticket->new($RT::SystemUser);
+ my $link_ticket = RT::Ticket->new(RT->SystemUser);
my ( $ret, $msg ) = $link_ticket->Create(
Subject => "link ticket $_",
Queue => 'general',
@@ -25,7 +25,7 @@ for ( 1 .. 3 ) {
}
for ( 1 .. 3 ) {
- my $ticket = RT::Ticket->new($RT::SystemUser);
+ my $ticket = RT::Ticket->new(RT->SystemUser);
my ( $ret, $msg ) = $ticket->Create(
Subject => "search ticket $_",
Queue => 'general',
@@ -41,7 +41,7 @@ $m->get_ok( $url . "/Search/Bulk.html?Query=id=$search_tickets[0]&Rows=10" );
$m->content_contains( 'Current Links', 'has current links part' );
$m->content_lacks( 'DeleteLink--', 'no delete link stuff' );
$m->submit_form(
- form_number => 3,
+ form_name => 'BulkUpdate',
fields => {
'Ticket-DependsOn' => $link_tickets[0],
'Ticket-MemberOf' => $link_tickets[1],
@@ -77,9 +77,17 @@ $m->get_ok( $url . "/Search/Bulk.html?Query=$query&Rows=10" );
$m->content_contains( 'Current Links', 'has current links part' );
$m->content_lacks( 'DeleteLink--', 'no delete link stuff' );
+$m->form_name('BulkUpdate');
+my @fields = qw/Owner AddRequestor DeleteRequestor AddCc DeleteCc AddAdminCc
+DeleteAdminCc Subject Priority Queue Status Starts_Date Told_Date Due_Date
+Resolved_Date UpdateSubject UpdateContent/;
+for my $field ( @fields ) {
+ is( $m->value($field), '', "default $field is empty" );
+}
+
# test DependsOn, MemberOf and RefersTo
$m->submit_form(
- form_number => 3,
+ form_name => 'BulkUpdate',
fields => {
'Ticket-DependsOn' => $link_tickets[0],
'Ticket-MemberOf' => $link_tickets[1],
@@ -98,7 +106,7 @@ $m->content_contains(
'found refers to link' );
$m->submit_form(
- form_number => 3,
+ form_name => 'BulkUpdate',
fields => {
"DeleteLink--DependsOn-fsck.com-rt://$rtname/ticket/$link_tickets[0]" =>
1,
@@ -114,7 +122,7 @@ $m->content_lacks( 'DeleteLink--', 'links are all deleted' );
# test DependedOnBy, Members and ReferredToBy
$m->submit_form(
- form_number => 3,
+ form_name => 'BulkUpdate',
fields => {
'DependsOn-Ticket' => $link_tickets[0],
'MemberOf-Ticket' => $link_tickets[1],
@@ -133,7 +141,7 @@ $m->content_contains(
'found referrd to link' );
$m->submit_form(
- form_number => 3,
+ form_name => 'BulkUpdate',
fields => {
"DeleteLink-fsck.com-rt://$rtname/ticket/$link_tickets[0]-DependsOn-" =>
1,
diff --git a/rt/t/web/search_cf_quotes.t b/rt/t/web/search_cf_quotes.t
new file mode 100644
index 000000000..360fe0dc9
--- /dev/null
+++ b/rt/t/web/search_cf_quotes.t
@@ -0,0 +1,53 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 24;
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+my $cf = RT::CustomField->new($RT::SystemUser);
+ok(
+ $cf->Create(
+ Name => "I'm a cf",
+ Type => 'Date',
+ LookupType => 'RT::Queue-RT::Ticket',
+ )
+);
+ok( $cf->AddToObject( RT::Queue->new($RT::SystemUser) ) );
+
+RT::Test->create_tickets(
+ { Queue => 'General' },
+ { Subject => 'ticket foo', 'CustomField-' . $cf->id => '2011-09-15' },
+ { Subject => 'ticket bar', 'CustomField-' . $cf->id => '2011-10-15' },
+ { Subject => 'ticket baz' },
+);
+
+ok( $m->login, 'logged in' );
+
+$m->get_ok('/Search/Build.html');
+$m->form_name( 'BuildQuery' );
+
+my ($cf_op) =
+ $m->find_all_inputs( type => 'option', name_regex => qr/I'm a cf/ );
+my ($cf_field) =
+ $m->find_all_inputs( type => 'text', name_regex => qr/I'm a cf/ );
+
+diag "search directly";
+$m->submit_form(
+ fields => { $cf_op->name => '<', $cf_field->name => '2011-09-30', },
+ button => 'DoSearch',
+);
+
+$m->title_is( 'Found 1 ticket', 'found only 1 ticket' );
+$m->content_contains( 'ticket foo', 'has ticket foo' );
+
+diag "first add clause, then search";
+$m->get_ok('/Search/Build.html?NewQuery=1');
+$m->form_name( 'BuildQuery' );
+$m->submit_form(
+ fields => { $cf_op->name => '<', $cf_field->name => '2011-09-30', },
+ button => 'AddClause',
+);
+$m->follow_link_ok( { text => 'Show Results' } );
+$m->title_is( 'Found 1 ticket', 'found only 1 ticket' );
+$m->content_contains( 'ticket foo', 'has ticket foo' );
+
diff --git a/rt/t/web/search_rss.t b/rt/t/web/search_rss.t
index 454dc0369..95de931c3 100644
--- a/rt/t/web/search_rss.t
+++ b/rt/t/web/search_rss.t
@@ -2,10 +2,10 @@
use strict;
-use RT::Test tests => 36;
-RT::Test->started_ok;
+use RT::Test tests => 38;
+my ($baseurl, $agent) = RT::Test->started_ok;
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
for ( 1 .. 5 ) {
$ticket->Create(
Subject => 'Ticket ' . $_,
@@ -15,7 +15,6 @@ for ( 1 .. 5 ) {
);
}
-my $agent = RT::Test::Web->new;
ok $agent->login('root', 'password'), 'logged in as root';
$agent->get_ok('/Search/Build.html');
@@ -23,7 +22,7 @@ $agent->form_name('BuildQuery');
$agent->field('idOp', '>');
$agent->field('ValueOfid', '0');
$agent->submit('DoSearch');
-$agent->follow_link_ok({text=>'Show Results'});
+$agent->follow_link_ok({id => 'page-results'});
for ( 1 .. 5 ) {
$agent->content_contains('Ticket ' . $_);
@@ -64,7 +63,7 @@ my $user_b = RT::Test->load_or_create_user(
Name => 'user_b', Password => 'password',
);
ok $user_b && $user_b->id, 'loaded or created user';
-$agent_b->login('user_b', 'password'), 'logged in as user B';
+$agent_b->login('user_b', 'password');
$agent_b->get_ok($noauth_uri);
is( $agent_b->content_type, 'application/rss+xml', 'content type' );
is( $agent_b->content, $rss_content, 'content' );
diff --git a/rt/t/web/search_simple.t b/rt/t/web/search_simple.t
new file mode 100644
index 000000000..1efc9a566
--- /dev/null
+++ b/rt/t/web/search_simple.t
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 16;
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+RT::Test->create_tickets(
+ { Queue => 'General' },
+ { Subject => 'ticket foo' },
+ { Subject => 'ticket bar' },
+);
+
+ok( $m->login, 'logged in' );
+
+$m->get_ok('/Search/Simple.html');
+$m->content_lacks( 'Show Results', 'no page menu' );
+$m->get_ok('/Search/Simple.html?q=ticket foo');
+$m->content_contains( 'Show Results', "has page menu" );
+$m->title_is( 'Found 1 ticket', 'title' );
+$m->content_contains( 'ticket foo', 'has ticket foo' );
+
+# TODO more simple search tests
diff --git a/rt/t/web/search_tabs.t b/rt/t/web/search_tabs.t
new file mode 100644
index 000000000..b3ed2cbdf
--- /dev/null
+++ b/rt/t/web/search_tabs.t
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use RT::Test tests => 21;
+my ($baseurl, $agent) = RT::Test->started_ok;
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+for ( 1 .. 3 ) {
+ $ticket->Create(
+ Subject => 'Ticket ' . $_,
+ Queue => 'General',
+ Owner => 'root',
+ Requestor => 'clownman@localhost',
+ );
+}
+
+ok $agent->login('root', 'password'), 'logged in as root';
+
+# [issues.bestpractical.com #16841] {
+$agent->get_ok('/Search/Build.html');
+
+$agent->form_name('BuildQuery');
+$agent->field('idOp', '=');
+$agent->field('ValueOfid', '1');
+$agent->submit('AddClause');
+
+$agent->form_name('BuildQuery');
+$agent->field('idOp', '=');
+$agent->field('ValueOfid', '2');
+$agent->field('AndOr', 'OR');
+$agent->submit('AddClause');
+
+$agent->follow_link_ok({id => 'page-results'});
+$agent->title_is('Found 2 tickets');
+# }
+
+# [issues.bestpractical.com #17237] {
+$agent->follow_link_ok({text => 'New Search'});
+$agent->title_is('Query Builder');
+
+$agent->form_name('BuildQuery');
+$agent->field('idOp', '=');
+$agent->field('ValueOfid', '1');
+$agent->submit('AddClause');
+
+$agent->form_name('BuildQuery');
+$agent->field('idOp', '=');
+$agent->field('ValueOfid', '2');
+$agent->field('AndOr', 'OR');
+$agent->click_button(name => 'DoSearch');
+
+$agent->title_is('Found 2 tickets');
+
+$agent->follow_link_ok({id => 'page-results'});
+$agent->title_is('Found 2 tickets');
+# }
+
+$agent->follow_link_ok({text => 'Chart'});
+$agent->text_contains('id = 1 OR id = 2');
+$agent->form_name('SaveSearch');
+$agent->field('SavedSearchDescription' => 'this is my saved chart');
+$agent->click_button(name => 'SavedSearchSave');
+
+# Confirm that we saved the chart and that it's the "current chart"
+$agent->text_contains('Chart this is my saved chart saved.');
+$agent->form_name('SaveSearch');
+is($agent->value('SavedSearchDescription'), 'this is my saved chart');
+
+$agent->follow_link_ok({text => 'Edit Search'});
+$agent->form_name('BuildQuery');
+$agent->field('idOp', '=');
+$agent->field('ValueOfid', '3');
+$agent->field('AndOr', 'OR');
+$agent->click_button(name => 'DoSearch');
+
+$agent->title_is('Found 3 tickets');
+
+$agent->follow_link_ok({text => 'Chart'});
+$agent->text_contains('id = 1 OR id = 2 OR id = 3');
+
+# The interesting bit: confirm that the chart we saved is still the
+# "current chart" after roundtripping through search builder
+$agent->form_name('SaveSearch');
+is($agent->value('SavedSearchDescription'), 'this is my saved chart');
+
diff --git a/rt/t/web/self_service.t b/rt/t/web/self_service.t
new file mode 100644
index 000000000..49d9e37ee
--- /dev/null
+++ b/rt/t/web/self_service.t
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+use RT::Test tests => 9;
+
+my ($url, $m) = RT::Test->started_ok;
+
+my ($ticket) =
+ RT::Test->create_ticket( Queue => 'General', Subject => 'test subject' );
+
+$m->login();
+
+$m->get_ok( '/SelfService/Display.html?id=' . $ticket->id,
+ 'got selfservice display page' );
+
+my $title = '#' . $ticket->id . ': test subject';
+$m->title_is( $title );
+$m->content_contains( "<h1>$title</h1>", "contains <h1>$title</h1>" );
+
+# TODO need more SelfService tests
diff --git a/rt/t/web/squish.t b/rt/t/web/squish.t
new file mode 100644
index 000000000..ff43e74fb
--- /dev/null
+++ b/rt/t/web/squish.t
@@ -0,0 +1,78 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test tests => 26;
+
+RT->Config->Set( DevelMode => 0 );
+RT->Config->Set( WebDefaultStylesheet => 'aileron' );
+RT->Config->Set( MasonLocalComponentRoot => RT::Test::get_abs_relocatable_dir('html') );
+
+my ( $url, $m ) = RT::Test->started_ok;
+$m->login;
+
+diag "test squished files with devel mode disabled";
+
+$m->follow_link_ok( { url_regex => qr!aileron-squished-([a-f0-9]{32})\.css! },
+ 'follow squished css' );
+$m->content_like( qr!/\*\* End of .*?.css \*/!, 'squished css' );
+$m->content_lacks( 'text-decoration: underline !important;',
+ 'no print.css by default' );
+
+$m->back;
+my ($js_link) =
+ $m->content =~ m!src="([^"]+?squished-([a-f0-9]{32})\.js)"!;
+$m->get_ok( $url . $js_link, 'follow squished js' );
+$m->content_lacks('function just_testing', "no not-by-default.js");
+$m->content_contains('jQuery.noConflict', "found default js content");
+
+RT::Test->stop_server;
+
+diag "test squished files with customized files and devel mode disabled";
+RT->AddJavaScript( 'not-by-default.js' );
+RT->AddStyleSheets( 'print.css' );
+
+( $url, $m ) = RT::Test->started_ok;
+
+$m->login;
+$m->follow_link_ok( { url_regex => qr!aileron-squished-([a-f0-9]{32})\.css! },
+ 'follow squished css' );
+$m->content_like( qr!/\*\* End of .*?.css \*/!, 'squished css' );
+$m->content_contains( 'text-decoration: underline !important;',
+ 'has print.css' );
+
+$m->back;
+($js_link) =
+ $m->content =~ m!src="([^"]+?squished-([a-f0-9]{32})\.js)"!;
+$m->get_ok( $url . $js_link, 'follow squished js' );
+$m->content_contains( 'function just_testing', "has not-by-default.js" );
+$m->content_contains('jQuery.noConflict', "found default js content");
+RT::Test->stop_server;
+
+
+diag "Test with a trivial jsmin which is a pass-through";
+RT->Config->Set( 'JSMinPath' => RT::Test::get_abs_relocatable_dir("passthrough-jsmin"));
+( $url, $m ) = RT::Test->started_ok;
+$m->login;
+($js_link) =
+ $m->content =~ m!src="([^"]+?squished-([a-f0-9]{32})\.js)"!;
+$m->get_ok( $url . $js_link, 'follow squished js' );
+$m->content_contains( 'passthrough-jsmin added this', "has passthrough-added content" );
+$m->content_contains( 'function just_testing', "has not-by-default.js" );
+$m->content_contains('jQuery.noConflict', "found default js content");
+RT::Test->stop_server;
+
+
+diag "test squished files with devel mode enabled";
+RT->Config->Set( 'DevelMode' => 1 );
+RT->AddJavaScript( 'not-by-default.js' );
+RT->AddStyleSheets( 'nottherebutwedontcare.css' );
+
+( $url, $m ) = RT::Test->started_ok;
+$m->login;
+$m->content_unlike( qr!squished-.*?\.(js|css)!,
+ 'no squished link with develmode' );
+
+$m->content_contains('not-by-default.js', "found extra javascript resource");
+$m->content_contains('nottherebutwedontcare.css', "found extra css resource");
+$m->content_contains('jquery_noconflict.js', "found a default js resource");
+
diff --git a/rt/t/web/template.t b/rt/t/web/template.t
new file mode 100644
index 000000000..40a5366dc
--- /dev/null
+++ b/rt/t/web/template.t
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test tests => 19;
+
+my $user_a = RT::Test->load_or_create_user(
+ Name => 'user_a', Password => 'password',
+);
+ok $user_a && $user_a->id, 'loaded or created user';
+
+my ($baseurl, $m) = RT::Test->started_ok;
+
+ok( RT::Test->set_rights(
+ { Principal => $user_a, Right => [qw(ShowConfigTab ShowTemplate ModifyTemplate)] },
+), 'set rights');
+
+ok $m->login('user_a', 'password'), 'logged in as user A';
+
+# get to the templates screen
+$m->follow_link( text => 'Configuration' );
+$m->title_is(q{RT Administration}, 'admin screen');
+
+$m->follow_link( text => 'Global' );
+$m->title_is(q{Admin/Global configuration}, 'global admin');
+
+$m->follow_link( text => 'Templates' );
+$m->title_is(q{Modify templates which apply to all queues}, 'global templates');
+
+$m->follow_link( text => 'Resolved' ); # template name
+$m->title_is(q{Modify template Resolved}, 'modifying the Resolved template');
+
+# now try changing Type back and forth
+$m->form_name('ModifyTemplate');
+is($m->value('Type'), 'Perl');
+
+$m->field(Type => 'Simple');
+$m->submit;
+
+$m->title_is(q{Modify template Resolved}, 'modifying the Resolved template');
+$m->form_name('ModifyTemplate');
+is($m->value('Type'), 'Simple', 'updated type to simple');
+
+$m->field(Type => 'Perl');
+$m->submit;
+
+$m->title_is(q{Modify template Resolved}, 'modifying the Resolved template');
+$m->form_name('ModifyTemplate');
+is($m->value('Type'), 'Simple', 'need the ExecuteCode right to update Type to Perl');
+$m->content_contains('Permission Denied');
+
+ok( RT::Test->add_rights(
+ { Principal => $user_a, Right => [qw(ExecuteCode)] },
+), 'add ExecuteCode rights');
+
+$m->field(Type => 'Perl');
+$m->submit;
+
+$m->title_is(q{Modify template Resolved}, 'modifying the Resolved template');
+$m->form_name('ModifyTemplate');
+is($m->value('Type'), 'Perl', 'now that we have ExecuteCode we can update Type to Perl');
+
diff --git a/rt/t/web/ticket-create-utf8.t b/rt/t/web/ticket-create-utf8.t
index f37eeec06..8d36bd19e 100644
--- a/rt/t/web/ticket-create-utf8.t
+++ b/rt/t/web/ticket-create-utf8.t
@@ -3,9 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 41;
-
-$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
+use RT::Test tests => 43;
use Encode;
@@ -32,7 +30,7 @@ ok $m->login, 'logged in';
# create a ticket with a subject only
foreach my $test_str ( $ru_test, $l1_test ) {
ok $m->goto_create_ticket( $q ), "go to create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->field( Subject => $test_str );
$m->submit;
@@ -49,7 +47,7 @@ foreach my $test_str ( $ru_test, $l1_test ) {
foreach my $test_str ( $ru_test, $l1_test ) {
foreach my $support_str ( $ru_support, $l1_support ) {
ok $m->goto_create_ticket( $q ), "go to create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->field( Subject => $test_str );
$m->field( Content => $support_str );
$m->submit;
@@ -58,8 +56,8 @@ foreach my $test_str ( $ru_test, $l1_test ) {
qr{<td\s+class="message-header-value"[^>]*>\s*\Q$test_str\E\s*</td>}i,
'header on the page'
);
- $m->content_like(
- qr{\Q$support_str\E}i,
+ $m->content_contains(
+ $support_str,
'content on the page'
);
@@ -72,7 +70,7 @@ foreach my $test_str ( $ru_test, $l1_test ) {
foreach my $test_str ( $ru_test, $l1_test ) {
foreach my $support_str ( $ru_support, $l1_support ) {
ok $m->goto_create_ticket( $q ), "go to create ticket";
- $m->form_number(3);
+ $m->form_name('TicketCreate');
$m->field( Subject => $test_str );
$m->field( Content => $support_str );
$m->submit;
@@ -81,8 +79,8 @@ foreach my $test_str ( $ru_test, $l1_test ) {
qr{<td\s+class="message-header-value"[^>]*>\s*\Q$test_str\E\s*</td>}i,
'header on the page'
);
- $m->content_like(
- qr{\Q$support_str\E}i,
+ $m->content_contains(
+ $support_str,
'content on the page'
);
diff --git a/rt/t/web/ticket_display.t b/rt/t/web/ticket_display.t
new file mode 100644
index 000000000..a9cab0cbf
--- /dev/null
+++ b/rt/t/web/ticket_display.t
@@ -0,0 +1,63 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 18;
+
+my $queue = RT::Test->load_or_create_queue( Name => 'General' );
+
+my $user = RT::Test->load_or_create_user(
+ Name => 'user',
+ Password => 'password',
+);
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok(
+ RT::Test->set_rights(
+ { Principal => $user, Right => [qw(SeeQueue CreateTicket)] },
+ ),
+ 'set rights'
+);
+
+ok $m->login( 'user', 'password' ), 'logged in as user';
+
+diag "test ShowTicket right";
+{
+
+ $m->get_ok( '/Ticket/Create.html?Queue=' . $queue->id,
+ 'go to ticket create page' );
+ my $form = $m->form_name('TicketCreate');
+ $m->submit_form( fields => { Subject => 'ticket foo' } );
+
+ my $ticket = RT::Test->last_ticket;
+ ok( $ticket->id, 'ticket is created' );
+ my $id = $ticket->id;
+
+ $m->content_lacks( "Ticket $id created", 'created ticket' );
+ $m->content_contains( "No permission to view newly created ticket #$id",
+ 'got no permission msg' );
+ $m->warning_like( qr/No permission to view newly created ticket #$id/,
+ 'got no permission warning' );
+
+
+ $m->goto_ticket($id);
+ $m->content_contains( "No permission to view ticket",
+ 'got no permission msg' );
+ $m->warning_like( qr/No permission to view ticket/, 'got warning' );
+ $m->title_is('RT Error');
+
+ ok(
+ RT::Test->add_rights(
+ { Principal => $user, Right => [qw(ShowTicket)] },
+ ),
+ 'add ShowTicket right'
+ );
+
+ $m->reload;
+
+ $m->content_lacks( "No permission to view ticket", 'no error msg' );
+ $m->title_is( "#$id: ticket foo", 'we can it' );
+}
+
+
+# TODO more /Ticket/Display.html tests here
+
diff --git a/rt/t/web/ticket_forward.t b/rt/t/web/ticket_forward.t
new file mode 100644
index 000000000..be06ad976
--- /dev/null
+++ b/rt/t/web/ticket_forward.t
@@ -0,0 +1,232 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test tests => undef;
+use File::Spec;
+my $att_file = File::Spec->catfile( RT::Test->temp_directory, 'attachment' );
+open my $att_fh, '>', $att_file or die $!;
+print $att_fh "this is an attachment";
+close $att_fh;
+my $att_name = ( File::Spec->splitpath($att_file) )[-1];
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+
+# Create a ticket with content and an attachment
+$m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
+
+$m->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test forward',
+ Content => 'this is content',
+ Attach => $att_file,
+ },
+);
+$m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+RT::Test->clean_caught_mails;
+
+diag "Forward Ticket" if $ENV{TEST_VERBOSE};
+{
+ $m->follow_link_ok(
+ { id => 'page-actions-forward' },
+ 'follow 1st Forward to forward ticket'
+ );
+
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test, rt-to@example.com',
+ Cc => 'rt-cc@example.com',
+ },
+ button => 'ForwardAndReturn'
+ );
+ $m->content_contains( 'Sent email successfully', 'sent mail msg' );
+ $m->content_contains(
+ 'Forwarded Ticket to rt-test, rt-to@example.com, rt-cc@example.com',
+ 'txn msg' );
+ my ($mail) = RT::Test->fetch_caught_mails;
+ like( $mail, qr!Subject: test forward!, 'Subject field' );
+ like( $mail, qr!To: rt-test, rt-to\@example.com!, 'To field' );
+ like( $mail, qr!Cc: rt-cc\@example.com!, 'Cc field' );
+ like( $mail, qr!This is a forward of ticket!, 'content' );
+ like( $mail, qr!this is an attachment!, 'att content' );
+ like( $mail, qr!$att_name!, 'att file name' );
+}
+
+diag "Forward Transaction" if $ENV{TEST_VERBOSE};
+{
+ $m->follow_link_ok( { text => 'Forward', n => 2 }, 'follow 2nd Forward' );
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test, rt-to@example.com',
+ Cc => 'rt-cc@example.com',
+ Bcc => 'rt-bcc@example.com'
+ },
+ button => 'ForwardAndReturn'
+ );
+ $m->content_contains( 'Sent email successfully', 'sent mail msg' );
+ $m->content_like(
+qr/Forwarded Transaction #\d+ to rt-test, rt-to\@example.com, rt-cc\@example.com, rt-bcc\@example.com/,
+ 'txn msg'
+ );
+ my ($mail) = RT::Test->fetch_caught_mails;
+ like( $mail, qr!Subject: test forward!, 'Subject field' );
+ like( $mail, qr!To: rt-test, rt-to\@example.com!, 'To field' );
+ like( $mail, qr!Cc: rt-cc\@example.com!, 'Cc field' );
+ like( $mail, qr!Bcc: rt-bcc\@example.com!, 'Bcc field' );
+ like( $mail, qr!This is a forward of transaction!, 'content' );
+ like( $mail, qr!$att_name!, 'att file name' );
+ like( $mail, qr!this is an attachment!, 'att content' );
+}
+
+diag "Forward Ticket without content" if $ENV{TEST_VERBOSE};
+{
+ my $ticket = RT::Test->create_ticket(
+ Subject => 'test forward without content',
+ Queue => 1,
+ );
+ $m->get_ok( $baseurl . '/Ticket/Forward.html?id=' . $ticket->id );
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => { To => 'rt-test@example.com', },
+ button => 'ForwardAndReturn'
+ );
+ $m->content_contains( 'Sent email successfully', 'sent mail msg' );
+ my ($mail) = RT::Test->fetch_caught_mails;
+ like( $mail, qr/Subject: Fwd: \[example\.com #\d\] test forward without content/, 'Subject field' );
+ like( $mail, qr/To: rt-test\@example\.com/, 'To field' );
+ like( $mail, qr/This is a forward of ticket #\d/, 'content' );
+}
+
+diag "Forward Transaction with attachments but empty content" if $ENV{TEST_VERBOSE};
+{
+ # Create a ticket without content but with a non-text/plain attachment
+ $m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
+
+ $m->form_name('TicketCreate');
+ my $attach = $m->current_form->find_input('Attach');
+ $attach->filename("awesome.patch");
+ $attach->headers('Content-Type' => 'text/x-diff');
+ $m->set_fields(
+ Subject => 'test forward, empty content but attachments',
+ Attach => $att_file, # from up top
+ );
+ $m->click('AddMoreAttach');
+ $m->form_name('TicketCreate');
+ $attach = $m->current_form->find_input('Attach');
+ $attach->filename("bpslogo.png");
+ $attach->headers('Content-Type' => 'image/png');
+ $m->set_fields(
+ Attach => RT::Test::get_relocatable_file('bpslogo.png', '..', 'data'), # an image!
+ );
+ $m->submit;
+ $m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+ $m->content_like( qr/awesome\.patch/, 'uploaded patch file' );
+ $m->content_like( qr/text\/x-diff/, 'uploaded patch file content type' );
+ $m->content_like( qr/bpslogo\.png/, 'uploaded image file' );
+ $m->content_like( qr/image\/png/, 'uploaded image file content type' );
+ RT::Test->clean_caught_mails;
+
+ $m->follow_link_ok( { text => 'Forward', n => 2 }, 'follow 2nd Forward' );
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test@example.com',
+ },
+ button => 'ForwardAndReturn'
+ );
+ $m->content_contains( 'Sent email successfully', 'sent mail msg' );
+ $m->content_like( qr/Forwarded Transaction #\d+ to rt-test\@example\.com/, 'txn msg' );
+ my ($mail) = RT::Test->fetch_caught_mails;
+ like( $mail, qr/Subject: test forward, empty content but attachments/, 'Subject field' );
+ like( $mail, qr/To: rt-test\@example.com/, 'To field' );
+ like( $mail, qr/This is a forward of transaction/, 'content' );
+ like( $mail, qr/awesome\.patch/, 'att file name' );
+ like( $mail, qr/this is an attachment/, 'att content' );
+ like( $mail, qr/text\/x-diff/, 'att content type' );
+ like( $mail, qr/bpslogo\.png/, 'att image file name' );
+ like( $mail, qr/image\/png/, 'att image content type' );
+}
+
+diag "Forward Transaction with attachments but no 'content' part" if $ENV{TEST_VERBOSE};
+{
+ my $mime = MIME::Entity->build(
+ From => 'test@example.com',
+ Subject => 'attachments for everyone',
+ Type => 'multipart/mixed',
+ );
+
+ $mime->attach(
+ Path => $att_file,
+ Type => 'text/x-diff',
+ Filename => 'awesome.patch',
+ Disposition => 'attachment',
+ );
+
+ $mime->attach(
+ Path => RT::Test::get_relocatable_file('bpslogo.png', '..', 'data'),
+ Type => 'image/png',
+ Filename => 'bpslogo.png',
+ Encoding => 'base64',
+ Disposition => 'attachment',
+ );
+
+ my $ticket = RT::Test->create_ticket(
+ Queue => 1,
+ Subject => 'test forward, attachments but no "content"',
+ MIMEObj => $mime,
+ );
+
+ $m->get_ok( $baseurl . '/Ticket/Display.html?id=' . $ticket->Id );
+ $m->content_like( qr/awesome\.patch/, 'uploaded patch file' );
+ $m->content_like( qr/text\/x-diff/, 'uploaded patch file content type' );
+ $m->content_like( qr/bpslogo\.png/, 'uploaded image file' );
+ $m->content_like( qr/image\/png/, 'uploaded image file content type' );
+ RT::Test->clean_caught_mails;
+
+ # Forward txn
+ $m->follow_link_ok( { text => 'Forward', n => 2 }, 'follow 2nd Forward' );
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test@example.com',
+ },
+ button => 'ForwardAndReturn'
+ );
+ $m->content_contains( 'Sent email successfully', 'sent mail msg' );
+ $m->content_like( qr/Forwarded Transaction #\d+ to rt-test\@example\.com/, 'txn msg' );
+
+ # Forward ticket
+ $m->follow_link_ok( { text => 'Forward', n => 1 }, 'follow 1st Forward' );
+ $m->submit_form(
+ form_name => 'ForwardMessage',
+ fields => {
+ To => 'rt-test@example.com',
+ },
+ button => 'ForwardAndReturn'
+ );
+ $m->content_contains( 'Sent email successfully', 'sent mail msg' );
+ $m->content_like( qr/Forwarded Ticket to rt-test\@example\.com/, 'txn msg' );
+
+ my ($forward_txn, $forward_ticket) = RT::Test->fetch_caught_mails;
+ my $tag = qr/Fwd: \[example\.com #\d+\]/;
+ like( $forward_txn, qr/Subject: $tag attachments for everyone/, 'Subject field is from txn' );
+ like( $forward_txn, qr/This is a forward of transaction/, 'forward description' );
+ like( $forward_ticket, qr/Subject: $tag test forward, attachments but no "content"/, 'Subject field is from ticket' );
+ like( $forward_ticket, qr/This is a forward of ticket/, 'forward description' );
+
+ for my $mail ($forward_txn, $forward_ticket) {
+ like( $mail, qr/To: rt-test\@example.com/, 'To field' );
+ like( $mail, qr/awesome\.patch/, 'att file name' );
+ like( $mail, qr/this is an attachment/, 'att content' );
+ like( $mail, qr/text\/x-diff/, 'att content type' );
+ like( $mail, qr/bpslogo\.png/, 'att image file name' );
+ like( $mail, qr/image\/png/, 'att image content type' );
+ }
+}
+
+undef $m;
+done_testing;
diff --git a/rt/t/web/ticket_links.t b/rt/t/web/ticket_links.t
new file mode 100644
index 000000000..cb30e92f9
--- /dev/null
+++ b/rt/t/web/ticket_links.t
@@ -0,0 +1,110 @@
+use strict;
+use warnings;
+use RT::Test tests => 106;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok( $m->login, "Logged in" );
+
+my $queue = RT::Test->load_or_create_queue( Name => 'General' );
+ok( $queue->id, "loaded the General queue" );
+
+my ( $deleted, $active, $inactive ) = RT::Test->create_tickets(
+ { Queue => 'General' },
+ { Subject => 'deleted ticket', },
+ { Subject => 'active ticket', },
+ { Subject => 'inactive ticket', }
+);
+
+my ( $deleted_id, $active_id, $inactive_id ) =
+ ( $deleted->id, $active->id, $inactive->id );
+
+$deleted->SetStatus('deleted');
+is( $deleted->Status, 'deleted', "deleted $deleted_id" );
+
+$inactive->SetStatus('resolved');
+is( $inactive->Status, 'resolved', 'resolved $inactive_id' );
+
+for my $type ( "DependsOn", "MemberOf", "RefersTo" ) {
+ for my $c (qw/base target/) {
+ my $id;
+
+ diag "create ticket with links of type $type $c";
+ {
+ ok( $m->goto_create_ticket($queue), "go to create ticket" );
+ $m->form_name('TicketCreate');
+ $m->field( Subject => "test ticket creation with $type $c" );
+ if ( $c eq 'base' ) {
+ $m->field( "new-$type", "$deleted_id $active_id $inactive_id" );
+ }
+ else {
+ $m->field( "$type-new", "$deleted_id $active_id $inactive_id" );
+ }
+
+ $m->submit;
+ $m->content_like(qr/Ticket \d+ created/, 'created ticket');
+ $m->content_contains("Can&#39;t link to a deleted ticket");
+ $id = RT::Test->last_ticket->id;
+ }
+
+ diag "add ticket links of type $type $c";
+ {
+ my $ticket = RT::Test->create_ticket(
+ Queue => 'General',
+ Subject => "test $type $c",
+ );
+ $id = $ticket->id;
+
+ $m->goto_ticket($id);
+ $m->follow_link_ok( { text => 'Links' }, "Followed link to Links" );
+
+ ok( $m->form_with_fields("$id-DependsOn"), "found the form" );
+ if ( $c eq 'base' ) {
+ $m->field( "$id-$type", "$deleted_id $active_id $inactive_id" );
+ }
+ else {
+ $m->field( "$type-$id", "$deleted_id $active_id $inactive_id" );
+ }
+ $m->submit;
+ $m->content_contains("Can&#39;t link to a deleted ticket");
+
+ if ( $c eq 'base' ) {
+ $m->content_like(
+ qr{"DeleteLink--$type-.*?ticket/$active_id"},
+ "$c for $type: has active ticket",
+ );
+ $m->content_like(
+ qr{"DeleteLink--$type-.*?ticket/$inactive_id"},
+ "base for $type: has inactive ticket",
+ );
+ $m->content_unlike(
+ qr{"DeleteLink--$type-.*?ticket/$deleted_id"},
+ "base for $type: no deleted ticket",
+ );
+ }
+ else {
+ $m->content_like(
+ qr{"DeleteLink-.*?ticket/$active_id-$type-"},
+ "$c for $type: has active ticket",
+ );
+ $m->content_like(
+ qr{"DeleteLink-.*?ticket/$inactive_id-$type-"},
+ "base for $type: has inactive ticket",
+ );
+ $m->content_unlike(
+ qr{"DeleteLink-.*?ticket/$deleted_id-$type-"},
+ "base for $type: no deleted ticket",
+ );
+ }
+ }
+
+ $m->goto_ticket($id);
+ $m->content_like( qr{$active_id:.*?\[new\]}, "has active ticket", );
+ $m->content_like(
+ qr{$inactive_id:.*?\[resolved\]},
+ "has inactive ticket",
+ );
+ $m->content_unlike( qr{$deleted_id.*?\[deleted\]}, "no deleted ticket",
+ );
+ }
+}
+
diff --git a/rt/t/web/ticket_modify_all.t b/rt/t/web/ticket_modify_all.t
new file mode 100644
index 000000000..c9dd7e7cd
--- /dev/null
+++ b/rt/t/web/ticket_modify_all.t
@@ -0,0 +1,44 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 15;
+
+my $ticket = RT::Test->create_ticket(
+ Subject => 'test bulk update',
+ Queue => 1,
+);
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login, 'logged in' );
+
+$m->get_ok( $url . "/Ticket/ModifyAll.html?id=" . $ticket->id );
+
+$m->submit_form(
+ form_number => 3,
+ fields => { 'UpdateContent' => 'this is update content' },
+ button => 'SubmitTicket',
+);
+
+$m->content_contains("Message recorded", 'updated ticket');
+$m->content_lacks("this is update content", 'textarea is clear');
+
+$m->get_ok($url . '/Ticket/Display.html?id=' . $ticket->id );
+$m->content_contains("this is update content", 'updated content in display page');
+
+# NOTE http://issues.bestpractical.com/Ticket/Display.html?id=18284
+RT::Test->stop_server;
+RT->Config->Set(AutocompleteOwners => 1);
+($url, $m) = RT::Test->started_ok;
+$m->login;
+
+$m->get_ok($url . '/Ticket/ModifyAll.html?id=' . $ticket->id);
+
+$m->form_name('TicketModifyAll');
+$m->field(Owner => 'root');
+$m->click('SubmitTicket');
+
+$m->form_name('TicketModifyAll');
+is($m->value('Owner'), 'root', 'owner was successfully changed to root');
+
+# XXX TODO test other parts, i.e. basic, dates, people and links
+
diff --git a/rt/t/web/ticket_modify_people.t b/rt/t/web/ticket_modify_people.t
new file mode 100644
index 000000000..750be3f2c
--- /dev/null
+++ b/rt/t/web/ticket_modify_people.t
@@ -0,0 +1,113 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 23;
+
+my $root = RT::Test->load_or_create_user( Name => 'root' );
+my $group_foo = RT::Group->new($RT::SystemUser);
+my ( $ret, $msg ) = $group_foo->CreateUserDefinedGroup(
+ Name => 'group_foo',
+ Description => 'group_foo',
+);
+ok( $ret, 'created group_foo' );
+
+my $ticket = RT::Test->create_ticket(
+ Subject => 'test modify people',
+ Queue => 'General',
+ Requestor => $root->id,
+ Cc => $group_foo->id,
+);
+
+my $user = RT::Test->load_or_create_user(
+ Name => 'user',
+ Password => 'password',
+);
+ok $user && $user->id, 'loaded or created user';
+
+ok(
+ RT::Test->set_rights(
+ { Principal => $user, Right => [qw(SeeQueue ShowTicket ModifyTicket)] },
+ ),
+ 'set rights'
+);
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login( 'user', 'password' ), 'logged in' );
+$m->get_ok( $url . "/Ticket/ModifyPeople.html?id=" . $ticket->id );
+
+ok(
+ !$m->find_link(
+ text => 'Enoch Root',
+ url_regex => qr!/Admin/Users/Modify\.html!,
+ ),
+ 'no link to modify user'
+);
+$m->content_contains('Enoch Root', 'still has the user name' );
+
+ok(
+ !$m->find_link(
+ text => 'group_foo',
+ url_regex => qr!/Admin/Groups/Modify\.html!,
+ ),
+ 'no link to modify group'
+);
+
+$m->content_contains('group_foo', 'still has the group name' );
+
+ok( RT::Test->add_rights( { Principal => $user, Right => ['AdminUsers'] }, ),
+ 'added AdminUsers right' );
+$m->reload;
+ok(
+ !$m->find_link(
+ text => 'Enoch Root',
+ url_regex => qr!/Admin/Users/Modify\.html!,
+ ),
+ 'still no link to modify user'
+);
+ok(
+ !$m->find_link(
+ text => 'group_foo',
+ url_regex => qr!/Admin/Groups/Modify\.html!,
+ ),
+ 'still no link to modify group'
+);
+
+ok(
+ RT::Test->add_rights( { Principal => $user, Right => ['ShowConfigTab'] }, ),
+ 'added ShowConfigTab right',
+);
+
+$m->reload;
+ok(
+ $m->find_link(
+ text => 'Enoch Root',
+ url_regex => qr!/Admin/Users/Modify\.html!,
+ ),
+ 'got link to modify user'
+);
+
+ok(
+ !$m->find_link(
+ text => 'group_foo',
+ url_regex => qr!/Admin/Groups/Modify\.html!,
+ ),
+ 'still no link to modify group'
+);
+
+ok(
+ RT::Test->add_rights( { Principal => $user, Right => ['AdminGroup'] }, ),
+ 'added AdminGroup right'
+);
+
+$m->reload;
+ok(
+ $m->find_link(
+ text => 'group_foo',
+ url_regex => qr!/Admin/Groups/Modify\.html!,
+ ),
+ 'got link to modify group'
+);
+
+
+# TODO test Add|Delete people
+
diff --git a/rt/t/web/ticket_owner.t b/rt/t/web/ticket_owner.t
index 0bacaf1bc..4db39e61a 100644
--- a/rt/t/web/ticket_owner.t
+++ b/rt/t/web/ticket_owner.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 91;
+use RT::Test nodata => 1, tests => 105;
my $queue = RT::Test->load_or_create_queue( Name => 'Regression' );
ok $queue && $queue->id, 'loaded or created queue';
@@ -18,26 +18,25 @@ my $user_b = RT::Test->load_or_create_user(
);
ok $user_b && $user_b->id, 'loaded or created user';
-RT::Test->started_ok;
+my ($baseurl, $agent_a) = RT::Test->started_ok;
ok( RT::Test->set_rights(
{ Principal => $user_a, Right => [qw(SeeQueue ShowTicket CreateTicket ReplyToTicket)] },
{ Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
), 'set rights');
-my $agent_a = RT::Test::Web->new;
ok $agent_a->login('user_a', 'password'), 'logged in as user A';
-diag "current user has no right to own, nobody selected as owner on create" if $ENV{TEST_VERBOSE};
+diag "current user has no right to own, nobody selected as owner on create";
{
$agent_a->get_ok('/', 'open home page');
$agent_a->form_name('CreateTicketInQueue');
$agent_a->select( 'Queue', $queue->id );
$agent_a->submit;
- $agent_a->content_like(qr/Create a new ticket/i, 'opened create ticket page');
+ $agent_a->content_contains('Create a new ticket', 'opened create ticket page');
my $form = $agent_a->form_name('TicketCreate');
- is $form->value('Owner'), $RT::Nobody->id, 'correct owner selected';
+ is $form->value('Owner'), RT->Nobody->id, 'correct owner selected';
ok !grep($_ == $user_a->id, $form->find_input('Owner')->possible_values),
'user A can not own tickets';
$agent_a->submit;
@@ -46,22 +45,22 @@ diag "current user has no right to own, nobody selected as owner on create" if $
my ($id) = ($agent_a->content =~ /Ticket (\d+) created in queue/);
ok $id, 'found id of the ticket';
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $id );
ok $ticket->id, 'loaded the ticket';
- is $ticket->Owner, $RT::Nobody->id, 'correct owner';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
}
-diag "user can chose owner of a new ticket" if $ENV{TEST_VERBOSE};
+diag "user can chose owner of a new ticket";
{
$agent_a->get_ok('/', 'open home page');
$agent_a->form_name('CreateTicketInQueue');
$agent_a->select( 'Queue', $queue->id );
$agent_a->submit;
- $agent_a->content_like(qr/Create a new ticket/i, 'opened create ticket page');
+ $agent_a->content_contains('Create a new ticket', 'opened create ticket page');
my $form = $agent_a->form_name('TicketCreate');
- is $form->value('Owner'), $RT::Nobody->id, 'correct owner selected';
+ is $form->value('Owner'), RT->Nobody->id, 'correct owner selected';
ok grep($_ == $user_b->id, $form->find_input('Owner')->possible_values),
'user B is listed as potential owner';
@@ -72,7 +71,7 @@ diag "user can chose owner of a new ticket" if $ENV{TEST_VERBOSE};
my ($id) = ($agent_a->content =~ /Ticket (\d+) created in queue/);
ok $id, 'found id of the ticket';
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $id );
ok $ticket->id, 'loaded the ticket';
is $ticket->Owner, $user_b->id, 'correct owner';
@@ -81,7 +80,7 @@ diag "user can chose owner of a new ticket" if $ENV{TEST_VERBOSE};
my $agent_b = RT::Test::Web->new;
ok $agent_b->login('user_b', 'password'), 'logged in as user B';
-diag "user A can not change owner after create" if $ENV{TEST_VERBOSE};
+diag "user A can not change owner after create";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -95,30 +94,29 @@ diag "user A can not change owner after create" if $ENV{TEST_VERBOSE};
# try the following group of tests twice with different agents(logins)
my $test_cb = sub {
my $agent = shift;
- $agent->goto_ticket( $id );
- $agent->follow_link_ok({text => 'Basics'}, 'Ticket -> Basics');
- my $form = $agent->form_number(3);
+ $agent->get("/Ticket/Modify.html?id=$id");
+ my $form = $agent->form_name('TicketModify');
is $form->value('Owner'), $user_b->id, 'correct owner selected';
- $agent->select('Owner', $RT::Nobody->id);
+ $agent->select('Owner', RT->Nobody->id);
$agent->submit;
- $agent->content_like(
- qr/Permission denied/i,
+ $agent->content_contains(
+ 'Permission Denied',
'no way to change owner after create if you have no rights'
);
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $id );
ok $ticket->id, 'loaded the ticket';
is $ticket->Owner, $user_b->id, 'correct owner';
};
$test_cb->($agent_a);
- diag "even owner(user B) can not change owner" if $ENV{TEST_VERBOSE};
+ diag "even owner(user B) can not change owner";
$test_cb->($agent_b);
}
-diag "on reply correct owner is selected" if $ENV{TEST_VERBOSE};
+diag "on reply correct owner is selected";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -130,13 +128,13 @@ diag "on reply correct owner is selected" if $ENV{TEST_VERBOSE};
is $ticket->Owner, $user_b->id, 'correct owner';
$agent_a->goto_ticket( $id );
- $agent_a->follow_link_ok({text => 'Reply'}, 'Ticket -> Basics');
+ $agent_a->follow_link_ok({text => 'Reply'}, 'Ticket -> Reply');
- my $form = $agent_a->form_number(3);
+ my $form = $agent_a->form_name('TicketUpdate');
is $form->value('Owner'), '', 'empty value selected';
$agent_a->submit;
- $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $id );
ok $ticket->id, 'loaded the ticket';
is $ticket->Owner, $user_b->id, 'correct owner';
@@ -147,7 +145,7 @@ ok( RT::Test->set_rights(
{ Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
), 'set rights');
-diag "Couldn't take without coresponding right" if $ENV{TEST_VERBOSE};
+diag "Couldn't take without coresponding right";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -155,7 +153,7 @@ diag "Couldn't take without coresponding right" if $ENV{TEST_VERBOSE};
Subject => 'test',
);
ok $id, 'created a ticket #'. $id or diag "error: $msg";
- is $ticket->Owner, $RT::Nobody->id, 'correct owner';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
$agent_a->goto_ticket( $id );
ok !($agent_a->find_all_links( text => 'Take' ))[0],
@@ -164,7 +162,7 @@ diag "Couldn't take without coresponding right" if $ENV{TEST_VERBOSE};
'no Steal link as well';
}
-diag "Couldn't steal without coresponding right" if $ENV{TEST_VERBOSE};
+diag "Couldn't steal without coresponding right";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -186,7 +184,7 @@ ok( RT::Test->set_rights(
{ Principal => $user_a, Right => [qw(SeeQueue ShowTicket CreateTicket TakeTicket)] },
), 'set rights');
-diag "TakeTicket require OwnTicket to work" if $ENV{TEST_VERBOSE};
+diag "TakeTicket require OwnTicket to work";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -194,7 +192,7 @@ diag "TakeTicket require OwnTicket to work" if $ENV{TEST_VERBOSE};
Subject => 'test',
);
ok $id, 'created a ticket #'. $id or diag "error: $msg";
- is $ticket->Owner, $RT::Nobody->id, 'correct owner';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
$agent_a->goto_ticket( $id );
ok !($agent_a->find_all_links( text => 'Take' ))[0],
@@ -208,7 +206,7 @@ ok( RT::Test->set_rights(
{ Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
), 'set rights');
-diag "TakeTicket+OwnTicket work" if $ENV{TEST_VERBOSE};
+diag "TakeTicket+OwnTicket work";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -216,20 +214,20 @@ diag "TakeTicket+OwnTicket work" if $ENV{TEST_VERBOSE};
Subject => 'test',
);
ok $id, 'created a ticket #'. $id or diag "error: $msg";
- is $ticket->Owner, $RT::Nobody->id, 'correct owner';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
$agent_a->goto_ticket( $id );
ok !($agent_a->find_all_links( text => 'Steal' ))[0],
'no Steal link';
$agent_a->follow_link_ok({text => 'Take'}, 'Ticket -> Take');
- $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $id );
ok $ticket->id, 'loaded the ticket';
is $ticket->Owner, $user_a->id, 'correct owner';
}
-diag "TakeTicket+OwnTicket don't work when owner is not nobody" if $ENV{TEST_VERBOSE};
+diag "TakeTicket+OwnTicket don't work when owner is not nobody";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -252,7 +250,7 @@ ok( RT::Test->set_rights(
{ Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
), 'set rights');
-diag "StealTicket require OwnTicket to work" if $ENV{TEST_VERBOSE};
+diag "StealTicket require OwnTicket to work";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -275,7 +273,7 @@ ok( RT::Test->set_rights(
{ Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
), 'set rights');
-diag "StealTicket+OwnTicket work" if $ENV{TEST_VERBOSE};
+diag "StealTicket+OwnTicket work";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -291,13 +289,13 @@ diag "StealTicket+OwnTicket work" if $ENV{TEST_VERBOSE};
'but no Take link';
$agent_a->follow_link_ok({text => 'Steal'}, 'Ticket -> Steal');
- $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket = RT::Ticket->new( RT->SystemUser );
$ticket->Load( $id );
ok $ticket->id, 'loaded the ticket';
is $ticket->Owner, $user_a->id, 'correct owner';
}
-diag "StealTicket+OwnTicket don't work when owner is nobody" if $ENV{TEST_VERBOSE};
+diag "StealTicket+OwnTicket don't work when owner is nobody";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -305,7 +303,7 @@ diag "StealTicket+OwnTicket don't work when owner is nobody" if $ENV{TEST_VERBOS
Subject => 'test',
);
ok $id, 'created a ticket #'. $id or diag "error: $msg";
- is $ticket->Owner, $RT::Nobody->id, 'correct owner';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
$agent_a->goto_ticket( $id );
ok !($agent_a->find_all_links( text => 'Steal' ))[0],
@@ -319,7 +317,7 @@ ok( RT::Test->set_rights(
{ Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
), 'set rights');
-diag "no Steal link when owner nobody" if $ENV{TEST_VERBOSE};
+diag "no Steal link when owner nobody";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -327,7 +325,7 @@ diag "no Steal link when owner nobody" if $ENV{TEST_VERBOSE};
Subject => 'test',
);
ok $id, 'created a ticket #'. $id or diag "error: $msg";
- is $ticket->Owner, $RT::Nobody->id, 'correct owner';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
$agent_a->goto_ticket( $id );
ok !($agent_a->find_all_links( text => 'Steal' ))[0],
@@ -336,7 +334,7 @@ diag "no Steal link when owner nobody" if $ENV{TEST_VERBOSE};
'but have Take link');
}
-diag "no Take link when owner is not nobody" if $ENV{TEST_VERBOSE};
+diag "no Take link when owner is not nobody";
{
my $ticket = RT::Ticket->new( $user_a );
my ($id, $txn, $msg) = $ticket->Create(
@@ -354,3 +352,68 @@ diag "no Take link when owner is not nobody" if $ENV{TEST_VERBOSE};
'but have Steal link');
}
+ok(
+ RT::Test->set_rights(
+ {
+ Principal => $user_a,
+ Right => [
+ qw(SeeQueue ShowTicket CreateTicket ReplyToTicket OwnTicket TakeTicket StealTicket)
+ ]
+ },
+ { Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
+ ),
+ 'set rights'
+);
+
+diag
+"action is Take if old owner is nobody and new owner is current user in update page";
+{
+ my $ticket = RT::Ticket->new( $user_a );
+ my ( $id, $txn, $msg ) = $ticket->Create(
+ Queue => $queue->id,
+ Subject => 'test',
+ );
+ ok $id, 'created a ticket #'. $id or diag "error: $msg";
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
+
+ $agent_a->goto_ticket( $id );
+ $agent_a->content_lacks('Taken', 'no Taken');
+ $agent_a->follow_link_ok({text => 'Reply'}, 'Ticket -> Reply');
+ $agent_a->submit_form(
+ form_name => 'TicketUpdate',
+ fields => { Owner => $user_a->id },
+ button => 'SubmitTicket',
+ );
+ $agent_a->content_like( qr/user_a\s+-\s+Taken/, 'got user_a Taken message' );
+
+ $agent_b->goto_ticket($id);
+ $agent_b->content_like( qr/user_a\s+-\s+Taken/, 'got user_a Taken message for user b ' );
+}
+
+diag
+"action is Take if old owner is nobody and new owner is current user in basics page";
+{
+ my $ticket = RT::Ticket->new($user_a);
+ my ( $id, $txn, $msg ) = $ticket->Create(
+ Queue => $queue->id,
+ Subject => 'test',
+ );
+ ok $id, 'created a ticket #' . $id or diag "error: $msg";
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
+
+ $agent_a->goto_ticket($id);
+ $agent_a->content_lacks('Taken', 'no Taken');
+ $agent_a->follow_link_ok( { text => 'Basics' }, 'Ticket -> Basics' );
+ $agent_a->submit_form(
+ form_name => 'TicketModify',
+ fields => { Owner => $user_a->id },
+ );
+ $agent_a->content_contains( 'Owner changed from Nobody to user_a',
+ 'got set message in Basics' );
+ $agent_a->goto_ticket($id);
+ $agent_a->content_like( qr/user_a\s+-\s+Taken/, 'got user_a Taken message' );
+
+ $agent_b->goto_ticket($id);
+ $agent_b->content_like( qr/user_a\s+-\s+Taken/, 'got user_a Taken message for user b ' );
+}
+
diff --git a/rt/t/web/ticket_owner_autocomplete.t b/rt/t/web/ticket_owner_autocomplete.t
new file mode 100644
index 000000000..3aa3f282f
--- /dev/null
+++ b/rt/t/web/ticket_owner_autocomplete.t
@@ -0,0 +1,185 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test nodata => 1, tests => 43;
+use JSON qw(from_json);
+
+my $queue = RT::Test->load_or_create_queue( Name => 'Regression' );
+ok $queue && $queue->id, 'loaded or created queue';
+
+my $user_a = RT::Test->load_or_create_user(
+ Name => 'user_a', Password => 'password',
+);
+ok $user_a && $user_a->id, 'loaded or created user';
+
+my $user_b = RT::Test->load_or_create_user(
+ Name => 'user_b', Password => 'password',
+);
+ok $user_b && $user_b->id, 'loaded or created user';
+
+RT->Config->Set( AutocompleteOwners => 1 );
+my ($baseurl, $agent_a) = RT::Test->started_ok;
+
+ok( RT::Test->set_rights(
+ { Principal => $user_a, Right => [qw(SeeQueue ShowTicket CreateTicket ReplyToTicket)] },
+ { Principal => $user_b, Right => [qw(SeeQueue ShowTicket OwnTicket)] },
+), 'set rights');
+
+ok $agent_a->login('user_a', 'password'), 'logged in as user A';
+
+diag "current user has no right to own, nobody selected as owner on create";
+{
+ $agent_a->get_ok('/', 'open home page');
+ $agent_a->form_name('CreateTicketInQueue');
+ $agent_a->select( 'Queue', $queue->id );
+ $agent_a->submit;
+
+ $agent_a->content_contains('Create a new ticket', 'opened create ticket page');
+ my $form = $agent_a->form_name('TicketCreate');
+ is $form->value('Owner'), RT->Nobody->Name, 'correct owner selected';
+ autocomplete_lacks( 'RT::Queue-'.$queue->id, 'user_a' );
+ $agent_a->submit;
+
+ $agent_a->content_like(qr/Ticket \d+ created in queue/i, 'created ticket');
+ my ($id) = ($agent_a->content =~ /Ticket (\d+) created in queue/);
+ ok $id, 'found id of the ticket';
+
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, 'loaded the ticket';
+ is $ticket->Owner, RT->Nobody->id, 'correct owner';
+}
+
+diag "user can chose owner of a new ticket";
+{
+ $agent_a->get_ok('/', 'open home page');
+ $agent_a->form_name('CreateTicketInQueue');
+ $agent_a->select( 'Queue', $queue->id );
+ $agent_a->submit;
+
+ $agent_a->content_contains('Create a new ticket', 'opened create ticket page');
+ my $form = $agent_a->form_name('TicketCreate');
+ is $form->value('Owner'), RT->Nobody->Name, 'correct owner selected';
+
+ autocomplete_contains( 'RT::Queue-'.$queue->id, 'user_b' );
+ $form->value('Owner', $user_b->Name);
+ $agent_a->submit;
+
+ $agent_a->content_like(qr/Ticket \d+ created in queue/i, 'created ticket');
+ my ($id) = ($agent_a->content =~ /Ticket (\d+) created in queue/);
+ ok $id, 'found id of the ticket';
+
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, 'loaded the ticket';
+ is $ticket->Owner, $user_b->id, 'correct owner';
+}
+
+my $agent_b = RT::Test::Web->new;
+ok $agent_b->login('user_b', 'password'), 'logged in as user B';
+
+diag "user A can not change owner after create";
+{
+ my $ticket = RT::Ticket->new( $user_a );
+ my ($id, $txn, $msg) = $ticket->Create(
+ Queue => $queue->id,
+ Owner => $user_b->id,
+ Subject => 'test',
+ );
+ ok $id, 'created a ticket #'. $id or diag "error: $msg";
+ is $ticket->Owner, $user_b->id, 'correct owner';
+
+ # try the following group of tests twice with different agents(logins)
+ my $test_cb = sub {
+ my $agent = shift;
+ $agent->get("/Ticket/Modify.html?id=$id");
+ my $form = $agent->form_name('TicketModify');
+ is $form->value('Owner'), $user_b->Name, 'correct owner selected';
+ $form->value('Owner', RT->Nobody->Name);
+ $agent->submit;
+
+ $agent->content_contains(
+ 'Permission Denied',
+ 'no way to change owner after create if you have no rights'
+ );
+
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, 'loaded the ticket';
+ is $ticket->Owner, $user_b->id, 'correct owner';
+ };
+
+ $test_cb->($agent_a);
+ diag "even owner(user B) can not change owner";
+ $test_cb->($agent_b);
+}
+
+diag "on reply correct owner is selected";
+{
+ my $ticket = RT::Ticket->new( $user_a );
+ my ($id, $txn, $msg) = $ticket->Create(
+ Queue => $queue->id,
+ Owner => $user_b->id,
+ Subject => 'test',
+ );
+ ok $id, 'created a ticket #'. $id or diag "error: $msg";
+ is $ticket->Owner, $user_b->id, 'correct owner';
+
+ $agent_a->goto_ticket( $id );
+ $agent_a->follow_link_ok( { id => 'page-actions-reply' }, 'Reply' );
+
+ my $form = $agent_a->form_number(3);
+ is $form->value('Owner'), 'user_b', 'current user selected';
+ $agent_a->submit;
+
+ $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, 'loaded the ticket';
+ is $ticket->Owner, $user_b->id, 'correct owner';
+}
+
+sub autocomplete {
+ my $limit = shift;
+ my $agent = shift;
+ $agent->get_ok("/Helpers/Autocomplete/Owners?term=&limit=$limit&return=Name", "fetched autocomplete values");
+ return from_json($agent->content);
+}
+
+sub autocomplete_contains {
+ my $limit = shift;
+ my $expected = shift;
+ my $agent = shift;
+
+ unless ( $agent ) {
+ $agent = RT::Test::Web->new;
+ $agent->login('user_a', 'password');
+ }
+
+ my $results = autocomplete( $limit, $agent );
+
+ my %seen;
+ $seen{$_->{value}}++ for @$results;
+ $expected = [$expected] unless ref $expected eq 'ARRAY';
+ is((scalar grep { not $seen{$_} } @$expected), 0, "got all expected values");
+}
+
+sub autocomplete_lacks {
+ my $limit = shift;
+ my $lacks = shift;
+ my $agent = shift;
+
+ unless ( $agent ) {
+ $agent = RT::Test::Web->new;
+ $agent->login('user_a', 'password');
+ }
+
+ my $results = autocomplete( $limit, $agent );
+
+ my %seen;
+ $seen{$_->{value}}++ for @$results;
+ $lacks = [$lacks] unless ref $lacks eq 'ARRAY';
+ is((scalar grep { $seen{$_} } @$lacks), 0, "didn't get any unexpected values");
+}
+
diff --git a/rt/t/web/ticket_owner_issues_16656.t b/rt/t/web/ticket_owner_issues_16656.t
new file mode 100644
index 000000000..a6306f740
--- /dev/null
+++ b/rt/t/web/ticket_owner_issues_16656.t
@@ -0,0 +1,63 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use RT::Test tests => 19;
+
+my $queue = RT::Test->load_or_create_queue( Name => 'Test' );
+ok $queue && $queue->id, 'loaded or created queue';
+
+my $user_a = RT::Test->load_or_create_user(
+ Name => 'user_a',
+ EmailAddress => 'user_a@example.com',
+ Password => 'password',
+);
+ok $user_a && $user_a->id, 'loaded or created user';
+
+RT->Config->Set( AutocompleteOwners => 0 );
+my ($baseurl, $agent_root) = RT::Test->started_ok;
+
+ok( RT::Test->set_rights({
+ Principal => 'Requestor',
+ Object => $queue,
+ Right => [qw(OwnTicket)]
+}), 'set rights');
+
+ok $agent_root->login('root', 'password'), 'logged in as user root';
+
+diag "user_a doesn't show up in create form";
+{
+ $agent_root->get_ok('/', 'open home page');
+ $agent_root->form_name('CreateTicketInQueue');
+ $agent_root->select( 'Queue', '1' );
+ $agent_root->submit;
+
+ $agent_root->content_contains('Create a new ticket', 'opened create ticket page');
+ my $form = $agent_root->form_name('TicketCreate');
+ my $input = $form->find_input('Owner');
+ is $input->value, RT->Nobody->Id, 'correct owner selected';
+ ok((not scalar grep { $_ == $user_a->Id } $input->possible_values), 'no user_a value in dropdown');
+ $form->value('Requestors', 'user_a@example.com');
+ $agent_root->submit;
+
+ $agent_root->content_like(qr/Ticket \d+ created in queue/i, 'created ticket');
+ my ($id) = ($agent_root->content =~ /Ticket (\d+) created in queue/);
+ ok $id, 'found id of the ticket';
+
+ my $ticket = RT::Ticket->new( RT->SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, 'loaded the ticket';
+ is $ticket->Queue, '1', 'correct queue';
+ is $ticket->Owner, RT->Nobody->Id, 'correct owner';
+ is $ticket->RequestorAddresses, 'user_a@example.com', 'correct requestor';
+}
+
+diag "user_a doesn't appear in owner list after being made requestor";
+{
+ $agent_root->get("/Ticket/Modify.html?id=1");
+ my $form = $agent_root->form_name('TicketModify');
+ my $input = $form->find_input('Owner');
+ is $input->value, RT->Nobody->Id, 'correct owner selected';
+ ok((not scalar grep { $_ == $user_a->Id } $input->possible_values), 'no user_a value in dropdown');
+}
+
diff --git a/rt/t/web/ticket_seen.t b/rt/t/web/ticket_seen.t
index 3a77a5899..8dacaf59f 100644
--- a/rt/t/web/ticket_seen.t
+++ b/rt/t/web/ticket_seen.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 21;
+use RT::Test nodata => 1, tests => 23, config => 'Set($ShowUnreadMessageNotifications, 1);';
my $queue = RT::Test->load_or_create_queue( Name => 'Regression' );
ok $queue && $queue->id, 'loaded or created queue';
@@ -30,7 +30,7 @@ ok $agent_a->login('user_a', 'password'), 'logged in as user A';
my $agent_b = RT::Test::Web->new;
ok $agent_b->login('user_b', 'password'), 'logged in as user B';
-diag "create a ticket for testing" if $ENV{TEST_VERBOSE};
+diag "create a ticket for testing";
my $tid;
{
my $ticket = RT::Ticket->new( $user_a );
@@ -44,7 +44,7 @@ my $tid;
is $ticket->Owner, $user_a->id, 'correct owner';
}
-diag "user B adds a message, we check that user A see notification and can clear it" if $ENV{TEST_VERBOSE};
+diag "user B adds a message, we check that user A see notification and can clear it";
{
my $ticket = RT::Ticket->new( $user_b );
$ticket->Load( $tid );
@@ -62,10 +62,10 @@ diag "user B adds a message, we check that user A see notification and can clear
ok( $reply_id, 'got correspond txn id' );
$agent_a->goto_ticket($tid);
- $agent_a->content_like(qr/bla-bla/ims, 'the message on the page');
+ $agent_a->content_contains('bla-bla', 'the message on the page');
- $agent_a->content_like(
- qr/unread message/ims,
+ $agent_a->content_contains(
+ 'unread message',
'we have not seen something'
);
@@ -76,20 +76,20 @@ diag "user B adds a message, we check that user A see notification and can clear
like( $agent_a->base, qr/#txn-$reply_id$/, 'contains anchor' );
$agent_a->follow_link_ok({text => 'jump to the first unread message and mark all messages as seen'}, 'try to mark all as seen');
- $agent_a->content_like(
- qr/Marked all messages as seen/ims,
+ $agent_a->content_contains(
+ 'Marked all messages as seen',
'see success message'
);
like( $agent_a->base, qr/#txn-$reply_id$/, 'contains anchor' );
- $agent_a->content_like(
- qr/Marked all messages as seen/ims,
+ $agent_a->content_contains(
+ 'Marked all messages as seen',
'see success message'
);
$agent_a->goto_ticket($tid);
- $agent_a->content_unlike(
- qr/unread message/ims,
+ $agent_a->content_lacks(
+ 'unread message',
'we have seen everything, so no messages'
);
}
diff --git a/rt/t/web/ticket_txn_content.t b/rt/t/web/ticket_txn_content.t
index 1c1056a3e..db4751218 100644
--- a/rt/t/web/ticket_txn_content.t
+++ b/rt/t/web/ticket_txn_content.t
@@ -1,37 +1,48 @@
#!/usr/bin/perl -w
use strict;
-use RT::Test tests => 37;
-use File::Temp 'tempfile';
-use File::Spec;
-my ( $plain_fh, $plain_file ) =
- tempfile( 'rttestXXXXXX', SUFFIX => '.txt', UNLINK => 1, TMPDIR => 1 );
+use RT::Test tests => 63;
+my $plain_file = File::Spec->catfile( RT::Test->temp_directory, 'attachment.txt' );
+open my $plain_fh, '>', $plain_file or die $!;
print $plain_fh "this is plain content";
close $plain_fh;
my $plain_name = (File::Spec->splitpath($plain_file))[-1];
-my ( $html_fh, $html_file ) =
- tempfile( 'rttestXXXXXX', SUFFIX => '.html', UNLINK => 1, TMPDIR => 1 );
-print $html_fh "this is html content";
+my $html_file = File::Spec->catfile( RT::Test->temp_directory, 'attachment.html' );
+open my $html_fh, '>', $html_file or die $!;
+print $html_fh "this is plain content";
close $html_fh;
my $html_name = (File::Spec->splitpath($html_file))[-1];
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in';
-my $queue = RT::Queue->new($RT::Nobody);
+my $queue = RT::Queue->new(RT->Nobody);
my $qid = $queue->Load('General');
ok( $qid, "Loaded General queue" );
-RT::Test->set_mail_catcher;
RT::Test->clean_caught_mails;
+sub follow_parent_with_headers_link {
+ my $m = shift;
+ my $link = $m->find_link(@_)->url;
+ $link =~ s{/(\d+)$}{"/" . ($1-1)}e; # get the parent attach
+ $m->get_ok($baseurl . $link);
+}
+
+sub follow_with_headers_link {
+ my $m = shift;
+ my $link = $m->find_link(@_)->url;
+ $link =~ s{/\d+/(\d+)/.+$}{/WithHeaders/$1}; # frob into a with headers url
+ $m->get_ok($baseurl . $link);
+}
+
for my $type ( 'text/plain', 'text/html' ) {
$m->form_name('CreateTicketInQueue');
$m->field( 'Queue', $qid );
$m->submit;
is( $m->status, 200, "request successful" );
- $m->content_like( qr/Create a new ticket/, 'ticket create page' );
+ $m->content_contains('Create a new ticket', 'ticket create page' );
$m->form_name('TicketCreate');
$m->field( 'Subject', 'with plain attachment' );
@@ -40,16 +51,26 @@ for my $type ( 'text/plain', 'text/html' ) {
$m->field( 'ContentType', $type ) unless $type eq 'text/plain';
$m->submit;
is( $m->status, 200, "request successful" );
- $m->content_like( qr/with plain attachment/,
+ $m->content_contains('with plain attachment',
'we have subject on the page' );
- $m->content_like( qr/this is main content/, 'main content' );
- $m->content_like( qr/Download $plain_name/, 'download plain file link' );
+ $m->content_contains('this is main content', 'main content' );
+ $m->content_contains("Download $plain_name", 'download plain file link' );
+
+ # Check for Message-IDs
+ follow_parent_with_headers_link($m, text => 'with headers', n => 1);
+ $m->content_like(qr/^Message-ID:/im, 'create content has one Message-ID');
+ $m->content_unlike(qr/^Message-ID:.+?Message-ID:/ism, 'but not two Message-IDs');
+ $m->back;
+
+ follow_with_headers_link($m, text => "Download $plain_name", n => 1);
+ $m->content_unlike(qr/^Message-ID:/im, 'attachment lacks a Message-ID');
+ $m->back;
my ( $mail ) = RT::Test->fetch_caught_mails;
like( $mail, qr/this is main content/, 'email contains main content' );
# check the email link in page too
$m->follow_link_ok( { text => 'Show' }, 'show the email outgoing' );
- $m->content_like( qr/this is main content/, 'email contains main content');
+ $m->content_contains('this is main content', 'email contains main content');
$m->back;
$m->follow_link_ok( { text => 'Reply' }, "reply to the ticket" );
@@ -67,13 +88,27 @@ for my $type ( 'text/plain', 'text/html' ) {
$m->click('SubmitTicket');
is( $m->status, 200, "request successful" );
- $m->content_like( qr/this is main reply content/, 'main reply content' );
- $m->content_like( qr/Download $html_name/, 'download html file link' );
+ $m->content_contains("this is main reply content", 'main reply content' );
+ $m->content_contains("Download $html_name", 'download html file link' );
+
+ # Check for Message-IDs
+ follow_parent_with_headers_link($m, text => 'with headers', n => 2);
+ $m->content_like(qr/^Message-ID:/im, 'correspondence has one Message-ID');
+ $m->content_unlike(qr/^Message-ID:.+?Message-ID:/ism, 'but not two Message-IDs');
+ $m->back;
+
+ follow_with_headers_link($m, text => "Download $plain_name", n => 2);
+ $m->content_unlike(qr/^Message-ID:/im, 'text/plain attach lacks a Message-ID');
+ $m->back;
+
+ follow_with_headers_link($m, text => "Download $html_name", n => 1);
+ $m->content_unlike(qr/^Message-ID:/im, 'text/html attach lacks a Message-ID');
+ $m->back;
( $mail ) = RT::Test->fetch_caught_mails;
like( $mail, qr/this is main reply content/, 'email contains main reply content' );
# check the email link in page too
$m->follow_link_ok( { text => 'Show', n => 2 }, 'show the email outgoing' );
- $m->content_like( qr/this is main reply content/, 'email contains main reply content');
+ $m->content_contains("this is main reply content", 'email contains main reply content');
$m->back;
}
diff --git a/rt/t/web/ticket_update_without_content.t b/rt/t/web/ticket_update_without_content.t
index 595cb74e9..54f0c5a8a 100644
--- a/rt/t/web/ticket_update_without_content.t
+++ b/rt/t/web/ticket_update_without_content.t
@@ -2,11 +2,11 @@
use strict;
use warnings;
-use RT::Test tests => 10;
+use RT::Test tests => 12;
my ( $url, $m ) = RT::Test->started_ok;
# merged tickets still show up in search
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my ( $ret, $msg ) = $ticket->Create(
Subject => 'base ticket' . $$,
Queue => 'general',
@@ -30,10 +30,10 @@ $m->submit_form(
fields => { Priority => '1', }
);
-$m->content_like(qr/priority changed/i);
-$m->content_unlike(qr/message recorded/i);
+$m->content_contains("Priority changed");
+$m->content_lacks("message recorded");
-my $root = RT::User->new( $RT::SystemUser );
+my $root = RT::User->new( RT->SystemUser );
$root->Load('root');
( $ret, $msg ) = $root->SetSignature(<<EOF);
best wishes
@@ -48,5 +48,5 @@ $m->submit_form(
form_number => 3,
fields => { Priority => '2', }
);
-$m->content_like(qr/priority changed/i);
-$m->content_unlike(qr/message recorded/i);
+$m->content_contains("Priority changed");
+$m->content_lacks("message recorded");
diff --git a/rt/t/web/transaction_batch.t b/rt/t/web/transaction_batch.t
new file mode 100644
index 000000000..ae04e1fca
--- /dev/null
+++ b/rt/t/web/transaction_batch.t
@@ -0,0 +1,55 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test tests => 12;
+
+
+my $q = RT::Test->load_or_create_queue ( Name => 'General' );
+
+my $s1 = RT::Scrip->new(RT->SystemUser);
+my ($val, $msg) =$s1->Create( Queue => $q->Id,
+ ScripCondition => 'User Defined',
+ ScripAction => 'User Defined',
+ CustomIsApplicableCode => 'return ($self->TransactionObj->Field||"") eq "TimeEstimated"',
+ CustomPrepareCode => 'return 1',
+ CustomCommitCode => '$self->TicketObj->SetPriority($self->TicketObj->Priority + 2); return 1;',
+ Template => 'Blank',
+ Stage => 'TransactionBatch',
+ );
+ok($val,$msg);
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id,
+ Subject => "hair on fire",
+ );
+ok($tv, $tm);
+
+# Flush the Create transaction off of the ticket
+$ticket->ApplyTransactionBatch;
+
+my $testuser = RT::Test->load_or_create_user( Name => 'bob', EmailAddress => 'bob@example.com', Password => 'password' );
+ok($testuser->Id, "Created test user bob");
+
+ok( RT::Test->add_rights({ Principal => 'Privileged', Right => [qw(ShowTicket ModifyTicket SeeQueue)]}), 'Granted ticket management rights');
+
+my $test_current_user = RT::CurrentUser->new();
+$test_current_user->LoadByName($testuser->Name);
+my $api_test = RT::Ticket->new($test_current_user);
+$api_test->Load($ticket->Id);
+is($api_test->Priority,0,"Ticket priority starts at 0");
+$api_test->SetTimeEstimated(12);
+$api_test->ApplyTransactionBatch;
+is($api_test->CurrentUser->UserObj->Name, $testuser->Name,"User didn't change running Transaction Batch scrips");
+$api_test->Load($api_test->Id);
+is($api_test->Priority,2,"Ticket priority updated");
+
+my ($baseurl, $m) = RT::Test->started_ok;
+$m->login('bob','password');
+$m->get_ok("$baseurl/Ticket/Modify.html?id=".$ticket->Id);
+ $m->submit_form( form_name => 'TicketModify',
+ fields => { TimeEstimated => 5 }
+ );
+
+
+$ticket->Load($ticket->Id);
+is ($ticket->Priority , 4, "Ticket priority is set right");
diff --git a/rt/t/web/unlimited_search.t b/rt/t/web/unlimited_search.t
index d98baaac0..988a2918d 100644
--- a/rt/t/web/unlimited_search.t
+++ b/rt/t/web/unlimited_search.t
@@ -2,12 +2,12 @@
use strict;
-use RT::Test tests => 8;
-RT::Test->started_ok;
+use RT::Test tests => 85;
+my ($baseurl, $agent) = RT::Test->started_ok;
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
for ( 1 .. 75 ) {
- $ticket->Create(
+ ok $ticket->Create(
Subject => 'Ticket ' . $_,
Queue => 'General',
Owner => 'root',
@@ -15,7 +15,6 @@ for ( 1 .. 75 ) {
);
}
-my $agent = RT::Test::Web->new;
ok $agent->login('root', 'password'), 'logged in as root';
$agent->get_ok('/Search/Build.html');
@@ -27,7 +26,7 @@ $agent->form_name('BuildQuery');
$agent->field('RowsPerPage', '0');
$agent->submit('DoSearch');
$agent->follow_link_ok({text=>'Show Results'});
-$agent->content_like(qr/Ticket 75/);
+$agent->content_contains("Ticket 75");
$agent->follow_link_ok({text=>'New Search'});
$agent->form_name('BuildQuery');
@@ -38,4 +37,4 @@ $agent->form_name('BuildQuery');
$agent->field('RowsPerPage', '50');
$agent->submit('DoSearch');
$agent->follow_link_ok({text=>'Bulk Update'});
-$agent->content_unlike(qr/Ticket 51/);
+$agent->content_lacks("Ticket 51");
diff --git a/rt/t/web/user_update.t b/rt/t/web/user_update.t
new file mode 100644
index 000000000..dc908fc10
--- /dev/null
+++ b/rt/t/web/user_update.t
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use utf8;
+use RT::Test tests => 9;
+
+my ( $url, $m ) = RT::Test->started_ok;
+ok( $m->login(), 'logged in' );
+
+$m->follow_link_ok({text => 'About me'});
+$m->form_with_fields('Lang');
+$m->field(Lang => 'ja');
+$m->submit;
+
+$m->text_contains("Lang changed from (no value) to 'ja'");
+
+# we only changed one field, and it wasn't the default, so this feedback is
+# spurious and annoying
+$m->content_lacks("That is already the current value");
+
+# change back to English
+$m->form_with_fields('Lang');
+$m->field(Lang => 'en_us');
+$m->submit;
+
+# This message shows up in Japanese
+# $m->text_contains("Lang changed from 'ja' to 'en_us'");
+$m->text_contains("Langは「'ja'」から「'en_us'」に変更されました");
+
+# another spurious update
+$m->content_lacks("That is already the current value");
+
diff --git a/rt/t/web/walk.t b/rt/t/web/walk.t
new file mode 100644
index 000000000..34fab1476
--- /dev/null
+++ b/rt/t/web/walk.t
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test;
+use HTML::TreeBuilder;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+ok( $m->login( 'root' => 'password' ), 'login as root' );
+
+my %viewed = ( '/NoAuth/Logout.html' => 1 ); # in case logout
+
+my $user = RT::User->new($RT::SystemUser);
+$user->Load('root');
+ok( $user->id, 'loaded root' );
+
+my $queue = RT::Queue->new($RT::SystemUser);
+$queue->Load('General');
+ok( $queue->id, 'loaded General queue' );
+
+my $group = RT::Group->new($RT::SystemUser);
+ok( $group->CreateUserDefinedGroup( Name => 'group_foo' ) );
+my $cf = RT::CustomField->new($RT::SystemUser);
+ok(
+ $cf->Create(
+ Name => 'cf_foo',
+ Type => 'Freeform',
+ LookupType => 'RT::Queue-RT::Ticket',
+ )
+);
+ok( $cf->id, 'created cf_foo' );
+
+my $class = RT::Class->new($RT::SystemUser);
+ok( $class->Create( Name => 'class_foo' ) );
+ok( $class->id, 'created class_foo' );
+
+# to make search have results
+my $open_ticket = RT::Test->create_ticket(
+ Subject => 'ticket_foo',
+ Queue => 1,
+);
+
+my $resolved_ticket = RT::Test->create_ticket(
+ Subject => 'ticket_bar',
+ Status => 'resolved',
+ Queue => 1,
+);
+
+my @links = (
+ '/',
+ '/Admin/Users/Modify.html?id=' . $user->id,
+ '/Admin/Groups/Modify.html?id=' . $group->id,
+ '/Admin/Queues/Modify.html?id=' . $queue->id,
+ '/Admin/CustomFields/Modify.html?id=' . $cf->id,
+ '/Admin/Global/Scrip.html?id=1',
+ '/Admin/Global/Template.html?Template=1',
+ '/Admin/Articles/Classes/Modify.html?id=' . $class->id,
+ '/Search/Build.html?Query=id<10',
+ '/Ticket/Display.html?id=' . $open_ticket->id,
+ '/Ticket/Display.html?id=' . $resolved_ticket->id,
+);
+
+for my $link (@links) {
+ test_page($m, $link);
+}
+
+$m->get_ok('/NoAuth/Logout.html');
+
+sub test_page {
+ my $m = shift;
+ my $link = shift;
+ $m->get_ok( $link, $link );
+ $m->no_warnings_ok($link);
+
+ my $tree = HTML::TreeBuilder->new();
+ $tree->parse( $m->content );
+ $tree->elementify;
+ my ($top_menu) = $tree->look_down( id => 'main-navigation' );
+ my ($page_menu) = $tree->look_down( id => 'page-navigation' );
+
+ my (@links) =
+ grep { !$viewed{$_}++ && /^[^#]/ }
+ map { $_->attr('href') || () } ( $top_menu ? $top_menu->find('a') : () ),
+ ( $page_menu ? $page_menu->find('a') : () );
+
+ for my $link (@links) {
+ test_page($m, $link);
+ }
+}
+