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.98';
4 96     96   3223 use strict;
  96         267  
  96         3042  
5 96     96   736 use warnings;
  96         2096  
  96         2899  
6              
7 96     95   561 use parent qw[ Exporter::Tiny ];
  96         317  
  95         2276  
8              
9 95     93   5624 use Test::More;
  95         256  
  95         837  
10 93     89   26782 use Test::Deep;
  93         9480  
  93         639  
11              
12 93     89   24063 use Moose qw[];
  89         248  
  89         1675  
13 89     89   629 use Moose::Object;
  89         237  
  89         2104  
14 89     89   517 use Moose::Util;
  89         237  
  89         1013  
15 89     89   26347 use XML::LibXML;
  89         241  
  89         1095  
16              
17 89     89   14983 use Net::Amazon::S3;
  89         249  
  89         2168  
18 89     89   569 use Net::Amazon::S3::Bucket;
  89         221  
  89         2126  
19              
20 89     89   1156 use Shared::Examples::Net::Amazon::S3;
  89         243  
  89         748  
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   1416 my ($xml) = @_;
30              
31 208 100       814 return $xml unless $xml;
32 78 50       234 return $xml if ref $xml;
33              
34 78         168 my $canonical = eval {
35 78         558 XML::LibXML->load_xml (
36             string => $xml,
37             no_blanks => 1,
38             )->toStringC14N
39             };
40              
41 78 100       31347 return $xml unless defined $canonical;
42 42         217 return $canonical;
43             }
44              
45             sub _test_meta_build_http_request {
46 206     206   694 my ($self, %params) = @_;
47              
48 206         1105 return $self->_build_signed_request (%params);
49             }
50              
51             sub _test_class {
52 70     70   265 my ($request_class, %params) = @_;
53              
54 70   50     540 $params{superclasses} ||= [];
55 70         353 $params{methods}{_build_http_request} = \& _test_meta_build_http_request;
56              
57 70         179 push @{ $params{superclasses} }, $request_class;
  70         261  
58              
59 70         768 return Moose::Meta::Class->create_anon_class (%params);
60             }
61              
62             sub expect_request_class {
63 67     67 0 834 my ($request_class) = @_;
64              
65 67         207 local $Test::Builder::Level = $Test::Builder::Level + 1;
66              
67 67     24   370 return use_ok $request_class;
  24     10   6270  
  24     9   70  
  24         57  
  24         1051  
  10         2680  
  10         28  
  10         23  
  10         147  
  9         2175  
  9         25  
  9         23  
  9         146  
68             }
69              
70             sub expect_request_instance {
71 70     70 0 2801 my (%params) = @_;
72              
73 70         237 local $Test::Builder::Level = $Test::Builder::Level + 1;
74              
75 70         1077 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     858 host => $params{with_host} || 's3.amazonaws.com',
82             );
83              
84             my $test_class = _test_class $params{request_class},
85             map +( $_ => $params{$_} ),
86 70         527 grep exists $params{$_},
87             qw [ roles ],
88             ;
89              
90 70         524715 my $request = eval { $test_class->name->new (%with) };
  70         3742  
91 70         121933 my $error = $@;
92              
93 70 100       571 if (exists $params{throws}) {
94 6 50       33 if (defined $request) {
95 0         0 fail "create instance should fail";
96             } else {
97 6         53 cmp_deeply $error, $params{throws}, "create instance should fail";
98             }
99             } else {
100 64 50       606 ok defined $request, "should create (mocked) instance of $params{request_class}"
101             or diag $error;
102             }
103              
104 70         52960 return $request;
105             }
106              
107             sub expect_request_uri {
108 54     54 0 183 my ($request, $expected) = @_;
109              
110 54         190 local $Test::Builder::Level = $Test::Builder::Level + 1;
111              
112 54         652 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 207 my ($request, $expected) = @_;
121              
122 58         178 local $Test::Builder::Level = $Test::Builder::Level + 1;
123              
124 58         332 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 179 my ($request, $expected) = @_;
133              
134 54         171 local $Test::Builder::Level = $Test::Builder::Level + 1;
135              
136 54         257 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 208 my ($request, $expected) = @_;
145              
146 40         120 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         219 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 104615 my ($title, %params) = @_;
161              
162 64         234 local $Test::Builder::Level = $Test::Builder::Level + 1;
163              
164             subtest $title => sub {
165 64     64   83128 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         59310 expect_request_class $params{request_class};
173 64         34037 my $request = expect_request_instance %params;
174              
175             expect_request_uri $request => $params{expect_request_uri}
176 64 100       1800 if exists $params{expect_request_uri};
177              
178             expect_request_method $request => $params{expect_request_method}
179 64 100       39492 if exists $params{expect_request_method};
180              
181             expect_request_headers $request => $params{expect_request_headers}
182 64 100       37910 if exists $params{expect_request_headers};
183              
184             expect_request_content $request => $params{expect_request_content}
185 64 100       295114 if exists $params{expect_request_content};
186 64         598 };
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.98
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