diff options
62 files changed, 628 insertions, 504 deletions
diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index 2be9ec203..297e39fbc 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -913,16 +913,6 @@ sub ocr_image { @lines; } -=item spool_formats - -Returns a list of the invoice spool formats. - -=cut - -sub spool_formats { - qw(default oneline billco bridgestone) -} - =back =head1 BUGS diff --git a/FS/FS/TicketSystem/RT_Internal.pm b/FS/FS/TicketSystem/RT_Internal.pm index b09647e18..01e2e2966 100644 --- a/FS/FS/TicketSystem/RT_Internal.pm +++ b/FS/FS/TicketSystem/RT_Internal.pm @@ -50,7 +50,7 @@ sub access_right { sub session { my( $self, $session ) = @_; - if ( $session && $session->{'Current_User'} ) { # does this even work? + if ( $session && $session->{'CurrentUser'} ) { # does this even work? warn "$me session: using existing session and CurrentUser: \n". Dumper($session->{'CurrentUser'}) if $DEBUG; diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 02774c954..11247a28f 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -1255,6 +1255,8 @@ sub _handle_taxes { $taxhash{'taxclass'} = $part_pkg->taxclass; + warn "taxhash:\n". Dumper(\%taxhash) if $DEBUG > 2; + my @taxes = (); # entries are cust_main_county objects my %taxhash_elim = %taxhash; my @elim = qw( district city county state ); diff --git a/FS/FS/cust_pkg_discount.pm b/FS/FS/cust_pkg_discount.pm index a20794027..5f4d0dccf 100644 --- a/FS/FS/cust_pkg_discount.pm +++ b/FS/FS/cust_pkg_discount.pm @@ -106,7 +106,8 @@ sub insert { 'amount' => $self->amount, 'percent' => $self->percent, 'months' => $self->months, - 'setup' => $self->setup, + 'setup' => $self->setup, + #'linked' => $self->linked, 'disabled' => 'Y', }; my $error = $discount->insert; diff --git a/FS/FS/discount.pm b/FS/FS/discount.pm index 88cbdd41c..f6f994599 100644 --- a/FS/FS/discount.pm +++ b/FS/FS/discount.pm @@ -136,6 +136,7 @@ sub check { || $self->ut_floatn('months') #actually decimal, but this will do || $self->ut_enum('disabled', [ '', 'Y' ]) || $self->ut_enum('setup', [ '', 'Y' ]) + #|| $self->ut_enum('linked', [ '', 'Y' ]) ; return $error if $error; diff --git a/FS/FS/part_event/Action/pkg_agent_credit.pm b/FS/FS/part_event/Action/pkg_agent_credit.pm index 4bcee983b..e1c77be07 100644 --- a/FS/FS/part_event/Action/pkg_agent_credit.pm +++ b/FS/FS/part_event/Action/pkg_agent_credit.pm @@ -18,7 +18,7 @@ sub do_action { my $agent_cust_main = $agent->agent_cust_main; #? or return "No customer record for agent ". $agent->agent; - my $amount = $self->_calc_credit($cust_pkg); + my $amount = $self->_calc_credit($cust_pkg); return '' unless $amount > 0; my $reasonnum = $self->option('reasonnum'); @@ -29,6 +29,7 @@ sub do_action { 'eventnum' => $cust_event->eventnum, 'addlinfo' => 'for customer #'. $cust_main->display_custnum. ': '.$cust_main->name, + #'commission_agentnum' => $agent->agentnum, ); die "Error crediting customer ". $agent_cust_main->custnum. " for agent commission: $error" diff --git a/FS/FS/part_export/freeswitch.pm b/FS/FS/part_export/freeswitch.pm index 7447849c8..eb490fd85 100644 --- a/FS/FS/part_export/freeswitch.pm +++ b/FS/FS/part_export/freeswitch.pm @@ -5,7 +5,8 @@ use vars qw( %info ); # $DEBUG ); #use Data::Dumper; use Tie::IxHash; use Text::Template; -#use FS::Record qw( qsearch qsearchs ); +use FS::Record qw( qsearch ); #qsearchs ); +use FS::svc_phone; #use FS::Schema qw( dbdef ); #$DEBUG = 1; @@ -15,7 +16,7 @@ tie my %options, 'Tie::IxHash', 'directory' => { label => 'Directory to store FreeSWITCH account XML files', default => '/usr/local/freeswitch/conf/directory/', }, - 'domain' => { label => 'Optional fixed SIP domain to use, overrides svc_phone domain', }, + #'domain' => { label => 'Optional fixed SIP domain to use, overrides svc_phone domain', }, 'reload' => { label => 'Reload command', default => '/usr/local/freeswitch/bin/fs_cli -x reloadxml', }, @@ -38,9 +39,9 @@ END 'desc' => 'Provision phone services to FreeSWITCH XML configuration files', 'options' => \%options, 'notes' => <<'END', -Export XML account configuration files to FreeSWITCH, one per phone services. +Export XML account configuration files to FreeSWITCH, one per domain. <br><br> -You will need to +You will need to enable the svc_phone-domain configuration setting and <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.9:Documentation:Administration:SSH_Keys">setup SSH for unattended operation</a>. END ); @@ -50,6 +51,33 @@ sub rebless { shift; } sub _export_insert { my( $self, $svc_phone ) = ( shift, shift ); + $self->_export_rebuild_domain($svc_phone); + +} + +sub _export_replace { + my( $self, $new, $old ) = ( shift, shift, shift ); + + my $error = $self->_export_rebuild_domain($new); + return $error if $error; + + if ( $new->domsvc ne $old->domsvc && $old->domsvc ) { + $error = $self->_export_rebuild_domain($old); + return $error if $error; + } + + ''; +} + +sub _export_delete { + my( $self, $svc_phone ) = ( shift, shift ); + + $self->_export_rebuild_domain($svc_phone); +} + +sub _export_rebuild_domain { + my($self, $svc_phone) = ( shift, shift ); + eval "use Net::SCP;"; die $@ if $@; @@ -57,24 +85,34 @@ sub _export_insert { my $tempdir = '%%%FREESIDE_CONF%%%/cache.'. $FS::UID::datasrc; - my $svcnum = $svc_phone->svcnum; + my $domain = $svc_phone->domain or return "domain required"; my $fh = new File::Temp( - TEMPLATE => "$tempdir/freeswitch.$svcnum.XXXXXXXX", + TEMPLATE => "$tempdir/freeswitch.$domain.XXXXXXXX", DIR => $dir, #UNLINK => 0, ); - print $fh $self->freeswitch_template_fillin( $svc_phone, 'user' ) - or die "print to freeswitch template failed: $!"; - close $fh; + print $fh qq(<domain name="$domain">\n); + + my @dom_svc_phone = qsearch( 'svc_phone', { 'domsvc'=>$svc_phone->domsvc } ); + + foreach my $dom_svc_phone (@dom_svc_phone) { + + print $fh $self->freeswitch_template_fillin( $dom_svc_phone, 'user' ) + or die "print to freeswitch template failed: $!"; + + } + + print $fh qq(</domain>\n); + $fh->flush; my $scp = new Net::SCP; my $user = $self->option('user')||'root'; my $host = $self->machine; my $dir = $self->option('directory'); - $scp->scp( $fh->filename, "$user\@$host:$dir/$svcnum.xml" ) + $scp->scp( $fh->filename, "$user\@$host:$dir/$domain.xml" ) or return $scp->{errstr}; #signal freeswitch to reload config @@ -84,27 +122,6 @@ sub _export_insert { } -sub _export_replace { - my( $self, $new, $old ) = ( shift, shift, shift ); - - $self->_export_insert($new, @_); -} - -sub _export_delete { - my( $self, $svc_phone ) = ( shift, shift ); - - my $dir = $self->option('directory'); - my $svcnum = $svc_phone->svcnum; - - #delete file - $self->freeswitch_ssh( command => "rm $dir/$svcnum.xml" ); - - #signal freeswitch to reload config - $self->freeswitch_ssh( command => $self->option('reload') ); - - ''; -} - sub freeswitch_template_fillin { my( $self, $svc_phone, $template ) = (shift, shift, shift); @@ -117,13 +134,8 @@ sub freeswitch_template_fillin { DELIMITERS => [ '<%', '%>' ], ); - my $domain = $self->option('domain') - || $svc_phone->domain - || '$${sip_profile}'; - #false lazinessish w/phone_shellcommands::_export_command my %hash = ( - 'domain' => $domain, map { $_ => $svc_phone->getfield($_) } $svc_phone->fields ); diff --git a/FS/FS/part_export/shellcommands.pm b/FS/FS/part_export/shellcommands.pm index ca4e52420..f964af31c 100644 --- a/FS/FS/part_export/shellcommands.pm +++ b/FS/FS/part_export/shellcommands.pm @@ -490,7 +490,7 @@ sub ssh_cmd { #subroutine, not method my ($output, $errput) = $ssh->capture2($ssh_opt, $opt->{'command'}); return if $opt->{'ignore_all_errors'}; - die "Error running SSH command: ". $ssh->error if $ssh->error; + #die "Error running SSH command: ". $ssh->error if $ssh->error; if ( ($output || $errput) && $opt->{'ignored_errors'} && length($opt->{'ignored_errors'}) @@ -504,7 +504,9 @@ sub ssh_cmd { #subroutine, not method $errput =~ s/[\s\n]//g; } - die "$errput\n" if $errput; + die (($errput || $ssh->error). "\n") if $errput || $ssh->error; + #die "$errput\n" if $errput; + die "$output\n" if $output and $opt->{'fail_on_output'}; ''; } diff --git a/FS/FS/rate.pm b/FS/FS/rate.pm index 02d8250eb..a2511cf99 100644 --- a/FS/FS/rate.pm +++ b/FS/FS/rate.pm @@ -387,7 +387,7 @@ sub rate_detail { =item process -Experimental job-queue processor for web interface adds/edits +Job-queue processor for web interface adds/edits =cut diff --git a/FS/FS/svc_Tower_Mixin.pm b/FS/FS/svc_Tower_Mixin.pm index 0b5588466..6adbc6f5e 100644 --- a/FS/FS/svc_Tower_Mixin.pm +++ b/FS/FS/svc_Tower_Mixin.pm @@ -52,5 +52,4 @@ sub tower_sector_sql { @where; } - 1; diff --git a/bin/231commit b/bin/231commit index ca28ede1e..6d09863ca 100755 --- a/bin/231commit +++ b/bin/231commit @@ -20,8 +20,8 @@ die "no files!" unless @ARGV; system join('', "( cd /home/$USER/freeside2.3/$prefix; git pull ) && ", "( cd /home/$USER/freeside2.1/$prefix; git pull ) && ", - "git diff -u @ARGV | ( cd /home/$USER/freeside2.3/$prefix; patch ) ", - " && git diff -u @ARGV | ( cd /home/$USER/freeside2.1/$prefix; patch ) ", + "git diff -u @ARGV | ( cd /home/$USER/freeside2.3/$prefix; patch -p1 ) ", + " && git diff -u @ARGV | ( cd /home/$USER/freeside2.1/$prefix; patch -p1 ) ", " && ( ( git commit -m $desc @ARGV && git push); ", "( cd /home/$USER/freeside2.3/$prefix; git commit -m $desc @ARGV && git push); ", "( cd /home/$USER/freeside2.1/$prefix; git commit -m $desc @ARGV && git push) )" diff --git a/bin/23diff b/bin/23diff index 0c0575aa6..d38c84834 100755 --- a/bin/23diff +++ b/bin/23diff @@ -3,7 +3,8 @@ my $file = shift; chomp(my $dir = `pwd`); -$dir =~ s/freeside\//freeside2.3\//; +$dir =~ s/freeside(\/?)/freeside2.3$1/; +warn $dir; #$cmd = "diff -u $file $dir/$file"; $cmd = "diff -u $dir/$file $file"; diff --git a/bin/cdr.import b/bin/cdr.import index 36266efbf..36266efbf 100644..100755 --- a/bin/cdr.import +++ b/bin/cdr.import diff --git a/bin/cust_main-bill_now b/bin/cust_main-bill_now index 17e48fbcf..f8a15803b 100644..100755 --- a/bin/cust_main-bill_now +++ b/bin/cust_main-bill_now @@ -13,7 +13,9 @@ my $custnum = shift or die &usage; my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) or die "unknown custnum $custnum\n"; -$cust_main->bill_and_collect( debug=>2, check_freq=>'1d' ); +$FS::cust_main::DEBUG = 3; + +$cust_main->bill_and_collect( debug=>3, check_freq=>'1d' ); sub usage { die "Usage:\n cust_main-bill_now user custnum\n"; @@ -7,12 +7,15 @@ chomp( my $mw_password = `cat .mw-password` ); my $site_perl = "./FS"; #my $html = "Freeside:1.7:Documentation:Developer"; -my $html = "Freeside:1.9:Documentation:Developer"; +#my $html = "Freeside:1.9:Documentation:Developer"; +my $html = "Freeside:3:Documentation:Developer"; foreach my $dir ( $html, - map "$html/$_", qw( bin FS FS/UI FS/part_export FS/part_pkg + map "$html/$_", qw( bin FS + FS/cdr FS/cust_main FS/cust_pkg FS/detail_format FS/part_event FS/part_event/Condition FS/part_event/Action + FS/part_export FS/part_pkg FS/pay_batch FS/ClientAPI FS/Cron FS/Misc FS/Report FS/Report/Table FS/TicketSystem FS/UI FS/SelfService @@ -43,6 +46,7 @@ foreach my $file ( use WWW::Mediawiki::Client; my $mvs = WWW::Mediawiki::Client->new( 'host' => 'www.freeside.biz', + 'protocol' => 'https', 'wiki_path' => 'mediawiki/index.php', 'username' => $mw_username, 'password' => $mw_password, diff --git a/fs_selfservice/DEPLOY b/fs_selfservice/DEPLOY index e73012f4b..bedb5eca9 100755 --- a/fs_selfservice/DEPLOY +++ b/fs_selfservice/DEPLOY @@ -11,7 +11,7 @@ perl Makefile.PL && make && make install cd .. #( cd ..; make deploy; cd fs_selfservice ) -( cd ..; make clean; make install-perl-modules; /etc/init.d/freeside restart; cd fs_selfservice ) +( cd ..; make clean; make configure-rt; make install-perl-modules; /etc/init.d/freeside restart; cd fs_selfservice ) #cp /home/ivan/freeside/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount #chown freeside /var/www/MyAccount/*.cgi diff --git a/fs_selfservice/FS-SelfService/cgi/agent.cgi b/fs_selfservice/FS-SelfService/cgi/agent.cgi index 0af94cd9e..0af94cd9e 100644..100755 --- a/fs_selfservice/FS-SelfService/cgi/agent.cgi +++ b/fs_selfservice/FS-SelfService/cgi/agent.cgi diff --git a/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi b/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi index 253f853f8..253f853f8 100644..100755 --- a/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi +++ b/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi diff --git a/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi b/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi index d5a8e2063..d5a8e2063 100644..100755 --- a/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi +++ b/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi diff --git a/httemplate/browse/cust_note_class.html b/httemplate/browse/cust_note_class.html index f5d450b9f..7928199b3 100644 --- a/httemplate/browse/cust_note_class.html +++ b/httemplate/browse/cust_note_class.html @@ -3,7 +3,7 @@ 'html_init' => $html_init, 'name' => 'customer note classes', 'disableable' => 1, - 'disabled_statuspos' => 2, + 'disabled_statuspos' => 1, 'query' => { 'table' => 'cust_note_class', 'hashref' => {}, 'order_by' => 'ORDER BY classnum', diff --git a/httemplate/docs/license.html b/httemplate/docs/license.html index fab8cd09f..e40b2436b 100644 --- a/httemplate/docs/license.html +++ b/httemplate/docs/license.html @@ -6,7 +6,7 @@ <P> -Copyright © 2005-2009 Freeside Internet Services, Inc.<BR> +Copyright © 2005-2012 Freeside Internet Services, Inc.<BR> Copyright © 2000-2005 Ivan Kohler<BR> Copyright © 1999 Silicon Interactive Software Design<BR> All rights reserved<BR> diff --git a/httemplate/edit/discount.html b/httemplate/edit/discount.html index b195eb37b..9bcd1e724 100644 --- a/httemplate/edit/discount.html +++ b/httemplate/edit/discount.html @@ -22,6 +22,7 @@ postfix => '<BR><FONT SIZE="-1"><I>(blank for non-expiring discount)</I></FONT>', }, { field => 'setup', type => 'checkbox', value=>'Y', }, + #{ field => 'linked', type => 'checkbox', value=>'Y', }, ], 'labels' => { 'discountnum' => 'Discount #', @@ -32,6 +33,7 @@ 'percent' => 'Percentage ', 'months' => 'Duration (months)', 'setup' => 'Apply to setup fees', + #'linked' => 'Apply to add-on packages', }, 'viewall_dir' => 'browse', 'new_callback' => $new_callback, @@ -114,6 +116,10 @@ my $javascript = <<END; document.getElementById('percent_label').style.visibility = 'hidden'; document.getElementById('percent_input0').style.display = 'none'; document.getElementById('percent_input0').style.visibility = 'hidden'; +// document.getElementById('linked_label').style.display = 'none'; +// document.getElementById('linked_label').style.visibility = 'hidden'; +// document.getElementById('linked').style.display = 'none'; +// document.getElementById('linked').style.visibility = 'hidden'; } else if ( _type == 'Amount' ) { document.getElementById('amount_label').style.display = ''; document.getElementById('amount_label').style.visibility = ''; @@ -123,6 +129,10 @@ my $javascript = <<END; document.getElementById('percent_label').style.visibility = 'hidden'; document.getElementById('percent_input0').style.display = 'none'; document.getElementById('percent_input0').style.visibility = 'hidden'; +// document.getElementById('linked_label').style.display = 'none'; +// document.getElementById('linked_label').style.visibility = 'hidden'; +// document.getElementById('linked').style.display = 'none'; +// document.getElementById('linked').style.visibility = 'hidden'; } else if ( _type == 'Percentage' ) { document.getElementById('amount_label').style.display = 'none'; document.getElementById('amount_label').style.visibility = 'hidden'; @@ -132,6 +142,10 @@ my $javascript = <<END; document.getElementById('percent_label').style.visibility = ''; document.getElementById('percent_input0').style.display = ''; document.getElementById('percent_input0').style.visibility = ''; +// document.getElementById('linked_label').style.display = ''; +// document.getElementById('linked_label').style.visibility = ''; +// document.getElementById('linked').style.display = ''; +// document.getElementById('linked').style.visibility = ''; } } diff --git a/httemplate/edit/process/cust_pkg_discount.html b/httemplate/edit/process/cust_pkg_discount.html index 6f97a791e..4a71f6975 100644 --- a/httemplate/edit/process/cust_pkg_discount.html +++ b/httemplate/edit/process/cust_pkg_discount.html @@ -39,7 +39,8 @@ my $cust_pkg_discount = new FS::cust_pkg_discount { 'amount' => scalar($cgi->param('discountnum_amount')), 'percent' => scalar($cgi->param('discountnum_percent')), 'months' => scalar($cgi->param('discountnum_months')), - 'setup' => scalar($cgi->param('discountnum_setup')), + 'setup' => scalar($cgi->param('discountnum_setup')), + #'linked' => scalar($cgi->param('discountnum_linked')), #'disabled' => $self->discountnum_disabled, }; my $error = $cust_pkg_discount->insert; diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi index ba4c5b1b6..c5eee0cb8 100644 --- a/httemplate/edit/process/quick-cust_pkg.cgi +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -2,19 +2,24 @@ % $cgi->param('error', $error); <% $cgi->redirect(popurl(3). 'misc/order_pkg.html?'. $cgi->query_string ) %> %} else { -% my $frag = "cust_pkg". $cust_pkg->pkgnum; % my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/ % ? '' % : ';show=packages'; -% my $redir_url = popurl(3) -% ."view/cust_main.cgi?custnum=$custnum$show;fragment=$frag#$frag"; +% +% my $redir_url = popurl(3); +% if ( $svcpart ) { # for going straight to service provisining after ordering +% $redir_url .= 'edit/'.$part_svc->svcdb.'.cgi?'. +% 'pkgnum='.$cust_pkg->pkgnum. ";svcpart=$svcpart"; +% $redir_url .= ";qualnum=$qualnum" if $qualnum; +% } elsif ( $quotationnum ) { +% $redir_url .= "view/quotation.html?quotationnum=$quotationnum"; +% } else { +% my $custnum = $cust_main->custnum; +% my $frag = "cust_pkg". $cust_pkg->pkgnum; +% $redir_url .= +% "view/cust_main.cgi?custnum=$custnum$show;fragment=$frag#$frag"; +% } % -% # for going right to a provision service after ordering a package -% if ( $svcpart ) { -% $redir_url = popurl(3)."edit/".$part_svc->svcdb.".cgi?". -% "pkgnum=".$cust_pkg->pkgnum. ";svcpart=$svcpart"; -% $redir_url .= ";qualnum=$qualnum" if $qualnum; -% } <% header('Package ordered') %> <SCRIPT TYPE="text/javascript"> // XXX fancy ajax rebuild table at some point, but a page reload will do for now @@ -33,16 +38,27 @@ my $curuser = $FS::CurrentUser::CurrentUser; die "access denied" unless $curuser->access_right('Order customer package'); -#untaint custnum (probably not necessary, searching for it is escape enough) -$cgi->param('custnum') =~ /^(\d+)$/ - or die 'illegal custnum '. $cgi->param('custnum'); -my $custnum = $1; -my $cust_main = qsearchs({ - 'table' => 'cust_main', - 'hashref' => { 'custnum' => $custnum }, - 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, -}); -die 'unknown custnum' unless $cust_main; +my $cust_main; +if ( $cgi->param('custnum') =~ /^(\d+)$/ ) { + my $custnum = $1; + $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $custnum }, + 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, + }); +} + +my $prospect_main; +if ( $cgi->param('prospectnum') =~ /^(\d+)$/ ) { + my $prospectnum = $1; + $prospect_main = qsearchs({ + 'table' => 'prospect_main', + 'hashref' => { 'prospectnum' => $prospectnum }, + 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, + }); +} + +die 'no custnum or prospectnum' unless $cust_main || $prospect_main; #probably not necessary, taken care of by cust_pkg::check $cgi->param('pkgpart') =~ /^(\d+)$/ @@ -72,47 +88,70 @@ if ( $cgi->param('svcpart') ) { } my $qualnum = ''; -if ( $cgi->param('qualnum') ) { - $cgi->param('qualnum') =~ /^(\d+)$/ or die 'illegal qualnum'; +if ( $cgi->param('qualnum') =~ /^(\d+)$/ ) { $qualnum = $1; } +my $quotationnum = ''; +if ( $cgi->param('quotationnum') =~ /^(\d+)$/ ) { + $quotationnum = $1; +} +# verify this quotation is visible to this user +my $cust_pkg = ''; +my $quotation_pkg = ''; +my $error = ''; -my $cust_pkg = new FS::cust_pkg { - 'custnum' => $custnum, - 'pkgpart' => $pkgpart, - 'quantity' => $quantity, - 'start_date' => ( scalar($cgi->param('start_date')) - ? parse_datetime($cgi->param('start_date')) - : '' - ), - 'no_auto' => scalar($cgi->param('no_auto')), - 'refnum' => $refnum, - 'locationnum' => $locationnum, - 'discountnum' => $discountnum, - #for the create a new discount case - 'discountnum__type' => scalar($cgi->param('discountnum__type')), - 'discountnum_amount' => scalar($cgi->param('discountnum_amount')), - 'discountnum_percent' => scalar($cgi->param('discountnum_percent')), - 'discountnum_months' => scalar($cgi->param('discountnum_months')), - 'discountnum_setup' => scalar($cgi->param('discountnum_setup')), - 'contract_end' => ( scalar($cgi->param('contract_end')) - ? parse_datetime($cgi->param('contract_end')) - : '' - ), - 'waive_setup' => ( $cgi->param('waive_setup') eq 'Y' ? 'Y' : '' ), -}; - -my %opt = ( 'cust_pkg' => $cust_pkg ); - -if ( $locationnum == -1 ) { - my $cust_location = new FS::cust_location { - map { $_ => scalar($cgi->param($_)) } - qw( custnum address1 address2 city county state zip country geocode ) - }; - $opt{'cust_location'} = $cust_location; -} +my %hash = ( + 'pkgpart' => $pkgpart, + 'quantity' => $quantity, + 'start_date' => ( scalar($cgi->param('start_date')) + ? parse_datetime($cgi->param('start_date')) + : '' + ), + 'refnum' => $refnum, + 'locationnum' => $locationnum, + 'discountnum' => $discountnum, + #for the create a new discount case + 'discountnum__type' => scalar($cgi->param('discountnum__type')), + 'discountnum_amount' => scalar($cgi->param('discountnum_amount')), + 'discountnum_percent' => scalar($cgi->param('discountnum_percent')), + 'discountnum_months' => scalar($cgi->param('discountnum_months')), + 'discountnum_setup' => scalar($cgi->param('discountnum_setup')), + 'contract_end' => ( scalar($cgi->param('contract_end')) + ? parse_datetime($cgi->param('contract_end')) + : '' + ), + 'waive_setup' => ( $cgi->param('waive_setup') eq 'Y' ? 'Y' : '' ), +); +$hash{'custnum'} = $cust_main->custnum if $cust_main; + +if ( $quotationnum ) { + + $quotation_pkg = new FS::quotation_pkg \%hash; + $quotation_pkg->quotationnum($quotationnum); + $quotation_pkg->prospectnum($prospect_main->prospectnum) if $prospect_main; -my $error = $cust_main->order_pkg( \%opt ); + #XXX handle new location + $error = $quotation_pkg->insert; + +} else { + + $cust_pkg = new FS::cust_pkg \%hash; + + $cust_pkg->no_auto( scalar($cgi->param('no_auto')) ); + + my %opt = ( 'cust_pkg' => $cust_pkg ); + + if ( $locationnum == -1 ) { + my $cust_location = new FS::cust_location { + map { $_ => scalar($cgi->param($_)) } + qw( custnum address1 address2 city county state zip country geocode ) + }; + $opt{'cust_location'} = $cust_location; + } + + $error = $cust_main->order_pkg( \%opt ); + +} </%init> diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi index 90eab4aad..25644e547 100644 --- a/httemplate/edit/process/svc_broadband.cgi +++ b/httemplate/edit/process/svc_broadband.cgi @@ -1,11 +1,10 @@ <& elements/svc_Common.html, - table => 'svc_broadband', - fields => [ fields('svc_broadband'), fields('nas'), 'usergroup' ], + table => 'svc_broadband', + fields => [ fields('svc_broadband'), fields('nas'), 'usergroup' ], precheck_callback => \&precheck, &> <%init> -# for historical reasons, process_m2m for usergroup tables is done -# in the svc_x::insert/replace/delete methods, not here + my $curuser = $FS::CurrentUser::CurrentUser; die "access denied" diff --git a/httemplate/elements/tr-select-discount.html b/httemplate/elements/tr-select-discount.html index 30a60ec85..ee862519f 100644 --- a/httemplate/elements/tr-select-discount.html +++ b/httemplate/elements/tr-select-discount.html @@ -6,7 +6,7 @@ % } else { <TR> - <TD ALIGN="right" WIDTH="176"><% $opt{'label'} || '<B>'.emt('Discount').'</B>' %></TD> + <TD ALIGN="right" WIDTH="275"><% $opt{'label'} || '<B>'.emt('Discount').'</B>' %></TD> <TD <% $colspan %>> <% include( '/elements/select-discount.html', 'curr_value' => $discountnum, @@ -74,6 +74,16 @@ ) %> +%# <% include( '/elements/tr-checkbox.html', +%# 'label' => '<B>Apply discount to add-on packages</B>', +%# 'field' => $name.'_linked', +%# 'id' => $name.'_linked', +%# 'curr_value' => scalar($cgi->param($name.'_linked')), +%# 'value' => 'Y', +%# 'colspan' => $opt{'colspan'}, +%# ) +%# %> + <SCRIPT TYPE="text/javascript"> % my $ge = 'document.getElementById'; @@ -136,6 +146,10 @@ <% $ge %>('<% $name %>_percent_label0').style.visibility = 'hidden'; <% $ge %>('<% $name %>_percent_input0').style.display = 'none'; <% $ge %>('<% $name %>_percent_input0').style.visibility = 'hidden'; +// <% $ge %>('<% $name %>_linked_label0').style.display = 'none'; +// <% $ge %>('<% $name %>_linked_label0').style.visibility = 'hidden'; +// <% $ge %>('<% $name %>_linked').style.display = 'none'; +// <% $ge %>('<% $name %>_linked').style.visibility = 'hidden'; } else if ( <% $name %>__type == 'Amount' ) { <% $ge %>('<% $name %>_amount_label0').style.display = ''; <% $ge %>('<% $name %>_amount_label0').style.visibility = ''; @@ -145,6 +159,11 @@ <% $ge %>('<% $name %>_percent_label0').style.visibility = 'hidden'; <% $ge %>('<% $name %>_percent_input0').style.display = 'none'; <% $ge %>('<% $name %>_percent_input0').style.visibility = 'hidden'; + <% $ge %>('<% $name %>_percent_input0').style.visibility = 'hidden'; +// <% $ge %>('<% $name %>_linked_label0').style.display = 'none'; +// <% $ge %>('<% $name %>_linked_label0').style.visibility = 'hidden'; +// <% $ge %>('<% $name %>_linked').style.display = 'none'; +// <% $ge %>('<% $name %>_linked').style.visibility = 'hidden'; } else if ( <% $name %>__type == 'Percentage' ) { <% $ge %>('<% $name %>_amount_label0').style.display = 'none'; <% $ge %>('<% $name %>_amount_label0').style.visibility = 'hidden'; @@ -154,6 +173,11 @@ <% $ge %>('<% $name %>_percent_label0').style.visibility = ''; <% $ge %>('<% $name %>_percent_input0').style.display = ''; <% $ge %>('<% $name %>_percent_input0').style.visibility = ''; + <% $ge %>('<% $name %>_percent_input0').style.visibility = ''; +// <% $ge %>('<% $name %>_linked_label0').style.display = ''; +// <% $ge %>('<% $name %>_linked_label0').style.visibility = ''; +// <% $ge %>('<% $name %>_linked').style.display = ''; +// <% $ge %>('<% $name %>_linked').style.visibility = ''; } } diff --git a/httemplate/view/cust_main/custom_content/.birthdate.html.swp b/httemplate/view/cust_main/custom_content/.birthdate.html.swp Binary files differdeleted file mode 100644 index 9571d22cf..000000000 --- a/httemplate/view/cust_main/custom_content/.birthdate.html.swp +++ /dev/null diff --git a/httemplate/view/cust_main/custom_content/.small_custview.html.swp b/httemplate/view/cust_main/custom_content/.small_custview.html.swp Binary files differdeleted file mode 100644 index a39f52dde..000000000 --- a/httemplate/view/cust_main/custom_content/.small_custview.html.swp +++ /dev/null diff --git a/httemplate/view/cust_main/custom_content/.spouse_birthdate.html.swp b/httemplate/view/cust_main/custom_content/.spouse_birthdate.html.swp Binary files differdeleted file mode 100644 index 0042012f7..000000000 --- a/httemplate/view/cust_main/custom_content/.spouse_birthdate.html.swp +++ /dev/null diff --git a/httemplate/view/cust_main/custom_content/.svc_Common.html.swp b/httemplate/view/cust_main/custom_content/.svc_Common.html.swp Binary files differdeleted file mode 100644 index 15591b96d..000000000 --- a/httemplate/view/cust_main/custom_content/.svc_Common.html.swp +++ /dev/null diff --git a/httemplate/view/cust_main/custom_content/.svc_acct.html.swp b/httemplate/view/cust_main/custom_content/.svc_acct.html.swp Binary files differdeleted file mode 100644 index e2db6d5d1..000000000 --- a/httemplate/view/cust_main/custom_content/.svc_acct.html.swp +++ /dev/null diff --git a/httemplate/view/cust_main/custom_content/.svc_hardware.html.swp b/httemplate/view/cust_main/custom_content/.svc_hardware.html.swp Binary files differdeleted file mode 100644 index 1106f9ed5..000000000 --- a/httemplate/view/cust_main/custom_content/.svc_hardware.html.swp +++ /dev/null diff --git a/httemplate/view/cust_main/custom_content/.svc_phone.html.swp b/httemplate/view/cust_main/custom_content/.svc_phone.html.swp Binary files differdeleted file mode 100644 index 79b8185e1..000000000 --- a/httemplate/view/cust_main/custom_content/.svc_phone.html.swp +++ /dev/null diff --git a/rt/sbin/rt-server.fcgi.in b/rt/sbin/rt-server.fcgi.in index 45c377088..f84f6c103 100644 --- a/rt/sbin/rt-server.fcgi.in +++ b/rt/sbin/rt-server.fcgi.in @@ -172,7 +172,7 @@ if (caller) { require Plack::Runner; my $is_fastcgi = $0 =~ m/fcgi$/; -my $r = Plack::Runner->new( $0 =~ 'standalone' ? ( server => 'Standalone' ) : +my $r = Plack::Runner->new( $0 =~ /standalone/ ? ( server => 'Standalone' ) : $is_fastcgi ? ( server => 'FCGI' ) : (), env => 'deployment' ); diff --git a/rt/sbin/rt-server.in b/rt/sbin/rt-server.in index 45c377088..f84f6c103 100644 --- a/rt/sbin/rt-server.in +++ b/rt/sbin/rt-server.in @@ -172,7 +172,7 @@ if (caller) { require Plack::Runner; my $is_fastcgi = $0 =~ m/fcgi$/; -my $r = Plack::Runner->new( $0 =~ 'standalone' ? ( server => 'Standalone' ) : +my $r = Plack::Runner->new( $0 =~ /standalone/ ? ( server => 'Standalone' ) : $is_fastcgi ? ( server => 'FCGI' ) : (), env => 'deployment' ); diff --git a/rt/sbin/rt-test-dependencies.in b/rt/sbin/rt-test-dependencies.in index 37ef32f64..960d640c3 100644 --- a/rt/sbin/rt-test-dependencies.in +++ b/rt/sbin/rt-test-dependencies.in @@ -56,9 +56,10 @@ no warnings qw(numeric redefine); use Getopt::Long; my %args; my %deps; +my @orig_argv = @ARGV; GetOptions( \%args, 'v|verbose', - 'install', 'with-MYSQL', + 'install!', 'with-MYSQL', 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', 'with-ORACLE', 'with-FASTCGI', 'with-MODPERL1', 'with-MODPERL2', @@ -293,7 +294,7 @@ Test::LongString . $deps{'FASTCGI'} = [ text_to_hash( << '.') ]; -FCGI +FCGI 0.74 FCGI::ProcManager . @@ -344,7 +345,7 @@ URI 1.59 $deps{'GRAPHVIZ'} = [ text_to_hash( << '.') ]; GraphViz -IPC::Run +IPC::Run 0.90 . $deps{'GD'} = [ text_to_hash( << '.') ]; @@ -359,6 +360,7 @@ Convert::Color my %AVOID = ( 'DBD::Oracle' => [qw(1.23)], + 'Email::Address' => [qw(1.893 1.894)], ); if ($args{'download'}) { @@ -403,7 +405,12 @@ foreach my $type (sort grep $args{$_}, keys %args) { $Missing_By_Type{$type} = \%missing if keys %missing; } -conclude(%Missing_By_Type); +if ( $args{'install'} && keys %Missing_By_Type ) { + exec($0, @orig_argv, '--no-install'); +} +else { + conclude(%Missing_By_Type); +} sub test_deps { my @deps = @_; diff --git a/rt/share/html/Search/Results.xls b/rt/share/html/Search/Results.xls index 52a05daed..8b94e22ba 100644 --- a/rt/share/html/Search/Results.xls +++ b/rt/share/html/Search/Results.xls @@ -54,6 +54,7 @@ $Format => undef <%INIT> use Spreadsheet::WriteExcel; +use OLE::Storage_Lite; use List::Util qw( max ); use Date::Format qw( time2str ); diff --git a/rt/t/api/config.t b/rt/t/api/config.t index a986c3c4f..62b77dffa 100644 --- a/rt/t/api/config.t +++ b/rt/t/api/config.t @@ -1,7 +1,8 @@ use strict; use warnings; use RT; -use RT::Test nodb => 1, tests => 9; +use RT::Test nodb => 1, tests => 11; +use Test::Warn; ok( RT::Config->AddOption( @@ -31,3 +32,12 @@ is( $meta->{Widget}, '/Widgets/Form/Boolean', 'widget is updated to boolean' ); ok( RT::Config->DeleteOption( Name => 'foo' ), 'removed option foo' ); is( RT::Config->Meta('foo'), undef, 'foo is indeed deleted' ); +# Test EmailInputEncodings PostLoadCheck code +RT::Config->Set('EmailInputEncodings', qw(utf-8 iso-8859-1 us-ascii foo)); +my @encodings = qw(utf-8-strict iso-8859-1 ascii); + +warning_is {RT::Config->PostLoadCheck} "Unknown encoding 'foo' in \@EmailInputEncodings option", + 'Correct warning for encoding foo'; + +my @canonical_encodings = RT::Config->Get('EmailInputEncodings'); +is_deeply(\@encodings, \@canonical_encodings, 'Got correct encoding list'); diff --git a/rt/t/api/template-insert.t b/rt/t/api/template-insert.t deleted file mode 100644 index 1bf5fc390..000000000 --- a/rt/t/api/template-insert.t +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl - -use warnings; -use strict; - - -use RT; -use RT::Test tests => 7; - - - -# This tiny little test script triggers an interaction bug between DBD::Oracle 1.16, SB 1.15 and RT 3.4 - -use_ok('RT::Template'); -my $template = RT::Template->new(RT->SystemUser); - -isa_ok($template, 'RT::Template'); -my ($val,$msg) = $template->Create(Queue => 1, - Name => 'InsertTest', - Content => 'This is template content'); -ok($val,$msg); -is($template->Name, 'InsertTest'); -is($template->Content, 'This is template content', "We created the object right"); -($val, $msg) = $template->SetContent( 'This is new template content'); -ok($val,$msg); -is($template->Content, 'This is new template content', "We managed to _Set_ the content"); diff --git a/rt/t/api/template-simple.t b/rt/t/api/template-simple.t deleted file mode 100644 index bbdebb31f..000000000 --- a/rt/t/api/template-simple.t +++ /dev/null @@ -1,275 +0,0 @@ -use strict; -use warnings; -use RT; -use RT::Test tests => 231; -use Test::Warn; - -my $queue = RT::Queue->new(RT->SystemUser); -$queue->Load("General"); - -my $ticket_cf = RT::CustomField->new(RT->SystemUser); -$ticket_cf->Create( - Name => 'Department', - Queue => '0', - Type => 'FreeformSingle', -); - -my $txn_cf = RT::CustomField->new(RT->SystemUser); -$txn_cf->Create( - Name => 'Category', - LookupType => RT::Transaction->CustomFieldLookupType, - Type => 'FreeformSingle', -); -$txn_cf->AddToObject($queue); - -my $ticket = RT::Ticket->new(RT->SystemUser); -my ($id, $msg) = $ticket->Create( - Subject => "template testing", - Queue => "General", - Owner => 'root@localhost', - Requestor => ["dom\@example.com"], - "CustomField-" . $txn_cf->id => "Special", -); -ok($id, "Created ticket: $msg"); -my $txn = $ticket->Transactions->First; - -$ticket->AddCustomFieldValue( - Field => 'Department', - Value => 'Coolio', -); - -TemplateTest( - Content => "\ntest", - PerlOutput => "test", - SimpleOutput => "test", -); - -TemplateTest( - Content => "\ntest { 5 * 5 }", - PerlOutput => "test 25", - SimpleOutput => "test { 5 * 5 }", -); - -TemplateTest( - Content => "\ntest { \$Requestor }", - PerlOutput => "test dom\@example.com", - SimpleOutput => "test dom\@example.com", -); - -TemplateTest( - Content => "\ntest { \$TicketSubject }", - PerlOutput => "test ", - SimpleOutput => "test template testing", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketQueueId }", - Output => "test 1", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketQueueName }", - Output => "test General", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketOwnerId }", - Output => "test 12", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketOwnerName }", - Output => "test root", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketOwnerEmailAddress }", - Output => "test root\@localhost", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketStatus }", - Output => "test new", -); - -SimpleTemplateTest( - Content => "\ntest #{ \$TicketId }", - Output => "test #" . $ticket->id, -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketCFDepartment }", - Output => "test Coolio", -); - -SimpleTemplateTest( - Content => "\ntest #{ \$TransactionId }", - Output => "test #" . $txn->id, -); - -SimpleTemplateTest( - Content => "\ntest { \$TransactionType }", - Output => "test Create", -); - -SimpleTemplateTest( - Content => "\ntest { \$TransactionCFCategory }", - Output => "test Special", -); - -SimpleTemplateTest( - Content => "\ntest { \$TicketDelete }", - Output => "test { \$TicketDelete }", -); - -SimpleTemplateTest( - Content => "\ntest { \$Nonexistent }", - Output => "test { \$Nonexistent }", -); - -warning_like { - TemplateTest( - Content => "\ntest { \$Ticket->Nonexistent }", - PerlOutput => undef, - SimpleOutput => "test { \$Ticket->Nonexistent }", - ); -} qr/RT::Ticket::Nonexistent Unimplemented/; - -warning_like { - TemplateTest( - Content => "\ntest { \$Nonexistent->Nonexistent }", - PerlOutput => undef, - SimpleOutput => "test { \$Nonexistent->Nonexistent }", - ); -} qr/Can't call method "Nonexistent" on an undefined value/; - -TemplateTest( - Content => "\ntest { \$Ticket->OwnerObj->Name }", - PerlOutput => "test root", - SimpleOutput => "test { \$Ticket->OwnerObj->Name }", -); - -warning_like { - TemplateTest( - Content => "\ntest { *!( }", - SyntaxError => 1, - PerlOutput => undef, - SimpleOutput => "test { *!( }", - ); -} qr/Template parsing error: syntax error/; - -TemplateTest( - Content => "\ntest { \$rtname ", - SyntaxError => 1, - PerlOutput => undef, - SimpleOutput => undef, -); - -is($ticket->Status, 'new', "test setup"); -SimpleTemplateTest( - Content => "\ntest { \$Ticket->SetStatus('resolved') }", - Output => "test { \$Ticket->SetStatus('resolved') }", -); -is($ticket->Status, 'new', "simple templates can't call ->SetStatus"); - -# Make sure changing the template's type works -my $template = RT::Template->new(RT->SystemUser); -$template->Create( - Name => "type chameleon", - Type => "Perl", - Content => "\ntest { 10 * 7 }", -); -ok($id = $template->id, "Created template"); -$template->Parse; -is($template->MIMEObj->stringify_body, "test 70", "Perl output"); - -$template = RT::Template->new(RT->SystemUser); -$template->Load($id); -is($template->Name, "type chameleon"); - -$template->SetType('Simple'); -$template->Parse; -is($template->MIMEObj->stringify_body, "test { 10 * 7 }", "Simple output"); - -$template = RT::Template->new(RT->SystemUser); -$template->Load($id); -is($template->Name, "type chameleon"); - -$template->SetType('Perl'); -$template->Parse; -is($template->MIMEObj->stringify_body, "test 70", "Perl output"); - -undef $ticket; - -my $counter = 0; -sub IndividualTemplateTest { - local $Test::Builder::Level = $Test::Builder::Level + 1; - - my %args = ( - Name => "Test-" . ++$counter, - Type => "Perl", - @_, - ); - - my $t = RT::Template->new(RT->SystemUser); - $t->Create( - Name => $args{Name}, - Type => $args{Type}, - Content => $args{Content}, - ); - - ok($t->id, "Created $args{Type} template"); - is($t->Name, $args{Name}, "$args{Type} template name"); - is($t->Content, $args{Content}, "$args{Type} content"); - is($t->Type, $args{Type}, "template type"); - - # this should never blow up! - my ($ok, $msg) = $t->CompileCheck; - - # we don't need to syntax check simple templates since if you mess them up - # it's safe to just use the input directly as the template's output - if ($args{SyntaxError} && $args{Type} eq 'Perl') { - ok(!$ok, "got a syntax error"); - } - else { - ok($ok, $msg); - } - - ($ok, $msg) = $t->Parse( - TicketObj => $ticket, - TransactionObj => $txn, - ); - if (defined $args{Output}) { - ok($ok, $msg); - is($t->MIMEObj->stringify_body, $args{Output}, "$args{Type} template's output"); - } - else { - ok(!$ok, "expected a failure"); - } -} - -sub TemplateTest { - local $Test::Builder::Level = $Test::Builder::Level + 1; - my %args = @_; - - for my $type ('Perl', 'Simple') { - next if $args{"Skip$type"}; - - IndividualTemplateTest( - %args, - Type => $type, - Output => $args{$type . 'Output'}, - ); - } -} - -sub SimpleTemplateTest { - local $Test::Builder::Level = $Test::Builder::Level + 1; - my %args = @_; - - IndividualTemplateTest( - %args, - Type => 'Simple', - ); -} - diff --git a/rt/t/api/template.t b/rt/t/api/template.t index 2fadede38..331d9f996 100644 --- a/rt/t/api/template.t +++ b/rt/t/api/template.t @@ -1,25 +1,34 @@ -use strict; use warnings; -use RT; -use RT::Test tests => 2; - - -{ - -ok(require RT::Template); +use strict; +use RT; +use RT::Test tests => 10; -} +my $queue = RT::Test->load_or_create_queue( Name => 'Templates' ); +ok $queue && $queue->id, "loaded or created a queue"; { - -my $t = RT::Template->new(RT->SystemUser); -$t->Create(Name => "Foo", Queue => 1); -my $t2 = RT::Template->new(RT->Nobody); -$t2->Load($t->Id); -ok($t2->QueueObj->id, "Got the template's queue objet"); - - + my $template = RT::Template->new( RT->SystemUser ); + isa_ok($template, 'RT::Template'); + my ($val,$msg) = $template->Create( + Queue => $queue->id, + Name => 'InsertTest', + Content => 'This is template content' + ); + ok $val, "created a template" or diag "error: $msg"; + ok my $id = $template->id, "id is defined"; + is $template->Name, 'InsertTest'; + is $template->Content, 'This is template content', "We created the object right"; + + ($val, $msg) = $template->SetContent( 'This is new template content'); + ok $val, "changed content" or diag "error: $msg"; + + is $template->Content, 'This is new template content', "We managed to _Set_ the content"; + + ($val, $msg) = $template->Delete; + ok $val, "deleted template"; + + $template->Load($id); + ok !$template->id, "can not load template after deletion"; } - diff --git a/rt/t/articles/search-interface.t b/rt/t/articles/search-interface.t index eb3a4f763..bcba3116b 100644 --- a/rt/t/articles/search-interface.t +++ b/rt/t/articles/search-interface.t @@ -3,7 +3,7 @@ use strict; use warnings; -use RT::Test tests => 23; +use RT::Test tests => 44; use RT::CustomField; use RT::Queue; @@ -67,7 +67,12 @@ my %cvals = ('article1q' => 'Some question about swallows', 'article3q' => 'Why should I eat my supper?', 'article3a' => 'There are starving children in Africa', 'article4q' => 'What did Brian originally write?', - 'article4a' => 'Romanes eunt domus'); + 'article4a' => 'This is an answer that is longer than 255 ' + . 'characters so these tests will be sure to use the LargeContent ' + . 'SQL as well as the normal SQL that would be generated if this ' + . 'was an answer that was shorter than 255 characters. This second ' + . 'sentence has a few extra characters to get this string to go ' + . 'over the 255 character boundary. Lorem ipsum.'); # Create an article or two with our custom field values. @@ -108,6 +113,52 @@ isa_ok($m, 'Test::WWW::Mechanize'); ok($m->login, 'logged in'); $m->follow_link_ok( { text => 'Articles', url_regex => qr!^/Articles/! }, 'UI -> Articles' ); -$m->follow_link_ok( {text => 'Search'}, 'Articles -> Search'); -$m->follow_link_ok( {text => 'in class '.$class->Name}, 'Articles in class '.$class->Name); -$m->content_contains($article1->Name); + +# In all of the search results below, the results page should +# have the summary text of the article it occurs in. + +# Case sensitive search on small field. +DoArticleSearch($m, $class->Name, 'Africa'); +$m->text_contains('Search results'); # Did we do a search? +$m->text_contains('blah blah 1'); + +# Case insensitive search on small field. +DoArticleSearch($m, $class->Name, 'africa'); +$m->text_contains('Search results'); # Did we do a search? +$m->text_contains('blah blah 1'); + +# Case sensitive search on large field. +DoArticleSearch($m, $class->Name, 'ipsum'); +$m->text_contains('Search results'); # Did we do a search? +$m->text_contains('hoi polloi 4'); + +# Case insensitive search on large field. +DoArticleSearch($m, $class->Name, 'lorem'); +$m->text_contains('Search results'); # Did we do a search? +TODO:{ + local $TODO = 'Case insensitive search on LONGBLOB not available in MySQL' + if RT->Config->Get('DatabaseType') eq 'mysql'; + $m->text_contains('hoi polloi 4'); +} + +# When you send $m to this sub, it must be on a page with +# a Search link. +sub DoArticleSearch{ + my $m = shift; + my $class_name = shift; + my $search_text = shift; + + $m->follow_link_ok( {text => 'Search'}, 'Articles -> Search'); + $m->follow_link_ok( {text => 'in class '. $class_name}, 'Articles in class '. $class_name); + $m->text_contains('First article'); + + $m->submit_form_ok( { + form_number => 3, + fields => { + 'Article~' => $search_text + }, + }, "Search for $search_text" + ); + return; +} + diff --git a/rt/t/articles/uri-a.t b/rt/t/articles/uri-a.t index 82d0f1b01..5c1fdaf36 100644 --- a/rt/t/articles/uri-a.t +++ b/rt/t/articles/uri-a.t @@ -3,7 +3,7 @@ use strict; use warnings; -use RT::Test tests => 7; +use RT::Test tests => 15; use_ok("RT::URI::a"); my $uri = RT::URI::a->new($RT::SystemUser); @@ -26,3 +26,39 @@ is(ref($uri->Object), "RT::Article", "Object loaded is an article"); is($uri->Object->Id, $article->Id, "Object loaded has correct ID"); is($article->URI, 'fsck.com-article://example.com/article/'.$article->Id, "URI object has correct URI string"); + +{ + my $aid = $article->id; + my $ticket = RT::Ticket->new( RT->SystemUser ); + my ($id, $msg) = $ticket->Create( + Queue => 1, + Subject => 'test ticket', + ); + ok $id, "Created a test ticket"; + + # Try searching + my $tickets = RT::Tickets->new( RT->SystemUser ); + $tickets->FromSQL(" RefersTo = 'a:$aid' "); + is $tickets->Count, 0, "No results yet"; + + # try with the full uri + $tickets->FromSQL(" RefersTo = '@{[ $article->URI ]}' "); + is $tickets->Count, 0, "Still no results"; + + # add the link + $ticket->AddLink( Type => 'RefersTo', Target => "a:$aid" ); + + # verify the ticket has it + my @links = @{$ticket->RefersTo->ItemsArrayRef}; + is scalar @links, 1, "Has one RefersTo link"; + is ref $links[0]->TargetObj, "RT::Article", "Link points to an article"; + is $links[0]->TargetObj->id, $aid, "Link points to the article we specified"; + + # search again + $tickets->FromSQL(" RefersTo = 'a:$aid' "); + is $tickets->Count, 1, "Found one ticket with short URI"; + + # search with the full uri + $tickets->FromSQL(" RefersTo = '@{[ $article->URI ]}' "); + is $tickets->Count, 1, "Found one ticket with full URI"; +} diff --git a/rt/t/data/configs/apache2.2+fastcgi.conf.in b/rt/t/data/configs/apache2.2+fastcgi.conf.in index 3ec36dd0f..03eaa9a70 100644 --- a/rt/t/data/configs/apache2.2+fastcgi.conf.in +++ b/rt/t/data/configs/apache2.2+fastcgi.conf.in @@ -12,6 +12,7 @@ Group @WEB_GROUP@ </IfModule> </IfModule> +ServerName localhost Listen %%LISTEN%% ErrorLog "%%LOG_FILE%%" diff --git a/rt/t/data/configs/apache2.2+mod_perl.conf.in b/rt/t/data/configs/apache2.2+mod_perl.conf.in index 3b1f3f618..20d2f44e5 100644 --- a/rt/t/data/configs/apache2.2+mod_perl.conf.in +++ b/rt/t/data/configs/apache2.2+mod_perl.conf.in @@ -30,6 +30,7 @@ Group @WEB_GROUP@ </IfModule> </IfModule> +ServerName localhost Listen %%LISTEN%% ErrorLog "%%LOG_FILE%%" diff --git a/rt/t/mail/dashboard-chart-with-utf8.t b/rt/t/mail/dashboard-chart-with-utf8.t index 6d07b963b..79f5f0e11 100644 --- a/rt/t/mail/dashboard-chart-with-utf8.t +++ b/rt/t/mail/dashboard-chart-with-utf8.t @@ -1,7 +1,17 @@ use strict; use warnings; -use RT::Test tests => 15; +BEGIN { + require RT::Test; + + if (eval { require GD }) { + RT::Test->import(tests => 15); + } + else { + RT::Test->import(skip_all => 'GD required.'); + } +} + use utf8; my $root = RT::Test->load_or_create_user( Name => 'root' ); diff --git a/rt/t/mail/dashboards.t b/rt/t/mail/dashboards.t index 7a7a54ce6..00cfc6acd 100644 --- a/rt/t/mail/dashboards.t +++ b/rt/t/mail/dashboards.t @@ -2,7 +2,7 @@ use strict; use warnings; -use RT::Test tests => 187; +use RT::Test tests => 181; use Test::Warn; use RT::Dashboard::Mailer; @@ -138,17 +138,6 @@ sub delete_dashboard { # {{{ ok($ok, $msg); } # }}} -sub delete_subscriptions { # {{{ - my $subscription_id = shift; - # delete the dashboard and make sure we get exactly one subscription failure - # notice - my $user = RT::User->new(RT->SystemUser); - $user->Load('root'); - for my $subscription ($user->Attributes->Named('Subscription')) { - $subscription->Delete; - } -} # }}} - my $good_time = 1290423660; # 6:01 EST on a monday my $bad_time = 1290427260; # 7:01 EST on a monday @@ -223,21 +212,9 @@ SKIP: { delete_dashboard($dashboard_id); -warning_like { - RT::Dashboard::Mailer->MailDashboards(All => 1); -} qr/Unable to load dashboard $dashboard_id of subscription $subscription_id for user root/; - -@mails = RT::Test->fetch_caught_mails; -is(@mails, 1, "one mail for subscription failure"); -$mail = parse_mail($mails[0]); -is($mail->head->get('Subject'), "[example.com] Missing dashboard!\n"); -is($mail->head->get('From'), "dashboard\@example.com\n"); -is($mail->head->get('X-RT-Dashboard-Id'), "$dashboard_id\n"); -is($mail->head->get('X-RT-Dashboard-Subscription-Id'), "$subscription_id\n"); - RT::Dashboard::Mailer->MailDashboards(All => 1); @mails = RT::Test->fetch_caught_mails; -is(@mails, 0, "no mail because the subscription notice happens only once"); +is(@mails, 0, "no mail because the subscription is deleted"); RT::Test->stop_server; RT::Test->clean_caught_mails; @@ -277,7 +254,6 @@ RT->Config->Set('EmailDashboardRemove' => (qr/My dashboards/, "Testing!")); ($baseurl, $m) = RT::Test->started_ok; delete_dashboard($dashboard_id); -delete_subscriptions(); RT::Test->clean_caught_mails; @@ -330,7 +306,6 @@ RT->Config->Set('EmailDashboardRemove' => (qr/My dashboards/, "Testing!")); ($baseurl, $m) = RT::Test->started_ok; delete_dashboard($dashboard_id); -delete_subscriptions(); RT::Test->clean_caught_mails; @@ -373,7 +348,6 @@ RT->Config->Set('EmailDashboardRemove' => (qr/My dashboards/, "Testing!")); ($baseurl, $m) = RT::Test->started_ok; delete_dashboard($dashboard_id); -delete_subscriptions(); RT::Test->clean_caught_mails; diff --git a/rt/t/mail/gateway.t b/rt/t/mail/gateway.t index 9f0e669a3..98eabd56e 100644 --- a/rt/t/mail/gateway.t +++ b/rt/t/mail/gateway.t @@ -57,7 +57,7 @@ use strict; use warnings; -use RT::Test config => 'Set( $UnsafeEmailCommands, 1);', tests => 221, actual_server => 1; +use RT::Test config => 'Set( $UnsafeEmailCommands, 1);', tests => 228, actual_server => 1; my ($baseurl, $m) = RT::Test->started_ok; use RT::Tickets; @@ -608,6 +608,35 @@ EOF $m->no_warnings_ok; } +diag "make sure we check that UTF-8 is really UTF-8"; +{ + my $text = <<EOF; +From: root\@localhost +To: rtemail\@@{[RT->Config->Get('rtname')]} +Subject: This is test wrong utf-8 chars +Content-Type: text/plain; charset="utf-8" + +utf-8: informaci\303\263n confidencial +latin1: informaci\363n confidencial + +bye +EOF + my ($status, $id) = RT::Test->send_via_mailgate_and_http($text); + is ($status >> 8, 0, "The mail gateway exited normally"); + ok ($id, "created ticket"); + + my $tick = RT::Test->last_ticket; + is ($tick->Id, $id, "correct ticket"); + + my $content = $tick->Transactions->First->Content; + Encode::_utf8_off($content); + + like $content, qr{informaci\303\263n confidencial}; + like $content, qr{informaci\357\277\275n confidencial}; + + $m->no_warnings_ok; +} + diag "check that mailgate doesn't suffer from empty Reply-To:"; { my $text = <<EOF; diff --git a/rt/t/shredder/01ticket.t b/rt/t/shredder/01ticket.t index 7dff16df3..a7abeef6e 100644 --- a/rt/t/shredder/01ticket.t +++ b/rt/t/shredder/01ticket.t @@ -78,7 +78,11 @@ cmp_deeply( dump_current_and_savepoint('clean'), "current DB equal to savepoint" my $shredder = shredder_new(); $shredder->PutObjects( Objects => $child ); $shredder->WipeoutAll; - cmp_deeply( dump_current_and_savepoint('parent_ticket'), "current DB equal to savepoint"); + + TODO: { + local $TODO = "Shredder doesn't delete all links and transactions"; + cmp_deeply( dump_current_and_savepoint('parent_ticket'), "current DB equal to savepoint"); + } $shredder->PutObjects( Objects => $parent ); $shredder->WipeoutAll; diff --git a/rt/t/shredder/03plugin_tickets.t b/rt/t/shredder/03plugin_tickets.t index 092b57052..e63eef8fd 100644 --- a/rt/t/shredder/03plugin_tickets.t +++ b/rt/t/shredder/03plugin_tickets.t @@ -34,6 +34,7 @@ use_ok('RT::Tickets'); my $child = RT::Ticket->new( RT->SystemUser ); my ($cid) = $child->Create( Subject => 'child', Queue => 1, MemberOf => $pid ); ok( $cid, "created new ticket" ); + $_->ApplyTransactionBatch for $parent, $child; my $plugin = RT::Shredder::Plugin::Tickets->new; isa_ok($plugin, 'RT::Shredder::Plugin::Tickets'); @@ -77,6 +78,8 @@ cmp_deeply( dump_current_and_savepoint('clean'), "current DB equal to savepoint" my ($status, $msg) = $child->AddLink( Target => $pid, Type => 'DependsOn' ); ok($status, "added reqursive link") or diag "error: $msg"; + $_->ApplyTransactionBatch for $parent, $child; + my $plugin = RT::Shredder::Plugin::Tickets->new; isa_ok($plugin, 'RT::Shredder::Plugin::Tickets'); @@ -121,6 +124,8 @@ cmp_deeply( dump_current_and_savepoint('clean'), "current DB equal to savepoint" ok( $cid2, "created new ticket" ); $child2->SetStatus('resolved'); + $_->ApplyTransactionBatch for $parent, $child1, $child2; + my $plugin = RT::Shredder::Plugin::Tickets->new; isa_ok($plugin, 'RT::Shredder::Plugin::Tickets'); diff --git a/rt/t/shredder/03plugin_users.t b/rt/t/shredder/03plugin_users.t index 4f4ecc89c..1f4cb4934 100644 --- a/rt/t/shredder/03plugin_users.t +++ b/rt/t/shredder/03plugin_users.t @@ -5,8 +5,8 @@ use warnings; use Test::Deep; use File::Spec; -use Test::More tests => 9; -use RT::Test nodb => 1; +use Test::More tests => 21; +use RT::Test (); BEGIN { my $shredder_utils = RT::Test::get_relocatable_file('utils.pl', File::Spec->curdir()); @@ -38,3 +38,61 @@ use_ok('RT::Shredder::Plugin::Users'); ok(!$status, "bad 'status' arg value"); } +init_db(); + +RT::Test->set_rights( + { Principal => 'Everyone', Right => [qw(CreateTicket)] }, +); + +create_savepoint('clean'); + +{ # Create two users and a ticket. Shred second user and replace relations with first user + my ($uidA, $uidB, $msg); + my $userA = RT::User->new( RT->SystemUser ); + ($uidA, $msg) = $userA->Create( Name => 'userA', Privileged => 1, Disabled => 0 ); + ok( $uidA, "created user A" ) or diag "error: $msg"; + + my $userB = RT::User->new( RT->SystemUser ); + ($uidB, $msg) = $userB->Create( Name => 'userB', Privileged => 1, Disabled => 0 ); + ok( $uidB, "created user B" ) or diag "error: $msg"; + + my ($tid, $trid); + my $ticket = RT::Ticket->new( RT::CurrentUser->new($userB) ); + ($tid, $trid, $msg) = $ticket->Create( Subject => 'UserB Ticket', Queue => 1 ); + ok( $tid, "created new ticket") or diag "error: $msg"; + + my $transaction = RT::Transaction->new( RT->SystemUser ); + $transaction->Load($trid); + is ( $transaction->Creator, $uidB, "ticket creator is user B" ); + + my $plugin = RT::Shredder::Plugin::Users->new; + isa_ok($plugin, 'RT::Shredder::Plugin::Users'); + + my $status; + ($status, $msg) = $plugin->TestArgs( status => 'any', name => 'userB', replace_relations => $uidA ); + ok($status, "plugin arguments are ok") or diag "error: $msg"; + + my @objs; + ($status, @objs) = $plugin->Run; + ok($status, "executed plugin successfully") or diag "error: @objs"; + @objs = RT::Shredder->CastObjectsToRecords( Objects => \@objs ); + is(scalar @objs, 1, "one object in the result set"); + + my $shredder = shredder_new(); + + ($status, $msg) = $plugin->SetResolvers( Shredder => $shredder ); + ok($status, "set conflicts resolver") or diag "error: $msg"; + + $shredder->PutObjects( Objects => \@objs ); + $shredder->WipeoutAll; + + $ticket->Load( $tid ); + is($ticket->id, $tid, 'loaded ticket'); + + $transaction->Load($trid); + is ( $transaction->Creator, $uidA, "ticket creator is now user A" ); + + $shredder->Wipeout( Object => $ticket ); + $shredder->Wipeout( Object => $userA ); +} +cmp_deeply( dump_current_and_savepoint('clean'), "current DB equal to savepoint"); diff --git a/rt/t/shredder/utils.pl b/rt/t/shredder/utils.pl index 5f5c1822f..9b848c662 100644 --- a/rt/t/shredder/utils.pl +++ b/rt/t/shredder/utils.pl @@ -283,7 +283,7 @@ sub dump_sqlite my $old_fhkn = $dbh->{'FetchHashKeyName'}; $dbh->{'FetchHashKeyName'} = 'NAME_lc'; - my $sth = $dbh->table_info( '', '', '%', 'TABLE' ) || die $DBI::err; + my $sth = $dbh->table_info( '', '%', '%', 'TABLE' ) || die $DBI::err; my @tables = keys %{$sth->fetchall_hashref( 'table_name' )}; my $res = {}; diff --git a/rt/t/ticket/search_by_watcher.t b/rt/t/ticket/search_by_watcher.t index 809450b56..cfc7b1c22 100644 --- a/rt/t/ticket/search_by_watcher.t +++ b/rt/t/ticket/search_by_watcher.t @@ -142,8 +142,8 @@ sub run_auto_tests { @conditions = ( 'Cc = "not@exist"' => sub { 0 }, 'Cc != "not@exist"' => sub { 1 }, - 'Cc IS NULL' => sub { $_[0] =~ 'c:-;' }, - 'Cc IS NOT NULL' => sub { $_[0] !~ 'c:-;' }, + 'Cc IS NULL' => sub { $_[0] =~ /c:-;/ }, + 'Cc IS NOT NULL' => sub { $_[0] !~ /c:-;/ }, 'Cc = "x@foo.com"' => sub { $_[0] =~ /c:[^;]*x/ }, 'Cc != "x@foo.com"' => sub { $_[0] !~ /c:[^;]*x/ }, 'Cc LIKE "@bar.com"' => sub { $_[0] =~ /c:[^;]*(?:y|z)/ }, @@ -152,8 +152,8 @@ sub run_auto_tests { 'Requestor = "not@exist"' => sub { 0 }, 'Requestor != "not@exist"' => sub { 1 }, - 'Requestor IS NULL' => sub { $_[0] =~ 'r:-;' }, - 'Requestor IS NOT NULL' => sub { $_[0] !~ 'r:-;' }, + 'Requestor IS NULL' => sub { $_[0] =~ /r:-;/ }, + 'Requestor IS NOT NULL' => sub { $_[0] !~ /r:-;/ }, 'Requestor = "x@foo.com"' => sub { $_[0] =~ /r:[^;]*x/ }, 'Requestor != "x@foo.com"' => sub { $_[0] !~ /r:[^;]*x/ }, 'Requestor LIKE "@bar.com"' => sub { $_[0] =~ /r:[^;]*(?:y|z)/ }, @@ -174,7 +174,7 @@ sub run_auto_tests { 'Subject LIKE "ne"' => sub { 0 }, 'Subject NOT LIKE "ne"' => sub { 1 }, 'Subject = "r:x;c:y;"' => sub { $_[0] eq 'r:x;c:y;' }, - 'Subject LIKE "x"' => sub { $_[0] =~ 'x' }, + 'Subject LIKE "x"' => sub { $_[0] =~ /x/ }, ); @tickets = generate_tix(); diff --git a/rt/t/web/attachments.t b/rt/t/web/attachments.t index 8c75f6caf..784cbbe88 100644 --- a/rt/t/web/attachments.t +++ b/rt/t/web/attachments.t @@ -1,10 +1,11 @@ #!/usr/bin/perl -w use strict; -use RT::Test tests => 25; +use RT::Test tests => 33; use constant LogoFile => $RT::MasonComponentRoot .'/NoAuth/images/bpslogo.png'; use constant FaviconFile => $RT::MasonComponentRoot .'/NoAuth/images/favicon.png'; +use constant TextFile => $RT::MasonComponentRoot .'/NoAuth/css/print.css'; my ($baseurl, $m) = RT::Test->started_ok; ok $m->login, 'logged in'; @@ -30,9 +31,18 @@ $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'); +open LOGO, "<", LogoFile or die "Can't open logo file: $!"; +binmode LOGO; +my $logo_contents = do {local $/; <LOGO>}; +close LOGO; +$m->follow_link_ok({text => "Download bpslogo.png"}); +is($m->content_type, "image/png"); +is($m->content, $logo_contents, "Binary content matches"); + +$m->back; $m->follow_link_ok({text => 'Reply'}, "reply to the ticket"); $m->form_name('TicketUpdate'); -$m->field('Attach', LogoFile); +$m->field('Attach', TextFile); $m->click('AddMoreAttach'); is($m->status, 200, "request successful"); @@ -44,7 +54,16 @@ is($m->status, 200, "request successful"); $m->content_contains('Download bpslogo.png', 'page has file name'); $m->content_contains('Download favicon.png', 'page has file name'); +$m->content_contains('Download print.css', 'page has file name'); + +$m->follow_link_ok( { text => 'Download bpslogo.png' } ); +is( $m->response->header('Content-Type'), 'image/png', 'Content-Type of png lacks charset' ); + +$m->back; +$m->follow_link_ok( { text => 'Download print.css' } ); +is( $m->response->header('Content-Type'), + 'text/css;charset=UTF-8', 'Content-Type of text has charset' ); diag "test mobile ui"; $m->get_ok( $baseurl . '/m/ticket/create?Queue=' . $qid ); diff --git a/rt/t/web/command_line.t b/rt/t/web/command_line.t index 1fed8e69e..394daaba9 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 => 303, actual_server => 1; +use RT::Test tests => 315, actual_server => 1; my ($baseurl, $m) = RT::Test->started_ok; use RT::User; @@ -480,6 +480,8 @@ expect_like(qr/Merged into ticket #$merge_ticket_A by root/, 'Merge recorded in expect_like(qr/Created link $link1_id $reln $link2_id/, 'Linked'); expect_send("show -s ticket/$link1_id/links", "Checking creation of $reln..."); expect_like(qr/$display_relns{$reln}: [\w\d\.\-]+:\/\/[\w\d\.]+\/ticket\/$link2_id/, "Created link $reln"); + expect_send("show ticket/$link1_id/links", "Checking show links without format"); + expect_like(qr/$display_relns{$reln}: [\w\d\.\-]+:\/\/[\w\d\.]+\/ticket\/$link2_id/, "Found link $reln"); # delete link expect_send("link -d $link1_id $reln $link2_id", "Delete $reln..."); diff --git a/rt/t/web/command_line_with_unknown_field.t b/rt/t/web/command_line_with_unknown_field.t index 736be4d1c..d63956be3 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 => 14, actual_server => 1; +use RT::Test tests => 17, actual_server => 1; my ($baseurl, $m) = RT::Test->started_ok; my $rt_tool_path = "$RT::BinPath/rt"; @@ -19,6 +19,11 @@ expect_run( prompt => 'rt> ', quit => 'quit', ); + +expect_send( q{create -t ticket set foo=bar}, "create ticket with unknown field" ); +expect_like(qr/foo: Unknown field/, 'foo is unknown field'); +expect_like(qr/Could not create ticket/, 'ticket is not created'); + 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"); diff --git a/rt/t/web/crypt-gnupg.t b/rt/t/web/crypt-gnupg.t index 6bdefdac7..8c0eb570d 100644 --- a/rt/t/web/crypt-gnupg.t +++ b/rt/t/web/crypt-gnupg.t @@ -53,6 +53,7 @@ RT::Test->clean_caught_mails; $m->goto_create_ticket( $queue ); $m->form_name('TicketCreate'); +$m->field('Requestors', 'recipient@example.com'); $m->field('Subject', 'Encryption test'); $m->field('Content', 'Some content'); ok($m->value('Encrypt', 2), "encrypt tick box is checked"); @@ -122,6 +123,7 @@ RT::Test->clean_caught_mails; $m->goto_create_ticket( $queue ); $m->form_name('TicketCreate'); +$m->field('Requestors', 'recipient@example.com'); $m->field('Subject', 'Signing test'); $m->field('Content', 'Some other content'); ok(!$m->value('Encrypt', 2), "encrypt tick box is unchecked"); @@ -195,6 +197,7 @@ RT::Test->clean_caught_mails; $m->goto_create_ticket( $queue ); $m->form_name('TicketCreate'); +$m->field('Requestors', 'recipient@example.com'); $m->field('Subject', 'Crypt+Sign test'); $m->field('Content', 'Some final? content'); ok($m->value('Encrypt', 2), "encrypt tick box is checked"); @@ -260,6 +263,7 @@ RT::Test->clean_caught_mails; $m->goto_create_ticket( $queue ); $m->form_name('TicketCreate'); +$m->field('Requestors', 'recipient@example.com'); $m->field('Subject', 'Test crypt-off on encrypted queue'); $m->field('Content', 'Thought you had me figured out didya'); $m->field(Encrypt => undef, 2); # turn off encryption diff --git a/rt/t/web/googleish_search.t b/rt/t/web/googleish_search.t index e2a4e9116..f4c8fa4b6 100644 --- a/rt/t/web/googleish_search.t +++ b/rt/t/web/googleish_search.t @@ -2,7 +2,8 @@ use strict; use warnings; -use RT::Test tests => 96, config => 'Set( %FullTextSearch, Enable => 1, Indexed => 0 );'; +use RT::Test tests => undef, + config => 'Set( %FullTextSearch, Enable => 1, Indexed => 0 );'; my ($baseurl, $m) = RT::Test->started_ok; my $url = $m->rt_base_url; @@ -57,6 +58,7 @@ ok $two_words_queue && $two_words_queue->id, 'loaded or created a queue'; 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('owner:root@localhost'), "( Owner.EmailAddress = 'root\@localhost' ) AND $active", "Email address as owner"; 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"; @@ -217,3 +219,5 @@ for my $quote ( q{'}, q{"} ) { } } +undef $m; +done_testing; diff --git a/rt/t/web/query_builder_queue_limits.t b/rt/t/web/query_builder_queue_limits.t index a3b976524..f583d64cc 100644 --- a/rt/t/web/query_builder_queue_limits.t +++ b/rt/t/web/query_builder_queue_limits.t @@ -11,6 +11,9 @@ $lifecycles->{foo} = { }; +# explicitly Set so RT::Test can catch our change +RT->Config->Set( Lifecycles => %$lifecycles ); + RT::Lifecycle->FillCache(); my $general = RT::Test->load_or_create_queue( Name => 'General' ); diff --git a/rt/t/web/search_simple.t b/rt/t/web/search_simple.t index 1efc9a566..a1a3ce806 100644 --- a/rt/t/web/search_simple.t +++ b/rt/t/web/search_simple.t @@ -1,7 +1,7 @@ use strict; use warnings; -use RT::Test tests => 16; +use RT::Test tests => 30; my ( $baseurl, $m ) = RT::Test->started_ok; RT::Test->create_tickets( @@ -19,4 +19,58 @@ $m->content_contains( 'Show Results', "has page menu" ); $m->title_is( 'Found 1 ticket', 'title' ); $m->content_contains( 'ticket foo', 'has ticket foo' ); +# Test searches on custom fields +my $cf1 = RT::Test->load_or_create_custom_field( + Name => 'Location', + Queue => 'General', + Type => 'FreeformSingle', ); +isa_ok( $cf1, 'RT::CustomField' ); + +my $cf2 = RT::Test->load_or_create_custom_field( + Name => 'Server-name', + Queue => 'General', + Type => 'FreeformSingle', ); +isa_ok( $cf2, 'RT::CustomField' ); + +my $t = RT::Ticket->new(RT->SystemUser); + +{ + my ($id,undef,$msg) = $t->Create( + Queue => 'General', + Subject => 'Test searching CFs'); + ok( $id, "Created ticket - $msg" ); +} + +{ + my ($status, $msg) = $t->AddCustomFieldValue( + Field => $cf1->id, + Value => 'Downtown'); + ok( $status, "Added CF value - $msg" ); +} + +{ + my ($status, $msg) = $t->AddCustomFieldValue( + Field => $cf2->id, + Value => 'Proxy'); + ok( $status, "Added CF value - $msg" ); +} + +# Regular search +my $search = 'cf.Location:Downtown'; +$m->get_ok("/Search/Simple.html?q=$search"); +$m->title_is( 'Found 1 ticket', 'Found 1 ticket' ); +$m->text_contains( 'Test searching CFs', "Found test CF ticket with $search" ); + +# Case insensitive +$search = "cf.Location:downtown"; +$m->get_ok("/Search/Simple.html?q=$search"); +$m->title_is( 'Found 1 ticket', 'Found 1 ticket' ); +$m->text_contains( 'Test searching CFs', "Found test CF ticket with $search" ); + +# With dash in CF name +$search = "cf.Server-name:Proxy"; +$m->get_ok("/Search/Simple.html?q=$search"); +$m->title_is( 'Found 1 ticket', 'Found 1 ticket' ); +$m->text_contains( 'Test searching CFs', "Found test CF ticket with $search" ); + # TODO more simple search tests diff --git a/rt/t/web/ticket_modify_all.t b/rt/t/web/ticket_modify_all.t index c9dd7e7cd..2f0c4d1b3 100644 --- a/rt/t/web/ticket_modify_all.t +++ b/rt/t/web/ticket_modify_all.t @@ -1,7 +1,7 @@ use strict; use warnings; -use RT::Test tests => 15; +use RT::Test tests => 22; my $ticket = RT::Test->create_ticket( Subject => 'test bulk update', @@ -40,5 +40,44 @@ $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 +$m->get_ok($url . "/Ticket/ModifyAll.html?id=" . $ticket->id); +$m->form_name('TicketModifyAll'); +$m->field('Starts_Date' => "2013-01-01 00:00:00"); +$m->click('SubmitTicket'); +$m->text_contains("Starts: (Tue Jan 01 00:00:00 2013)", 'start date successfully updated'); + +$m->form_name('TicketModifyAll'); +$m->field('Started_Date' => "2014-01-01 00:00:00"); +$m->click('SubmitTicket'); +$m->text_contains("Started: (Wed Jan 01 00:00:00 2014)", 'started date successfully updated'); + +$m->form_name('TicketModifyAll'); +$m->field('Told_Date' => "2015-01-01 00:00:00"); +$m->click('SubmitTicket'); +$m->text_contains("Last Contact: (Thu Jan 01 00:00:00 2015)", 'told date successfully updated'); + +$m->form_name('TicketModifyAll'); +$m->field('Due_Date' => "2016-01-01 00:00:00"); +$m->click('SubmitTicket'); +$m->text_contains("Due: (Fri Jan 01 00:00:00 2016)", 'due date successfully updated'); + +$m->get( $url . '/Ticket/ModifyAll.html?id=' . $ticket->id ); +$m->form_name('TicketModifyAll'); +$m->field(WatcherTypeEmail => 'Requestor'); +$m->field(WatcherAddressEmail => 'root@localhost'); +$m->click('SubmitTicket'); +$m->text_contains( + "Added principal as a Requestor for this ticket", + 'watcher is added', +); +$m->form_name('TicketModifyAll'); +$m->field(WatcherTypeEmail => 'Requestor'); +$m->field(WatcherAddressEmail => 'root@localhost'); +$m->click('SubmitTicket'); +$m->text_contains( + "That principal is already a Requestor for this ticket", + 'no duplicate watchers', +); + +# XXX TODO test other parts, i.e. links diff --git a/rt/t/web/transaction_batch.t b/rt/t/web/transaction_batch.t index ae04e1fca..12d01fba4 100644 --- a/rt/t/web/transaction_batch.t +++ b/rt/t/web/transaction_batch.t @@ -12,7 +12,14 @@ my ($val, $msg) =$s1->Create( Queue => $q->Id, ScripAction => 'User Defined', CustomIsApplicableCode => 'return ($self->TransactionObj->Field||"") eq "TimeEstimated"', CustomPrepareCode => 'return 1', - CustomCommitCode => '$self->TicketObj->SetPriority($self->TicketObj->Priority + 2); return 1;', + CustomCommitCode => ' +if ( $self->TicketObj->CurrentUser->Name ne "RT_System" ) { + warn "Ticket obj has incorrect CurrentUser (should be RT_System) ".$self->TicketObj->CurrentUser->Name +} +if ( $self->TicketObj->QueueObj->CurrentUser->Name ne "RT_System" ) { + warn "Queue obj has incorrect CurrentUser (should be RT_System) ".$self->TicketObj->QueueObj->CurrentUser->Name +} +$self->TicketObj->SetPriority($self->TicketObj->Priority + 2); return 1;', Template => 'Blank', Stage => 'TransactionBatch', ); |