Bug 26384: Fix executable flags
[koha.git] / t / db_dependent / api / v1 / biblios.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 => 3;
21 use Test::MockModule;
22 use Test::Mojo;
23 use Test::Warn;
24
25 use t::lib::Mocks;
26 use t::lib::TestBuilder;
27
28 use C4::Auth;
29 use Koha::Biblios;
30 use Koha::Database;
31
32 my $schema  = Koha::Database->new->schema;
33 my $builder = t::lib::TestBuilder->new;
34
35 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
36
37 my $t = Test::Mojo->new('Koha::REST::V1');
38
39 subtest 'get() tests' => sub {
40
41     plan tests => 21;
42
43     $schema->storage->txn_begin;
44
45     my $patron = $builder->build_object(
46         {
47             class => 'Koha::Patrons',
48             value => { flags => 0 }
49         }
50     );
51     my $password = 'thePassword123';
52     $patron->set_password( { password => $password, skip_validation => 1 } );
53     $patron->discard_changes;
54     my $userid = $patron->userid;
55
56     my $biblio = $builder->build_sample_biblio({
57         title  => 'The unbearable lightness of being',
58         author => 'Milan Kundera'
59     });
60     $t->get_ok("//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber)
61       ->status_is(403);
62
63     $patron->flags(4)->store;
64
65     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
66                 => { Accept => 'application/weird+format' } )
67       ->status_is(406)
68       ->json_is( [ "application/json",
69                    "application/marcxml+xml",
70                    "application/marc-in-json",
71                    "application/marc",
72                    "text/plain" ] );
73
74     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
75                  => { Accept => 'application/json' } )
76       ->status_is(200)
77       ->json_is( '/title', 'The unbearable lightness of being' )
78       ->json_is( '/author', 'Milan Kundera' );
79
80     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
81                  => { Accept => 'application/marcxml+xml' } )
82       ->status_is(200);
83
84     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
85                  => { Accept => 'application/marc-in-json' } )
86       ->status_is(200);
87
88     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
89                  => { Accept => 'application/marc' } )
90       ->status_is(200);
91
92     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
93                  => { Accept => 'text/plain' } )
94       ->status_is(200)
95       ->content_is($biblio->metadata->record->as_formatted);
96
97     $biblio->delete;
98     $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
99                  => { Accept => 'application/marc' } )
100       ->status_is(404)
101       ->json_is( '/error', 'Object not found.' );
102
103     $schema->storage->txn_rollback;
104 };
105
106 subtest 'delete() tests' => sub {
107
108     plan tests => 9;
109
110     $schema->storage->txn_begin;
111
112     my $patron = $builder->build_object(
113         {
114             class => 'Koha::Patrons',
115             value => { flags => 0 } # no permissions
116         }
117     );
118     my $password = 'thePassword123';
119     $patron->set_password( { password => $password, skip_validation => 1 } );
120     my $userid = $patron->userid;
121
122     my $item      = $builder->build_sample_item();
123     my $biblio_id = $item->biblionumber;
124
125     $t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
126       ->status_is(403, 'Not enough permissions makes it return the right code');
127
128     # Add permissions
129     $builder->build(
130         {
131             source => 'UserPermission',
132             value  => {
133                 borrowernumber => $patron->borrowernumber,
134                 module_bit     => 9,
135                 code           => 'edit_catalogue'
136             }
137         }
138     );
139
140
141     # Bibs with items cannot be deleted
142     $t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
143       ->status_is(409);
144
145     $item->delete();
146
147     # Bibs with no items can be deleted
148     $t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
149       ->status_is(204, 'SWAGGER3.2.4')
150       ->content_is('', 'SWAGGER3.3.4');
151
152     $t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
153       ->status_is(404);
154
155     $schema->storage->txn_rollback;
156 };
157
158 subtest 'get_public() tests' => sub {
159
160     plan tests => 25;
161
162     $schema->storage->txn_begin;
163
164     my $category = $builder->build_object({ class => 'Koha::Patron::Categories' });
165     my $patron = $builder->build_object(
166         {
167             class => 'Koha::Patrons',
168             value => {
169                 flags        => undef, # opac user
170                 categorycode => $category->categorycode
171             }
172         }
173     );
174     my $password = 'thePassword123';
175     $patron->set_password( { password => $password, skip_validation => 1 } );
176     $patron->discard_changes;
177     my $userid = $patron->userid;
178
179     my $biblio = $builder->build_sample_biblio({
180         title  => 'The unbearable lightness of being',
181         author => 'Milan Kundera'
182     });
183
184     # Make sure author in shown in the OPAC
185     my $subfields = Koha::MarcSubfieldStructures->search({ tagfield => '100' });
186     while ( my $subfield = $subfields->next ) {
187         $subfield->set({ hidden => -1 })->store;
188     }
189     Koha::Caches->get_instance()->flush_all;
190
191     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
192                 => { Accept => 'application/weird+format' } )
193       ->status_is(406)
194       ->json_is( [ "application/marcxml+xml",
195                    "application/marc-in-json",
196                    "application/marc",
197                    "text/plain" ] );
198
199     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
200                  => { Accept => 'text/plain' } )
201       ->status_is(200)
202       ->content_like( qr{100\s+_aMilan Kundera} )
203       ->content_like( qr{245\s+_aThe unbearable lightness of being} );
204
205     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
206                  => { Accept => 'application/marcxml+xml' } )
207       ->status_is(200);
208
209     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
210                  => { Accept => 'application/marc-in-json' } )
211       ->status_is(200);
212
213     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
214                  => { Accept => 'application/marc' } )
215       ->status_is(200);
216
217     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
218                  => { Accept => 'text/plain' } )
219       ->status_is(200)
220       ->content_is($biblio->metadata->record->as_formatted);
221
222     subtest 'anonymous access' => sub {
223         plan tests => 9;
224
225         $t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
226                  => { Accept => 'application/marcxml+xml' } )
227           ->status_is(200);
228
229         $t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
230                     => { Accept => 'application/marc-in-json' } )
231         ->status_is(200);
232
233         $t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
234                     => { Accept => 'application/marc' } )
235         ->status_is(200);
236
237         $t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
238                     => { Accept => 'text/plain' } )
239         ->status_is(200)
240         ->content_is($biblio->metadata->record->as_formatted);
241     };
242
243     # Hide author in OPAC
244     $subfields = Koha::MarcSubfieldStructures->search({ tagfield => '100' });
245     while ( my $subfield = $subfields->next ) {
246         $subfield->set({ hidden => 1 })->store;
247     }
248
249     Koha::Caches->get_instance()->flush_all;
250
251     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
252                  => { Accept => 'text/plain' } )
253       ->status_is(200)
254       ->content_unlike( qr{100\s+_aMilan Kundera} )
255       ->content_like( qr{245\s+_aThe unbearable lightness of being} );
256
257     subtest 'hidden_in_opac tests' => sub {
258
259         plan tests => 6;
260
261         my $biblio_hidden_in_opac = 1;
262
263         my $biblio_class = Test::MockModule->new('Koha::Biblio');
264         # force biblio hidden in OPAC
265         $biblio_class->mock( 'hidden_in_opac', sub { return $biblio_hidden_in_opac; } );
266
267         $t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
268                  => { Accept => 'text/plain' } )
269           ->status_is(404, 'hidden_in_opac + anonymous => hidden');
270
271         my $category_override_hidden_items = 0;
272         my $category_class = Test::MockModule->new('Koha::Patron::Category');
273         $category_class->mock( 'override_hidden_items', sub { return $category_override_hidden_items; } );
274         $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
275                  => { Accept => 'text/plain' } )
276           ->status_is(404, "hidden_in_opac + patron whose category doesn't override => hidden");
277
278         # Make the category override
279         $category_override_hidden_items = 1;
280         $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
281                  => { Accept => 'text/plain' } )
282           ->status_is(200, "hidden_in_opac + patron whose category that overrides => displayed");
283
284         t::lib::Mocks::mock_preference('OpacHiddenItems');
285     };
286
287     $biblio->delete;
288     $t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
289                  => { Accept => 'application/marc' } )
290       ->status_is(404)
291       ->json_is( '/error', 'Object not found.' );
292
293     $schema->storage->txn_rollback;
294 };