Bugzilla – Attachment 176467 Details for
Bug 38050
Add REST endpoints for working with "lists"/"virtual shelves"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 38050: create tests for public CRUD list endpoints
Bug-38050-create-tests-for-public-CRUD-list-endpoi.patch (text/plain), 18.41 KB, created by
Jacob O'Mara
on 2025-01-13 17:51:09 UTC
(
hide
)
Description:
Bug 38050: create tests for public CRUD list endpoints
Filename:
MIME Type:
Creator:
Jacob O'Mara
Created:
2025-01-13 17:51:09 UTC
Size:
18.41 KB
patch
obsolete
>From 10ab8c220b585a21cd69067154781a2e47847991 Mon Sep 17 00:00:00 2001 >From: Jacob O'Mara <jacobomara901@gmail.com> >Date: Tue, 7 Jan 2025 16:01:54 +0000 >Subject: [PATCH] Bug 38050: create tests for public CRUD list endpoints > >--- > t/db_dependent/api/v1/public/lists.t | 428 +++++++++++++++++++++++---- > 1 file changed, 376 insertions(+), 52 deletions(-) > >diff --git a/t/db_dependent/api/v1/public/lists.t b/t/db_dependent/api/v1/public/lists.t >index 5a3653fd3c..818c085452 100755 >--- a/t/db_dependent/api/v1/public/lists.t >+++ b/t/db_dependent/api/v1/public/lists.t >@@ -17,7 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 1; >+use Test::More tests => 5; > use Test::Mojo; > > use JSON qw(encode_json); >@@ -51,73 +51,397 @@ subtest 'list_public() tests' => sub { > $patron_2->set_password( { password => $password, skip_validation => 1 } ); > my $patron_2_userid = $patron_2->userid; > >- my $list_1 = >- $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_1->id, public => 1 } } ); >- my $list_2 = >- $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_1->id, public => 0 } } ); >- my $list_3 = >- $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_2->id, public => 1 } } ); >- my $list_4 = >- $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_2->id, public => 0 } } ); >- >- my $q = encode_json( >+ my $list_1 = $builder->build_object( > { >- list_id => { >- -in => [ >- $list_1->id, >- $list_2->id, >- $list_3->id, >- $list_4->id, >- ] >- } >+ class => 'Koha::Virtualshelves', >+ value => { owner => $patron_1->id, public => 1 } >+ } >+ ); >+ my $list_2 = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { owner => $patron_1->id, public => 0 } >+ } >+ ); >+ my $list_3 = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { owner => $patron_2->id, public => 1 } >+ } >+ ); >+ my $list_4 = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { owner => $patron_2->id, public => 0 } > } > ); > >+ my $q = encode_json( { list_id => { -in => [ $list_1->id, $list_2->id, $list_3->id, $list_4->id, ] } } ); >+ > # anonymous >- $t->get_ok("/api/v1/public/lists?q=$q")->status_is( 200, "Anonymous users can only fetch public lists" ) >- ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); >+ $t->get_ok("/api/v1/public/lists?q=$q")->status_is( 200, "Anonymous users can only fetch public lists" )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_3->to_api( { public => 1 } ) >+ ] >+ ); > > $t->get_ok("/api/v1/public/lists?q=$q&only_public=1") >- ->status_is( 200, "Anonymous users can only fetch public lists" ) >- ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); >+ ->status_is( 200, "Anonymous users can only fetch public lists" )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_3->to_api( { public => 1 } ) >+ ] >+ ); > >- $t->get_ok("/api/v1/public/lists?q=$q&only_mine=1") >- ->status_is( 400, "Passing only_mine on an anonymous session generates a 400 code" ) >- ->json_is( '/error_code' => q{only_mine_forbidden} ); >+ $t->get_ok("/api/v1/public/lists?q=$q&only_mine=1")->status_is( >+ 400, >+ "Passing only_mine on an anonymous session generates a 400 code" >+ )->json_is( '/error_code' => q{only_mine_forbidden} ); > >- $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_mine=1") >- ->status_is( 200, "Passing only_mine with a logged in user makes it return only their lists" ) >- ->json_is( [ $list_1->to_api( { public => 1 } ), $list_2->to_api( { public => 1 } ) ] ); >+ $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_mine=1")->status_is( >+ 200, >+ "Passing only_mine with a logged in user makes it return only their lists" >+ )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_2->to_api( { public => 1 } ) >+ ] >+ ); > >- $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_mine=1") >- ->status_is( 200, "Passing only_mine with a logged in user makes it return only their lists" ) >- ->json_is( [ $list_3->to_api( { public => 1 } ), $list_4->to_api( { public => 1 } ) ] ); >+ $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_mine=1")->status_is( >+ 200, >+ "Passing only_mine with a logged in user makes it return only their lists" >+ )->json_is( >+ [ >+ $list_3->to_api( { public => 1 } ), >+ $list_4->to_api( { public => 1 } ) >+ ] >+ ); > > # only public >- $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1") >- ->status_is( 200, "Passing only_public with a logged in user makes it return only public lists" ) >- ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); >- >- $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_public=1") >- ->status_is( 200, "Passing only_public with a logged in user makes it return only public lists" ) >- ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); >- >- $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q") >- ->status_is( 200, "Not filtering with only_mine or only_public makes it return all accessible lists" ) >- ->json_is( >- [ $list_1->to_api( { public => 1 } ), $list_2->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] >+ $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1")->status_is( >+ 200, >+ "Passing only_public with a logged in user makes it return only public lists" >+ )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_3->to_api( { public => 1 } ) >+ ] >+ ); >+ >+ $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_public=1")->status_is( >+ 200, >+ "Passing only_public with a logged in user makes it return only public lists" >+ )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_3->to_api( { public => 1 } ) >+ ] >+ ); >+ >+ $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q")->status_is( >+ 200, >+ "Not filtering with only_mine or only_public makes it return all accessible lists" >+ )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_2->to_api( { public => 1 } ), >+ $list_3->to_api( { public => 1 } ) >+ ] >+ ); >+ >+ $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q")->status_is( >+ 200, >+ "Not filtering with only_mine or only_public makes it return all accessible lists" >+ )->json_is( >+ [ >+ $list_1->to_api( { public => 1 } ), >+ $list_3->to_api( { public => 1 } ), >+ $list_4->to_api( { public => 1 } ) >+ ] >+ ); >+ >+ # conflicting params >+ $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1&only_mine=1")->status_is( >+ 200, >+ "Passing only_public with a logged in user makes it return only public lists" >+ )->json_is( [ $list_1->to_api( { public => 1 } ) ] ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'public_get() tests' => sub { >+ plan tests => 12; >+ >+ $schema->storage->txn_begin; >+ >+ my $password = 'thePassword123'; >+ my $patron_1 = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $patron_2 = $builder->build_object( { class => 'Koha::Patrons' } ); >+ >+ $patron_1->set_password( { password => $password, skip_validation => 1 } ); >+ $patron_2->set_password( { password => $password, skip_validation => 1 } ); >+ >+ my $patron_1_userid = $patron_1->userid; >+ my $patron_2_userid = $patron_2->userid; >+ >+ # Create test lists >+ my $public_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $patron_1->id, >+ public => 1, >+ allow_change_from_owner => 1 >+ } >+ } >+ ); >+ >+ my $private_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $patron_1->id, >+ public => 0, >+ allow_change_from_owner => 0 >+ } >+ } >+ ); >+ >+ # Test anonymous access to public list >+ $t->get_ok( "/api/v1/public/lists/" . $public_list->id )->status_is(200)->json_is( $public_list->to_api ); >+ >+ # Test anonymous access to private list >+ $t->get_ok( "/api/v1/public/lists/" . $private_list->id ) >+ ->status_is( 403, 'Anonymous user cannot access private list' ); >+ >+ # Test authenticated access - owner can see their private list >+ $t->get_ok( "//$patron_1_userid:$password@/api/v1/public/lists/" . $private_list->id )->status_is(200) >+ ->json_is( $private_list->to_api ); >+ >+ # Test non-owner access to private list >+ $t->get_ok( "//$patron_2_userid:$password@/api/v1/public/lists/" . $private_list->id ) >+ ->status_is( 403, 'Non-owner cannot access private list' ); >+ >+ # Test non-existent list >+ $t->get_ok("/api/v1/public/lists/99999999")->status_is( 404, "List not found" ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'public_add() tests' => sub { >+ plan tests => 9; # Reduced test count since we're removing one assertion >+ >+ $schema->storage->txn_begin; >+ >+ my $password = 'thePassword123'; >+ my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $another_patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $patron_userid = $patron->userid; >+ >+ my $list_data = { >+ name => "Test List", >+ public => 1, >+ allow_change_from_owner => 1, >+ allow_change_from_others => 0, >+ default_sort_field => 'title' >+ }; >+ >+ # Test anonymous attempt >+ $t->post_ok( "/api/v1/public/lists" => json => $list_data )->status_is( 401, 'Anonymous user cannot create list' ); >+ >+ # Test authenticated user can create list >+ $t->post_ok( "//$patron_userid:$password@/api/v1/public/lists" => json => $list_data )->status_is(201) >+ ->json_has( '/list_id', 'List ID is present in response' ) >+ ->json_has( '/name', 'List name is present in response' )->json_is( >+ '/owner_id' => $patron->id, >+ 'List created with logged in user as owner' > ); > >- $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q") >- ->status_is( 200, "Not filtering with only_mine or only_public makes it return all accessible lists" ) >- ->json_is( >- [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ), $list_4->to_api( { public => 1 } ) ] >+ # Test attempt to specify owner_id >+ my $list_with_owner = { >+ name => "Test List", >+ owner_id => $another_patron->id, # Should be rejected >+ public => 1, >+ allow_change_from_owner => 1, >+ allow_change_from_others => 0, >+ default_sort_field => 'title' >+ }; >+ >+ $t->post_ok( "//$patron_userid:$password@/api/v1/public/lists" => json => $list_with_owner )->status_is(400); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'public_update() tests' => sub { >+ plan tests => 15; >+ >+ $schema->storage->txn_begin; >+ >+ my $password = 'thePassword123'; >+ my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $another_patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ $another_patron->set_password( { password => $password, skip_validation => 1 } ); >+ >+ my $patron_userid = $patron->userid; >+ my $another_patron_userid = $another_patron->userid; >+ >+ # Create a list that can be modified >+ my $modifiable_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $patron->id, >+ public => 1, >+ allow_change_from_owner => 1 >+ } >+ } >+ ); >+ >+ # Create a list that cannot be modified >+ my $unmodifiable_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $patron->id, >+ public => 1, >+ allow_change_from_owner => 0 >+ } >+ } >+ ); >+ >+ my $update_data = { >+ name => "Updated List Name", >+ public => 0, >+ allow_change_from_owner => 1, >+ allow_change_from_others => 0, >+ default_sort_field => 'title' >+ }; >+ >+ # Test anonymous attempt >+ $t->put_ok( "/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) >+ ->status_is( 401, 'Anonymous user cannot update list' ); >+ >+ # Test non-owner update attempt >+ $t->put_ok( >+ "//$another_patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) >+ ->status_is( 403, 'Non-owner cannot update list' ); >+ >+ # Test owner update success >+ $t->put_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) >+ ->status_is(200)->json_is( '/name' => 'Updated List Name', 'List name updated' ) >+ ->json_is( '/public' => 0, 'List privacy updated' ); >+ >+ # Test update of non-existent list >+ $t->put_ok( "//$patron_userid:$password@/api/v1/public/lists/99999999" => json => $update_data ) >+ ->status_is( 404, "List not found" ); >+ >+ # Test update of unmodifiable list >+ $t->put_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $unmodifiable_list->id => json => $update_data ) >+ ->status_is( >+ 403, >+ "Cannot update list when allow_change_from_owner is false" >+ )->json_is( '/error_code' => 'forbidden', 'Correct error code returned' ); >+ >+ # Create librarian with necessary permissions >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 2**13 } >+ } >+ ); >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $librarian_userid = $librarian->userid; >+ >+ # Test librarian using public endpoint >+ $t->put_ok( "//$librarian_userid:$password@/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) >+ ->status_is( >+ 403, >+ 'Librarian must use admin endpoint to modify others lists' > ); > >- # conflicting params >- $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1&only_mine=1") >- ->status_is( 200, "Passing only_public with a logged in user makes it return only public lists" ) >- ->json_is( [ $list_1->to_api( { public => 1 } ) ] ); >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'public_delete() tests' => sub { >+ plan tests => 12; >+ >+ $schema->storage->txn_begin; >+ >+ my $password = 'thePassword123'; >+ my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $another_patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ $another_patron->set_password( { password => $password, skip_validation => 1 } ); >+ >+ my $patron_userid = $patron->userid; >+ my $another_patron_userid = $another_patron->userid; >+ >+ # Create test lists for different scenarios >+ my $modifiable_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $patron->id, >+ public => 1, >+ allow_change_from_owner => 1 >+ } >+ } >+ ); >+ >+ my $other_patron_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $another_patron->id, >+ public => 1, >+ allow_change_from_owner => 1 >+ } >+ } >+ ); >+ >+ my $unmodifiable_list = $builder->build_object( >+ { >+ class => 'Koha::Virtualshelves', >+ value => { >+ owner => $patron->id, >+ public => 1, >+ allow_change_from_owner => 0 >+ } >+ } >+ ); >+ >+ # Test anonymous attempt >+ $t->delete_ok( "/api/v1/public/lists/" . $modifiable_list->id ) >+ ->status_is( 401, 'Anonymous user cannot delete list' ); >+ >+ # Test non-owner delete attempt >+ $t->delete_ok( "//$another_patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id ) >+ ->status_is( 403, 'Non-owner cannot delete list' ); >+ >+ # Test attempt to delete another patron's list >+ $t->delete_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $other_patron_list->id ) >+ ->status_is( 403, "Cannot delete another patron's list" ); >+ >+ # Test delete of unmodifiable list >+ $t->delete_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $unmodifiable_list->id )->status_is( >+ 403, >+ "Cannot delete list when allow_change_from_owner is false" >+ ); >+ >+ # Test delete of non-existent list >+ $t->delete_ok("//$patron_userid:$password@/api/v1/public/lists/99999999")->status_is( 404, "List not found" ); >+ >+ # Test successful delete by owner >+ $t->delete_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id ) >+ ->status_is( 204, 'List deleted successfully' ); > > $schema->storage->txn_rollback; > }; >+ >+1; >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 38050
:
174807
|
174808
|
174809
|
174810
|
176462
|
176463
|
176464
|
176465
|
176466
|
176467
|
176769
|
176770
|
176771
|
176772
|
176773
|
176774