File Coverage

blib/lib/PONAPI/DAO/Request.pm
Criterion Covered Total %
statement 61 62 98.3
branch 27 30 90.0
condition 8 9 88.8
subroutine 15 15 100.0
pod 1 3 33.3
total 112 119 94.1


line stmt bran cond sub pod time code
1             # ABSTRACT: DAO request class
2             package PONAPI::DAO::Request;
3              
4 8     8   4494 use Moose;
  8         19  
  8         56  
5 8     8   51685 use JSON::MaybeXS;
  8         11925  
  8         555  
6              
7 8     8   3692 use PONAPI::Document;
  8         7122493  
  8         6510  
8              
9             has repository => (
10             is => 'ro',
11             does => 'PONAPI::Repository',
12             required => 1,
13             );
14              
15             has document => (
16             is => 'ro',
17             isa => 'PONAPI::Document',
18             required => 1,
19             );
20              
21             has type => (
22             is => 'ro',
23             isa => 'Str',
24             required => 1,
25             );
26              
27             has send_doc_self_link => (
28             is => 'ro',
29             isa => 'Bool',
30             default => sub { 0 },
31             );
32              
33             has is_valid => (
34             is => 'ro',
35             isa => 'Bool',
36             default => sub { 1 },
37             writer => '_set_is_valid',
38             );
39              
40             has json => (
41             is => 'ro',
42             isa => JSON::MaybeXS::JSON(),
43             default => sub { JSON::MaybeXS->new->allow_nonref->utf8->canonical },
44             );
45              
46             sub BUILDARGS {
47 243     243 1 582 my $class = shift;
48 243 50       689 my %args = @_ == 1 ? %{ $_[0] } : @_;
  243         1580  
49              
50             die "[__PACKAGE__] missing arg `version`"
51 243 50       937 unless defined $args{version};
52              
53             $args{document} = PONAPI::Document->new(
54             version => $args{version},
55             req_path => $args{req_path} // '/',
56 243   100     9521 req_base => $args{req_base} // '/',
      100        
57             );
58              
59 243         718642 return \%args;
60             }
61              
62             # These validation methods will be overwritten in the appropriate roles.
63             # They cover the case where an attribute is NOT expected.
64             sub _validate_id {
65 56     56   168 my ( $self, $args ) = @_;
66 56 100       193 return unless defined $args->{id};
67 3         13 $self->_bad_request( "`id` is not allowed for this request" )
68             }
69              
70             sub _validate_rel_type {
71 152     152   342 my ( $self, $args ) = @_;
72 152 100       512 return unless defined $args->{rel_type};
73 11         50 $self->_bad_request( "`relationship type` is not allowed for this request" );
74             }
75              
76             sub _validate_include {
77 128     128   288 my ( $self, $args ) = @_;
78 128 100       357 return unless defined $args->{include};
79 7         45 $self->_bad_request( "`include` is not allowed for this request" );
80             }
81              
82             sub _validate_fields {
83 128     128   240 my ( $self, $args ) = @_;
84 128 100       317 return unless defined $args->{fields};
85 7         31 $self->_bad_request( "`fields` is not allowed for this request" );
86             }
87              
88             sub _validate_filter {
89 113     113   229 my ( $self, $args ) = @_;
90 113 50       319 return unless defined $args->{filter};
91 0         0 $self->_bad_request( "`filter` is not allowed for this request" );
92             }
93              
94             sub _validate_sort {
95 113     113   241 my ( $self, $args ) = @_;
96 113 100       320 return unless defined $args->{sort};
97 6         51 $self->_bad_request( "`sort` is not allowed for this request" );
98             }
99              
100             sub _validate_page {
101 113     113   237 my ( $self, $args ) = @_;
102 113 100       283 return unless defined $args->{page};
103 6         26 $self->_bad_request( "`page` is not allowed for this request" );
104             }
105              
106             sub BUILD {
107 235     235 0 669 my ( $self, $args ) = @_;
108              
109             # `type` exists
110 235         6899 my $type = $self->type;
111 235 100       6740 return $self->_bad_request( "Type `$type` doesn't exist.", 404 )
112             unless $self->repository->has_type( $type );
113              
114 225         1130 $self->_validate_id($args);
115 225         1041 $self->_validate_rel_type($args);
116 225         1042 $self->_validate_include($args);
117 225         927 $self->_validate_fields($args);
118 225         855 $self->_validate_filter($args);
119 225         842 $self->_validate_sort($args);
120 225         808 $self->_validate_page($args);
121              
122             # validate `data`
123 225 100       4940 if ( exists $args->{data} ) {
    100          
124 97 100       562 if ( $self->can('data') ) {
125 87         404 $self->_validate_data;
126             }
127             else {
128 10         36 $self->_bad_request( "request body is not allowed" );
129             }
130             }
131             elsif ( $self->can('has_data') ) {
132 7         24 $self->_bad_request( "request body is missing `data`" );
133             }
134             }
135              
136             sub response {
137 196     196 0 490 my ( $self, @headers ) = @_;
138 196         5467 my $doc = $self->document;
139              
140 196 100 66     5890 $doc->add_self_link
141             if $self->send_doc_self_link && !$doc->has_link('self');
142              
143             return (
144 196 100       29795 $doc->status,
145             \@headers,
146             (
147             $doc->status != 204
148             ? $doc->build
149             : ()
150             ),
151             );
152             }
153              
154             sub _bad_request {
155 105     105   274 my ( $self, $detail, $status ) = @_;
156 105   100     2976 $self->document->raise_error( $status||400, { detail => $detail } );
157 105         102080 $self->_set_is_valid(0);
158 105         1358 return;
159             }
160              
161             __PACKAGE__->meta->make_immutable;
162 8     8   102 no Moose; 1;
  8         57  
  8         78  
163              
164             __END__
165              
166             =pod
167              
168             =encoding UTF-8
169              
170             =head1 NAME
171              
172             PONAPI::DAO::Request - DAO request class
173              
174             =head1 VERSION
175              
176             version 0.003003
177              
178             =head1 AUTHORS
179              
180             =over 4
181              
182             =item *
183              
184             Mickey Nasriachi <mickey@cpan.org>
185              
186             =item *
187              
188             Stevan Little <stevan@cpan.org>
189              
190             =item *
191              
192             Brian Fraser <hugmeir@cpan.org>
193              
194             =back
195              
196             =head1 COPYRIGHT AND LICENSE
197              
198             This software is copyright (c) 2019 by Mickey Nasriachi, Stevan Little, Brian Fraser.
199              
200             This is free software; you can redistribute it and/or modify it under
201             the same terms as the Perl 5 programming language system itself.
202              
203             =cut