+sub run_validator {
+ my $self = shift;
+ my %args = (check => 1, resolve => 0, force => 1, timeout => 0, @_ );
+
+ my $cmd = "$RT::SbinPath/rt-validator";
+ die "Couldn't find $cmd command" unless -f $cmd;
+
+ my $timeout = delete $args{timeout};
+
+ while( my ($k,$v) = each %args ) {
+ next unless $v;
+ $cmd .= " --$k '$v'";
+ }
+ $cmd .= ' 2>&1';
+
+ require IPC::Open2;
+ my ($child_out, $child_in);
+ my $pid = IPC::Open2::open2($child_out, $child_in, $cmd);
+ close $child_in;
+
+ local $SIG{ALRM} = sub { kill KILL => $pid; die "Timeout!" };
+
+ alarm $timeout if $timeout;
+ my $result = eval { local $/; <$child_out> };
+ warn $@ if $@;
+ close $child_out;
+ waitpid $pid, 0;
+ alarm 0;
+
+ DBIx::SearchBuilder::Record::Cachable->FlushCache
+ if $args{'resolve'};
+
+ return ($?, $result);
+}
+
+sub db_is_valid {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ my $self = shift;
+ my ($ecode, $res) = $self->run_validator;
+ Test::More::is( $ecode, 0, 'no invalid records' )
+ or Test::More::diag "errors:\n$res";
+}
+
+=head2 object_scrips_are
+
+Takes an L<RT::Scrip> object or ID as the first argument and an arrayref of
+L<RT::Queue> objects and/or Queue IDs as the second argument.
+
+The scrip's applications (L<RT::ObjectScrip> records) are tested to ensure they
+exactly match the arrayref.
+
+An optional third arrayref may be passed to enumerate and test the queues the
+scrip is B<not> added to. This is most useful for testing the API returns the
+correct results.
+
+=cut
+
+sub object_scrips_are {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my $self = shift;
+ my $scrip = shift;
+ my $to = shift || [];
+ my $not_to = shift;
+
+ unless (blessed($scrip)) {
+ my $id = $scrip;
+ $scrip = RT::Scrip->new( RT->SystemUser );
+ $scrip->Load($id);
+ }
+
+ $to = [ map { blessed($_) ? $_->id : $_ } @$to ];
+ Test::More::ok($scrip->IsAdded($_), "added to queue $_" ) foreach @$to;
+ Test::More::is_deeply(
+ [sort map $_->id, @{ $scrip->AddedTo->ItemsArrayRef }],
+ [sort grep $_, @$to ],
+ 'correct list of added to queues',
+ );
+
+ if ($not_to) {
+ $not_to = [ map { blessed($_) ? $_->id : $_ } @$not_to ];
+ Test::More::ok(!$scrip->IsAdded($_), "not added to queue $_" ) foreach @$not_to;
+ Test::More::is_deeply(
+ [sort map $_->id, @{ $scrip->NotAddedTo->ItemsArrayRef }],
+ [sort grep $_, @$not_to ],
+ 'correct list of not added to queues',
+ );
+ }
+}
+