Bug 32030: (QA follow-up) Enable BasicAuth for ERM tests
[koha-ffzg.git] / t / db_dependent / api / v1 / erm_eholdings_titles.t
1 #!/usr/bin/env perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use Test::More tests => 5;
21 use Test::Mojo;
22
23 use t::lib::TestBuilder;
24 use t::lib::Mocks;
25
26 use Koha::ERM::EHoldings::Titles;
27 use Koha::ERM::EHoldings::Packages;
28 use Koha::Virtualshelves;
29 use Koha::Database;
30
31 my $schema  = Koha::Database->new->schema;
32 my $builder = t::lib::TestBuilder->new;
33
34 my $t = Test::Mojo->new('Koha::REST::V1');
35 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
36
37 subtest 'list() tests' => sub {
38
39     plan tests => 23;
40
41     $schema->storage->txn_begin;
42
43     Koha::ERM::EHoldings::Titles->search->delete;
44
45     my $librarian = $builder->build_object(
46         {
47             class => 'Koha::Patrons',
48             value => { flags => 2**28 }
49         }
50     );
51     my $password = 'thePassword123';
52     $librarian->set_password( { password => $password, skip_validation => 1 } );
53     my $userid = $librarian->userid;
54
55     my $patron = $builder->build_object(
56         {
57             class => 'Koha::Patrons',
58             value => { flags => 0 }
59         }
60     );
61
62     $patron->set_password( { password => $password, skip_validation => 1 } );
63     my $unauth_userid = $patron->userid;
64
65     ## Authorized user tests
66     # No EHoldings title, so empty array should be returned
67     $t->get_ok("//$userid:$password@/api/v1/erm/eholdings/local/titles")
68       ->status_is(200)->json_is( [] );
69
70     my $ehtitle =
71       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } );
72
73     # One EHoldings title created, should get returned
74     $t->get_ok("//$userid:$password@/api/v1/erm/eholdings/local/titles")
75       ->status_is(200)->json_is( [ $ehtitle->to_api ] );
76
77     my $another_ehtitle = $builder->build_object(
78         {
79             class => 'Koha::ERM::EHoldings::Titles',
80             value => { publication_type => $ehtitle->publication_type }
81         }
82     );
83     my $ehtitle_with_another_publication_type =
84       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } );
85
86     # Two EHoldings titles created, they should both be returned
87     $t->get_ok("//$userid:$password@/api/v1/erm/eholdings/local/titles")
88       ->status_is(200)->json_is(
89         [
90             $ehtitle->to_api,
91             $another_ehtitle->to_api,
92             $ehtitle_with_another_publication_type->to_api
93         ]
94       );
95
96     # Filtering works, two EHoldings titles sharing publication_type
97     $t->get_ok(
98 "//$userid:$password@/api/v1/erm/eholdings/local/titles?publication_type="
99           . $ehtitle->publication_type )->status_is(200)
100       ->json_is( [ $ehtitle->to_api, $another_ehtitle->to_api ] );
101
102     # Attempt to search by publication_title like 'ko'
103     $ehtitle->delete;
104     $another_ehtitle->delete;
105     $ehtitle_with_another_publication_type->delete;
106     $t->get_ok(qq~//$userid:$password@/api/v1/erm/eholdings/local/titles?q=[{"me.publication_title":{"like":"%ko%"}}]~)
107       ->status_is(200)->json_is( [] );
108
109     my $ehtitle_to_search = $builder->build_object(
110         {
111             class => 'Koha::ERM::EHoldings::Titles',
112             value => {
113                 publication_title => 'koha',
114             }
115         }
116     );
117
118     # Search works, searching for publication_title like 'ko'
119     $t->get_ok(qq~//$userid:$password@/api/v1/erm/eholdings/local/titles?q=[{"me.publication_title":{"like":"%ko%"}}]~)
120       ->status_is(200)->json_is( [ $ehtitle_to_search->to_api ] );
121
122     # Warn on unsupported query parameter
123     $t->get_ok(
124         "//$userid:$password@/api/v1/erm/eholdings/local/titles?blah=blah")
125       ->status_is(400)
126       ->json_is(
127         [ { path => '/query/blah', message => 'Malformed query string' } ] );
128
129     # Unauthorized access
130     $t->get_ok("//$unauth_userid:$password@/api/v1/erm/eholdings/local/titles")
131       ->status_is(403);
132
133     $schema->storage->txn_rollback;
134 };
135
136 subtest 'get() tests' => sub {
137
138     plan tests => 11;
139
140     $schema->storage->txn_begin;
141
142     my $ehtitle =
143       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } );
144     my $librarian = $builder->build_object(
145         {
146             class => 'Koha::Patrons',
147             value => { flags => 2**28 }
148         }
149     );
150     my $password = 'thePassword123';
151     $librarian->set_password( { password => $password, skip_validation => 1 } );
152     my $userid = $librarian->userid;
153
154     my $patron = $builder->build_object(
155         {
156             class => 'Koha::Patrons',
157             value => { flags => 0 }
158         }
159     );
160
161     $patron->set_password( { password => $password, skip_validation => 1 } );
162     my $unauth_userid = $patron->userid;
163
164     # This EHoldings title exists, should get returned
165     $t->get_ok( "//$userid:$password@/api/v1/erm/eholdings/local/titles/"
166           . $ehtitle->title_id )->status_is(200)->json_is( $ehtitle->to_api );
167
168     # Return one EHoldings title with embed
169     $t->get_ok( "//$userid:$password@/api/v1/erm/eholdings/local/titles/"
170           . $ehtitle->title_id =>
171           { 'x-koha-embed' => 'resources,resources.package' } )->status_is(200)
172       ->json_is( { %{ $ehtitle->to_api }, resources => [] } );
173
174     # Unauthorized access
175     $t->get_ok( "//$unauth_userid:$password@/api/v1/erm/eholdings/local/titles/"
176           . $ehtitle->title_id )->status_is(403);
177
178     # Attempt to get non-existent EHoldings title
179     my $ehtitle_to_delete =
180       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } );
181     my $non_existent_id = $ehtitle_to_delete->title_id;
182     $ehtitle_to_delete->delete;
183
184     $t->get_ok(
185 "//$userid:$password@/api/v1/erm/eholdings/local/titles/$non_existent_id"
186     )->status_is(404)->json_is( '/error' => 'eHolding title not found' );
187
188     $schema->storage->txn_rollback;
189 };
190
191 subtest 'add() tests' => sub {
192
193     plan tests => 24;
194
195     $schema->storage->txn_begin;
196
197     my $librarian = $builder->build_object(
198         {
199             class => 'Koha::Patrons',
200             value => { flags => 2**28 }
201         }
202     );
203     my $password = 'thePassword123';
204     $librarian->set_password( { password => $password, skip_validation => 1 } );
205     my $userid = $librarian->userid;
206
207     my $patron = $builder->build_object(
208         {
209             class => 'Koha::Patrons',
210             value => { flags => 0 }
211         }
212     );
213
214     $patron->set_password( { password => $password, skip_validation => 1 } );
215     my $unauth_userid = $patron->userid;
216
217     my $ehtitle = {
218         publication_title => "Publication title",
219         print_identifier  => "Print-format identifier",
220         online_identifier => "Online-format identifier",
221         date_first_issue_online =>
222           "Date of first serial issue available online",
223         num_first_vol_online   => "Number of first volume available online",
224         num_first_issue_online => "Number of first issue available online",
225         date_last_issue_online => "Date of last issue available online",
226         num_last_vol_online    => "Number of last volume available online",
227         num_last_issue_online  => "Number of last issue available online",
228         title_url              => "Title-level URL",
229         first_author           => "First author",
230         embargo_info           => "Embargo information",
231         coverage_depth         => "Coverage depth",
232         notes                  => "Notes",
233         publisher_name         => "Publisher name",
234         publication_type       => "Book",
235         date_monograph_published_print =>
236           "Date the monograph is first published in print",
237         date_monograph_published_online =>
238           "Date the monograph is first published online",
239         monograph_volume  => "Number of volume for monograph",
240         monograph_edition => "Edition of the monograph",
241         first_editor      => "First editor",
242         parent_publication_title_id =>
243           "Title identifier of the parent publication",
244         preceeding_publication_title_id =>
245           "Title identifier of any preceding publication title",
246         access_type => "Access type"
247     };
248
249     # Unauthorized attempt to write
250     $t->post_ok(
251         "//$unauth_userid:$password@/api/v1/erm/eholdings/local/titles" =>
252           json => $ehtitle )->status_is(403);
253
254     # Authorized attempt to write invalid data
255     my $ehtitle_with_invalid_field = {
256         blah              => "EHolding Title Blah",
257         publication_title => "Publication title",
258         print_identifier  => "Print-format identifier"
259     };
260
261     $t->post_ok(
262         "//$userid:$password@/api/v1/erm/eholdings/local/titles" => json =>
263           $ehtitle_with_invalid_field )->status_is(400)->json_is(
264         "/errors" => [
265             {
266                 message => "Properties not allowed: blah.",
267                 path    => "/body"
268             }
269         ]
270           );
271
272     # Authorized attempt to write
273     my $ehtitle_id =
274       $t->post_ok(
275         "//$userid:$password@/api/v1/erm/eholdings/local/titles" => json =>
276           $ehtitle )->status_is( 201, 'SWAGGER3.2.1' )->header_like(
277         Location => qr|^/api/v1/erm/eholdings/local/titles/\d*|,
278         'SWAGGER3.4.1'
279     )->json_is( '/publication_title' => $ehtitle->{publication_title} )
280       ->json_is( '/print_identifier' => $ehtitle->{print_identifier} )
281       ->json_is( '/notes'            => $ehtitle->{notes} )
282       ->json_is( '/publisher_name'   => $ehtitle->{publisher_name} )
283       ->tx->res->json->{title_id};
284
285     # Import titles from virtualshelf to package
286     my $ehpackage_id =
287       $builder->build_object( { class => 'Koha::ERM::EHoldings::Packages' } )
288       ->package_id;
289
290     my $virtual_shelf =
291       $builder->build_object(
292         {
293           class => 'Koha::Virtualshelves',
294       } );
295     $virtual_shelf->transfer_ownership($librarian->borrowernumber);
296      my $virtual_shelf_id = $virtual_shelf->shelfnumber;
297
298     my $import_request =
299     {
300         list_id  => $virtual_shelf_id,
301         package_id => $ehpackage_id
302     };
303
304     $t->post_ok(
305     "//$userid:$password@/api/v1/erm/eholdings/local/titles/import" => json =>
306       $import_request )->status_is(201)->json_has('/job_id');
307
308     # Attempt to import titles from a virtualshelf that doesn't exist
309     $virtual_shelf->delete;
310     $t->post_ok(
311     "//$userid:$password@/api/v1/erm/eholdings/local/titles/import" => json =>
312       $import_request )->status_is(404)->json_is(
313         { error => 'List not found' }
314       );
315
316     # Authorized attempt to create with null id
317     $ehtitle->{title_id} = undef;
318     $t->post_ok(
319         "//$userid:$password@/api/v1/erm/eholdings/local/titles" => json =>
320           $ehtitle )->status_is(400)->json_has('/errors');
321
322     # Authorized attempt to create with existing id
323     $ehtitle->{title_id} = $ehtitle_id;
324     $t->post_ok(
325         "//$userid:$password@/api/v1/erm/eholdings/local/titles" => json =>
326           $ehtitle )->status_is(400)->json_is(
327         "/errors" => [
328             {
329                 message => "Read-only.",
330                 path    => "/body/title_id"
331             }
332         ]
333           );
334
335     $schema->storage->txn_rollback;
336 };
337
338 subtest 'update() tests' => sub {
339
340     plan tests => 15;
341
342     $schema->storage->txn_begin;
343
344     my $librarian = $builder->build_object(
345         {
346             class => 'Koha::Patrons',
347             value => { flags => 2**28 }
348         }
349     );
350     my $password = 'thePassword123';
351     $librarian->set_password( { password => $password, skip_validation => 1 } );
352     my $userid = $librarian->userid;
353
354     my $patron = $builder->build_object(
355         {
356             class => 'Koha::Patrons',
357             value => { flags => 0 }
358         }
359     );
360
361     $patron->set_password( { password => $password, skip_validation => 1 } );
362     my $unauth_userid = $patron->userid;
363
364     my $ehtitle_id =
365       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } )
366       ->title_id;
367
368     # Unauthorized attempt to update
369     $t->put_ok(
370 "//$unauth_userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id"
371           => json =>
372           { publication_title => 'New unauthorized publication_title change' } )
373       ->status_is(403);
374
375     # Attempt partial update on a PUT
376     my $ehtitle_with_missing_field = { date_first_issue_online =>
377           "Date of first serial issue available online", };
378
379     $t->put_ok(
380         "//$userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id" =>
381           json => $ehtitle_with_missing_field )->status_is(400)->json_is(
382         "/errors" => [
383             {
384                 message => "Missing property.",
385                 path    => "/body/publication_title"
386             }
387         ]
388           );
389
390     # Full object update on PUT
391     my $ehtitle_with_updated_field = {
392         publication_title => "Publication title",
393         print_identifier  => "Print-format identifier",
394         online_identifier => "Online-format identifier",
395         date_first_issue_online =>
396           "Date of first serial issue available online",
397         num_first_vol_online   => "Number of first volume available online",
398         num_first_issue_online => "Number of first issue available online",
399         date_last_issue_online => "Date of last issue available online",
400         num_last_vol_online    => "Number of last volume available online",
401         num_last_issue_online  => "Number of last issue available online",
402         title_url              => "Title-level URL",
403         first_author           => "First author",
404         embargo_info           => "Embargo information",
405         coverage_depth         => "Coverage depth",
406         notes                  => "Notes",
407         publisher_name         => "Publisher name",
408         publication_type       => "Book",
409         date_monograph_published_print =>
410           "Date the monograph is first published in print",
411         date_monograph_published_online =>
412           "Date the monograph is first published online",
413         monograph_volume  => "Number of volume for monograph",
414         monograph_edition => "Edition of the monograph",
415         first_editor      => "First editor",
416         parent_publication_title_id =>
417           "Title identifier of the parent publication",
418         preceeding_publication_title_id =>
419           "Title identifier of any preceding publication title",
420         access_type => "Access type"
421     };
422
423     $t->put_ok(
424         "//$userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id" =>
425           json => $ehtitle_with_updated_field )->status_is(200)
426       ->json_is( '/publication_title' => 'Publication title' );
427
428     # Authorized attempt to write invalid data
429     my $ehtitle_with_invalid_field = {
430         blah              => "EHolding Title Blah",
431         publication_title => "Publication title",
432         print_identifier  => "Print-format identifier"
433     };
434
435     $t->put_ok(
436         "//$userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id" =>
437           json => $ehtitle_with_invalid_field )->status_is(400)->json_is(
438         "/errors" => [
439             {
440                 message => "Properties not allowed: blah.",
441                 path    => "/body"
442             }
443         ]
444           );
445
446     # Attempt to update non-existent EHolding title
447     my $ehtitle_to_delete =
448       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } );
449     my $non_existent_id = $ehtitle_to_delete->title_id;
450     $ehtitle_to_delete->delete;
451
452     $t->put_ok(
453 "//$userid:$password@/api/v1/erm/eholdings/local/titles/$non_existent_id"
454           => json => $ehtitle_with_updated_field )->status_is(404);
455
456     # Wrong method (POST)
457     $ehtitle_with_updated_field->{title_id} = 2;
458
459     $t->post_ok(
460         "//$userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id" =>
461           json => $ehtitle_with_updated_field )->status_is(404);
462
463     $schema->storage->txn_rollback;
464 };
465
466 subtest 'delete() tests' => sub {
467
468     plan tests => 7;
469
470     $schema->storage->txn_begin;
471
472     my $librarian = $builder->build_object(
473         {
474             class => 'Koha::Patrons',
475             value => { flags => 2**28 }
476         }
477     );
478     my $password = 'thePassword123';
479     $librarian->set_password( { password => $password, skip_validation => 1 } );
480     my $userid = $librarian->userid;
481
482     my $patron = $builder->build_object(
483         {
484             class => 'Koha::Patrons',
485             value => { flags => 0 }
486         }
487     );
488
489     $patron->set_password( { password => $password, skip_validation => 1 } );
490     my $unauth_userid = $patron->userid;
491
492     my $ehtitle_id =
493       $builder->build_object( { class => 'Koha::ERM::EHoldings::Titles' } )
494       ->title_id;
495
496     # Unauthorized attempt to delete
497     $t->delete_ok(
498 "//$unauth_userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id"
499     )->status_is(403);
500
501     # Delete existing EHolding title
502     $t->delete_ok(
503         "//$userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id")
504       ->status_is( 204, 'SWAGGER3.2.4' )->content_is( '', 'SWAGGER3.3.4' );
505
506     # Attempt to delete non-existent EHolding title
507     $t->delete_ok(
508         "//$userid:$password@/api/v1/erm/eholdings/local/titles/$ehtitle_id")
509       ->status_is(404);
510
511     $schema->storage->txn_rollback;
512 };