File Coverage

blib/lib/WebService/Mattermost/V4/API/Resource.pm
Criterion Covered Total %
statement 107 135 79.2
branch 16 24 66.6
condition 9 12 75.0
subroutine 24 29 82.7
pod n/a
total 156 200 78.0


line stmt bran cond sub pod time code
1             package WebService::Mattermost::V4::API::Resource;
2              
3             # ABSTRACT: Base class for API resources.
4              
5 7     7   6208 use List::MoreUtils 'all';
  7         52849  
  7         57  
6 7     7   6800 use Moo;
  7         18  
  7         44  
7 7     7   2513 use Types::Standard qw(Bool HashRef Object Str);
  7         15  
  7         46  
8              
9 7     7   8968 use WebService::Mattermost::Helper::Alias qw(v4 view);
  7         21  
  7         455  
10 7     7   3405 use WebService::Mattermost::V4::API::Object::Channel;
  7         26  
  7         264  
11 7     7   3399 use WebService::Mattermost::V4::API::Object::Icon;
  7         48  
  7         277  
12 7     7   3503 use WebService::Mattermost::V4::API::Object::Status;
  7         19  
  7         281  
13 7     7   3483 use WebService::Mattermost::V4::API::Object::Team;
  7         21  
  7         249  
14 7     7   3657 use WebService::Mattermost::V4::API::Object::TeamMember;
  7         23  
  7         277  
15 7     7   3484 use WebService::Mattermost::V4::API::Object::TeamStats;
  7         23  
  7         215  
16 7     7   3658 use WebService::Mattermost::V4::API::Object::Plugins;
  7         27  
  7         243  
17 7     7   3497 use WebService::Mattermost::V4::API::Object::Results;
  7         21  
  7         208  
18 7     7   3461 use WebService::Mattermost::V4::API::Object::User;
  7         21  
  7         224  
19 7     7   3383 use WebService::Mattermost::V4::API::Request;
  7         23  
  7         235  
20 7     7   3117 use WebService::Mattermost::V4::API::Response;
  7         33  
  7         8212  
21              
22             with qw(
23             WebService::Mattermost::Role::Logger
24             WebService::Mattermost::Role::Returns
25             WebService::Mattermost::Role::UserAgent
26             WebService::Mattermost::V4::API::Role::RequireID
27             );
28              
29             ################################################################################
30              
31             has api => (is => 'ro', isa => Object, required => 1);
32             has base_url => (is => 'ro', isa => Str, required => 1);
33             has resource => (is => 'ro', isa => Str, required => 1);
34             has auth_token => (is => 'rw', isa => Str, required => 1);
35              
36             has DELETE => (is => 'ro', isa => Str, default => 'DELETE');
37             has GET => (is => 'ro', isa => Str, default => 'GET');
38             has headers => (is => 'ro', isa => HashRef, default => sub { {} });
39             has POST => (is => 'ro', isa => Str, default => 'POST');
40             has PUT => (is => 'ro', isa => Str, default => 'PUT');
41             has debug => (is => 'ro', isa => Bool, default => 0);
42              
43             ################################################################################
44              
45             sub _delete {
46 0     0   0     my $self = shift;
47 0         0     my $args = shift;
48              
49 0         0     $args->{method} = $self->DELETE;
50              
51 0         0     return $self->_call($args);
52             }
53              
54             sub _single_view_delete {
55 0     0   0     my $self = shift;
56 0         0     my $args = shift;
57              
58 0         0     $args->{single} = 1;
59              
60 0         0     return $self->_delete($args);
61             }
62              
63             sub _get {
64 7     7   18     my $self = shift;
65 7         14     my $args = shift;
66              
67 7         38     $args->{method} = $self->GET;
68              
69 7         34     return $self->_call($args);
70             }
71              
72             sub _single_view_get {
73 3     3   12     my $self = shift;
74 3         7     my $args = shift;
75              
76 3         11     $args->{single} = 1;
77              
78 3         16     return $self->_get($args);
79             }
80              
81             sub _post {
82 2     2   7     my $self = shift;
83 2         5     my $args = shift;
84              
85 2         17     $args->{method} = $self->POST;
86              
87 2         12     return $self->_call($args);
88             }
89              
90             sub _single_view_post {
91 0     0   0     my $self = shift;
92 0         0     my $args = shift;
93              
94 0         0     $args->{single} = 1;
95              
96 0         0     return $self->_post($args);
97             }
98              
99             sub _put {
100 1     1   2     my $self = shift;
101 1         3     my $args = shift;
102              
103 1         5     $args->{method} = $self->PUT;
104              
105 1         6     return $self->_call($args);
106             }
107              
108             sub _single_view_put {
109 0     0   0     my $self = shift;
110 0         0     my $args = shift;
111              
112 0         0     $args->{method} = $self->PUT;
113              
114 0         0     return $self->_put($args);
115             }
116              
117             sub _call {
118 10     10   23     my $self = shift;
119 10         15     my $args = shift;
120              
121 10 100       38     if ($args->{required}) {
122 3         19         my $validation = $self->_validate($args->{parameters}, $args->{required});
123              
124 3 50       20         return $validation unless $validation->{valid};
125                 }
126              
127 10         42     my %headers = ('Keep-Alive' => 1);
128              
129 10 50       229     if ($self->auth_token) {
130 10         266         $headers{Authorization} = $self->bearer($self->auth_token);
131                 }
132              
133 10         79     my $request = $self->_as_request($args);
134 10         12041     my $method = lc $request->method;
135              
136 10         21     my $form_type;
137              
138 10 100       76     if (grep { $_ eq $request->method } ($self->PUT, $self->POST)) {
  20         89  
139 3         9         $form_type = 'json';
140                 } else {
141 7         15         $form_type = 'form';
142                 }
143              
144 10 50       38     $form_type = $args->{override_data_type} if $args->{override_data_type};
145              
146 10         209     my $tx = $self->ua->$method(
147                     $request->url => \%headers,
148                     $form_type => $request->parameters,
149                 );
150              
151 10 50       2064     if (my $error = $tx->req->error) {
152 0         0         $self->logger->warn('No HTTP code was received from Mattermost. Is your server alive?');
153 0         0         $self->logger->warnf('The following may be useful: %s', $error->{message});
154                 }
155              
156 10         371     return $self->_as_response($tx->res, $args);
157             }
158              
159             sub _as_request {
160 10     10   27     my $self = shift;
161 10         28     my $args = shift;
162              
163 10         159     $args->{auth_token} = $self->auth_token;
164 10         100     $args->{base_url} = $self->base_url;
165 10         63     $args->{resource} = $self->resource;
166 10         42     $args->{debug} = $self->debug;
167              
168 10   100     63     $args->{endpoint} ||= '';
169 10   100     34     $args->{parameters} ||= {};
170              
171 10         166     return WebService::Mattermost::V4::API::Request->new($args);
172             }
173              
174             sub _as_response {
175 10     10   81     my $self = shift;
176 10         20     my $res = shift;
177 10         23     my $args = shift;
178              
179 10   33     102     my $view_name = $self->can('view_name') && $self->view_name;
180              
181 10 50       37     if ($args->{view}) {
182 0         0         $view_name = $args->{view};
183                 }
184              
185 10 100 100     76     if ($res->is_error && $self->debug) {
186 1         55         $self->logger->warnf('An API error occurred: %s', $res->message);
187                 }
188              
189                 return WebService::Mattermost::V4::API::Response->new({
190                     auth_token => $self->auth_token,
191                     base_url => $self->base_url,
192                     code => $res->code || 0,
193                     headers => $res->headers,
194                     is_error => $res->is_error ? 1 : 0,
195                     is_success => $res->is_success ? 1 : 0,
196                     message => $res->message,
197                     prev => $res,
198                     raw_content => $res->body,
199                     item_view => $view_name,
200                     single_item => $args->{single},
201 10 100 50     489     });
    100          
202             }
203              
204             sub _validate {
205 3     3   7     my $self = shift;
206 3         7     my $args = shift;
207 3         6     my $required = shift;
208              
209 3         8     my %slice;
210              
211             # Grab a slice of the keys from given arguments
212 3         23     @slice{@{$required}} = @{$args}{@{$required}};
  3         17  
  3         11  
  3         6  
213              
214             # Return early, all's well
215 3 50   5   82     return { valid => 1 } if all { defined($_) } values %slice;
  5         27  
216              
217 0               my @missing;
218              
219 0               foreach my $kx (@{$required}) {
  0            
220 0 0                 push @missing, $kx unless $args->{$kx};
221                 }
222              
223                 return {
224 0                   valid => 0,
225                     missing => \@missing,
226                     error => sprintf('Required parameters missing: %s', join(', ', @missing)),
227                 };
228             }
229              
230             sub _new_related_resource {
231 0     0         my $self = shift;
232 0               my $base = shift;
233 0               my $resource = shift;
234              
235 0               return v4($resource)->new({
236                     auth_token => $self->auth_token,
237                     base_url => $self->base_url,
238                     resource => $base,
239                 });
240             }
241              
242             ################################################################################
243              
244             1;
245              
246             __END__
247            
248             =pod
249            
250             =encoding UTF-8
251            
252             =head1 NAME
253            
254             WebService::Mattermost::V4::API::Resource - Base class for API resources.
255            
256             =head1 VERSION
257            
258             version 0.26
259            
260             =head1 DESCRIPTION
261            
262             =head2 ATTRIBUTES
263            
264             =over 4
265            
266             =item C<auth_token>
267            
268             An auth token to use in the headers for every API call. Authentication is
269             required to use the Mattermost API.
270            
271             =item C<base_url>
272            
273             The API's base URL.
274            
275             =item C<resource>
276            
277             The name of the API resource, for example L<WebService::Mattermost::V4::API::Brand>'s
278             resource is 'brand'.
279            
280             =back
281            
282             =head1 AUTHOR
283            
284             Mike Jones <mike@netsplit.org.uk>
285            
286             =head1 COPYRIGHT AND LICENSE
287            
288             This software is Copyright (c) 2020 by Mike Jones.
289            
290             This is free software, licensed under:
291            
292             The MIT (X11) License
293            
294             =cut
295