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