| Lines 18-24
          
      
      
        Link Here | 
        
          | 18 | use Modern::Perl; | 18 | use Modern::Perl; | 
        
          | 19 |  | 19 |  | 
        
          | 20 | use Test::NoWarnings; | 20 | use Test::NoWarnings; | 
          
            
              | 21 | use Test::More tests => 2; | 21 | use Test::More tests => 6; | 
        
          | 22 | use Test::Mojo; | 22 | use Test::Mojo; | 
        
          | 23 |  | 23 |  | 
        
          | 24 | use JSON qw(encode_json); | 24 | use JSON qw(encode_json); | 
  
    | Lines 52-124
          subtest 'list_public() tests' => sub {
      
      
        Link Here | 
        
          | 52 |     $patron_2->set_password( { password => $password, skip_validation => 1 } ); | 52 |     $patron_2->set_password( { password => $password, skip_validation => 1 } ); | 
        
          | 53 |     my $patron_2_userid = $patron_2->userid; | 53 |     my $patron_2_userid = $patron_2->userid; | 
        
          | 54 |  | 54 |  | 
          
            
              | 55 |     my $list_1 = | 55 |     my $list_1 = $builder->build_object( | 
            
              | 56 |         $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_1->id, public => 1 } } ); |  |  | 
            
              | 57 |     my $list_2 = | 
            
              | 58 |         $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_1->id, public => 0 } } ); | 
            
              | 59 |     my $list_3 = | 
            
              | 60 |         $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_2->id, public => 1 } } ); | 
            
              | 61 |     my $list_4 = | 
            
              | 62 |         $builder->build_object( { class => 'Koha::Virtualshelves', value => { owner => $patron_2->id, public => 0 } } ); | 
            
              | 63 |  | 
            
              | 64 |     my $q = encode_json( | 
        
          | 65 |         { | 56 |         { | 
          
            
              | 66 |             list_id => { | 57 |             class => 'Koha::Virtualshelves', | 
            
              | 67 |                 -in => [ | 58 |             value => { owner => $patron_1->id, public => 1 } | 
            
              | 68 |                     $list_1->id, | 59 |         } | 
            
              | 69 |                     $list_2->id, | 60 |     ); | 
            
              | 70 |                     $list_3->id, | 61 |     my $list_2 = $builder->build_object( | 
            
              | 71 |                     $list_4->id, | 62 |         { | 
            
              | 72 |                 ] | 63 |             class => 'Koha::Virtualshelves', | 
            
              | 73 |             } | 64 |             value => { owner => $patron_1->id, public => 0 } | 
            
              |  |  | 65 |         } | 
            
              | 66 |     ); | 
            
              | 67 |     my $list_3 = $builder->build_object( | 
            
              | 68 |         { | 
            
              | 69 |             class => 'Koha::Virtualshelves', | 
            
              | 70 |             value => { owner => $patron_2->id, public => 1 } | 
            
              | 71 |         } | 
            
              | 72 |     ); | 
            
              | 73 |     my $list_4 = $builder->build_object( | 
            
              | 74 |         { | 
            
              | 75 |             class => 'Koha::Virtualshelves', | 
            
              | 76 |             value => { owner => $patron_2->id, public => 0 } | 
        
          | 74 |         } | 77 |         } | 
        
          | 75 |     ); | 78 |     ); | 
        
          | 76 |  | 79 |  | 
            
              |  |  | 80 |     my $q = encode_json( { list_id => { -in => [ $list_1->id, $list_2->id, $list_3->id, $list_4->id, ] } } ); | 
            
              | 81 |  | 
        
          | 77 |     # anonymous | 82 |     # anonymous | 
          
            
              | 78 |     $t->get_ok("/api/v1/public/lists?q=$q")->status_is( 200, "Anonymous users can only fetch public lists" ) | 83 |     $t->get_ok("/api/v1/public/lists?q=$q")->status_is( 200, "Anonymous users can only fetch public lists" )->json_is( | 
            
              | 79 |         ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); | 84 |         [ | 
            
              |  |  | 85 |             $list_1->to_api( { public => 1 } ), | 
            
              | 86 |             $list_3->to_api( { public => 1 } ) | 
            
              | 87 |         ] | 
            
              | 88 |     ); | 
        
          | 80 |  | 89 |  | 
        
          | 81 |     $t->get_ok("/api/v1/public/lists?q=$q&only_public=1") | 90 |     $t->get_ok("/api/v1/public/lists?q=$q&only_public=1") | 
          
            
              | 82 |         ->status_is( 200, "Anonymous users can only fetch public lists" ) | 91 |         ->status_is( 200, "Anonymous users can only fetch public lists" )->json_is( | 
            
              | 83 |         ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); | 92 |         [ | 
            
              |  |  | 93 |             $list_1->to_api( { public => 1 } ), | 
            
              | 94 |             $list_3->to_api( { public => 1 } ) | 
            
              | 95 |         ] | 
            
              | 96 |         ); | 
        
          | 84 |  | 97 |  | 
          
            
              | 85 |     $t->get_ok("/api/v1/public/lists?q=$q&only_mine=1") | 98 |     $t->get_ok("/api/v1/public/lists?q=$q&only_mine=1")->status_is( | 
            
              | 86 |         ->status_is( 400, "Passing only_mine on an anonymous session generates a 400 code" ) | 99 |         400, | 
            
              | 87 |         ->json_is( '/error_code' => q{only_mine_forbidden} ); | 100 |         "Passing only_mine on an anonymous session generates a 400 code" | 
            
              |  |  | 101 |     )->json_is( '/error_code' => q{only_mine_forbidden} ); | 
        
          | 88 |  | 102 |  | 
          
            
              | 89 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_mine=1") | 103 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_mine=1")->status_is( | 
            
              | 90 |         ->status_is( 200, "Passing only_mine with a logged in user makes it return only their lists" ) | 104 |         200, | 
            
              | 91 |         ->json_is( [ $list_1->to_api( { public => 1 } ), $list_2->to_api( { public => 1 } ) ] ); | 105 |         "Passing only_mine with a logged in user makes it return only their lists" | 
            
              |  |  | 106 |     )->json_is( | 
            
              | 107 |         [ | 
            
              | 108 |             $list_1->to_api( { public => 1 } ), | 
            
              | 109 |             $list_2->to_api( { public => 1 } ) | 
            
              | 110 |         ] | 
            
              | 111 |     ); | 
        
          | 92 |  | 112 |  | 
          
            
              | 93 |     $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_mine=1") | 113 |     $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_mine=1")->status_is( | 
            
              | 94 |         ->status_is( 200, "Passing only_mine with a logged in user makes it return only their lists" ) | 114 |         200, | 
            
              | 95 |         ->json_is( [ $list_3->to_api( { public => 1 } ), $list_4->to_api( { public => 1 } ) ] ); | 115 |         "Passing only_mine with a logged in user makes it return only their lists" | 
            
              |  |  | 116 |     )->json_is( | 
            
              | 117 |         [ | 
            
              | 118 |             $list_3->to_api( { public => 1 } ), | 
            
              | 119 |             $list_4->to_api( { public => 1 } ) | 
            
              | 120 |         ] | 
            
              | 121 |     ); | 
        
          | 96 |  | 122 |  | 
        
          | 97 |     # only public | 123 |     # only public | 
          
            
              | 98 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1") | 124 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1")->status_is( | 
            
              | 99 |         ->status_is( 200, "Passing only_public with a logged in user makes it return only public lists" ) | 125 |         200, | 
            
              | 100 |         ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); | 126 |         "Passing only_public with a logged in user makes it return only public lists" | 
            
              | 101 |  | 127 |     )->json_is( | 
            
              | 102 |     $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_public=1") | 128 |         [ | 
            
              | 103 |         ->status_is( 200, "Passing only_public with a logged in user makes it return only public lists" ) | 129 |             $list_1->to_api( { public => 1 } ), | 
            
              | 104 |         ->json_is( [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] ); | 130 |             $list_3->to_api( { public => 1 } ) | 
            
              | 105 |  | 131 |         ] | 
            
              | 106 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q") | 132 |     ); | 
            
              | 107 |         ->status_is( 200, "Not filtering with only_mine or only_public makes it return all accessible lists" ) | 133 |  | 
            
              | 108 |         ->json_is( | 134 |     $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q&only_public=1")->status_is( | 
            
              | 109 |         [ $list_1->to_api( { public => 1 } ), $list_2->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ) ] | 135 |         200, | 
            
              |  |  | 136 |         "Passing only_public with a logged in user makes it return only public lists" | 
            
              | 137 |     )->json_is( | 
            
              | 138 |         [ | 
            
              | 139 |             $list_1->to_api( { public => 1 } ), | 
            
              | 140 |             $list_3->to_api( { public => 1 } ) | 
            
              | 141 |         ] | 
            
              | 142 |     ); | 
            
              | 143 |  | 
            
              | 144 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q")->status_is( | 
            
              | 145 |         200, | 
            
              | 146 |         "Not filtering with only_mine or only_public makes it return all accessible lists" | 
            
              | 147 |     )->json_is( | 
            
              | 148 |         [ | 
            
              | 149 |             $list_1->to_api( { public => 1 } ), | 
            
              | 150 |             $list_2->to_api( { public => 1 } ), | 
            
              | 151 |             $list_3->to_api( { public => 1 } ) | 
            
              | 152 |         ] | 
            
              | 153 |     ); | 
            
              | 154 |  | 
            
              | 155 |     $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q")->status_is( | 
            
              | 156 |         200, | 
            
              | 157 |         "Not filtering with only_mine or only_public makes it return all accessible lists" | 
            
              | 158 |     )->json_is( | 
            
              | 159 |         [ | 
            
              | 160 |             $list_1->to_api( { public => 1 } ), | 
            
              | 161 |             $list_3->to_api( { public => 1 } ), | 
            
              | 162 |             $list_4->to_api( { public => 1 } ) | 
            
              | 163 |         ] | 
            
              | 164 |     ); | 
            
              | 165 |  | 
            
              | 166 |     # conflicting params | 
            
              | 167 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1&only_mine=1")->status_is( | 
            
              | 168 |         200, | 
            
              | 169 |         "Passing only_public with a logged in user makes it return only public lists" | 
            
              | 170 |     )->json_is( [ $list_1->to_api( { public => 1 } ) ] ); | 
            
              | 171 |  | 
            
              | 172 |     $schema->storage->txn_rollback; | 
            
              | 173 | }; | 
            
              | 174 |  | 
            
              | 175 | subtest 'public_get() tests' => sub { | 
            
              | 176 |     plan tests => 12; | 
            
              | 177 |  | 
            
              | 178 |     $schema->storage->txn_begin; | 
            
              | 179 |  | 
            
              | 180 |     my $password = 'thePassword123'; | 
            
              | 181 |     my $patron_1 = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 182 |     my $patron_2 = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 183 |  | 
            
              | 184 |     $patron_1->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 185 |     $patron_2->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 186 |  | 
            
              | 187 |     my $patron_1_userid = $patron_1->userid; | 
            
              | 188 |     my $patron_2_userid = $patron_2->userid; | 
            
              | 189 |  | 
            
              | 190 |     # Create test lists | 
            
              | 191 |     my $public_list = $builder->build_object( | 
            
              | 192 |         { | 
            
              | 193 |             class => 'Koha::Virtualshelves', | 
            
              | 194 |             value => { | 
            
              | 195 |                 owner                   => $patron_1->id, | 
            
              | 196 |                 public                  => 1, | 
            
              | 197 |                 allow_change_from_owner => 1 | 
            
              | 198 |             } | 
            
              | 199 |         } | 
            
              | 200 |     ); | 
            
              | 201 |  | 
            
              | 202 |     my $private_list = $builder->build_object( | 
            
              | 203 |         { | 
            
              | 204 |             class => 'Koha::Virtualshelves', | 
            
              | 205 |             value => { | 
            
              | 206 |                 owner                   => $patron_1->id, | 
            
              | 207 |                 public                  => 0, | 
            
              | 208 |                 allow_change_from_owner => 0 | 
            
              | 209 |             } | 
            
              | 210 |         } | 
            
              | 211 |     ); | 
            
              | 212 |  | 
            
              | 213 |     # Test anonymous access to public list | 
            
              | 214 |     $t->get_ok( "/api/v1/public/lists/" . $public_list->id )->status_is(200)->json_is( $public_list->to_api ); | 
            
              | 215 |  | 
            
              | 216 |     # Test anonymous access to private list | 
            
              | 217 |     $t->get_ok( "/api/v1/public/lists/" . $private_list->id ) | 
            
              | 218 |         ->status_is( 403, 'Anonymous user cannot access private list' ); | 
            
              | 219 |  | 
            
              | 220 |     # Test authenticated access - owner can see their private list | 
            
              | 221 |     $t->get_ok( "//$patron_1_userid:$password@/api/v1/public/lists/" . $private_list->id )->status_is(200) | 
            
              | 222 |         ->json_is( $private_list->to_api ); | 
            
              | 223 |  | 
            
              | 224 |     # Test non-owner access to private list | 
            
              | 225 |     $t->get_ok( "//$patron_2_userid:$password@/api/v1/public/lists/" . $private_list->id ) | 
            
              | 226 |         ->status_is( 403, 'Non-owner cannot access private list' ); | 
            
              | 227 |  | 
            
              | 228 |     # Test non-existent list | 
            
              | 229 |     $t->get_ok("/api/v1/public/lists/99999999")->status_is( 404, "List not found" ); | 
            
              | 230 |  | 
            
              | 231 |     $schema->storage->txn_rollback; | 
            
              | 232 | }; | 
            
              | 233 |  | 
            
              | 234 | subtest 'public_add() tests' => sub { | 
            
              | 235 |     plan tests => 9;    # Reduced test count since we're removing one assertion | 
            
              | 236 |  | 
            
              | 237 |     $schema->storage->txn_begin; | 
            
              | 238 |  | 
            
              | 239 |     my $password       = 'thePassword123'; | 
            
              | 240 |     my $patron         = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 241 |     my $another_patron = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 242 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 243 |     my $patron_userid = $patron->userid; | 
            
              | 244 |  | 
            
              | 245 |     my $list_data = { | 
            
              | 246 |         name                     => "Test List", | 
            
              | 247 |         public                   => 1, | 
            
              | 248 |         allow_change_from_owner  => 1, | 
            
              | 249 |         allow_change_from_others => 0, | 
            
              | 250 |         default_sort_field       => 'title' | 
            
              | 251 |     }; | 
            
              | 252 |  | 
            
              | 253 |     # Test anonymous attempt | 
            
              | 254 |     $t->post_ok( "/api/v1/public/lists" => json => $list_data )->status_is( 401, 'Anonymous user cannot create list' ); | 
            
              | 255 |  | 
            
              | 256 |     # Test authenticated user can create list | 
            
              | 257 |     $t->post_ok( "//$patron_userid:$password@/api/v1/public/lists" => json => $list_data )->status_is(201) | 
            
              | 258 |         ->json_has( '/list_id', 'List ID is present in response' ) | 
            
              | 259 |         ->json_has( '/name',    'List name is present in response' )->json_is( | 
            
              | 260 |         '/owner_id' => $patron->id, | 
            
              | 261 |         'List created with logged in user as owner' | 
        
          | 110 |         ); | 262 |         ); | 
        
          | 111 |  | 263 |  | 
          
            
              | 112 |     $t->get_ok("//$patron_2_userid:$password@/api/v1/public/lists?q=$q") | 264 |     # Test attempt to specify owner_id | 
            
              | 113 |         ->status_is( 200, "Not filtering with only_mine or only_public makes it return all accessible lists" ) | 265 |     my $list_with_owner = { | 
            
              | 114 |         ->json_is( | 266 |         name                     => "Test List", | 
            
              | 115 |         [ $list_1->to_api( { public => 1 } ), $list_3->to_api( { public => 1 } ), $list_4->to_api( { public => 1 } ) ] | 267 |         owner_id                 => $another_patron->id,    # Should be rejected | 
            
              |  |  | 268 |         public                   => 1, | 
            
              | 269 |         allow_change_from_owner  => 1, | 
            
              | 270 |         allow_change_from_others => 0, | 
            
              | 271 |         default_sort_field       => 'title' | 
            
              | 272 |     }; | 
            
              | 273 |  | 
            
              | 274 |     $t->post_ok( "//$patron_userid:$password@/api/v1/public/lists" => json => $list_with_owner )->status_is(400); | 
            
              | 275 |  | 
            
              | 276 |     $schema->storage->txn_rollback; | 
            
              | 277 | }; | 
            
              | 278 |  | 
            
              | 279 | subtest 'public_update() tests' => sub { | 
            
              | 280 |     plan tests => 15; | 
            
              | 281 |  | 
            
              | 282 |     $schema->storage->txn_begin; | 
            
              | 283 |  | 
            
              | 284 |     my $password       = 'thePassword123'; | 
            
              | 285 |     my $patron         = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 286 |     my $another_patron = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 287 |  | 
            
              | 288 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 289 |     $another_patron->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 290 |  | 
            
              | 291 |     my $patron_userid         = $patron->userid; | 
            
              | 292 |     my $another_patron_userid = $another_patron->userid; | 
            
              | 293 |  | 
            
              | 294 |     # Create a list that can be modified | 
            
              | 295 |     my $modifiable_list = $builder->build_object( | 
            
              | 296 |         { | 
            
              | 297 |             class => 'Koha::Virtualshelves', | 
            
              | 298 |             value => { | 
            
              | 299 |                 owner                   => $patron->id, | 
            
              | 300 |                 public                  => 1, | 
            
              | 301 |                 allow_change_from_owner => 1 | 
            
              | 302 |             } | 
            
              | 303 |         } | 
            
              | 304 |     ); | 
            
              | 305 |  | 
            
              | 306 |     # Create a list that cannot be modified | 
            
              | 307 |     my $unmodifiable_list = $builder->build_object( | 
            
              | 308 |         { | 
            
              | 309 |             class => 'Koha::Virtualshelves', | 
            
              | 310 |             value => { | 
            
              | 311 |                 owner                   => $patron->id, | 
            
              | 312 |                 public                  => 1, | 
            
              | 313 |                 allow_change_from_owner => 0 | 
            
              | 314 |             } | 
            
              | 315 |         } | 
            
              | 316 |     ); | 
            
              | 317 |  | 
            
              | 318 |     my $update_data = { | 
            
              | 319 |         name                     => "Updated List Name", | 
            
              | 320 |         public                   => 0, | 
            
              | 321 |         allow_change_from_owner  => 1, | 
            
              | 322 |         allow_change_from_others => 0, | 
            
              | 323 |         default_sort_field       => 'title' | 
            
              | 324 |     }; | 
            
              | 325 |  | 
            
              | 326 |     # Test anonymous attempt | 
            
              | 327 |     $t->put_ok( "/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) | 
            
              | 328 |         ->status_is( 401, 'Anonymous user cannot update list' ); | 
            
              | 329 |  | 
            
              | 330 |     # Test non-owner update attempt | 
            
              | 331 |     $t->put_ok( | 
            
              | 332 |         "//$another_patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) | 
            
              | 333 |         ->status_is( 403, 'Non-owner cannot update list' ); | 
            
              | 334 |  | 
            
              | 335 |     # Test owner update success | 
            
              | 336 |     $t->put_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) | 
            
              | 337 |         ->status_is(200)->json_is( '/name' => 'Updated List Name', 'List name updated' ) | 
            
              | 338 |         ->json_is( '/public' => 0, 'List privacy updated' ); | 
            
              | 339 |  | 
            
              | 340 |     # Test update of non-existent list | 
            
              | 341 |     $t->put_ok( "//$patron_userid:$password@/api/v1/public/lists/99999999" => json => $update_data ) | 
            
              | 342 |         ->status_is( 404, "List not found" ); | 
            
              | 343 |  | 
            
              | 344 |     # Test update of unmodifiable list | 
            
              | 345 |     $t->put_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $unmodifiable_list->id => json => $update_data ) | 
            
              | 346 |         ->status_is( | 
            
              | 347 |         403, | 
            
              | 348 |         "Cannot update list when allow_change_from_owner is false" | 
            
              | 349 |     )->json_is( '/error_code' => 'forbidden', 'Correct error code returned' ); | 
            
              | 350 |  | 
            
              | 351 |     # Create librarian with necessary permissions | 
            
              | 352 |     my $librarian = $builder->build_object( | 
            
              | 353 |         { | 
            
              | 354 |             class => 'Koha::Patrons', | 
            
              | 355 |             value => { flags => 2**13 } | 
            
              | 356 |         } | 
            
              | 357 |     ); | 
            
              | 358 |     $librarian->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 359 |     my $librarian_userid = $librarian->userid; | 
            
              | 360 |  | 
            
              | 361 |     # Test librarian using public endpoint | 
            
              | 362 |     $t->put_ok( "//$librarian_userid:$password@/api/v1/public/lists/" . $modifiable_list->id => json => $update_data ) | 
            
              | 363 |         ->status_is( | 
            
              | 364 |         403, | 
            
              | 365 |         'Librarian must use admin endpoint to modify others lists' | 
        
          | 116 |         ); | 366 |         ); | 
        
          | 117 |  | 367 |  | 
          
            
              | 118 |     # conflicting params | 368 |     $schema->storage->txn_rollback; | 
            
              | 119 |     $t->get_ok("//$patron_1_userid:$password@/api/v1/public/lists?q=$q&only_public=1&only_mine=1") | 369 | }; | 
            
              | 120 |         ->status_is( 200, "Passing only_public with a logged in user makes it return only public lists" ) | 370 |  | 
            
              | 121 |         ->json_is( [ $list_1->to_api( { public => 1 } ) ] ); | 371 | subtest 'public_delete() tests' => sub { | 
            
              |  |  | 372 |     plan tests => 12; | 
            
              | 373 |  | 
            
              | 374 |     $schema->storage->txn_begin; | 
            
              | 375 |  | 
            
              | 376 |     my $password       = 'thePassword123'; | 
            
              | 377 |     my $patron         = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 378 |     my $another_patron = $builder->build_object( { class => 'Koha::Patrons' } ); | 
            
              | 379 |  | 
            
              | 380 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 381 |     $another_patron->set_password( { password => $password, skip_validation => 1 } ); | 
            
              | 382 |  | 
            
              | 383 |     my $patron_userid         = $patron->userid; | 
            
              | 384 |     my $another_patron_userid = $another_patron->userid; | 
            
              | 385 |  | 
            
              | 386 |     # Create test lists for different scenarios | 
            
              | 387 |     my $modifiable_list = $builder->build_object( | 
            
              | 388 |         { | 
            
              | 389 |             class => 'Koha::Virtualshelves', | 
            
              | 390 |             value => { | 
            
              | 391 |                 owner                   => $patron->id, | 
            
              | 392 |                 public                  => 1, | 
            
              | 393 |                 allow_change_from_owner => 1 | 
            
              | 394 |             } | 
            
              | 395 |         } | 
            
              | 396 |     ); | 
            
              | 397 |  | 
            
              | 398 |     my $other_patron_list = $builder->build_object( | 
            
              | 399 |         { | 
            
              | 400 |             class => 'Koha::Virtualshelves', | 
            
              | 401 |             value => { | 
            
              | 402 |                 owner                   => $another_patron->id, | 
            
              | 403 |                 public                  => 1, | 
            
              | 404 |                 allow_change_from_owner => 1 | 
            
              | 405 |             } | 
            
              | 406 |         } | 
            
              | 407 |     ); | 
            
              | 408 |  | 
            
              | 409 |     my $unmodifiable_list = $builder->build_object( | 
            
              | 410 |         { | 
            
              | 411 |             class => 'Koha::Virtualshelves', | 
            
              | 412 |             value => { | 
            
              | 413 |                 owner                   => $patron->id, | 
            
              | 414 |                 public                  => 1, | 
            
              | 415 |                 allow_change_from_owner => 0 | 
            
              | 416 |             } | 
            
              | 417 |         } | 
            
              | 418 |     ); | 
            
              | 419 |  | 
            
              | 420 |     # Test anonymous attempt | 
            
              | 421 |     $t->delete_ok( "/api/v1/public/lists/" . $modifiable_list->id ) | 
            
              | 422 |         ->status_is( 401, 'Anonymous user cannot delete list' ); | 
            
              | 423 |  | 
            
              | 424 |     # Test non-owner delete attempt | 
            
              | 425 |     $t->delete_ok( "//$another_patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id ) | 
            
              | 426 |         ->status_is( 403, 'Non-owner cannot delete list' ); | 
            
              | 427 |  | 
            
              | 428 |     # Test attempt to delete another patron's list | 
            
              | 429 |     $t->delete_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $other_patron_list->id ) | 
            
              | 430 |         ->status_is( 403, "Cannot delete another patron's list" ); | 
            
              | 431 |  | 
            
              | 432 |     # Test delete of unmodifiable list | 
            
              | 433 |     $t->delete_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $unmodifiable_list->id )->status_is( | 
            
              | 434 |         403, | 
            
              | 435 |         "Cannot delete list when allow_change_from_owner is false" | 
            
              | 436 |     ); | 
            
              | 437 |  | 
            
              | 438 |     # Test delete of non-existent list | 
            
              | 439 |     $t->delete_ok("//$patron_userid:$password@/api/v1/public/lists/99999999")->status_is( 404, "List not found" ); | 
            
              | 440 |  | 
            
              | 441 |     # Test successful delete by owner | 
            
              | 442 |     $t->delete_ok( "//$patron_userid:$password@/api/v1/public/lists/" . $modifiable_list->id ) | 
            
              | 443 |         ->status_is( 204, 'List deleted successfully' ); | 
        
          | 122 |  | 444 |  | 
        
          | 123 |     $schema->storage->txn_rollback; | 445 |     $schema->storage->txn_rollback; | 
        
          | 124 | }; | 446 | }; | 
          
            
              | 125 | -  | 447 |  | 
            
              |  |  | 448 | 1; |