File Coverage

blib/lib/Facebook/OpenGraph/Response.pm
Criterion Covered Total %
statement 68 69 98.5
branch 7 12 58.3
condition 25 33 75.7
subroutine 23 23 100.0
pod 18 18 100.0
total 141 155 90.9


line stmt bran cond sub pod time code
1             package Facebook::OpenGraph::Response;
2 34     34   68696 use strict;
  34         79  
  34         1001  
3 34     34   168 use warnings;
  34         69  
  34         831  
4 34     34   508 use 5.008001;
  34         117  
5              
6 34     34   210 use Carp qw(croak);
  34         67  
  34         1867  
7 34     34   11604 use JSON 2 ();
  34         220421  
  34         26811  
8              
9             sub new {
10 58     58 1 10767 my $class = shift;
11 58   100     228 my $args = shift || +{};
12              
13             return bless +{
14             json => $args->{json} || JSON->new->utf8,
15             headers => $args->{headers},
16             code => $args->{code},
17             message => $args->{message},
18             content => $args->{content},
19             req_headers => $args->{req_headers} || q{},
20 58   66     927 req_content => $args->{req_content} || q{},
      100        
      50        
21             }, $class;
22             }
23              
24             # accessors
25 61     61 1 607 sub code { shift->{code} }
26 36     36 1 130 sub headers { shift->{headers} }
27 2     2 1 9 sub message { shift->{message} }
28 54     54 1 204 sub content { shift->{content} }
29 5     5 1 20 sub req_headers { shift->{req_headers} }
30 1     1 1 5 sub req_content { shift->{req_content} }
31 50     50 1 709 sub json { shift->{json} }
32 1     1 1 4 sub etag { shift->header('etag') }
33              
34             sub api_version {
35 23     23 1 45 my $self = shift;
36 23         58 return $self->header('facebook-api-version');
37             }
38              
39             sub is_api_version_eq_or_later_than {
40 14     14 1 45 my ($self, $comparing_version) = @_;
41 14 50       38 croak 'comparing version is not given.' unless $comparing_version;
42              
43 14         106 (my $comp_major, my $comp_minor)
44             = $comparing_version =~ m/ (\d+) \. (\d+ )/x;
45              
46 14         44 (my $response_major, my $response_minor)
47             = $self->api_version =~ m/ (\d+) \. (\d+ )/x;
48              
49 14   66     150 return $comp_major < $response_major || ($comp_major == $response_major && $comp_minor <= $response_minor);
50             }
51              
52             sub is_api_version_eq_or_older_than {
53 8     8 1 27 my ($self, $comparing_version) = @_;
54 8 50       19 croak 'comparing version is not given.' unless $comparing_version;
55              
56 8         55 (my $comp_major, my $comp_minor)
57             = $comparing_version =~ m/ (\d+) \. (\d+ )/x;
58              
59 8         20 (my $response_major, my $response_minor)
60             = $self->api_version =~ m/ (\d+) \. (\d+ )/x;
61              
62 8   66     63 return $response_major < $comp_major || ($response_major == $comp_major && $response_minor <= $comp_minor);
63             }
64              
65             sub header {
66 24     24 1 60 my ($self, $key) = @_;
67              
68 24 50       65 croak 'header field name is not given' unless $key;
69              
70 24   66     109 $self->{header} ||= do {
71 9         20 my $ref = +{};
72              
73 9         28 while (my ($k, $v) = splice @{ $self->headers }, 0, 2) {
  35         81  
74 26         71 $ref->{$k} = $v;
75             }
76              
77 9         45 $ref;
78             };
79              
80 24         127 return $self->{header}->{$key};
81             }
82              
83             sub is_success {
84 53     53 1 109 my $self = shift;
85             # code 2XX or 304
86             # 304 is returned when you use ETag and the data is not changed
87 53   100     144 return substr($self->code, 0, 1) == 2 || $self->code == 304;
88             }
89              
90             # Using the Graph API > Handling Errors
91             # https://developers.facebook.com/docs/graph-api/using-graph-api/
92             sub error_string {
93 5     5 1 23 my $self = shift;
94              
95             # When an error occurs, the response should be given in a form below:
96             #{
97             # "error": {
98             # "message": "Message describing the error",
99             # "type": "OAuthException",
100             # "code": 190,
101             # "error_subcode": 460,
102             # "error_user_title": "A title",
103             # "error_user_msg": "A message",
104             # "fbtrace_id": "EJplcsCHuLu"
105             # }
106             #}
107 5         12 my $error = eval { $self->as_hashref->{error}; };
  5         16  
108              
109 5         12 my $err_str = q{};
110 5 50 33     53 if ($@ || !$error) {
111 0         0 $err_str = $self->message;
112             }
113             else {
114             # sometimes error_subcode is not given
115             $err_str = sprintf(
116             qq{%s:%s\t%s:%s\t%s\t%s:%s},
117             $error->{code},
118             $error->{error_subcode} || '-',
119             $error->{type},
120             $error->{message},
121             $error->{fbtrace_id},
122             $error->{error_user_title} || '-',
123 5   100     89 $error->{error_user_msg} || '-',
      100        
      100        
124             );
125             }
126              
127 5         31 return $err_str;
128             }
129              
130             sub as_json {
131 48     48 1 95 my $self = shift;
132              
133 48         141 my $content = $self->content;
134 48 100       260 if ($content =~ m{\A (true|false) \z}xms) {
135             # On v2.0 and older version, some endpoints return plain text saying
136             # 'true' or 'false' to indicate result, so make it JSON formatted for
137             # our convinience. The key is named "success" so its format matches with
138             # other endpoints that return {"success": "(true|false)"}.
139             # From v2.1 they always return in form of {"success": "(true|false)"}.
140             # See https://developers.facebook.com/docs/apps/changelog#v2_1_changes
141 1         23 $content = sprintf('{"success" : "%s"}', $1);
142             };
143              
144 48         838 return $content; # content is JSON formatted
145             }
146              
147             sub as_hashref {
148 48     48 1 99 my $self = shift;
149             # just in case content is not properly formatted
150 48         91 my $hash_ref = eval { $self->json->decode( $self->as_json ); };
  48         125  
151 48 50       174 croak $@ if $@;
152 48         322 return $hash_ref;
153             }
154              
155             # Indicates whether the data is modified.
156             # It should be used when you request with ETag.
157             # https://developers.facebook.com/docs/reference/ads-api/etags-reference/
158             sub is_modified {
159 2     2 1 5 my $self = shift;
160 2   66     5 my $not_modified = $self->code == 304 && $self->message eq 'Not Modified';
161 2         17 return !$not_modified;
162             }
163              
164             1;
165             __END__