File Coverage

inc/WebService/Cmis/Test.pm
Criterion Covered Total %
statement 18 19 94.7
branch 1 2 50.0
condition n/a
subroutine 6 6 100.0
pod n/a
total 25 27 92.5


line stmt bran cond sub pod time code
1             package WebService::Cmis::Test;
2 13     13   73 use base qw(Test::Class);
  13         23  
  13         15285  
3 13     13   494831 use Test::More;
  13         90437  
  13         137  
4              
5 13     13   4077 use constant TEST_FOLDER_PREFIX => "Test_";
  13         27  
  13         771  
6              
7 13     13   67 use strict;
  13         28  
  13         400  
8 13     13   2221 use warnings;
  13         26  
  13         696  
9              
10             BEGIN {
11 13 50   13   26 if (!eval { require "cmis.cfg"; 1 }) {
  13         3054  
  0         0  
12 13         69 plan skip_all => "WARNING: You need to create a cmis.cfg. See the example file in the inc/ directory.";
13             }
14             }
15              
16             binmode(STDERR, ":utf8");
17             binmode(STDOUT, ":utf8");
18              
19             use WebService::Cmis qw(:collections :utils :relations :namespaces :contenttypes);
20             use File::Temp ();
21             use Error qw(:try);
22             use Cache::FileCache ();
23             use XML::LibXML ();
24              
25             my %brokenFeatures = (
26             "Alfresco" => {
27             "numItems" => {
28             version => [4.20],
29             message => "counting results broken in Alfresco 4.2.0 (ALF-19186)",
30             },
31             "paging" => {
32             version => [4.20],
33             message => "paging changes too buggy in Alfresco 4.2.0 (ALF-19173)",
34             },
35             "updateSummary" => {
36             message => "updating summary not available in OpenCMIS Connector",
37             }
38             },
39             );
40              
41             require "cmis.cfg";
42              
43             sub new {
44             my $class = shift;
45             my $connection = shift || $ENV{CMIS_CONNECTION} || $WebService::Cmis{DefaultConnection};
46              
47             my $config = $WebService::Cmis{Connections}{$connection};
48             die "ERROR: unknown connection $connection" unless defined $config;
49              
50             $config->{testRoot} ||= $WebService::Cmis{TestRoot};
51             $config->{testFile} ||= $WebService::Cmis{TestFile};
52             $config->{testXml} ||= $WebService::Cmis{TestXml};
53              
54             my $this = $class->SUPER::new(@_);
55             $this->{config} = $config;
56              
57             note("connection=$connection");
58              
59             return $this;
60             }
61              
62              
63             sub DESTROY {
64             my $this = shift;
65              
66             $this->reset;
67             $this->{client}->logout if $this->{client};
68             $this->{client} = undef;
69             }
70              
71             sub reset {
72             my $this = shift;
73              
74             foreach my $key (keys %{$this->{testFolders}}) {
75             $this->deleteTestFolder($key);
76             }
77              
78             $this->{testXmlDoc} = undef;
79             }
80              
81             sub getClient {
82             my $this = shift;
83              
84             unless (defined $this->{client}) {
85             note("constructing a new client");
86             my $cache;
87             if ($this->{cacheEnabled}) {
88             my $tempDir = File::Temp::tempdir(CLEANUP => 1);
89             note("temporary cache in $tempDir");
90             my $cache = Cache::FileCache->new({
91             cache_root => $tempDir
92             }
93             );
94             }
95              
96             $this->{testRoot} = delete $this->{config}{testRoot};
97             $this->{testFile} = delete $this->{config}{testFile};
98              
99             $this->{client} = WebService::Cmis::getClient(
100             %{$this->{config}},
101             cache => $cache,
102             @_
103             );
104             $this->{client}->login();
105             }
106              
107             return $this->{client};
108             }
109              
110             sub getRepository {
111             return $_[0]->getClient->getRepository;
112             }
113              
114             sub getTestFolderName {
115             my $this = shift;
116             my $key = shift;
117              
118             $key ||= 'default';
119             $this->{testFolderNames} = {} unless defined $this->{testFolderNames};
120              
121             unless (defined $this->{testFolderNames}{$key}) {
122             $this->{testFolderNames}{$key} = TEST_FOLDER_PREFIX.$key."_".time;
123             }
124              
125             return $this->{testFolderNames}{$key};
126             }
127              
128             sub getTestFolderPath {
129             my $this = shift;
130             my $key = shift;
131              
132             my $name = $this->getTestFolderName($key);
133             return $this->{testRoot}."/".$name;
134             }
135              
136             sub deleteTestFolder {
137             my $this = shift;
138             my $key = shift;
139              
140             $key ||= 'default';
141             $this->{testFolders} = {} unless defined $this->{testFolders};
142              
143             note("called deleteTestFolder($key)");
144              
145             if (defined $this->{testFolders}{$key}) {
146             $this->{testFolders}{$key}->deleteTree;
147             }
148              
149             delete $this->{testFolders}{$key};
150             }
151              
152             sub getTestFolder {
153             my $this = shift;
154             my $key = shift;
155              
156             $key ||= 'default';
157             $this->{testFolders} = {} unless defined $this->{testFolders};
158              
159             note("called getTestFolder($key)");
160             unless (defined $this->{testFolders}{$key}) {
161             my $name = $this->getTestFolderName($key);
162             die "testFolder does not start with '".TEST_FOLDER_PREFIX."'" unless $name =~ "^".TEST_FOLDER_PREFIX;
163              
164             my $repo = $this->getRepository;
165             my $folder = $repo->getObjectByPath($this->{testRoot});
166             die "no folder at $this->{testRoot}" unless defined $folder;
167             note("testRoot=".$folder->getPath);
168              
169             note("creating sub-folder '$this->{testRoot}/$name'");
170             $this->{testFolders}{$key} = $folder->createFolder($name, summary=>"this is a test folder used by WebService::Cmis' testsuite");
171              
172             my $id = $this->{testFolders}{$key}->getId;
173             note("test folder id=$id");
174             my $rootFolderId = $repo->getRepositoryInfo->{'rootFolderId'};
175             if ($id eq $rootFolderId) {
176             print STDERR "ERROR: don't use root as test folder\n\n";
177             exit; #emergency
178             }
179              
180             die "failed creating a test folder at $this->{testRoot}/$name"
181             unless defined $this->{testFolders}{$key};
182              
183             my $allowableActions = $folder->getAllowableActions;
184             return unless $allowableActions->{canCreateDocument};
185             return unless $allowableActions->{canCreateFolder};
186             }
187              
188             return $this->{testFolders}{$key};
189             }
190              
191             sub deleteTestDocument {
192             my $this = shift;
193             my $key = shift;
194              
195             $key ||= 'default';
196             $this->{testDocuments} = {} unless defined $this->{testDocuments};
197              
198             note("called deleteTestDocument($key)");
199              
200             try {
201             my $obj = $this->{testDocuments}{$key};
202             if (defined $obj) {
203             note("deleting test document id=".$obj->getId);
204             $obj->delete;
205             delete $this->{testDocuments}{$key};
206             }
207             } catch WebService::Cmis::ClientException with {
208             my $error = shift;
209             note("ERROR in deleteTestDocument: $error ... ignoring");
210             # ignore
211             };
212             }
213              
214             sub getTestDocument {
215             my $this = shift;
216             my $key = shift;
217              
218             $key ||= 'default';
219              
220             note("called getTestDocument($key)");
221             $this->{testDocuments} = {} unless defined $this->{testDocuments};
222              
223             unless (defined $this->{testDocuments}{$key}) {
224              
225             my $folder = $this->getTestFolder($key);
226             die "can't get test folder" unless defined $folder;
227              
228             my $path = $folder->getPath();
229             my $repo = $this->getRepository;
230              
231             my $testFile = $this->{testFile};
232             die "got no {testFile}" unless -e $testFile;
233              
234             my $testFolderPath = $this->getTestFolderPath($key);
235             die "can't get test folder path" unless defined $testFolderPath;
236              
237             die "woops repository created folder at path '$path' but we expected '$testFolderPath'"
238             unless $testFolderPath eq $path;
239              
240             die "invalid test folder '$testFolderPath'. please check the {testRoot} setting"
241             unless $repo->getObjectByPath($testFolderPath);
242              
243             # first delete it if it exists
244             $path = "$testFolderPath/free.jpg";
245             note("path=$path");
246              
247             note("uploading $testFile to $path");
248             my $document = $folder->createDocument(
249             "free.jpg",
250             summary => "this is a file folder used by WebService::Cmis' testsuite",
251             contentFile => $testFile
252             );
253             die "unable to create test document at $path" unless defined $document;
254             note("new document=".$document->toString);
255              
256             $this->{testDocuments}{$key} = $document;
257             }
258              
259             return $this->{testDocuments}{$key};
260             }
261              
262             sub getTestXml {
263             my $this = shift;
264             my $key = shift;
265              
266             unless (defined $this->{testXmlDoc}{$key}) {
267             my $fileName = $this->{config}{testXml}{$key};
268             die "no testXml for '$key'" unless defined $fileName;
269              
270             die "file not found '$fileName'" unless -e $fileName;
271             my $doc = XML::LibXML->load_xml(location=>$fileName);
272             $this->{testXmlDoc}{$key} = $doc->documentElement;
273             }
274              
275             return $this->{testXmlDoc}{$key};
276             }
277              
278             sub diffXml {
279             my ($this, $xml1, $xml2) = @_;
280              
281             unless (defined $this->{differ}) {
282             require XML::SemanticDiff;
283             $this->{differ} = XML::SemanticDiff->new(keeplinenums => 1);
284             }
285              
286             return $this->{differ}->compare($xml1, $xml2);
287             }
288              
289             sub reportXmlDiff {
290             my ($this, $xml1, $xml2, $changes) = @_;
291              
292             $changes = [$this->diffXml($xml1, $xml2)] unless defined $changes;
293              
294             foreach my $change (@$changes) {
295             diag(" $change->{message} (between lines $change->{startline} and $change->{endline})");
296             }
297             }
298              
299             sub testXml {
300             my ($this, $xml1, $xml2, $testName) = @_;
301              
302             my @changes = $this->diffXml($xml1, $xml2);
303             if (@changes) {
304             fail($testName);
305             $this->reportXmlDiff($xml1, $xml2, \@changes);
306             }
307             }
308              
309             sub isBrokenFeature {
310             my ($this, $feature) = @_;
311              
312             #print STDERR "called isBrokenFeature($feature)\n";
313              
314             my $repo = $this->getRepository();
315             my $vendorName = $repo->getRepositoryInfo->{vendorName};
316              
317             my $record = $brokenFeatures{$vendorName}{$feature};
318             unless (defined $record) {
319             note("no feature record found for $vendorName");
320             return;
321             }
322              
323             # test feature
324             return $record->{message} unless defined $record->{version};
325              
326             # test version
327             my $productVersion = $repo->getRepositoryInfo->{productVersion};
328             my $major = 0;
329             my $minor = 0;
330             my $patch = 0;
331             ($major, $minor, $patch) = $productVersion =~ /(\d+)\.(\d+)\.(\d+)/;
332             $productVersion = $major + $minor / 10 + $patch / 100;
333              
334             if (ref($record->{version})) {
335             foreach my $v (@{$record->{version}}) {
336             return $productVersion == $v?$record->{message}:"";
337             }
338             } else {
339             return $record->{message} if $productVersion <= $record->{version};
340             }
341             }
342              
343             1;