File Coverage

blib/lib/PayProp/API/Public/Client/Role/APIRequest.pm
Criterion Covered Total %
statement 33 44 75.0
branch 6 10 60.0
condition 7 18 38.8
subroutine 10 12 83.3
pod 1 1 100.0
total 57 85 67.0


line stmt bran cond sub pod time code
1             package PayProp::API::Public::Client::Role::APIRequest;
2              
3 26     26   236245 use strict;
  26         71  
  26         991  
4 26     26   129 use warnings;
  26         58  
  26         1420  
5              
6 26     26   476 use Mouse::Role;
  26         1013  
  26         227  
7             with qw/ PayProp::API::Public::Client::Role::Request /;
8             with qw/ PayProp::API::Public::Client::Role::Attribute::Domain /;
9             with qw/ PayProp::API::Public::Client::Role::Attribute::APIVersion /;
10             with qw/ PayProp::API::Public::Client::Role::Attribute::Authorization /;
11              
12 26     26   25611 use PayProp::API::Public::Client::Exception::Response;
  26         100  
  26         17172  
13              
14             sub api_request_p {
15 44     44 1 1733 my ( $self, $args ) = @_;
16              
17             $self
18             ->_api_request_p( $args )
19             ->catch( sub {
20 0     0   0 my ( $error ) = @_;
21              
22 0 0       0 if ( $self->_can_retry_request( $error ) ) {
23             return $self
24             ->authorization
25             ->remove_token_from_storage_p
26 0         0 ->then( sub { $self->_api_request_p( $args ) } )
27 0         0 ;
28             }
29              
30 0         0 $error->rethrow;
31             } )
32 44         474 ;
33             }
34              
35             sub _api_request_p {
36 44     44   233 my ( $self, $args ) = @_;
37              
38 44   50     213 $args //= {};
39 44   50     479 my $headers = $args->{headers} // {};
40 44   100     367 my $method = $args->{method} // 'GET';
41 44         159 my $handle_response_cb = $args->{handle_response_cb};
42              
43             my $request_method = {
44             GET => 'get_req_p',
45             PUT => 'put_req_p',
46             POST => 'post_req_p',
47             DELETE => 'delete_req_p',
48 44 100 50     1313 }->{ uc( $method // '' ) }
49             or die "method $method not suported for api_request_p"
50             ;
51              
52 43 100 66     644 die 'handle_response_cb must be CODE ref'
53             if $handle_response_cb && ref $handle_response_cb ne 'CODE'
54             ;
55              
56             return $self
57             ->authorization
58             ->token_request_p
59             ->then( sub {
60 42     42   86771 my ( $token_info ) = @_;
61              
62 42         209 my ( $token, $token_type ) = @$token_info{qw/ token token_type /};
63              
64 42         1546 return $self
65             ->$request_method({
66             $args->%*,
67             headers => {
68             Authorization => "$token_type $token",
69             $headers->%*,
70             },
71             })
72             ;
73             } )
74             ->then( sub {
75 42     42   919717 my ( $Transaction ) = @_;
76              
77 42         605 my $Result = $Transaction->result;
78 42         1615 $self->_maybe_throw_response_exception( $Result );
79              
80 42         1105 return $Result->json;
81             } )
82             ->then( sub {
83 42     42   10825 my ( $response_json ) = @_;
84              
85             return (
86             ( $handle_response_cb ? $handle_response_cb->( $response_json ) : $response_json ),
87             {
88             pagination => $response_json->{pagination},
89             }
90 42 50       359 );
91             } )
92 42         1580 ;
93             }
94              
95             sub _maybe_throw_response_exception {
96 42     42   122 my ( $self, $Result ) = @_;
97              
98 42 50       240 return undef if $Result->is_success;
99              
100 0   0       my $json = $Result->json // {};
101 0   0       my $errors = $json->{errors} // [ { path => '/NO_PATH', message => 'NO_ERROR_MESSAGE' } ];
102              
103             PayProp::API::Public::Client::Exception::Response->throw(
104             status_code => $Result->code,
105             errors => [
106 0           map { +{ %$_{qw/ path message /} } } $errors->@*
  0            
107             ],
108             );
109             }
110              
111             sub _can_retry_request {
112 0     0     my ( $self, $error ) = @_;
113              
114             return
115 0   0       $self->authorization->has_storage
116             && $self->authorization->is_token_from_storage
117             && ref( $error ) eq 'PayProp::API::Public::Client::Exception::Response'
118             && ( $error->status_code // -1 ) == 401
119             ;
120             }
121              
122             1;
123              
124             __END__