File Coverage

blib/lib/Whelk/Endpoint.pm
Criterion Covered Total %
statement 42 42 100.0
branch 10 14 71.4
condition 6 10 60.0
subroutine 6 6 100.0
pod 0 1 0.0
total 64 73 87.6


line stmt bran cond sub pod time code
1             package Whelk::Endpoint;
2             $Whelk::Endpoint::VERSION = '1.04';
3 21     21   719 use Whelk::StrictBase;
  21         45  
  21         196  
4 21     21   150 use Carp;
  21         91  
  21         1607  
5 21     21   834 use Whelk::Schema;
  21         58  
  21         677  
6 21     21   11246 use Whelk::Endpoint::Parameters;
  21         72  
  21         189  
7              
8             our @CARP_NOT = qw(Whelk::Role::Resource Kelp::Base);
9              
10             attr '?-id' => sub { $_[0]->route->has_name ? $_[0]->route->name : undef };
11             attr '?-summary' => undef;
12             attr '?-description' => undef;
13             attr -resource => sub { croak 'resource is required in endpoint' };
14             attr -route => sub { croak 'route is required in endpoint' };
15             attr -formatter => sub { croak 'formatter is required in endpoint' };
16             attr -wrapper => sub { croak 'wrapper is required in endpoint' };
17             attr code => undef;
18             attr path => undef;
19             attr '?request' => undef;
20             attr '?response' => undef;
21             attr '?response_code' => undef;
22             attr '?parameters' => undef;
23              
24             # to be built in wrapers
25             attr -response_schemas => sub { {} };
26              
27             sub new
28             {
29 117     117 0 1829 my $class = shift;
30 117         526 my $self = $class->SUPER::new(@_);
31              
32             # build request and response schemas
33 116         1280 $self->request(Whelk::Schema->build_if_defined($self->request));
34 116   100     659 $self->response(Whelk::Schema->build($self->response // {type => 'empty'}));
35              
36 116 100       601 if (!defined $self->response_code) {
37 113 100       1144 $self->response_code($self->response->empty ? 204 : 200);
38             }
39             else {
40 3 50       20 croak 'invalid response code'
41             unless $self->response_code =~ /^2\d\d$/;
42              
43 3 50 33     31 croak 'invalid non-204 code for empty response schema'
44             if $self->response->empty && $self->response_code != 204;
45              
46 3 50 33     10 croak 'invalid 204 code for non-empty response schema'
47             if !$self->response->empty && $self->response_code == 204;
48             }
49              
50             # initial build of the parameters
51 116   100     528 $self->parameters(Whelk::Endpoint::Parameters->new(%{$self->parameters // {}}));
  116         264  
52              
53             # build path
54 115         1073 $self->path($self->_build_path);
55              
56             # build schemas to get any errors reported early
57 115         615 $self->parameters->path_schema;
58 115         333 $self->parameters->query_schema;
59 115         277 $self->parameters->header_schema;
60 115         261 $self->parameters->cookie_schema;
61              
62             # wrap the endpoint sub
63 115         353 $self->code($self->route->dest->[1]);
64 115         1639 $self->route->dest->[1] = $self->wrapper->wrap($self);
65              
66 115         1169 return $self;
67             }
68              
69             sub _build_path
70             {
71 115     115   228 my ($self) = @_;
72 115         326 my $pattern = $self->route->pattern;
73              
74 115 50       1334 croak 'only :normal placeholders are allowed in Whelk'
75             if $pattern =~ m/[*>?]/;
76              
77             # Make path. First replace curlies with \0, same as in Kelp. Then adjust
78             # parameters to OpenAPI format. Lastly remove \0
79 115         193 my $path = $pattern;
80 115         240 $path =~ s/[{}]/\0/g;
81              
82 115         540 while ($path =~ s/:(\w+)/{$1}/) {
83 29         218 my $token = $1;
84              
85             # add path parameter if not exists already and mark as required
86 29 100       72 if (!$self->parameters->path->{$token}) {
87 9         33 $self->parameters->path->{$token}{type} = 'string';
88             }
89             }
90              
91 115         409 $path =~ s/\0//g;
92              
93 115         484 return $path;
94             }
95              
96             1;
97