Bug 35215: Add few assumptions in Suggestions.t around emailing
[koha.git] / t / db_dependent / Virtualshelves.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4 use Test::More tests => 7;
5 use DateTime::Duration;
6
7 use C4::Context;
8 use Koha::Database;
9 use Koha::DateUtils qw( dt_from_string );
10 use Koha::Virtualshelves;
11 use Koha::Virtualshelfshares;
12 use Koha::Virtualshelfcontents;
13
14 use t::lib::Dates;
15 use t::lib::TestBuilder;
16
17 my $builder = t::lib::TestBuilder->new;
18
19 my $schema = Koha::Database->new->schema;
20 $schema->storage->txn_begin;
21 my $dbh = C4::Context->dbh;
22 teardown();
23
24 subtest 'CRUD' => sub {
25     plan tests => 15;
26     my $patron = $builder->build({
27         source => 'Borrower',
28     });
29
30     my $number_of_shelves = Koha::Virtualshelves->search->count;
31
32     is( $number_of_shelves, 0, 'No shelves should exist' );
33
34     my $shelf = Koha::Virtualshelf->new({
35             shelfname => "my first shelf",
36             owner => $patron->{borrowernumber},
37             public => 0,
38         }
39     )->store;
40
41     is( ref( $shelf ), 'Koha::Virtualshelf', 'The constructor should return a valid object' );
42
43     $number_of_shelves = Koha::Virtualshelves->search->count;
44     is( $number_of_shelves, 1, '1 shelf should have been inserted' );
45     is( $shelf->allow_change_from_owner, 1, 'The default value for allow_change_from_owner should be 1' );
46     is( $shelf->allow_change_from_others, 0, 'The default value for allow_change_from_others should be 0' );
47     is ( $shelf->allow_change_from_staff, 0, 'The default value for allow_change_from_staff should be 0');
48     is ( $shelf->allow_change_from_permitted_staff, 0, 'The default value for allow_change_from_permitted_staff should be 0');
49     is( t::lib::Dates::compare( $shelf->created_on, dt_from_string), 0, 'The creation time should have been set to today' );
50
51     # Test if creation date will not be overwritten by store
52     my $created = dt_from_string->subtract( hours => 1 );
53     $shelf->created_on( $created );
54     $shelf->store;
55
56     my $retrieved_shelf = Koha::Virtualshelves->find( $shelf->shelfnumber );
57
58     is( $retrieved_shelf->shelfname, $shelf->shelfname, 'Find should correctly return the shelfname' );
59     is( t::lib::Dates::compare( $retrieved_shelf->created_on, $created), 0, 'Creation date is the same after update (Bug 18672)' );
60
61     # Insert with the same name
62     eval {
63         $shelf = Koha::Virtualshelf->new({
64                 shelfname => "my first shelf",
65                 owner => $patron->{borrowernumber},
66                 public => 0,
67             }
68         )->store;
69     };
70     is( ref($@), 'Koha::Exceptions::Virtualshelf::DuplicateObject',
71         'Exception on duplicate name' );
72     $number_of_shelves = Koha::Virtualshelves->search->count;
73     is( $number_of_shelves, 1, 'To be sure the number of shelves is still 1' );
74
75     my $another_patron = $builder->build({
76         source => 'Borrower',
77     });
78
79     $shelf = Koha::Virtualshelf->new({
80             shelfname => "my first shelf",
81             owner => $another_patron->{borrowernumber},
82             public => 0,
83         }
84     )->store;
85     $number_of_shelves = Koha::Virtualshelves->search->count;
86     is( $number_of_shelves, 2, 'Another patron should be able to create a shelf with an existing shelfname');
87
88     my $is_deleted = Koha::Virtualshelves->find( $shelf->shelfnumber )->delete;
89     ok( $is_deleted, 'The shelf has been deleted correctly' );
90     $number_of_shelves = Koha::Virtualshelves->search->count;
91     is( $number_of_shelves, 1, 'To be sure the shelf has been deleted' );
92
93     teardown();
94 };
95
96 subtest 'Sharing' => sub {
97     plan tests => 21;
98     my $patron_wants_to_share = $builder->build({
99         source => 'Borrower',
100     });
101     my $share_with_me = $builder->build({
102         source => 'Borrower',
103     });
104     my $just_another_patron = $builder->build({
105         source => 'Borrower',
106     });
107
108     my $number_of_shelves_shared = Koha::Virtualshelfshares->search->count;
109     is( $number_of_shelves_shared, 0, 'No shelves should exist' );
110
111     my $shelf_to_share = Koha::Virtualshelf->new({
112             shelfname => "my first shelf",
113             owner => $patron_wants_to_share->{borrowernumber},
114             public => 0,
115         }
116     )->store;
117
118     my $shelf_not_to_share = Koha::Virtualshelf->new({
119             shelfname => "my second shelf",
120             owner => $patron_wants_to_share->{borrowernumber},
121             public => 0,
122         }
123     )->store;
124
125     my $shared_shelf = eval { $shelf_to_share->share };
126     is ( ref( $@ ), 'Koha::Exceptions::Virtualshelf::InvalidKeyOnSharing', 'Do not share if no key given' );
127     $shared_shelf = eval { $shelf_to_share->share('valid key') };
128     is( ref( $shared_shelf ), 'Koha::Virtualshelfshare', 'On sharing, the method should return a valid Koha::Virtualshelfshare object' );
129
130     my $another_shared_shelf = eval { $shelf_to_share->share('valid key2') }; # Just to have 2 shares in DB
131
132     $number_of_shelves_shared = Koha::Virtualshelfshares->search->count;
133     is( $number_of_shelves_shared, 2, '2 shares should have been inserted' );
134
135     my $is_accepted = eval {
136         $shared_shelf->accept( 'invalid k', $share_with_me->{borrowernumber} );
137     };
138     is( $is_accepted, undef, 'The share should have not been accepted if the key is invalid' );
139     is( ref( $@ ), 'Koha::Exceptions::Virtualshelf::InvalidInviteKey', 'accept with an invalid key should raise an exception' );
140
141     $is_accepted = $shared_shelf->accept( 'valid key', $share_with_me->{borrowernumber} );
142     ok( defined($is_accepted), 'The share should have been accepted if the key valid' );
143
144     is( $shelf_to_share->is_shared, 1, 'first shelf is shared' );
145     is( $shelf_not_to_share->is_shared, 0, 'second shelf is not shared' );
146
147     is( $shelf_to_share->is_shared_with( $patron_wants_to_share->{borrowernumber} ), 0 , "The shelf should not be shared with the owner" );
148     is( $shelf_to_share->is_shared_with( $share_with_me->{borrowernumber} ), 1 , "The shelf should be shared with share_with_me" );
149     is( $shelf_to_share->is_shared_with( $just_another_patron->{borrowernumber} ), 0, "The shelf should not be shared with just_another_patron" );
150
151     is( $shelf_to_share->remove_share( $just_another_patron->{borrowernumber} ), 0, 'No share should be removed if the share has not been done with this patron' );
152     $number_of_shelves_shared = Koha::Virtualshelfshares->search->count;
153     is( $number_of_shelves_shared, 2, 'To be sure no shares have been removed' );
154
155     is( $shelf_not_to_share->remove_share( $share_with_me->{borrowernumber} ), 0, '0 share should have been removed if the shelf is not share' );
156     $number_of_shelves_shared = Koha::Virtualshelfshares->search->count;
157     is( $number_of_shelves_shared, 2, 'To be sure no shares have been removed' );
158
159     # Test double accept (BZ 11943) before removing the accepted share
160     my $third_share = $shelf_to_share->share('valid key3');
161     is( Koha::Virtualshelfshares->search->count, 3, 'Three shares' );
162     $is_accepted = $third_share->accept( 'valid key3', $share_with_me->{borrowernumber} );
163     is( $is_accepted->shelfnumber, $shelf_to_share->shelfnumber, 'Accept returned the existing share' );
164     is( Koha::Virtualshelfshares->search->count, 2, 'Check that number of shares went down again' );
165
166     # Remove the first accept
167     ok( $shelf_to_share->remove_share( $share_with_me->{borrowernumber} ), '1 share should have been removed if the shelf was shared with this patron' );
168     $number_of_shelves_shared = Koha::Virtualshelfshares->search->count;
169     is( $number_of_shelves_shared, 1, 'To be sure the share has been removed' );
170
171     teardown();
172 };
173
174 subtest 'Shelf content' => sub {
175
176     plan tests => 26;
177     my $patron1 = $builder->build( { source => 'Borrower', } );
178     my $patron2 = $builder->build( { source => 'Borrower', } );
179     my $patron3 = $builder->build( { source => 'Borrower', value => {flags => 1} });
180     my $patron4 = $builder->build( { source => 'Borrower', } );
181     $builder->build(
182         {
183             source => 'UserPermission',
184             value  => {
185                 borrowernumber => $patron4->{borrowernumber},
186                 module_bit     => 20,                            # lists
187                 code           => 'eit_public_list_contents',
188             },
189         }
190     );
191     my $biblio1 = $builder->build_sample_biblio;
192     my $biblio2 = $builder->build_sample_biblio;
193     my $biblio3 = $builder->build_sample_biblio;
194     my $biblio4 = $builder->build_sample_biblio;
195     my $number_of_contents = Koha::Virtualshelfcontents->search->count;
196
197     is( $number_of_contents, 0, 'No content should exist' );
198
199     my $dt_yesterday = dt_from_string->subtract_duration( DateTime::Duration->new( days => 1 ) );
200     my $shelf = Koha::Virtualshelf->new(
201         {   shelfname    => "my first shelf",
202             owner        => $patron1->{borrowernumber},
203             public       => 0,
204             lastmodified => $dt_yesterday,
205         }
206     )->store;
207
208     $shelf = Koha::Virtualshelves->find( $shelf->shelfnumber );
209     is( t::lib::Dates::compare( $shelf->lastmodified, $dt_yesterday), 0, 'The lastmodified has been set to yesterday, will be useful for another test later' );
210     my $content1 = $shelf->add_biblio( $biblio1->biblionumber, $patron1->{borrowernumber} );
211     is( ref($content1), 'Koha::Virtualshelfcontent', 'add_biblio to a shelf should return a Koha::Virtualshelfcontent object if inserted' );
212     $shelf = Koha::Virtualshelves->find( $shelf->shelfnumber );
213     is( t::lib::Dates::compare( $shelf->lastmodified, dt_from_string), 0, 'Adding a biblio to a shelf should update the lastmodified for the shelf' );
214     my $content2 = $shelf->add_biblio( $biblio2->biblionumber, $patron1->{borrowernumber} );
215     $number_of_contents = Koha::Virtualshelfcontents->search->count;
216     is( $number_of_contents, 2, '2 biblio should have been inserted' );
217
218     my $content1_bis = $shelf->add_biblio( $biblio1->biblionumber, $patron1->{borrowernumber} );
219     is( $content1_bis, undef, 'add_biblio should return undef on duplicate' );    # Or an exception ?
220     $number_of_contents = Koha::Virtualshelfcontents->search->count;
221     is( $number_of_contents, 2, 'The biblio should not have been duplicated' );
222
223     $shelf = Koha::Virtualshelves->find( $shelf->shelfnumber );
224     my $contents = $shelf->get_contents;
225     is( $contents->count, 2, 'There are 2 biblios on this shelf' );
226
227     # Patron 2 will try to remove biblios
228     # allow_change_from_owner = 1, allow_change_from_others = 0 (defaults)
229     my $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio1->biblionumber ], borrowernumber => $patron2->{borrowernumber} } );
230     is( $number_of_deleted_biblios, 0, 'Patron 2 removed nothing' );
231     # Now try with patron 1
232     $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio1->biblionumber ], borrowernumber => $patron1->{borrowernumber} } );
233     is( $number_of_deleted_biblios, 1, 'Patron 1 removed biblio' );
234     $number_of_contents = Koha::Virtualshelfcontents->search->count;
235     is( $number_of_contents, 1, 'To be sure the content has been deleted' );
236
237     # allow_change_from_owner == 0 (readonly)
238     $shelf->allow_change_from_owner( 0 );
239     $shelf->store;
240     $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio2->biblionumber ], borrowernumber => $patron1->{borrowernumber} } );
241     is( $number_of_deleted_biblios, 0, 'Owner could not delete' );
242     $number_of_contents = Koha::Virtualshelfcontents->search->count;
243     is( $number_of_contents, 1, 'Number of entries still equal to 1' );
244     $shelf->add_biblio( $biblio2->biblionumber, $patron1->{borrowernumber} );
245     $number_of_contents = Koha::Virtualshelfcontents->search->count;
246     is( $number_of_contents, 1, 'Biblio not added to the list' );
247     # Add back biblio1
248     $shelf->allow_change_from_owner( 1 );
249     $shelf->add_biblio( $biblio1->biblionumber, $patron1->{borrowernumber} );
250     $number_of_contents = Koha::Virtualshelfcontents->search->count;
251     is( $number_of_contents, 2, 'Biblio added to the list' );
252
253     # allow_change_from_others == 1
254     $shelf->allow_change_from_others( 1 );
255     my $content3 = $shelf->add_biblio( $biblio3->biblionumber, $patron2->{borrowernumber} );
256     my $content4 = $shelf->add_biblio( $biblio4->biblionumber, $patron2->{borrowernumber} );
257     $number_of_contents = Koha::Virtualshelfcontents->search->count;
258     is( $number_of_contents, 4, 'The biblio should have been added to the shelf by the patron 2' );
259     $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio3->biblionumber ], borrowernumber => $patron2->{borrowernumber} } );
260     is( $number_of_deleted_biblios, 1, 'Biblio 3 deleted by patron 2' );
261     $number_of_contents = Koha::Virtualshelfcontents->search->count;
262     is( $number_of_contents, 3, 'Back to three entries' );
263
264     # allow_change_from_staff == 1 and allow_change_from_others == 0
265     $shelf->allow_change_from_staff( 1 );
266     $shelf->allow_change_from_others( 0 );
267     $content4 = $shelf->add_biblio( $biblio3->biblionumber, $patron3->{borrowernumber} );
268     $number_of_contents = Koha::Virtualshelfcontents->search->count;
269     is( $number_of_contents, 4, 'The biblio should have been added to the shelf by patron 2');
270     $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio3->biblionumber ], borrowernumber => $patron3->{borrowernumber} } );
271     is( $number_of_deleted_biblios, 1, 'Biblio 3 deleted by patron 2' );
272     $number_of_contents = Koha::Virtualshelfcontents->search->count;
273     is( $number_of_contents, 3, 'Back to three entries' );
274
275     # allow_change_from_permitted_staff == 1 and allow_change_from_staff = 1 and allow_change_from_others == 0
276     $shelf->allow_change_from_permitted_staff( 1 );
277     $shelf->allow_change_from_staff( 0 );
278     $shelf->allow_change_from_others( 1 );
279     $content4 = $shelf->add_biblio( $biblio3->biblionumber, $patron3->{borrowernumber} );
280     $number_of_contents = Koha::Virtualshelfcontents->search->count;
281     is( $number_of_contents, 4, 'The biblio should have been added to the shelf by patron 3');
282     $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio3->biblionumber ], borrowernumber => $patron3->{borrowernumber} } );
283     is( $number_of_deleted_biblios, 1, 'Biblio 3 deleted by patron 3' );
284     $number_of_contents = Koha::Virtualshelfcontents->search->count;
285     is( $number_of_contents, 3, 'Back to three entries' );
286
287     $content4 = $shelf->add_biblio( $biblio3->biblionumber, $patron4->{borrowernumber} );
288     $number_of_contents = Koha::Virtualshelfcontents->search->count;
289     is( $number_of_contents, 4, 'The biblio should have been added to the shelf by patron 4');
290     $number_of_deleted_biblios = $shelf->remove_biblios( { biblionumbers => [ $biblio3->biblionumber ], borrowernumber => $patron4->{borrowernumber} } );
291     $number_of_contents = Koha::Virtualshelfcontents->search->count;
292     is( $number_of_contents, 3, 'Back to three entries' );
293
294     teardown();
295 };
296
297 subtest 'Shelf permissions' => sub {
298
299     plan tests => 175;
300     my $patron1 = $builder->build( { source => 'Borrower', value => { flags => '2096766' } } ); # 2096766 is everything checked but not superlibrarian
301     my $patron2 = $builder->build( { source => 'Borrower', value => { flags => '1048190' } } ); # 1048190 is everything checked but not superlibrarian and delete_public_lists
302     my $patron3 = $builder->build( { source => 'Borrower', value => { flags => '0' } } ); # this is a patron with no special permissions
303     my $patron4 = $builder->build( { source => 'Borrower', value => { flags => '0' } } );
304     my $patron5 = $builder->build( { source => 'Borrower', value => { flags => '4' } } );
305     my $sth = $dbh->prepare("INSERT INTO user_permissions (borrowernumber, module_bit, code) VALUES (?,?,?)");
306     $sth->execute($patron4->{borrowernumber}, 20, 'edit_public_lists'); # $patron4 only has the edit_public_lists sub-permission checked
307     $sth->execute($patron5->{borrowernumber}, 20, 'edit_public_list_contents'); # $patron5 has the 'catalogue' permission and edit_public_list_contents sub-permission checked
308
309     my $biblio1 = $builder->build_sample_biblio;
310     my $biblio2 = $builder->build_sample_biblio;
311     my $biblio3 = $builder->build_sample_biblio;
312     my $biblio4 = $builder->build_sample_biblio;
313     my $biblio5 = $builder->build_sample_biblio;
314     my $biblio6 = $builder->build_sample_biblio;
315
316     my $public_shelf = Koha::Virtualshelf->new(
317         {   shelfname    => "my first shelf",
318             owner        => $patron1->{borrowernumber},
319             public       => 1,
320             allow_change_from_owner           => 0,
321             allow_change_from_others          => 0,
322             allow_change_from_staff           => 0,
323             allow_change_from_permitted_staff => 0
324         }
325     )->store;
326
327     is( $public_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their public list' );
328     is( $public_shelf->can_be_viewed( $patron2->{borrowernumber} ), 1, 'Public list should be viewed by another staff member');
329     is( $public_shelf->can_be_viewed( $patron3->{borrowernumber} ), 1, 'Public list should be viewed by someone with no special permissions' );
330     is( $public_shelf->can_be_viewed( $patron4->{borrowernumber} ), 1, 'Public list should be viewed by someone with the edit_public_lists sub-permission checked' );
331     is( $public_shelf->can_be_viewed( $patron5->{borrowernumber} ), 1, 'Public list should be viewed by someone with the edit_public_list_contents sub-permission checked' );
332
333     is( $public_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
334     is( $public_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Public list should not be deleted by another staff member' );
335     is( $public_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Public list should not be deleted by someone with no special permissions' );
336     is( $public_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_lists sub-permission checked' );
337     is( $public_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_list_contents sub-permission checked' );
338
339     is( $public_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
340     is( $public_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Public list should not be managed by another staff member' );
341     is( $public_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Public list should not be managed by someone with no special permissions' );
342     is( $public_shelf->can_be_managed( $patron4->{borrowernumber} ), 1, 'Public list should be managed by someone with the edit_public_lists sub-permission checked' );
343     is( $public_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Public list should be managed by someone with the edit_public_list_contents sub-permission checked' );
344
345     is( $public_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 0, 'The owner should not be able to add biblios to their list' );
346     is( $public_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 0, 'Public list should not be modified (add) by another staff member' );
347     is( $public_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with no special permissions' );
348     is( $public_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with the edit_public_lists sub-permission checked' );
349     is( $public_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with the edit_public_list_contents sub-permission checked' );
350
351     is( $public_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 0, 'The owner should not be able to remove biblios to their list' );
352     is( $public_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 0, 'Public list should not be modified (remove) by another staff member' );
353     is ( $public_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (removed) by someone with no special permissions' );
354     is( $public_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (removed) by someone with the edit_public_lists sub-permission checked' );
355     is( $public_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 0, 'Public list should not be modified (removed) by someone with the edit_public_list_contents sub-permission checked' );
356
357     $public_shelf->allow_change_from_owner(1);
358     $public_shelf->store;
359
360     is( $public_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their public list' );
361     is( $public_shelf->can_be_viewed( $patron2->{borrowernumber} ), 1, 'Public list should be viewed by staff member' );
362     is( $public_shelf->can_be_viewed( $patron3->{borrowernumber} ), 1, 'Public list should be viewed by someone with no special permissions' );
363     is( $public_shelf->can_be_viewed( $patron4->{borrowernumber} ), 1, 'Public list should be viewable by someone with the edit_public_lists sub-permission checked' );
364     is( $public_shelf->can_be_viewed( $patron5->{borrowenumber} ), 1, 'Public list should be viewable by someone with the edit_public_list_contents sub-permission checked' );
365
366     is( $public_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
367     is( $public_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Public list should not be deleted by another staff member' );
368     is( $public_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Public list should not be deleted by someone with no special permissions' );
369     is( $public_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_lists sub-permission checked' );
370     is( $public_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Public list should not be deleted by someome with the edit_public_list_contents sub-permission checked' );
371
372     is( $public_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
373     is( $public_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Public list should not be managed by another staff member' );
374     is( $public_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Public list should not be managed by someone with no special permissions' );
375     is( $public_shelf->can_be_managed( $patron4->{borrowernumber} ), 1, 'Public list should be managed by someone with the edit_public_lists sub-permission checked' );
376     is( $public_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Public list should be managed by someone with the edit_public_list_contents sub-permission checked' );
377
378     is( $public_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 1, 'The owner should be able to add biblios to their list' );
379     is( $public_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 0, 'Public list should not be modified (add) by another staff member' );
380     is( $public_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with no special permissions' );
381     is( $public_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with the edit_public_lists sub-permission checked' );
382     is( $public_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with the edit_public_list_contents sub-permission checked' );
383
384     is( $public_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 1, 'The owner should be able to remove biblios to their list' );
385     is( $public_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 0, 'Public list should not be modified (remove) by another staff member' );
386     is( $public_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someone with no special permissions' );
387     is( $public_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someone with the edit_public_list sub-permission checked' );
388     is( $public_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someome with the edit_public_list_contents sub-permission checked' );
389
390     $public_shelf->allow_change_from_staff(1);
391     $public_shelf->store;
392
393     is( $public_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their public list' );
394     is( $public_shelf->can_be_viewed( $patron2->{borrowernumber} ), 1, 'Public list should be viewed by staff member' );
395     is( $public_shelf->can_be_viewed( $patron3->{borrowernumber} ), 1, 'Public list should be viewed by someone with no special permissions' );
396     is( $public_shelf->can_be_viewed( $patron4->{borrowernumber} ), 1, 'Public list should be viewable by someone with the edit_public_lists sub-permission checked' );
397     is( $public_shelf->can_be_viewed( $patron5->{borrowernumber} ), 1, 'Public list should be viewable by someone with the edit_public_list_contents sub-permission checked' );
398
399     is( $public_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
400     is( $public_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Public list should not be deleted by another staff member' );
401     is( $public_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Public list should not be deleted by someone with no special permissions' );
402     is( $public_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_lists sub-permission checked' );
403     is( $public_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_list_contents sub-permission checked' );
404
405     is( $public_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
406     is( $public_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Public list should not be managed by another staff member' );
407     is( $public_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Public list should not be managed by someone with no special permissions' );
408     is( $public_shelf->can_be_managed( $patron4->{borrowernumber} ), 1, 'Public list should be managed by someone with the edit_public_lists sub-permission checked' );
409     is( $public_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Public list should be managed by someone with the edit_public_list_contents sub-permission checked' );
410
411     is( $public_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 1, 'The owner should be able to add biblios to their list' );
412     is( $public_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 1, 'Public list should not be modified (add) by another staff member' );
413     is( $public_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with no special permissions' );
414     is( $public_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with the edit_public_lists sub-permission checked' );
415     is( $public_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 1, 'Public list should be modified (add) by someone with the edit_public_list_contents sub-permission checked' );
416
417     is( $public_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 1, 'The owner should be able to remove biblios to their list' );
418     is( $public_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 1, 'Public list should not be modified (remove) by another staff member' );
419     is( $public_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someone with no special permissions' );
420     is( $public_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someone with the edit_public_list sub-permission checked' );
421     is( $public_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 1, 'Public list should be modified (remove) by someone with the edit_public_list_contents sub-permission checked' );
422
423     $public_shelf->allow_change_from_permitted_staff(1);
424     $public_shelf->store;
425
426     is( $public_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their public list' );
427     is( $public_shelf->can_be_viewed( $patron2->{borrowernumber} ), 1, 'Public list should be viewed by staff member' );
428     is( $public_shelf->can_be_viewed( $patron3->{borrowernumber} ), 1, 'Public list should be viewed by someone with no special permissions' );
429     is( $public_shelf->can_be_viewed( $patron4->{borrowernumber} ), 1, 'Public list should be viewable by someone with the edit_public_lists sub-permission checked' );
430     is( $public_shelf->can_be_viewed( $patron5->{borrowernumber} ), 1, 'Public list should be viewable by someone with the edit_public_list_contents sub-permission checked' );
431
432     is( $public_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
433     is( $public_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Public list should not be deleted by another staff member' );
434     is( $public_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Public list should not be deleted by someone with no special permissions' );
435     is( $public_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_lists sub-permission checked' );
436     is( $public_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Public list should not be deleted by someone with the edit_public_list_contents sub-permission checked' );
437
438     is( $public_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
439     is( $public_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Public list should not be managed by another staff member' );
440     is( $public_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Public list should not be managed by someone with no special permissions' );
441     is( $public_shelf->can_be_managed( $patron4->{borrowernumber} ), 1, 'Public list should be managed by someone with the edit_public_lists sub-permission checked' );
442     is( $public_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Public list should be managed by someone with the edit_public_list_contents sub-permission checked' );
443
444     is( $public_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 1, 'The owner should be able to add biblios to their list' );
445     is( $public_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 1, 'Public list should be modified (add) by another staff member' );
446     is( $public_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with no special permissions' );
447     is( $public_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (add) by someone with the edit_public_lists sub-permission checked' );
448     is( $public_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 1, 'Public list should not be modified (add) by someone with the edit_public_list_contents sub-permission checked' );
449
450     is( $public_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 1, 'The owner should be able to remove biblios to their list' );
451     is( $public_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 1, 'Public list should be modified (remove) by another staff member' );
452     is( $public_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someone with no special permissions' );
453     is( $public_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 0, 'Public list should not be modified (remove) by someone with the edit_public_list sub-permission checked' );
454     is( $public_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 1, 'Public list should be modified (remove) by someone with the edit_public_list_contents sub-permission checked' );
455
456     my $private_shelf = Koha::Virtualshelf->new(
457         {   shelfname    => "my first shelf",
458             owner        => $patron1->{borrowernumber},
459             public       => 0,
460             allow_change_from_owner => 0,
461             allow_change_from_others => 0,
462             allow_change_from_staff => 0,
463             allow_change_from_permitted_staff => 0
464         }
465     )->store;
466
467     is( $private_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their list' );
468     is( $private_shelf->can_be_viewed( $patron2->{borrowernumber} ), 0, 'Private list should not be viewed by another staff member' );
469     is( $private_shelf->can_be_viewed( $patron3->{borrowernumber} ), 0, 'Private list should not be viewed by someone with no special permissions' );
470     is( $private_shelf->can_be_viewed( $patron4->{borrowernumber} ), 0, 'Private list should not be viewed by someone with the edit_public_lists sub-permission checked' );
471     is( $private_shelf->can_be_viewed( $patron5->{borrowernumber} ), 0, 'Private list should not be viewed by someone with the edit_public_list_contents sub-permission checked' );
472
473     is( $private_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
474     is( $private_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Private list should not be deleted by another staff member' );
475     is( $private_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Private list should not be deleted by someone with no special permissions' );
476     is( $private_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Private list should not be deleted by someone with the edit_public_lists sub-permission checked' );
477     is( $private_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Private list should not be deleted by someome with the edit_public_list_contents sub-permission checked' );
478
479     is( $private_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
480     is( $private_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Private list should not be managed by another staff member' );
481     is( $private_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Private list should not be managed by someone with no special permissions' );
482     is( $private_shelf->can_be_managed( $patron4->{borrowernumber} ), 0, 'Private list should not be managed by someone with the edit_public_lists sub-permission checked' );
483     is( $private_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Private list should not be managed by someone with the edit_public_list_contents sub-permission checked' );
484
485     is( $private_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 0, 'The owner should not be able to add biblios to their list' );
486     is( $private_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 0, 'Private list should not be modified (add) by another staff member' );
487     is( $private_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 0, 'Private list should not be modified (add) by someone with no special permissions' );
488     is( $private_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 0, 'Private list should not be modified (add) by someone with the edit_public_lists sub-permission checked' );
489     is( $private_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 0, 'Private list should not be modified (add) by someone with the edit_public_list_contents sub-permission checked' );
490
491     is( $private_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 0, 'The owner should not be able to remove biblios to their list' );
492     is( $private_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 0, 'Private list should not be modified (remove) by another staff member' );
493     is( $private_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 0, 'Private list should not be modified (remove) by someone with no special permissions' );
494     is( $private_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 0, 'Private list should not be modified (remove) by someone with the edit_public_lists sub-permissions' );
495     is( $private_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 0, 'Private list should not be modified (remove) by someone with the edit_public_list_contents sub-permissions' );
496
497     $private_shelf->allow_change_from_owner(1);
498     $private_shelf->allow_change_from_staff(1);
499     $private_shelf->allow_change_from_others(0);
500     $private_shelf->allow_change_from_permitted_staff(0);
501     $private_shelf->store;
502     is( $private_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their list' );
503     is( $private_shelf->can_be_viewed( $patron2->{borrowernumber} ), 0, 'Private list should not be viewed by another staff member' );
504     is( $private_shelf->can_be_viewed( $patron3->{borrowernumber} ), 0, 'Private list should not be viewed by someone with no special permissions' );
505     is( $private_shelf->can_be_viewed( $patron4->{borrowernumber} ), 0, 'Private list should not be viewed by someone with the edit_public_lists sub-permission checked' );
506     is( $private_shelf->can_be_viewed( $patron5->{borrowernumber} ), 0, 'Private list should not be viewed by someone with the edit_public_list_contents sub-permission checked' );
507
508     is( $private_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
509     is( $private_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Private list should not be deleted by another staff member' );
510     is( $private_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Private list should not be deleted by someone with no special permissions' );
511     is( $private_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Private list should not be deleted by someone with the edit_public_lists sub-permission checked' );
512     is( $private_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Private list should not be viewed by someone with the edit_public_list_contents sub-permission checked' );
513
514     is( $private_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
515     is( $private_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Private list should not be managed by another staff member' );
516     is( $private_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Private list should not be managed by someone with no special permissions' );
517     is( $private_shelf->can_be_managed( $patron4->{borrowernumber} ), 0, 'Private list should not be managed by someone with the edit_public_lists sub-permission checked' );
518     is( $private_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Private list should not be managed by someone with the edit_public_list_contents sub-permission checked' );
519
520     is( $private_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 1, 'The owner should be able to add biblios to their list' );
521     is( $private_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 1, 'Private list should be modified (add) by another staff member # individual check done later' );
522     is( $private_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 0, 'Private list should not be modified (add) by someone with no special permissions' );
523     is ( $private_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 0, 'Private list should not be modified (add) by someone with the edit_public_lists sub-permission checked' );
524     is( $private_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 1, 'Private list should be modififed (add) by someone with the edit_public_list_contents sub-permission checked' );
525
526     is( $private_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 1, 'The owner should be able to remove biblios to their list' );
527     is( $private_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 1, 'Private list should be modified (remove) by another staff member # individual check done later' );
528     is( $private_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 0, 'Private list should not be modified (remove) by someone with no special permissions' );
529     is( $private_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 0, 'Private list should not be modified (remove) by someone with the edit_public_lists sub-permission checked' );
530     is( $private_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 1, 'Private list should be modified (remove) by someone with the edit_public_list_contents sub-permission checked' );
531
532     $private_shelf->allow_change_from_owner(1);
533     $private_shelf->allow_change_from_others(1);
534     $private_shelf->store;
535
536     is( $private_shelf->can_be_viewed( $patron1->{borrowernumber} ), 1, 'The owner should be able to view their list' );
537     is( $private_shelf->can_be_viewed( $patron2->{borrowernumber} ), 0, 'Private list should not be viewed by another staff member' );
538     is( $private_shelf->can_be_viewed( $patron3->{borrowernumber} ), 0, 'Private list should not be viewed by someone with no special permissions' );
539     is( $private_shelf->can_be_viewed( $patron4->{borrowernumber} ), 0, 'Private list should not be viewed by someone with the edit_public_lists sub-permission checked' );
540     is( $private_shelf->can_be_viewed( $patron5->{borrowernumber} ), 0, 'Private list should not be viewed by someome with the edit_public_list_contents sub-permission checked' );
541
542     is( $private_shelf->can_be_deleted( $patron1->{borrowernumber} ), 1, 'The owner should be able to delete their list' );
543     is( $private_shelf->can_be_deleted( $patron2->{borrowernumber} ), 0, 'Private list should not be deleted by another staff member' );
544     is( $private_shelf->can_be_deleted( $patron3->{borrowernumber} ), 0, 'Private list should not be deleted by someone with no special permissions' );
545     is( $private_shelf->can_be_deleted( $patron4->{borrowernumber} ), 0, 'Private list should not be deleted by someone with the edit_public_lists sub-permission checked' );
546     is( $private_shelf->can_be_deleted( $patron5->{borrowernumber} ), 0, 'Private list should not be deleted by someone with the edit_public_list_contents sub-permission checked' );
547
548     is( $private_shelf->can_be_managed( $patron1->{borrowernumber} ), 1, 'The owner should be able to manage their list' );
549     is( $private_shelf->can_be_managed( $patron2->{borrowernumber} ), 0, 'Private list should not be managed by another staff member' );
550     is( $private_shelf->can_be_managed( $patron3->{borrowernumber} ), 0, 'Private list should not be managed by someone with no special permissions' );
551     is( $private_shelf->can_be_managed( $patron4->{borrowernumber} ), 0, 'Private list should not be managed by someone with the edit_public_lists sub-permission checked' );
552     is( $private_shelf->can_be_managed( $patron5->{borrowernumber} ), 0, 'Private list should not be managed by someone with the edit_public_list_contents sub-permission checked' );
553
554     is( $private_shelf->can_biblios_be_added( $patron1->{borrowernumber} ), 1, 'The owner should be able to add biblios to their list' );
555     is( $private_shelf->can_biblios_be_added( $patron2->{borrowernumber} ), 1, 'Private list could be modified (add) by another staff member # individual check done later' );
556     is( $private_shelf->can_biblios_be_added( $patron3->{borrowernumber} ), 1, 'Private list could be modified (add) by someone with no special permissions' );
557     is( $private_shelf->can_biblios_be_added( $patron4->{borrowernumber} ), 1, 'Private list could be modified (add) by someone with the edit_public_lists sub-permission checked' );
558     is( $private_shelf->can_biblios_be_added( $patron5->{borrowernumber} ), 1, 'Private list could be modified (add) by someone with the edit_public_list_contents sub-permission checked' );
559
560     is( $private_shelf->can_biblios_be_removed( $patron1->{borrowernumber} ), 1, 'The owner should be able to remove biblios to their list' );
561     is( $private_shelf->can_biblios_be_removed( $patron2->{borrowernumber} ), 1, 'Private list could be modified (remove) by another staff member # individual check done later' );
562     is( $private_shelf->can_biblios_be_removed( $patron3->{borrowernumber} ), 1, 'Private list could be modified (remove) by someone with no special permissions' );
563     is( $private_shelf->can_biblios_be_removed( $patron4->{borrowernumber} ), 1, 'Private list could be modified (remove) by someone with the edit_public_lists sub-permission checked' );
564     is( $private_shelf->can_biblios_be_removed( $patron5->{borrowernumber} ), 1, 'Private list could be modified (remove) by someone with the edit_public_list_contents sub-permission checked' );
565
566     teardown();
567 };
568
569 subtest 'Get shelves' => sub {
570     plan tests => 5;
571     my $patron1 = $builder->build({
572         source => 'Borrower',
573     });
574     my $patron2 = $builder->build({
575         source => 'Borrower',
576     });
577
578     my $private_shelf1_1 = Koha::Virtualshelf->new({
579             shelfname => "private shelf 1 for patron 1",
580             owner => $patron1->{borrowernumber},
581             public => 0,
582         }
583     )->store;
584     my $private_shelf1_2 = Koha::Virtualshelf->new({
585             shelfname => "private shelf 2 for patron 1",
586             owner => $patron1->{borrowernumber},
587             public => 0,
588         }
589     )->store;
590     my $private_shelf2_1 = Koha::Virtualshelf->new({
591             shelfname => "private shelf 1 for patron 2",
592             owner => $patron2->{borrowernumber},
593             public => 0,
594         }
595     )->store;
596     my $public_shelf1_1 = Koha::Virtualshelf->new({
597             shelfname => "public shelf 1 for patron 1",
598             owner => $patron1->{borrowernumber},
599             public => 1,
600         }
601     )->store;
602     my $public_shelf1_2 = Koha::Virtualshelf->new({
603             shelfname => "public shelf 2 for patron 1",
604             owner => $patron1->{borrowernumber},
605             public => 1,
606         }
607     )->store;
608     my $shelf_to_share = Koha::Virtualshelf->new({
609             shelfname => "shared shelf",
610             owner => $patron1->{borrowernumber},
611             public => 0,
612         }
613     )->store;
614
615     my $private_shelves = Koha::Virtualshelves->get_private_shelves;
616     is( $private_shelves->count, 0, 'Without borrowernumber given, get_private_shelves should not return any shelf' );
617     $private_shelves = Koha::Virtualshelves->get_private_shelves({ borrowernumber => $patron1->{borrowernumber} });
618     is( $private_shelves->count, 3, 'get_private_shelves should return all shelves for a given patron' );
619
620     $private_shelf2_1->share('a key')->accept('a key', $patron1->{borrowernumber});
621     $private_shelves = Koha::Virtualshelves->get_private_shelves({ borrowernumber => $patron1->{borrowernumber} });
622     is( $private_shelves->count, 4, 'get_private_shelves should return all shelves for a given patron, even the shared ones' );
623
624     my $public_shelves = Koha::Virtualshelves->get_public_shelves;
625     is( $public_shelves->count, 2, 'get_public_shelves should return all public shelves, no matter who is the owner' );
626
627     my $shared_shelf = eval { $shelf_to_share->share("valid key") };
628     my $shared_shelves = Koha::Virtualshelfshares->search({ borrowernumber => $patron1->{borrowernumber} });
629     is( $shared_shelves->count, 1, 'Found the share for patron1' );
630
631     teardown();
632 };
633
634 subtest 'Get shelves containing biblios' => sub {
635
636     plan tests => 9;
637     my $patron1 = $builder->build( { source => 'Borrower', } );
638     my $patron2 = $builder->build( { source => 'Borrower', } );
639     my $biblio1 = $builder->build_sample_biblio;
640     my $biblio2 = $builder->build_sample_biblio;
641     my $biblio3 = $builder->build_sample_biblio;
642     my $biblio4 = $builder->build_sample_biblio;
643
644     my $shelf1 = Koha::Virtualshelf->new(
645         {   shelfname    => "my first shelf",
646             owner        => $patron1->{borrowernumber},
647             public       => 0,
648         }
649     )->store;
650     my $shelf2 = Koha::Virtualshelf->new(
651         {   shelfname    => "my x second shelf", # 'x' to make it sorted after 'third'
652             owner        => $patron2->{borrowernumber},
653             public       => 0,
654         }
655     )->store;
656     my $shelf3 = Koha::Virtualshelf->new(
657         {   shelfname    => "my third shelf",
658             owner        => $patron1->{borrowernumber},
659             public       => 1,
660         }
661     )->store;
662
663     my $content1 = $shelf1->add_biblio( $biblio1->biblionumber, $patron1->{borrowernumber} );
664     my $content2 = $shelf1->add_biblio( $biblio2->biblionumber, $patron1->{borrowernumber} );
665     my $content3 = $shelf2->add_biblio( $biblio2->biblionumber, $patron2->{borrowernumber} );
666     my $content4 = $shelf2->add_biblio( $biblio3->biblionumber, $patron2->{borrowernumber} );
667     my $content5 = $shelf2->add_biblio( $biblio4->biblionumber, $patron2->{borrowernumber} );
668     my $content6 = $shelf3->add_biblio( $biblio4->biblionumber, $patron1->{borrowernumber} );
669
670     my $shelves_with_biblio1_for_any_patrons = Koha::Virtualshelves->get_shelves_containing_record(
671         {
672             biblionumber => $biblio1->biblionumber,
673         }
674     );
675     is ( $shelves_with_biblio1_for_any_patrons->count, 0, 'shelf1 is private and should not be displayed if patron is not logged in' );
676
677     my $shelves_with_biblio4_for_any_patrons = Koha::Virtualshelves->get_shelves_containing_record(
678         {
679             biblionumber => $biblio4->biblionumber,
680         }
681     );
682     is ( $shelves_with_biblio4_for_any_patrons->count, 1, 'shelf3 is public and should be displayed for any patrons' );
683     is ( $shelves_with_biblio4_for_any_patrons->next->shelfname, $shelf3->shelfname, 'The correct shelf (3) should be displayed' );
684
685     my $shelves_with_biblio1_for_other_patrons = Koha::Virtualshelves->get_shelves_containing_record(
686         {
687             biblionumber => $biblio1->biblionumber,
688             borrowernumber => $patron2->{borrowernumber},
689         }
690     );
691     is ( $shelves_with_biblio1_for_other_patrons->count, 0, 'shelf1 is private and should not be displayed for other patrons' );
692
693     my $shelves_with_biblio1_for_owner = Koha::Virtualshelves->get_shelves_containing_record(
694         {
695             biblionumber => $biblio1->biblionumber,
696             borrowernumber => $patron1->{borrowernumber},
697         }
698     );
699     is ( $shelves_with_biblio1_for_owner->count, 1, 'shelf1 is private and should be displayed for the owner' );
700
701     my $shelves_with_biblio2_for_patron1 = Koha::Virtualshelves->get_shelves_containing_record(
702         {
703             biblionumber => $biblio2->biblionumber,
704             borrowernumber => $patron1->{borrowernumber},
705         }
706     );
707     is ( $shelves_with_biblio2_for_patron1->count, 1, 'Only shelf1 should be displayed for patron 1 and biblio 1' );
708     is ( $shelves_with_biblio2_for_patron1->next->shelfname, $shelf1->shelfname, 'The correct shelf (1) should be displayed for patron 1' );
709
710     my $shelves_with_biblio4_for_patron2 = Koha::Virtualshelves->get_shelves_containing_record(
711         {
712             biblionumber => $biblio4->biblionumber,
713             borrowernumber => $patron2->{borrowernumber},
714         }
715     );
716     is ( $shelves_with_biblio4_for_patron2->count, 2, 'Patron should shown private and public lists for a given biblio' );
717     is ( $shelves_with_biblio4_for_patron2->next->shelfname, $shelf3->shelfname, 'The shelves should be sorted by shelfname' );
718
719     teardown();
720 };
721
722 subtest 'cannot_be_transferred' => sub {
723     plan tests => 12;
724
725     # Three patrons and a deleted one
726     my $staff = $builder->build_object({ class => 'Koha::Patrons', value => { flags => undef } });
727     my $listowner = $builder->build_object({ class => 'Koha::Patrons' });
728     my $receiver = $builder->build_object({ class => 'Koha::Patrons' });
729     my $removed_patron = $builder->build_object({ class => 'Koha::Patrons' });
730     $removed_patron->delete;
731
732     # Create three lists
733     my $private_list = Koha::Virtualshelf->new({ shelfname => "A", owner => $listowner->id })->store;
734     my $public_list = Koha::Virtualshelf->new({ shelfname => "B", public => 1, owner => $listowner->id })->store;
735     my $shared_list = Koha::Virtualshelf->new({ shelfname => "C", owner => $listowner->id })->store;
736     $shared_list->share("key")->accept( "key", $receiver->id );
737
738     # Test on private list
739     is( $private_list->cannot_be_transferred, 'unauthorized_transfer', 'Private list can never be transferred' );
740
741     # Test on public list
742     is( $public_list->cannot_be_transferred, 'missing_by_parameter', 'Public list, no parameters' );
743     is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id }), 'unauthorized_transfer', 'Lacks permission' );
744     my $perms = $builder->build({ source => 'UserPermission', value  => {
745         borrowernumber => $staff->id, module_bit => 20, code => 'edit_public_lists',
746     }});
747     is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id }), 0, 'Minimum permission passes' );
748     $staff->flags(1)->store;
749     is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id }), 0, 'Superlibrarian permission passes' );
750     is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id, interface => 'opac' }), 'unauthorized_transfer',
751         'Not supported on OPAC' );
752     is( $public_list->cannot_be_transferred({ by => $staff->id, to => $removed_patron->id }), 'new_owner_not_found', 'Removed patron cannot own' );
753
754     # Test on shared list
755     is( $shared_list->cannot_be_transferred({ by => $staff->id }), 'unauthorized_transfer', 'Shared list, transfer limited to owner' );
756     is( $shared_list->cannot_be_transferred({ by => $receiver->id }), 'unauthorized_transfer', 'Shared list, transfer still limited to owner' );
757     is( $shared_list->cannot_be_transferred({ by => $listowner->id, to => $receiver->id }), 0, 'sharee could become owner' );
758     is( $shared_list->cannot_be_transferred({ by => $listowner->id, to => $receiver->id, interface => 'intranet' }), 'unauthorized_transfer',
759         'Intranet not supported' );
760     is( $shared_list->cannot_be_transferred({ by => $listowner->id, to => $staff->id }), 'new_owner_has_no_share', 'staff has no share' );
761 };
762
763 $schema->storage->txn_rollback;
764
765 sub teardown {
766     $dbh->do(q|DELETE FROM virtualshelfshares|);
767     $dbh->do(q|DELETE FROM virtualshelfcontents|);
768     $dbh->do(q|DELETE FROM virtualshelves|);
769 }