File Coverage

blib/lib/Web/Solid/Test/Basic.pm
Criterion Covered Total %
statement 38 104 36.5
branch 0 4 0.0
condition n/a
subroutine 13 20 65.0
pod 4 5 80.0
total 55 133 41.3


line stmt bran cond sub pod time code
1             package Web::Solid::Test::Basic;
2              
3 1     1   682 use 5.010001;
  1         2  
4 1     1   4 use strict;
  1         2  
  1         16  
5 1     1   4 use warnings;
  1         1  
  1         21  
6 1     1   375 use parent 'Test::FITesque::Fixture';
  1         252  
  1         5  
7 1     1   2037 use Test::More ;
  1         1  
  1         7  
8 1     1   1181 use LWP::UserAgent;
  1         40305  
  1         28  
9 1     1   862 use Test::Deep;
  1         8601  
  1         8  
10 1     1   719 use Test::RDF;
  1         1200954  
  1         13  
11              
12             our $AUTHORITY = 'cpan:KJETILK';
13             our $VERSION = '0.010';
14              
15             sub http_read_unauthenticated : Test : Plan(4) {
16 0     0 1 0 my ($self, $args) = @_;
17 0         0 my $ua = LWP::UserAgent->new;
18 0         0 my $url = $args->{url};
19 0         0 my $reshead = $ua->head( $url );
20 0         0 note($args->{description});
21 0         0 ok($reshead->is_success, "Successful HEAD request for $url");
22              
23 0         0 my $resget = $ua->get( $url );
24 0         0 ok($resget->is_success, "Successful GET request for $url");
25              
26 0         0 my @head_headers_fields = $reshead->headers->header_field_names;
27 0         0 my @get_headers_fields = $resget->headers->header_field_names;
28 0         0 cmp_bag(\@head_headers_fields, \@get_headers_fields, "HEAD and GET request has the same header fields");
29              
30 0         0 @get_headers_fields = grep { !/Date/ } @get_headers_fields; # Do not test date-fields since they may change between HEAD and GET
  0         0  
31 0         0 @get_headers_fields = grep { !/^Client/ } @get_headers_fields; # Do not test client-side added fields
  0         0  
32              
33             subtest 'Testing all headers' => sub {
34 0     0   0 plan tests => scalar @get_headers_fields;
35 0         0 foreach my $get_header_field (@get_headers_fields) {
36 0         0 is($resget->header($get_header_field), $reshead->header($get_header_field), "$get_header_field is the same for both");
37             }
38 0         0 };
39              
40 1     1   426 }
  1         23  
  1         8  
41              
42              
43             sub http_check_header_unauthenticated : Test : Plan(2) {
44 0     0 0 0 my ($self, $args) = @_;
45 0         0 my $ua = LWP::UserAgent->new;
46 0         0 my $url = $args->{url};
47 0         0 note($args->{description});
48 0         0 delete $args->{url};
49 0         0 delete $args->{description};
50 0         0 my $reshead = $ua->head( $url );
51 0         0 ok($reshead->is_success, "Successful HEAD request for $url");
52             subtest 'Testing HTTP header content' => sub {
53 0     0   0 plan tests => scalar keys(%{$args});
  0         0  
54 0         0 while (my ($predicate, $value) = each(%{$args})) {
  0         0  
55 0         0 my ($key) = $predicate =~ m/\#(.*)$/; # TODO: Use URI::NamespaceMap for this
56 0         0 $key =~ s/_/-/g; # Some heuristics for creating HTTP headers
57 0         0 $key =~ s/\b(\w)/\u$1/g;
58 0         0 is($reshead->header($key), $value, "$key has correct value");
59             }
60             }
61 1     1   546 }
  1         2  
  1         4  
  0         0  
62              
63              
64             sub http_put_readback_unauthenticated : Test : Plan(4) {
65 0     0 1 0 my ($self, $args) = @_;
66 0         0 my $ua = LWP::UserAgent->new;
67 0         0 my $url = $args->{url};
68 0         0 my $content = '<https://example.org/foo> a <https://example.org/Dahut> .';
69 0         0 my $resput = $ua->put( $url, Content => $content );
70 0         0 note($args->{description});
71 0         0 ok($resput->is_success, "Successful PUT request for $url");
72 0         0 my $resget = $ua->get( $url );
73 0         0 ok($resget->is_success, "Successful GET request for $url");
74 0         0 my $rescontent = $resget->content;
75 0         0 is_valid_rdf($rescontent, "Returned content is valid RDF");
76 0         0 is_rdf($rescontent, $content, "Same content returned");
77 1     1   295 }
  1         2  
  1         4  
78              
79              
80             sub http_write_with_bearer : Test : Plan(1) {
81 0     0 1 0 my ($self, $args) = @_;
82             SKIP: {
83 0 0       0 skip 'SOLID_BEARER_TOKEN needs to set for this test', 1 unless ($ENV{SOLID_BEARER_TOKEN});
  0         0  
84 0         0 my $ua = LWP::UserAgent->new;
85             $ua->default_header('Authorization' => 'Bearer ' . $ENV{SOLID_BEARER_TOKEN},
86 0         0 'Content-Type' => 'text/turtle'
87             );
88 0         0 my $url = $args->{url};
89 0         0 my $res = $ua->put( $url, Content => '<https://example.org/foo> a <https://example.org/Dahut> .' );
90 0         0 ok($res->is_success, "Successful PUT request for $url");
91             }
92 1     1   265 };
  1         2  
  1         5  
93              
94              
95             sub http_methods_with_bearer : Test : Plan(1) {
96 0     0 1   my ($self, $args) = @_;
97             SKIP: {
98 0 0         skip 'SOLID_BEARER_TOKEN needs to set for this test', 1 unless ($ENV{SOLID_BEARER_TOKEN});
  0            
99 0           note($args->{description});
100 0           my $ua = LWP::UserAgent->new;
101             $ua->default_header('Authorization' => 'Bearer ' . $ENV{SOLID_BEARER_TOKEN},
102 0           'Content-Type' => 'text/turtle',
103             'Accept' => 'text/turtle',
104             );
105 0           my $url = $args->{url};
106 0           my $method = $args->{method};
107 0           my $res = $ua->request( HTTP::Request->new($method => $url), Content => $args->{body} );
108 0           is($res->code, $args->{code}, "Using $method for request for $url");
109             }
110 1     1   328 };
  1         2  
  1         4  
111              
112              
113              
114              
115              
116             1;
117              
118             __END__
119              
120             =pod
121              
122             =encoding utf-8
123              
124             =head1 NAME
125              
126             Web::Solid::Test::Basic - Basic Solid Tests
127              
128             =head1 SYNOPSIS
129              
130             use Test::FITesque::RDF;
131             my $suite = Test::FITesque::RDF->new(source => $file, base_uri => $ENV{SOLID_REMOTE_BASE})->suite;
132             $suite->run_tests;
133             done_testing;
134              
135             See C<tests/basic.t> for a full example.
136              
137             =head1 DESCRIPTION
138              
139             =head2 Introduction
140              
141             The basic idea with these tests is to simplify reuse and formulation
142             of fixture tables using the Resource Description Framework (RDF). It
143             is in a very early stage, but there are running tests in this module.
144              
145             This system is built on L<Test::FITesque::RDF>, which adds RDF fixture
146             tables to L<Test::FITesque>.
147              
148             Then, the idea is that modules such as this will provide a reusable
149             implementation of certain tests, and that they can be adapted to
150             concrete test scenarios by either passing parameters from the RDF
151             tables (for both input variables and expected outcomes), or using
152             environment variables.
153              
154             To run the actual tests, test scripts will be made, but they should be
155             terse as their only mission is to initialize the test framework, see
156             the synopsis for an example of such a script. The script can then be
157             invoked by e.g. CI systems or used in development.
158              
159             The RDF fixture tables and the small wrapper scripts can exist
160             independently of the module, and modules can be installed easily so
161             that they can be reused. Nevertheless, it is also natural to package
162             these together, like it has been done in this package.
163              
164             Each module like this one will need to document the tests it
165             implements, consider the below an example of how this should be done.
166              
167              
168              
169             =head1 IMPLEMENTED TESTS
170              
171             =head2 Test scripts
172              
173             This package provides C<tests/basic.t> which runs tests over the
174             fixture table in C<tests/data/basic.ttl>. The test script requires the
175             environment variable C<SOLID_REMOTE_BASE> to be set to the base URL
176             that any relative URLs in the fixture tables will be resolved
177             against. Thus, the fixture tables themselves are independent of the
178             host that will run them.
179              
180             To run the test script in the clone of this package, invoke it like this:
181              
182             SOLID_REMOTE_BASE="https://kjetiltest4.dev.inrupt.net/" prove -l tests/basic.t
183              
184              
185              
186              
187             =head2 C<< http_read_unauthenticated >>
188              
189             Some basic tests for HTTP reads.
190              
191             =head3 Parameters
192              
193             =over
194              
195             =item * C<url>
196              
197             The URL to request.
198              
199             =back
200              
201             =head3 Environment
202              
203             None
204              
205             =head3 Implements
206              
207             =over
208              
209             =item 1. That an HTTP HEAD request to the given URL succeeds.
210              
211             =item 2. That an HTTP GET request to the given URL succeeds.
212              
213             =item 3. That the HEAD and GET requests had the same header fields.
214              
215             =item 4. That the values of the header fields are the same.
216              
217             =back
218              
219             =head2 C<< http_put_readback_unauthenticated >>
220              
221             First writes some content with a PUT request, then reads it back with a GET and checks RDF validity.
222              
223             =head3 Parameters
224              
225             =over
226              
227             =item * C<url>
228              
229             The URL to request.
230              
231             =back
232              
233             =head3 Environment
234              
235             None
236              
237             =head3 Implements
238              
239             =over
240              
241             =item 1. That an HTTP PUT with content request to the given URL succeeds.
242              
243             =item 2. That an HTTP GET request to the given URL succeeds.
244              
245             =item 3. That the content is valid RDF.
246              
247             =item 4. That the triples in the written and read RDF is the same.
248              
249             =back
250              
251              
252             =head2 C<< http_write_with_bearer >>
253              
254             Test for successful HTTP PUT authenticated with a Bearer token
255              
256             =head3 Parameters
257              
258             =over
259              
260             =item * C<url>
261              
262             The URL to request.
263              
264             =back
265              
266             =head3 Environment
267              
268             Set C<SOLID_BEARER_TOKEN> to the bearer token to be used in the authorization header.
269              
270             =head3 Implements
271              
272             =over
273              
274             =item 1. That an HTTP PUT request to the given URL with a short Turtle payload succeeds.
275              
276             =back
277              
278              
279             =head2 C<< http_methods_with_bearer >>
280              
281             Tests for whether a certain HTTP request, authenticated with a Bearer token, returns a certain status code.
282              
283             =head3 Parameters
284              
285             =over
286              
287             =item * C<url>
288              
289             The URL to request.
290              
291             =item * C<method>
292              
293             The HTTP method to use in the request.
294              
295             =item * C<body>
296              
297             The body of the request (optional).
298              
299             =item * C<code>
300              
301             The expected status code to tests for.
302              
303             =back
304              
305             =head3 Environment
306              
307             Set C<SOLID_BEARER_TOKEN> to the bearer token to be used in the authorization header.
308              
309             =head3 Implements
310              
311             =over
312              
313             =item 1. That an HTTP request with the given method and body to the
314             given URL with an payload returns the given status code.
315              
316             =back
317              
318              
319              
320              
321              
322             =head1 NOTE
323              
324             The parameters above are in the RDF formulated as actual full URIs,
325             but where the local part is used here and resolved by the
326             L<Test::FITesque::RDF> framework, see its documentation for details.
327              
328             =head1 TODO
329              
330             The namespaces used in the current fixture tables are examples, and
331             will be changed before an 1.0 release of the system.
332              
333              
334             =head1 BUGS
335              
336             Please report any bugs to
337             L<https://github.com/kjetilk/p5-web-solid-test-basic/issues>.
338              
339             =head1 SEE ALSO
340              
341             =head1 AUTHOR
342              
343             Kjetil Kjernsmo E<lt>kjetilk@cpan.orgE<gt>.
344              
345             =head1 COPYRIGHT AND LICENCE
346              
347             This software is Copyright (c) 2019 by Inrupt Inc.
348              
349             This is free software, licensed under:
350              
351             The MIT (X11) License
352              
353              
354             =head1 DISCLAIMER OF WARRANTIES
355              
356             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
357             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
358             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
359