File Coverage

blib/lib/Shared/Examples/Net/Amazon/S3/Request.pm
Criterion Covered Total %
statement 101 102 99.0
branch 17 20 85.0
condition 2 4 50.0
subroutine 26 26 100.0
pod 0 7 0.0
total 146 159 91.8


line stmt bran cond sub pod time code
1             package Shared::Examples::Net::Amazon::S3::Request;
2             # ABSTRACT: used for testing and as example
3             $Shared::Examples::Net::Amazon::S3::Request::VERSION = '0.99';
4 97     97   3048 use strict;
  97         303  
  97         3045  
5 97     97   758 use warnings;
  97         2064  
  97         2881  
6              
7 97     96   620 use parent qw[ Exporter::Tiny ];
  97         368  
  96         2309  
8              
9 96     94   6169 use Test::More;
  96         270  
  96         837  
10 94     90   26387 use Test::Deep;
  94         9149  
  94         652  
11              
12 94     90   24205 use Moose qw[];
  90         252  
  90         1743  
13 90     90   537 use Moose::Object;
  90         240  
  90         2401  
14 90     90   575 use Moose::Util;
  90         239  
  90         1038  
15 90     90   25022 use XML::LibXML;
  90         266  
  90         1091  
16              
17 90     90   15751 use Net::Amazon::S3;
  90         279  
  90         2375  
18 90     90   649 use Net::Amazon::S3::Bucket;
  90         246  
  90         2663  
19              
20 90     90   1305 use Shared::Examples::Net::Amazon::S3;
  90         289  
  90         757  
21              
22             our @EXPORT_OK = (
23             qw[ behaves_like_net_amazon_s3_request ],
24             qw[ expect_request_class ],
25             qw[ expect_request_instance ],
26             );
27              
28             sub _canonical_xml {
29 208     208   1457 my ($xml) = @_;
30              
31 208 100       767 return $xml unless $xml;
32 78 50       253 return $xml if ref $xml;
33              
34 78         158 my $canonical = eval {
35 78         655 XML::LibXML->load_xml (
36             string => $xml,
37             no_blanks => 1,
38             )->toStringC14N
39             };
40              
41 78 100       33300 return $xml unless defined $canonical;
42 42         197 return $canonical;
43             }
44              
45             sub _test_meta_build_http_request {
46 206     206   581 my ($self, %params) = @_;
47              
48 206         996 return $self->_build_signed_request (%params);
49             }
50              
51             sub _test_class {
52 70     70   253 my ($request_class, %params) = @_;
53              
54 70   50     466 $params{superclasses} ||= [];
55 70         358 $params{methods}{_build_http_request} = \& _test_meta_build_http_request;
56              
57 70         200 push @{ $params{superclasses} }, $request_class;
  70         236  
58              
59 70         674 return Moose::Meta::Class->create_anon_class (%params);
60             }
61              
62             sub expect_request_class {
63 67     67 0 929 my ($request_class) = @_;
64              
65 67         210 local $Test::Builder::Level = $Test::Builder::Level + 1;
66              
67 67     24   329 return use_ok $request_class;
  24     10   5001  
  24     9   69  
  24         56  
  24         980  
  10         2488  
  10         29  
  10         22  
  10         141  
  9         2153  
  9         27  
  9         21  
  9         151  
68             }
69              
70             sub expect_request_instance {
71 70     70 0 2330 my (%params) = @_;
72              
73 70         235 local $Test::Builder::Level = $Test::Builder::Level + 1;
74              
75 70         1032 my %with = map +( substr ($_, 5) => delete $params{$_} ),
76             grep m/^with_/,
77             keys %params
78             ;
79              
80             $with{s3} = Shared::Examples::Net::Amazon::S3::s3_api_with_signature_2 (
81 70   50     793 host => $params{with_host} || 's3.amazonaws.com',
82             );
83              
84             my $test_class = _test_class $params{request_class},
85             map +( $_ => $params{$_} ),
86 70         446 grep exists $params{$_},
87             qw [ roles ],
88             ;
89              
90 70         508405 my $request = eval { $test_class->name->new (%with) };
  70         3600  
91 70         116592 my $error = $@;
92              
93 70 100       580 if (exists $params{throws}) {
94 6 50       25 if (defined $request) {
95 0         0 fail "create instance should fail";
96             } else {
97 6         32 cmp_deeply $error, $params{throws}, "create instance should fail";
98             }
99             } else {
100 64 50       530 ok defined $request, "should create (mocked) instance of $params{request_class}"
101             or diag $error;
102             }
103              
104 70         45558 return $request;
105             }
106              
107             sub expect_request_uri {
108 54     54 0 161 my ($request, $expected) = @_;
109              
110 54         160 local $Test::Builder::Level = $Test::Builder::Level + 1;
111              
112 54         569 return cmp_deeply
113             $request->http_request->request_uri,
114             $expected,
115             "it builds expected request uri"
116             ;
117             }
118              
119             sub expect_request_method {
120 58     58 0 215 my ($request, $expected) = @_;
121              
122 58         167 local $Test::Builder::Level = $Test::Builder::Level + 1;
123              
124 58         330 return cmp_deeply
125             $request->http_request->method,
126             $expected,
127             "it builds expected request method"
128             ;
129             }
130              
131             sub expect_request_headers {
132 54     54 0 224 my ($request, $expected) = @_;
133              
134 54         141 local $Test::Builder::Level = $Test::Builder::Level + 1;
135              
136 54         231 return cmp_deeply
137             $request->http_request->headers,
138             $expected,
139             "it builds expected request headers"
140             ;
141             }
142              
143             sub expect_request_content {
144 40     40 0 153 my ($request, $expected) = @_;
145              
146 40         124 local $Test::Builder::Level = $Test::Builder::Level + 1;
147              
148             # XML builders doesn't need to produce whitespaces for readability
149             # wherease test expectation should be as readable as possible
150             # compare canonicalized xml strings than
151              
152 40         187 return is
153             _canonical_xml ($request->http_request->content),
154             _canonical_xml ($expected),
155             "it builds expected request XML content"
156             ;
157             }
158              
159             sub behaves_like_net_amazon_s3_request {
160 64     64 0 105880 my ($title, %params) = @_;
161              
162 64         221 local $Test::Builder::Level = $Test::Builder::Level + 1;
163              
164             subtest $title => sub {
165 64     64   83709 plan tests => 2 + scalar grep exists $params{$_},
166             qw[ expect_request_uri ],
167             qw[ expect_request_method ],
168             qw[ expect_request_headers ],
169             qw[ expect_request_content ],
170             ;
171              
172 64         59526 expect_request_class $params{request_class};
173 64         34228 my $request = expect_request_instance %params;
174              
175             expect_request_uri $request => $params{expect_request_uri}
176 64 100       1814 if exists $params{expect_request_uri};
177              
178             expect_request_method $request => $params{expect_request_method}
179 64 100       37866 if exists $params{expect_request_method};
180              
181             expect_request_headers $request => $params{expect_request_headers}
182 64 100       35880 if exists $params{expect_request_headers};
183              
184             expect_request_content $request => $params{expect_request_content}
185 64 100       281409 if exists $params{expect_request_content};
186 64         546 };
187             }
188              
189             1;
190              
191             __END__
192              
193             =pod
194              
195             =encoding UTF-8
196              
197             =head1 NAME
198              
199             Shared::Examples::Net::Amazon::S3::Request - used for testing and as example
200              
201             =head1 VERSION
202              
203             version 0.99
204              
205             =head1 AUTHOR
206              
207             Branislav Zahradník <barney@cpan.org>
208              
209             =head1 COPYRIGHT AND LICENSE
210              
211             This software is copyright (c) 2021 by Amazon Digital Services, Leon Brocard, Brad Fitzpatrick, Pedro Figueiredo, Rusty Conover, Branislav Zahradník.
212              
213             This is free software; you can redistribute it and/or modify it under
214             the same terms as the Perl 5 programming language system itself.
215              
216             =cut