File Coverage

blib/lib/Plack/Middleware/Signposting/JSON.pm
Criterion Covered Total %
statement 51 51 100.0
branch 7 14 50.0
condition 2 5 40.0
subroutine 11 11 100.0
pod 1 1 100.0
total 72 82 87.8


line stmt bran cond sub pod time code
1             package Plack::Middleware::Signposting::JSON;
2              
3 2     2   52392 use strict;
  2         5  
  2         49  
4 2     2   8 use warnings;
  2         4  
  2         46  
5              
6 2     2   401 use parent 'Plack::Middleware';
  2         224  
  2         10  
7 2     2   11654 use JSON qw(decode_json);
  2         7275  
  2         9  
8 2     2   1022 use Plack::Request;
  2         92315  
  2         64  
9 2     2   17 use Plack::Util::Accessor qw(fix);
  2         6  
  2         18  
10 2     2   872 use Catmandu;
  2         393091  
  2         12  
11 2     2   393 use Catmandu::Fix;
  2         4  
  2         683  
12              
13             our $VERSION = '0.02';
14              
15             sub call {
16 1     1 1 14855 my ($self, $env) = @_;
17              
18 1         8 my $request = Plack::Request->new($env);
19 1         18 my $res = $self->app->($env);
20              
21             # only get/head requests
22 1 50       46 return $res unless $request->method =~ m{^get|head$}i;
23              
24             # see http://search.cpan.org/~miyagawa/Plack-1.0044/lib/Plack/Middleware.pm#RESPONSE_CALLBACK
25             return $self->response_cb($res, sub {
26 1     1   24 my $res = shift;
27              
28 1   50     5 my $content_type = Plack::Util::header_get($res->[1], 'Content-Type') || '';
29             # only json responses
30 1 50       30 return unless $content_type =~ m{^application/json}i;
31             # ignore streaming response for now
32 1 50       5 return unless ref $res->[2] eq 'ARRAY';
33              
34 1         2 my $body = join('', @{$res->[2]});
  1         16  
35 1         126 my $data = decode_json($body);
36              
37 1 50 33     9 if (ref $data && ref $data eq 'ARRAY') {
38 1         3 $data = $data->[0];
39             }
40              
41             # harcoded fix file
42 1 50       13 my $fix = $self->fix ? $self->fix : 'nothing()';
43 1         20 my $fixer = Catmandu::Fix->new(fixes => [$fix]);
44 1         1722 $fixer->fix($data);
45              
46             # add information to the 'Link' header
47 1 50       117078 if ($data->{signs}) {
48             Plack::Util::header_push(
49             $res->[1],
50 1         4 'Link' => $self->_to_link_format( @{$data->{signs}} )
  1         9  
51             );
52             }
53 1         23 });
54             }
55              
56             # produces the link format
57             sub _to_link_format {
58 1     1   4 my ($self, @signs) = @_;
59              
60             my $body = join(", ", map {
61 1         3 my ($uri, $relation, $type) = @$_;
  3         6  
62 3         9 my $link_text = qq|<$uri>; rel="$relation"|;
63 3 50       9 $link_text .= qq|; type="$type"| if $type;
64 3         9 $link_text;
65             } @signs);
66              
67 1         22 $body;
68             }
69              
70             1;
71              
72             __END__
73              
74             =encoding utf-8
75              
76             =head1 NAME
77              
78             Plack::Middleware::Signposting::JSON - A Signposting implementation from JSON content
79              
80             =begin markdown
81              
82             [![Build Status](https://travis-ci.org/LibreCat/Plack-Middleware-Signposting.svg?branch=master)](https://travis-ci.org/LibreCat/Plack-Middleware-Signposting)
83             [![Coverage Status](https://coveralls.io/repos/github/LibreCat/Plack-Middleware-Signposting/badge.svg?branch=master)](https://coveralls.io/github/LibreCat/Plack-Middleware-Signposting?branch=master)
84              
85             =end markdown
86              
87              
88             =head1 SYNOPSIS
89              
90             builder {
91             enable "Plack::Middleware::Signposting::JSON";
92              
93             sub {200, ['Content-Type' => 'text/plain'], ['hello world']};
94             };
95              
96             =head1 DESCRIPTION
97              
98             Plack::Middleware::Signposting::JSON is a base class for Signposting(https://signposting.org) protocol.
99              
100             =head1 AUTHOR
101              
102             Nicolas Steenlant, C<< <nicolas.steenlant at ugent.be> >>
103              
104             Vitali Peil, C<< <vitali.peil at uni-bielefeld.de> >>
105              
106             =head1 COPYRIGHT
107              
108             Copyright 2017 - Vitali Peil
109              
110             =head1 LICENSE
111              
112             This library is free software; you can redistribute it and/or modify
113             it under the same terms as Perl itself.
114              
115             =head1 SEE ALSO
116              
117             =cut