File Coverage

blib/lib/Net/Google/Code/Issue/Search.pm
Criterion Covered Total %
statement 60 64 93.7
branch 19 26 73.0
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 88 99 88.8


line stmt bran cond sub pod time code
1             package Net::Google::Code::Issue::Search;
2 2     2   57491 use Any::Moose;
  2         32799  
  2         16  
3 2     2   2143 use Params::Validate qw(:all);
  2         9228  
  2         677  
4 2     2   16 use Any::Moose 'Util::TypeConstraints';
  2         5  
  2         15  
5             with 'Net::Google::Code::Role::URL';
6             with 'Net::Google::Code::Role::Fetchable';
7             with 'Net::Google::Code::Role::Pageable';
8             with 'Net::Google::Code::Role::HTMLTree';
9 2     2   1510 use Net::Google::Code::Issue;
  2         5  
  2         2003  
10              
11             our %CAN_MAP = (
12             'all' => 1,
13             'open' => 2,
14             'new' => 6,
15             'verify' => 7,
16             );
17              
18              
19             has 'project' => (
20             isa => 'Str',
21             is => 'rw',
22             );
23              
24             has 'results' => (
25             isa => 'ArrayRef[Net::Google::Code::Issue]',
26             is => 'rw',
27             default => sub { [] },
28             );
29              
30             sub updated_after {
31 4     4 1 12054 my $self = shift;
32 4         87 my ( $after, $fallback_to_search ) =
33             validate_pos( @_, { isa => 'DateTime' },
34             { optional => 1, default => 1 } );
35            
36 4         205 my @results;
37              
38 4         48 my $content = $self->fetch( $self->base_feeds_url . 'issueupdates/basic' );
39 4         2336 require Net::Google::Code::AtomParser;
40 4         28 my $atom_parser = Net::Google::Code::AtomParser->new;
41 4         24 my ( $feed, $entries ) = $atom_parser->parse( $content );
42 4 50       18 if (@$entries) {
43 4         40 my $min_updated =
44             Net::Google::Code::DateTime->new_from_string( $entries->[-1]->{updated} );
45 4 100       1634 if ( $min_updated < $after ) {
46              
47             # yeah! we can get all the results by parsing the feed
48 2         641 my %seen;
49 2         8 for my $entry (@$entries) {
50 40         6450 my $updated = Net::Google::Code::DateTime->new_from_string(
51             $entry->{updated} );
52 40 100       11620 next unless $updated >= $after;
53 11 50       1647 if ( $entry->{title} =~ /issue\s+(\d+)/i ) {
54 11 100       53 next if $seen{$1}++;
55 4         97 push @results,
56             Net::Google::Code::Issue->new(
57             project => $self->project,
58             id => $1,
59             );
60             }
61             }
62 2         682 $_->load for @results;
63 2         2098 return $self->results( \@results );
64             }
65             }
66              
67 2 50       484 return unless $fallback_to_search;
68              
69             # now we have to find issues by search
70 2 50       14 if ( $self->search( load_after_search => 1, can => 'all', q => '' ) ) {
71 2         10 my $results = $self->results;
72 2         9 @$results = grep { $_->updated >= $after } @$results;
  16         1141  
73             }
74             }
75              
76             sub search {
77 3     3 1 1651 my $self = shift;
78 3         30 my %args = (
79             limit => 999_999_999,
80             load_after_search => 1,
81             can => 2,
82             colspec => 'ID+Type+Status+Priority+Milestone+Owner+Summary',
83             @_
84             );
85              
86 3 100       40 if ( $args{can} !~ /^\d$/ ) {
87 2         9 $args{can} = $CAN_MAP{ $args{can} };
88             }
89              
90 3         6 my @results;
91              
92 3         29 my $mech = $self->mech;
93 3         32 my $url = $self->base_url . 'issues/list?';
94 3         9 for my $type (qw/can q sort colspec/) {
95 12 100       42 next unless defined $args{$type};
96 8         24 $url .= $type . '=' . $args{$type} . '&';
97             }
98 3         251 $self->fetch($url);
99              
100 3 50       41 die "Server threw an error " . $mech->response->status_line . 'when search'
101             unless $mech->response->is_success;
102              
103 3         273 my $content = $mech->response->content;
104 3         348 utf8::downgrade( $content, 1 );
105              
106 3 50       14 if ( $mech->title =~ /issue\s+(\d+)/i ) {
    50          
107              
108             # get only one ticket
109 0         0 my $issue = Net::Google::Code::Issue->new(
110             project => $self->project,
111             id => $1,
112             );
113 0         0 @results = $issue;
114             }
115             elsif ( $mech->title =~ /issues/i ) {
116              
117             # get a ticket list
118 3         67 my @rows = $self->rows(
119             html => $content,
120             limit => $args{limit},
121             );
122              
123 3         13 for my $row (@rows) {
124 24         599 push @results,
125             Net::Google::Code::Issue->new(
126             project => $self->project,
127             %$row,
128             );
129             }
130             }
131             else {
132 0         0 warn "no idea what the content like";
133 0         0 return;
134             }
135              
136 3 100       27 if ( $args{load_after_search} ) {
137 2         17 $_->load for @results;
138             }
139 3         7807 $self->results( \@results );
140             }
141              
142 2     2   20 no Any::Moose;
  2         4  
  2         23  
143             __PACKAGE__->meta->make_immutable;
144             1;
145              
146             __END__