view release on metacpan or search on metacpan
lib/App/SD/CLI/Command/Ticket/Comment/Update.pm view on Meta::CPAN
$self->print_usage if $self->has_arg('h');
$self->require_uuid;
my $record = $self->_load_record;
my @prop_set = $self->prop_set;
# we don't want to do prop: value editing by default for comments since
# it's just a blob of text
if (!@prop_set || $self->has_arg('edit')) {
my $updated_comment = $self->edit_text($record->prop('content'));
$record->set_prop(name => 'content', value => $updated_comment);
print "Updated comment " . $record->luid . " (" . $record->uuid . ")\n";
} else {
super();
}
};
__PACKAGE__->meta->make_immutable;
no Any::Moose;
1;
lib/App/SD/CLI/Command/Ticket/Create.pm view on Meta::CPAN
$done = $self->try_to_edit( template => \$template_to_edit, record => $record);
}
};
sub process_template {
my $self = shift;
my %args = validate( @_, { template => 1, edited => 1, record => 1 } );
my $record = $args{record};
my $updated = $args{edited};
( my $props_ref, my $comment ) = $self->parse_record_template($updated);
for my $prop ( keys %$props_ref ) {
$self->context->set_prop( $prop => $props_ref->{$prop} );
}
my $error;
local $@;
eval { super(); } or chomp ($error = $@ || "Something went wrong!");
return $self->handle_template_errors(
error => $error . "\n\nYou can bypass validation for a "
."property by appending a ! to it.",
template_ref => $args{template},
bad_template => $updated,
rtype => $record->type,
) if ($error);
$self->add_comment( content => $comment, uuid => $self->record->uuid )
if $comment;
return 1;
}
lib/App/SD/CLI/Command/Ticket/Update.pm view on Meta::CPAN
$done = $self->try_to_edit( template => \$template_to_edit, record => $record);
}
};
sub process_template {
my $self = shift;
my %args = validate( @_, { template => 1, edited => 1, record => 1 } );
my $record = $args{record};
my $updated = $args{edited};
my ( $props_ref, $comment ) = $self->parse_record_template($updated);
no warnings 'uninitialized';
# if a formerly existing prop was removed from the output, delete it
# (deleting is currently the equivalent of setting to '', and
# we want to do this all in one changeset)
for my $prop ( keys %{ $record->get_props } ) {
next if ( grep { $_ eq $prop } $record->immutable_props );
$props_ref->{$prop} = ''
if (!exists $props_ref->{$prop} &&
lib/App/SD/CLI/Command/Ticket/Update.pm view on Meta::CPAN
# set the new props
if ( keys %$props_ref ) {
my $error;
local $@;
eval { $record->set_props( props => $props_ref ) }
or $error = $@ || "Something went wrong!";
return $self->handle_template_errors(
error => $error,
template_ref => $args{template},
bad_template => $updated
) if ($error);
print 'Updated ticket ' . $record->luid . ' (' . $record->uuid . ")\n";
} else {
print "No changes in properties.\n";
}
$self->add_comment( content => $comment, uuid => $record->uuid ) if $comment;
return 1;
}
lib/App/SD/ForeignReplica.pm view on Meta::CPAN
my $self = shift;
my %args = validate( @_,
{ ticket => 1,
changeset => { isa => 'Prophet::ChangeSet' }, start_time => 1} );
my $earliest_valid_txn_date;
# walk through every transaction on the ticket, starting with the latest
for my $txn ( $self->get_txn_list_by_date($args{ticket}) ) {
# walk backwards through all transactions on the ticket we just updated
# Skip any transaction where the remote user isn't me, this might
# include any transaction RT created with a scrip on your behalf
next unless $txn->{creator} eq $self->foreign_username;
# get the completion time _after_ we do our next round trip to rt to
# try to make sure a bit of lag doesn't skew us to the wrong side of a
# 1s boundary
if (!$earliest_valid_txn_date){
my $change_window = time() - $args{start_time};
lib/App/SD/Replica/gcode/PullEncoder.pm view on Meta::CPAN
if ( $Net::Google::Code::VERSION lt '0.15' ) {
die
"query support is only for Net::Google::Code version not less than 0.15"
if $args{query};
require Net::Google::Code::Issue::Search;
my $search =
Net::Google::Code::Issue::Search->new(
project => $self->sync_source->project, );
if ( $search->updated_after($last_changeset_seen_dt) ) {
return $search->results;
}
else {
return [];
}
}
else {
my $issue = Net::Google::Code::Issue->new(
map { $_ => $self->sync_source->gcode->$_ }
grep { $self->sync_source->gcode->$_ }
qw/project email password/ );
if ( keys %query == 0 ) {
# we can use old updated_after method here if no query strings
# loading issue by checking feeds update is more effective, if
# possible
local $Net::Google::Code::Issue::USE_HYBRID = 0;
require Net::Google::Code::Issue::Search;
my $search =
Net::Google::Code::Issue::Search->new(
project => $self->sync_source->project, );
# 0 here is to not fallback to ->search method
if ( $search->updated_after( $last_changeset_seen_dt, 0 ) ) {
return $search->results;
}
}
$query{can} ||= 'all';
$query{max_results} ||= 1_000_000_000;
delete $query{q} unless defined $query{q};
my $results = $issue->list( %query,
updated_min => $query{updated_min}
&& $query{updated_min} gt "$last_changeset_seen_dt"
? $query{updated_min}
: "$last_changeset_seen_dt" );
$_->load for @$results;
return $results;
}
}
sub _only_pull_tickets_modified_after {
my $self = shift;
lib/App/SD/Replica/github.pm view on Meta::CPAN
Tickets have two states: open or closed.
Once a ticket is created, the following modifications can be made to it:
- edit ticket body/title
- add a new comment
- edit a comment's body
- close a ticket (or reopen)
Thus, there is no "history" API call---we just get the current state, and we
can formulate our own history based on the list of comments, updated_at
timestamps, and comparing our state with the current state.
GitHub issues can also have arbitrary "labels" applied to them, but we're
currently ignoring this functionality.
=cut
sub BUILD {
my $self = shift;
lib/App/SD/Replica/github/PullEncoder.pm view on Meta::CPAN
=head2 translate_ticket_state
=cut
sub translate_ticket_state {
my $self = shift;
my $ticket = shift;
$ticket->{created_at} =
App::SD::Util::string_to_datetime($ticket->{created_at});
$ticket->{updated_at} =
App::SD::Util::string_to_datetime($ticket->{updated_at});
return $ticket;
}
=head2 find_matching_tickets QUERY
Returns a array of all tickets found matching your QUERY hash.
=cut
sub find_matching_tickets {
my $self = shift;
my %query = (@_);
my $last_changeset_seen_dt = $self->_only_pull_tickets_modified_after()
|| DateTime->from_epoch( epoch => 0 );
my $issue = $self->sync_source->github->issue;
my @updated = grep {
App::SD::Util::string_to_datetime($_->{updated_at}) > $last_changeset_seen_dt }
( @{ $issue->list('open') }, @{ $issue->list('closed') } );
return \@updated;
}
sub _only_pull_tickets_modified_after {
my $self = shift;
my $last_pull = $self->sync_source->upstream_last_modified_date();
return unless $last_pull;
my $before = App::SD::Util::string_to_datetime($last_pull);
$self->log_debug( "Failed to parse '" . $self->sync_source->upstream_last_modified_date() . "' as a timestamp. That means we have to sync ALL history") unless ($before);
return $before;
lib/App/SD/Replica/github/PullEncoder.pm view on Meta::CPAN
=cut
sub find_matching_transactions {
my $self = shift;
my %args = validate( @_, { ticket => 1, starting_transaction => 1 } );
my @raw_txns =
@{ $self->sync_source->github->issue->comments( $args{ticket}->{number} ) };
for my $comment (@raw_txns) {
$comment->{updated_at} =
App::SD::Util::string_to_datetime( $comment->{updated_at} );
$comment->{created_at} =
App::SD::Util::string_to_datetime( $comment->{created_at} );
}
my @txns;
for my $txn ( sort { $a->{id} <=> $b->{id} } @raw_txns ) {
my $txn_date = $txn->{updated_at}->epoch;
# Skip things we know we've already pulled
next if $txn_date < ( $args{'starting_transaction'} || 0 );
# Skip things we've pushed
next if (
$self->sync_source->foreign_transaction_originated_locally(
$txn_date, $args{'ticket'}->{number}
)
);
lib/App/SD/Replica/lighthouse/PullEncoder.pm view on Meta::CPAN
=cut
sub find_matching_tickets {
my $self = shift;
my %args = (@_);
my $last_changeset_seen_dt = $self->_only_pull_tickets_modified_after()
|| DateTime->from_epoch( epoch => 0 );
my @tickets =
$self->sync_source->lighthouse->tickets( query => $args{query} );
my @updated = map { $_->load( $_->number ); $_ }
grep { $_->{updated_at} ge $last_changeset_seen_dt } @tickets;
return \@updated;
}
sub _only_pull_tickets_modified_after {
my $self = shift;
my $last_pull = $self->sync_source->upstream_last_modified_date();
return unless $last_pull;
my $before = App::SD::Util::string_to_datetime($last_pull);
$self->log_debug( "Failed to parse '" . $self->sync_source->upstream_last_modified_date() . "' as a timestamp. That means we have to sync ALL history") unless ($before);
return $before;
lib/App/SD/Replica/rt/PullEncoder.pm view on Meta::CPAN
=cut
sub find_matching_tickets {
my $self = shift;
my %args = validate(@_,{query => 1});
my $query = $args{query};
# If we've ever synced, we can limit our search to only newer things
if ( my $before = $self->_only_pull_tickets_modified_after ) {
$query = "($query) AND LastUpdated >= '" . $before->ymd('-') . " " . $before->hms(':') . "'";
$self->sync_source->log( "Skipping all tickets not updated since " . $before->iso8601 );
}
return [map {
Prophet::CLI->end_pager();
# squelch chatty RT::Client::REST "Unknown key" warnings unless debugging turned on
local $SIG{__WARN__} = sub { $self->sync_source->log_debug(@_) };
my $hash = $self->sync_source->rt->show( type => 'ticket', id => $_ );
$hash->{id} =~ s|^ticket/||g;
$hash
} $self->sync_source->rt->search( type => 'ticket', query => $query )];
}
lib/App/SD/Replica/rt/PullEncoder.pm view on Meta::CPAN
dependedonby => 'depended_on_by',
hasmember => 'members',
memberof => 'member_of',
priority => 'priority_integer',
resolved => 'completed',
due => 'due',
creator => 'creator',
timeworked => 'time_worked',
timeleft => 'time_left',
timeestimated => 'time_estimated',
lastupdated => '_delete',
created => 'created',
queue => 'queue',
starts => '_delete',
started => '_delete',
);
sub translate_status {
my $self = shift;
my $status = shift;
lib/App/SD/Replica/trac/PullEncoder.pm view on Meta::CPAN
sub transcode_create_txn {
my $self = shift;
my $txn = shift;
my $create_data = shift;
my $final_data = shift;
my $ticket = $txn->ticket;
# this sequence_no only works because trac tickets only allow one update
# per ticket per second.
# we decrement by 1 on the off chance that someone created and
# updated the ticket in the first second
my $changeset = Prophet::ChangeSet->new(
{ original_source_uuid => $self->sync_source->uuid_for_remote_id( $ticket->id ),
original_sequence_no => ( $ticket->created->epoch-1),
creator => $self->resolve_user_id_to( email_address => $create_data->{reporter} ),
created => $ticket->created->ymd ." ".$ticket->created->hms
}
);
my $change = Prophet::Change->new(
{ record_type => 'ticket',
lib/App/SD/Test.pm view on Meta::CPAN
Updates the ticket #ID, passing ARGS along to the update command.
Returns nothing interesting.
=cut
sub update_ticket_ok {
my ($id, @args) = (@_);
local $Test::Builder::Level = $Test::Builder::Level + 1;
run_output_matches( 'sd', [ 'ticket', 'update', $id, '--', @args ],
[qr/ticket \d+\s+\([^)]*\)\s+updated\./i]
);
}
=head2 create_ticket_comment_ok ARGS
Creates a new ticket comment, passing ARGS along to the creation command.
Returns a list of the luid and uuid of the newly created comment.
=cut
t/sd-attachments.t view on Meta::CPAN
],
[],
"Found the attachment"
);
run_output_matches(
'sd',
[ qw/ticket attachment update --uuid/, $attachment_uuid,
'--',
qw/--name/, "plague_recipe.doc"
],
[qr/Attachment \d+ \($attachment_uuid\) updated/],
[],
"updated the attachment"
);
run_output_matches(
'sd',
[ qw/ticket attachment show --batch --uuid/, $attachment_uuid ],
[
qr/id: (\d+) \($attachment_uuid\)/,
"content: stub",
"content_type: text/plain",
qr/created: \d{4}-\d{2}-\d{2}.+/,
qr/creator: /,
t/sd-comments.t view on Meta::CPAN
[],
"Found the comment"
);
run_output_matches(
'sd',
[ qw/ticket comment update --uuid/, $comment_uuid,
'--',
qw/--content/, "I hate you"
],
[qr/Comment \d+ \($comment_uuid\) updated/],
[],
"updated the comment"
);
run_output_matches(
'sd',
[ qw/ticket comment show --batch --uuid/, $comment_uuid ],
[ qr/id: (\d+) \($comment_uuid\)/,
qr/I hate you/,
qr/created: /i,
qr/creator: /i,
"original_replica: $replica_uuid",
t/sd-comments.t view on Meta::CPAN
[],
"Found the comment $comment_uuid when we tried to search for all comments on a ticket by the ticket's uuid, $yatta_uuid"
);
run_output_matches(
'sd',
[ qw/ticket comment update --uuid/, $comment_uuid,
'--',
qw/--content/, "A\nmultiline\ncomment"
],
[qr/Comment \d+ \($comment_uuid\) updated/],
[],
"updated the comment to a multiline content"
);
run_output_matches(
'sd',
[ qw/ticket comment show --batch --uuid/, $comment_uuid ],
[ qr/id: (\d+) \($comment_uuid\)/,
qr/^content: A/,
qr/^multiline$/,
qr/^comment$/,
qr/created: /i,
t/sd-dispatcher.t view on Meta::CPAN
[ qr/(\d+) YATTA new/]
);
run_output_matches( 'sd', [ 'list', 'ticket',
'--regex', '.' ],
[ qr/(\d+) YATTA new/]
);
# test claim
run_output_matches( 'sd', [ 'ticket', 'claim', $yatta_id ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: new',
'milestone: alpha',
'component: core',
'owner: ' . $ENV{PROPHET_EMAIL},
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
# revert back the change so we can check the alias for claim, take
run_output_matches( 'sd', [ 'ticket', 'update', $yatta_id, '--', 'owner', '' ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: new',
'milestone: alpha',
'component: core',
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
# test take
run_output_matches( 'sd', [ 'ticket', 'take', $yatta_id ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: new',
'milestone: alpha',
'component: core',
'owner: ' . $ENV{PROPHET_EMAIL},
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
# test resolve
run_output_matches( 'sd', [ 'ticket', 'resolve', $yatta_id ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: closed',
'milestone: alpha',
'component: core',
'owner: ' . $ENV{PROPHET_EMAIL},
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
# revert that change so we can test resolve's alias, close
run_output_matches( 'sd', [ 'ticket', 'update', $yatta_id, '--', 'status', 'new' ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: new',
'milestone: alpha',
'component: core',
'owner: ' . $ENV{PROPHET_EMAIL},
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
# test close
run_output_matches( 'sd', [ 'ticket', 'close', $yatta_id ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: closed',
'milestone: alpha',
'component: core',
'owner: ' . $ENV{PROPHET_EMAIL},
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
# test give
run_output_matches( 'sd', [ 'ticket', 'give', $yatta_id, 'jesse@bestpractical.com' ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: closed',
'milestone: alpha',
'component: core',
'owner: jesse@bestpractical.com',
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
'reporter: ' . $ENV{PROPHET_EMAIL},
"original_replica: " . replica_uuid,
]
);
run_output_matches( 'sd', [ 'ticket', 'assign', $yatta_id, 'spang@bestpractical.com' ],
[ "Ticket $yatta_id ($yatta_uuid) updated." ]
);
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $yatta_id ],
[
"id: $yatta_id ($yatta_uuid)",
'summary: YATTA',
'status: closed',
'milestone: alpha',
'component: core',
'owner: spang@bestpractical.com',
t/sd-hm/update.t view on Meta::CPAN
[ 'clone', '--from', $sd_hm_url, '--non-interactive' ] );
run_output_matches( 'sd', [qw(ticket list --regex .)], [qr/(.*?)(?{ $yatta_uuid = $1 }) YATTA (.*)/] );
( $ret, $out, $err ) = run_script( 'sd', [ qw(ticket show --batch --id), $yatta_uuid ] );
diag($out);
diag($err);
($yatta_id, $yatta_uuid) = ($1, $2) if $out =~ /^id: (\d+)\s*\((.*)\)/m;
}
is_script_output( 'sd', [ qw(ticket update --uuid), $yatta_uuid, qw(-- --summary BLABLA) ],
[qr/ticket \d+ \(\Q$yatta_uuid\E\) updated./i], # stdout
[undef], # stderr
"updated summary"
);
{
my ( $ret, $out, $err ) = run_script( 'sd', [ 'push','--to', $sd_hm_url ] );
my $task = BTDT::Model::Task->new( current_user => $GOODUSER );
ok( $task->load_by_cols( summary => 'BLABLA' ), "loaded a task" );
is( $task->id, $remote_id, "the same task" );
}
qr/status: set to new/,
qr/milestone: set to alpha/,
qr/reporter: set to $ENV{PROPHET_EMAIL}/,
qr/^$/,
], [], "log output is correct",
);
# change a prop
run_output_matches( 'sd', [ 'ticket',
'update', '--uuid', $log_uuid, '--', '--reporter', 'foo@bar.com',
],
[qr/Ticket $log_id \($log_uuid\) updated/], #stdout
[], # stderr
"deleting a prop went ok",
);
# check the log
run_output_matches( 'sd', [ 'log', 'LATEST' ],
[
'',
qr/^=+/,
qr/^\d{4}-\d{2}-\d{2}.+ - $ENV{PROPHET_EMAIL} : \d+\@\Q$ENV{PROPHET_REPO}\E$/,
qr/^Ticket \d+ \(logs rock!\)$/,
t/sd-redmine/basic.t view on Meta::CPAN
diag "sd clone --from ${sd_redmine_url} --non-interactive";
my ( $ret, $out, $err )
= run_script( 'sd',
[ 'clone', '--from', $sd_redmine_url, '--non-interactive' ] );
is(count_tickets_in_sd(),5, "the total cloned tickets is 5.");
note "close one of them, push it to server.";
( $ret, $out, $err ) = run_script( 'sd', [ "ticket", "update", $tickets[0]->id, "--", "status=Closed" ] );
like( $out, qr/^Ticket(.*)updated/ );
diag($out);
diag($err);
( $ret, $out, $err ) = run_script( 'sd', [ 'push', '--to', $sd_redmine_url ] );
diag($out);
diag($err);
note "verify the update with Net::Redmine";
my $ticket = $r->lookup(ticket => { id => $tickets[0]->id });
t/sd-rt/basic.t view on Meta::CPAN
= run_script( 'sd',
[ 'ticket', 'comment', $helium_id, '--content', 'helium is a noble gas' ] );
ok( $ret, $out );
like( $out, qr/Created comment/ );
{ # resolve a ticket
( $ret, $out, $err )
= run_script( 'sd', [ 'ticket', 'resolve', $helium_id ] );
ok( $ret, $out );
like( $out, qr/Ticket .* updated/ );
( $ret, $out, $err ) = run_script( 'sd', [ 'push', '--to', $sd_rt_url ] );
ok( $ret, $out );
( $ret, $out, $err ) = run_script( 'sd', [ 'pull', '--from', $sd_rt_url ] );
ok( $ret, $out );
my $fetched_ticket = RT::Client::REST::Ticket->new(
rt => $rt,
id => $ticket->id
t/sd-rt/rt-auto-open-conflict.t view on Meta::CPAN
( $ret, $out, $err ) = run_script( 'sd', [ 'ticket', 'comment', $helium_id, '--content', 'helium is a noble gas' ] );
ok( $ret, $out );
like( $out, qr/Created comment/ );
diag($out);
diag($err);
{ # resolve a ticket
diag("Resolve a ticket in SD");
( $ret, $out, $err ) = run_script( 'sd', [ 'ticket', 'resolve', $helium_id ] );
ok( $ret, $out );
like( $out, qr/Ticket .* updated/ );
sleep(1);
diag("Push to rt");
( $ret, $out, $err ) = run_script( 'sd', [ 'push', '--to', $sd_rt_url, '--prefer', 'source' ] );
ok( $ret, $out );
diag($err);
sleep(1);
( $ret, $out, $err ) = run_script( 'sd', [ 'pull', '--from', $sd_rt_url, '--prefer', 'source'] );
ok( $ret, $out );
diag($err);
my $fetched_ticket = RT::Client::REST::Ticket->new(
t/sd-rt/sd-rt-permission.t view on Meta::CPAN
ok($ret);
run_output_matches( 'sd', [ 'ticket', 'list', '--regex', '.' ],
[qr/(.*?)(?{ $flyman_id = $1 }) Fly Man new/] );
};
diag("without write rights, ensure that trying to push it gives a sane error");
as_alice {
run_output_matches('sd', ['ticket', 'update', $flyman_id, '--', 'priority=20'],
[qr/ticket .*$flyman_id.* updated/i],
);
($ret, $out, $err) = run_script('sd', ['push', '--to', $alice_rt_url]);
ok($ret);
like($err, qr/You are not allowed to modify ticket $ticket_id/);
SKIP: {
skip "test needs fixing", 1;
# we should know exactly how many changesets there are.. used to be 1,
t/sd-rt/sd-rt-permission.t view on Meta::CPAN
TODO: {
local $TODO = "we mark all changesets as merged even if some failed";
}
};
$ticket = RT::Client::REST::Ticket->new(
rt => $root,
id => $ticket_id,
)->retrieve;
is($ticket->priority, 10, "ticket not updated");
diag("give write rights, try to push again");
$alice->PrincipalObj->GrantRight(Right => 'ModifyTicket', Object => $queue);
as_alice {
($ret, $out, $err) = run_script('sd', ['push', '--to', $alice_rt_url]);
ok($ret);
TODO: {
local $TODO = "Prophet thinks it already merged this changeset!";
}
};
$ticket = RT::Client::REST::Ticket->new(
rt => $root,
id => $ticket_id,
)->retrieve;
TODO: {
local $TODO = "ticket is NOT updated!";
is($ticket->priority, 20, "ticket updated");
}
diag("move the ticket, ensure it doesn't just disappear");
$ticket = RT::Client::REST::Ticket->new(
rt => $root,
id => $ticket_id,
queue => $refuge->Id,
status => 'stalled',
)->store;
t/sd-rt/sd-rt-permission.t view on Meta::CPAN
[qr/Fly Man new/] );
};
diag("update the moved ticket");
$alice->PrincipalObj->GrantRight(Right => 'ModifyTicket', Object => $refuge);
$alice->PrincipalObj->GrantRight(Right => 'SeeQueue', Object => $refuge);
$alice->PrincipalObj->GrantRight(Right => 'ShowTicket', Object => $refuge);
as_alice {
run_output_matches('sd', ['ticket', 'resolve', $flyman_id],
[qr/ticket .*$flyman_id.* updated/i],
);
($ret, $out, $err) = run_script('sd', ['push', '--to', $alice_rt_url]);
ok($ret);
};
$ticket = RT::Client::REST::Ticket->new(
rt => $root,
id => $ticket_id,
)->retrieve;
is($ticket->status, 'resolved', "ticket is updated");
t/sd-trac/basic.t view on Meta::CPAN
# Update a ticket in trac
#
can_ok( $ticket, 'load' );
ok( $ticket->load(1) );
like( $ticket->state->{'summary'}, qr/pony/ );
like( $ticket->summary, qr/moose/, "The summary looks like a moose" );
sleep 2; # to make trac happy
ok( $ticket->update( summary => 'The product does not contain a pony' ),
"updated!" );
unlike( $ticket->summary, qr/moose/, "The summary does not look like a moose" );
my ($fh, $filename) = File::Temp::tempfile(SUFFIX => '.txt', UNLINK => 1);
print $fh "TIMTOWTDI\n";
close $fh;
sleep 2; # to make trac happy
ok($ticket->attach( file => $filename ), "Attaching file.");
my $history = $ticket->history;
ok( $history, "The ticket has some history" );
t/sd-trac/basic.t view on Meta::CPAN
like( $settings,
qr/statuses: \["new","accepted","assigned","reopened","closed","fixed","invalid","wontfix","duplicate","worksforme","test_resolution"\]/,
'statuses setting'
);
#
# Modify the ticket we pulled from trac
( $ret, $out, $err ) = run_script( 'sd', [ "ticket", "update", $pony_id, "--", "status=closed" ] );
like( $out, qr/^Ticket(.*)updated/ );
diag($out);
diag($err);
( $ret, $out, $err ) = run_script( 'sd' => [ "ticket", "basics", $pony_id, "--batch" ] );
like( $out, qr/status: closed/ );
diag("The pony is $pony_id");
my $new_ticket = Net::Trac::Ticket->new( connection => $trac );
ok( $new_ticket->load(1) );
is( $new_ticket->status, 'new', "The ticket is new before we push to trac" );
t/sd-validation.t view on Meta::CPAN
],
[], # stdout
[qr/Validation error for 'component': 'awesome' is not a valid component/,
qr/Validation error for 'status': 'super' is not a valid status/], # stderr
"Despite the magic power phrase of 'yatta', super is not a valid bug status"
);
run_output_matches( 'sd', [ 'ticket',
'update', '--uuid', $yatta_uuid, '--', '--status', 'stalled'
],
[qr/Ticket \d+ \($yatta_uuid\) updated./], # stdout
[], # stderr
"Setting the status to stalled went ok"
);
run_output_matches( 'sd', [ 'ticket',
'list', '--regex', '.' ],
[ qr/(\d+) YATTA stalled/]
);
t/sd-validation.t view on Meta::CPAN
run_output_matches( 'sd', [ 'ticket',
'list', '--regex', '.' ],
[ qr/(\d+) YATTA stalled/]
);
# check to make sure that we can force-set props
run_output_matches( 'sd', [ 'ticket',
'update', '--uuid', $yatta_uuid, '--', '--status', 'super!'
],
[qr/Ticket $yatta_id \($yatta_uuid\) updated/], #stdout
[], # stderr
"we can force-set an invalid prop"
);
1;