File Coverage

blib/lib/Net/Correios.pm
Criterion Covered Total %
statement 52 62 83.8
branch 9 22 40.9
condition 6 17 35.2
subroutine 14 14 100.0
pod 3 5 60.0
total 84 120 70.0


line stmt bran cond sub pod time code
1 8     8   1851036 use strict;
  8         19  
  8         319  
2 8     8   90 use warnings;
  8         21  
  8         481  
3              
4 8     8   6469 use HTTP::Tiny;
  8         586560  
  8         558  
5 8     8   5086 use MIME::Base64 ();
  8         7055  
  8         318  
6 8     8   58 use Carp ();
  8         15  
  8         148  
7 8     8   60 use Scalar::Util ();
  8         16  
  8         120  
8 8     8   4084 use JSON ();
  8         67205  
  8         2167  
9              
10             $Carp::Internal{ 'Net::Correios' }++;
11              
12             package Net::Correios;
13              
14             our $VERSION = '0.003';
15              
16             my %libs = (
17             token => 'Token',
18             cep => 'CEP',
19             sro => 'SRO',
20             preco => 'Preco',
21             prazo => 'Prazo',
22             empresas => 'Empresas',
23             prepostagens => 'Prepostagens',
24             faturas => 'Faturas',
25             agencias => 'Agencias',
26             manifestacao => 'Manifestacao',
27             );
28              
29             # create lazy accessors.
30             foreach my $method (keys %libs) {
31             $Carp::Internal{ 'Net::Correios::' . $libs{$method} }++;
32             my $sub = sub {
33 6     6   4609 my ($self, %args) = @_;
34 6         24 my $internal_key = 'endpoint_' . $method;
35 6 50       53 if (!$self->{$internal_key}) {
36 6         24 my $module = 'Net/Correios/' . $libs{$method} . '.pm';
37 6         5684 require $module;
38 6         34 my $class = 'Net::Correios::' . $libs{$method};
39 6         35 $self->{$internal_key} = $class->new( $self );
40             }
41 6         89 return $self->{$internal_key};
42             };
43 8     8   80 { no strict 'refs';
  8         20  
  8         5946  
44             *{"Net\::Correios\::$method"} = $sub;
45             }
46             }
47              
48             sub new {
49 11     11 1 1767039 my ($class, %args) = @_;
50             Carp::croak 'Net::Correios::new - "username" and "password" are required'
51 11 100 100     589 unless $args{username} && $args{password};
52 8         78 my $auth_basic = MIME::Base64::encode_base64($args{username} . ':' . $args{password}, '');
53             return bless {
54             contrato => $args{contrato},
55             cartao => $args{cartao},
56             sandbox => !!$args{sandbox},
57             base_url => 'https://api' . (('hom')x!!$args{sandbox}) . '.correios.com.br/',
58             auth_basic => $auth_basic,
59             agent => HTTP::Tiny->new(
60             default_headers => {
61             'Accept' => 'application/json',
62             'Content-Type' => 'application/json',
63             },
64             verify_SSL => 1,
65 8   50     213 timeout => $args{timeout} || 5,
66             ),
67             }, $class;
68             }
69              
70 2     2 1 289 sub is_sandbox { $_[0]->{sandbox} }
71              
72             sub access_token {
73 10     10 1 63 my ($self, $token_type) = @_;
74 10 50 33     117 die 'token deve ser "cartao", "contrato" ou undef'
      33        
75             if defined $token_type && $token_type ne 'cartao' && $token_type ne 'contrato';
76              
77 10 50       53 my $storage_key = 'token' . (defined $token_type ? '_' . $token_type : '');
78 10 50       52 return $self->{$storage_key} if defined $self->{$storage_key};
79              
80             my $token_res = $self->token->autentica(
81 0 0       0 (defined $token_type ? ($token_type => $self->{$token_type}) : ())
82             );
83              
84 0         0 $self->{$storage_key} = $token_res->{token};
85 0 0 0     0 if ($token_res->{cartaoPostagem} && (!$self->{cartao} || $self->{cartao} eq $token_res->{cartaoPostagem}{numero})) {
      0        
86 0         0 $self->{dr} = $token_res->{cartaoPostagem}{dr};
87 0 0       0 $self->{contrato} = $token_res->{cartaoPostagem}{contrato} if !$self->{contrato};
88             }
89 0         0 return $self->{$storage_key};
90             }
91              
92             sub make_request {
93 8     8 0 32 my ($self, $token_type, $method, $url, $args) = @_;
94 8 100       29 $args = {} if !defined $args;
95 8         40 $url = $self->{base_url} . $url;
96 8         34 my $token = $self->access_token($token_type);
97 8         44 $args->{headers}{Authorization} = 'Bearer ' . $token;
98 8         57 my $res = $self->{agent}->request($method, $url, $args);
99 8         31974 return $res;
100             }
101              
102             sub parse_response {
103 9     9 0 27 my ($self, $res) = @_;
104 9 50       49 if ($res->{success}) {
105 9         255 my $data = JSON::decode_json($res->{content});
106 9         64 return $data;
107             }
108             else {
109 0           my $error = $res->{status} . ' ' . $res->{reason};
110 0 0         $error .= ":\n" . $res->{content} if length $res->{content};
111 0           $error .= "\n " . $res->{url};
112 0           Carp::croak($error);
113             }
114             }
115              
116             1;
117             __END__