| Lines 61-70
          subtest 'list() tests' => sub {
      
      
        Link Here | 
        
          | 61 |     my $unauth_userid = $patron->userid; | 61 |     my $unauth_userid = $patron->userid; | 
        
          | 62 |  | 62 |  | 
        
          | 63 |     ## Authorized user tests | 63 |     ## Authorized user tests | 
          
            
              | 64 |     # No FTP/SFTP servers, so empty array should be returned | 64 |     # No File transports, so empty array should be returned | 
            
              | 65 |     $t->get_ok("//$userid:$password@/api/v1/config/sftp_servers")->status_is(200)->json_is( [] ); | 65 |     $t->get_ok("//$userid:$password@/api/v1/config/file_transports")->status_is(200)->json_is( [] ); | 
        
          | 66 |  | 66 |  | 
          
            
              | 67 |     my $sftp_server = $builder->build_object( | 67 |     my $file_transport = $builder->build_object( | 
        
          | 68 |         { | 68 |         { | 
        
          | 69 |             class => 'Koha::File::Transports', | 69 |             class => 'Koha::File::Transports', | 
        
          | 70 |             value => { | 70 |             value => { | 
  
    | Lines 76-85
          subtest 'list() tests' => sub {
      
      
        Link Here | 
        
          | 76 |         } | 76 |         } | 
        
          | 77 |     ); | 77 |     ); | 
        
          | 78 |  | 78 |  | 
          
            
              | 79 |     # One sftp server created, should get returned | 79 |     # One file transport created, should get returned | 
            
              | 80 |     $t->get_ok("//$userid:$password@/api/v1/config/sftp_servers")->status_is(200)->json_is( [ $sftp_server->to_api ] ); | 80 |     $t->get_ok("//$userid:$password@/api/v1/config/file_transports")->status_is(200) | 
            
              |  |  | 81 |         ->json_is( [ $file_transport->to_api ] ); | 
        
          | 81 |  | 82 |  | 
          
            
              | 82 |     my $another_sftp_server = $builder->build_object( | 83 |     my $another_file_transport = $builder->build_object( | 
        
          | 83 |         { | 84 |         { | 
        
          | 84 |             class => 'Koha::File::Transports', | 85 |             class => 'Koha::File::Transports', | 
        
          | 85 |             value => { | 86 |             value => { | 
  
    | Lines 91-102
          subtest 'list() tests' => sub {
      
      
        Link Here | 
        
          | 91 |         } | 92 |         } | 
        
          | 92 |     ); | 93 |     ); | 
        
          | 93 |  | 94 |  | 
          
            
              | 94 |     # Two FTP/SFTP servers created, they should both be returned | 95 |     # Two File transports created, they should both be returned | 
            
              | 95 |     $t->get_ok("//$userid:$password@/api/v1/config/sftp_servers")->status_is(200) | 96 |     $t->get_ok("//$userid:$password@/api/v1/config/file_transports")->status_is(200) | 
            
              | 96 |         ->json_is( [ $sftp_server->to_api, $another_sftp_server->to_api, ] ); | 97 |         ->json_is( [ $file_transport->to_api, $another_file_transport->to_api, ] ); | 
        
          | 97 |  | 98 |  | 
        
          | 98 |     # Unauthorized access | 99 |     # Unauthorized access | 
          
            
              | 99 |     $t->get_ok("//$unauth_userid:$password@/api/v1/config/sftp_servers")->status_is(403); | 100 |     $t->get_ok("//$unauth_userid:$password@/api/v1/config/file_transports")->status_is(403); | 
        
          | 100 |  | 101 |  | 
        
          | 101 |     $schema->storage->txn_rollback; | 102 |     $schema->storage->txn_rollback; | 
        
          | 102 | }; | 103 | }; | 
  
    | Lines 107-113
          subtest 'get() tests' => sub {
      
      
        Link Here | 
        
          | 107 |  | 108 |  | 
        
          | 108 |     $schema->storage->txn_begin; | 109 |     $schema->storage->txn_begin; | 
        
          | 109 |  | 110 |  | 
          
            
              | 110 |     my $sftp_server = $builder->build_object( | 111 |     my $file_transport = $builder->build_object( | 
        
          | 111 |         { | 112 |         { | 
        
          | 112 |             class => 'Koha::File::Transports', | 113 |             class => 'Koha::File::Transports', | 
        
          | 113 |             value => { | 114 |             value => { | 
  
    | Lines 138-149
          subtest 'get() tests' => sub {
      
      
        Link Here | 
        
          | 138 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 139 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
        
          | 139 |     my $unauth_userid = $patron->userid; | 140 |     my $unauth_userid = $patron->userid; | 
        
          | 140 |  | 141 |  | 
          
            
              | 141 |     $t->get_ok( "//$userid:$password@/api/v1/config/sftp_servers/" . $sftp_server->id )->status_is(200) | 142 |     $t->get_ok( "//$userid:$password@/api/v1/config/file_transports/" . $file_transport->id )->status_is(200) | 
            
              | 142 |         ->json_is( $sftp_server->to_api ); | 143 |         ->json_is( $file_transport->to_api ); | 
        
          | 143 |  | 144 |  | 
          
            
              | 144 |     $t->get_ok( "//$unauth_userid:$password@/api/v1/config/sftp_servers/" . $sftp_server->id )->status_is(403); | 145 |     $t->get_ok( "//$unauth_userid:$password@/api/v1/config/file_transports/" . $file_transport->id )->status_is(403); | 
        
          | 145 |  | 146 |  | 
          
            
              | 146 |     my $sftp_server_to_delete = $builder->build_object( | 147 |     my $file_transport_to_delete = $builder->build_object( | 
        
          | 147 |         { | 148 |         { | 
        
          | 148 |             class => 'Koha::File::Transports', | 149 |             class => 'Koha::File::Transports', | 
        
          | 149 |             value => { | 150 |             value => { | 
  
    | Lines 154-164
          subtest 'get() tests' => sub {
      
      
        Link Here | 
        
          | 154 |             }, | 155 |             }, | 
        
          | 155 |         } | 156 |         } | 
        
          | 156 |     ); | 157 |     ); | 
          
            
              | 157 |     my $non_existent_id = $sftp_server_to_delete->id; | 158 |     my $non_existent_id = $file_transport_to_delete->id; | 
            
              | 158 |     $sftp_server_to_delete->delete; | 159 |     $file_transport_to_delete->delete; | 
        
          | 159 |  | 160 |  | 
          
            
              | 160 |     $t->get_ok("//$userid:$password@/api/v1/config/sftp_servers/$non_existent_id")->status_is(404) | 161 |     $t->get_ok("//$userid:$password@/api/v1/config/file_transports/$non_existent_id")->status_is(404) | 
            
              | 161 |         ->json_is( '/error' => 'FTP/SFTP server not found' ); | 162 |         ->json_is( '/error' => 'File transport not found' ); | 
        
          | 162 |  | 163 |  | 
        
          | 163 |     $schema->storage->txn_rollback; | 164 |     $schema->storage->txn_rollback; | 
        
          | 164 | }; | 165 | }; | 
  
    | Lines 191-197
          subtest 'add() tests' => sub {
      
      
        Link Here | 
        
          | 191 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 192 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
        
          | 192 |     my $unauth_userid = $patron->userid; | 193 |     my $unauth_userid = $patron->userid; | 
        
          | 193 |  | 194 |  | 
          
            
              | 194 |     my $sftp_server = $builder->build_object( | 195 |     my $file_transport = $builder->build_object( | 
        
          | 195 |         { | 196 |         { | 
        
          | 196 |             class => 'Koha::File::Transports', | 197 |             class => 'Koha::File::Transports', | 
        
          | 197 |             value => { | 198 |             value => { | 
  
    | Lines 202-222
          subtest 'add() tests' => sub {
      
      
        Link Here | 
        
          | 202 |             }, | 203 |             }, | 
        
          | 203 |         } | 204 |         } | 
        
          | 204 |     ); | 205 |     ); | 
          
            
              | 205 |     my $sftp_server_data = $sftp_server->to_api; | 206 |     my $file_transport_data = $file_transport->to_api; | 
            
              | 206 |     delete $sftp_server_data->{sftp_server_id}; | 207 |     delete $file_transport_data->{file_transport_id}; | 
            
              | 207 |     $sftp_server->delete; | 208 |     $file_transport->delete; | 
        
          | 208 |  | 209 |  | 
        
          | 209 |     # Unauthorized attempt to write | 210 |     # Unauthorized attempt to write | 
          
            
              | 210 |     $t->post_ok( "//$unauth_userid:$password@/api/v1/config/sftp_servers" => json => $sftp_server_data ) | 211 |     $t->post_ok( "//$unauth_userid:$password@/api/v1/config/file_transports" => json => $file_transport_data ) | 
        
          | 211 |         ->status_is(403); | 212 |         ->status_is(403); | 
        
          | 212 |  | 213 |  | 
        
          | 213 |     # Authorized attempt to write invalid data | 214 |     # Authorized attempt to write invalid data | 
          
            
              | 214 |     my $sftp_server_with_invalid_field = { | 215 |     my $file_transport_with_invalid_field = { | 
        
          | 215 |         name => 'Some other server', | 216 |         name => 'Some other server', | 
        
          | 216 |         blah => 'blah' | 217 |         blah => 'blah' | 
        
          | 217 |     }; | 218 |     }; | 
        
          | 218 |  | 219 |  | 
          
            
              | 219 |     $t->post_ok( "//$userid:$password@/api/v1/config/sftp_servers" => json => $sftp_server_with_invalid_field ) | 220 |     $t->post_ok( "//$userid:$password@/api/v1/config/file_transports" => json => $file_transport_with_invalid_field ) | 
        
          | 220 |         ->status_is(400)->json_is( | 221 |         ->status_is(400)->json_is( | 
        
          | 221 |         "/errors" => [ | 222 |         "/errors" => [ | 
        
          | 222 |             { | 223 |             { | 
  
    | Lines 227-251
          subtest 'add() tests' => sub {
      
      
        Link Here | 
        
          | 227 |         ); | 228 |         ); | 
        
          | 228 |  | 229 |  | 
        
          | 229 |     # Authorized attempt to write | 230 |     # Authorized attempt to write | 
          
            
              | 230 |     my $sftp_server_id = | 231 |     my $file_transport_id = | 
            
              | 231 |         $t->post_ok( "//$userid:$password@/api/v1/config/sftp_servers" => json => $sftp_server_data ) | 232 |         $t->post_ok( "//$userid:$password@/api/v1/config/file_transports" => json => $file_transport_data ) | 
        
          | 232 |         ->status_is( 201, 'SWAGGER3.2.1' ) | 233 |         ->status_is( 201, 'SWAGGER3.2.1' ) | 
          
            
              | 233 |         ->header_like( Location => qr|^\/api\/v1\/config\/sftp_servers\/\d*|, 'SWAGGER3.4.1' ) | 234 |         ->header_like( Location => qr|^\/api\/v1\/config\/file_transports\/\d*|, 'SWAGGER3.4.1' ) | 
            
              | 234 |         ->json_is( '/name' => $sftp_server_data->{name} )->tx->res->json->{sftp_server_id}; | 235 |         ->json_is( '/name' => $file_transport_data->{name} )->tx->res->json->{file_transport_id}; | 
        
          | 235 |  | 236 |  | 
        
          | 236 |     # Authorized attempt to create with null id | 237 |     # Authorized attempt to create with null id | 
          
            
              | 237 |     $sftp_server_data->{sftp_server_id} = undef; | 238 |     $file_transport_data->{file_transport_id} = undef; | 
            
              | 238 |     $t->post_ok( "//$userid:$password@/api/v1/config/sftp_servers" => json => $sftp_server_data )->status_is(400) | 239 |     $t->post_ok( "//$userid:$password@/api/v1/config/file_transports" => json => $file_transport_data )->status_is(400) | 
        
          | 239 |         ->json_has('/errors'); | 240 |         ->json_has('/errors'); | 
        
          | 240 |  | 241 |  | 
        
          | 241 |     # Authorized attempt to create with existing id | 242 |     # Authorized attempt to create with existing id | 
          
            
              | 242 |     $sftp_server_data->{sftp_server_id} = $sftp_server_id; | 243 |     $file_transport_data->{file_transport_id} = $file_transport_id; | 
            
              | 243 |     $t->post_ok( "//$userid:$password@/api/v1/config/sftp_servers" => json => $sftp_server_data )->status_is(400) | 244 |     $t->post_ok( "//$userid:$password@/api/v1/config/file_transports" => json => $file_transport_data )->status_is(400) | 
        
          | 244 |         ->json_is( | 245 |         ->json_is( | 
        
          | 245 |         "/errors" => [ | 246 |         "/errors" => [ | 
        
          | 246 |             { | 247 |             { | 
        
          | 247 |                 message => "Read-only.", | 248 |                 message => "Read-only.", | 
          
            
              | 248 |                 path    => "/body/sftp_server_id" | 249 |                 path    => "/body/file_transport_id" | 
        
          | 249 |             } | 250 |             } | 
        
          | 250 |         ] | 251 |         ] | 
        
          | 251 |         ); | 252 |         ); | 
  
    | Lines 279-285
          subtest 'update() tests' => sub {
      
      
        Link Here | 
        
          | 279 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 280 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
        
          | 280 |     my $unauth_userid = $patron->userid; | 281 |     my $unauth_userid = $patron->userid; | 
        
          | 281 |  | 282 |  | 
          
            
              | 282 |     my $sftp_server_id = $builder->build_object( | 283 |     my $file_transport_id = $builder->build_object( | 
        
          | 283 |         { | 284 |         { | 
        
          | 284 |             class => 'Koha::File::Transports', | 285 |             class => 'Koha::File::Transports', | 
        
          | 285 |             value => { | 286 |             value => { | 
  
    | Lines 292-338
          subtest 'update() tests' => sub {
      
      
        Link Here | 
        
          | 292 |     )->id; | 293 |     )->id; | 
        
          | 293 |  | 294 |  | 
        
          | 294 |     # Unauthorized attempt to update | 295 |     # Unauthorized attempt to update | 
          
            
              | 295 |     $t->put_ok( "//$unauth_userid:$password@/api/v1/config/sftp_servers/$sftp_server_id" => json => | 296 |     $t->put_ok( "//$unauth_userid:$password@/api/v1/config/file_transports/$file_transport_id" => json => | 
        
          | 296 |             { name => 'New unauthorized name change' } )->status_is(403); | 297 |             { name => 'New unauthorized name change' } )->status_is(403); | 
        
          | 297 |  | 298 |  | 
        
          | 298 |     # Attempt partial update on a PUT | 299 |     # Attempt partial update on a PUT | 
          
            
              | 299 |     my $sftp_server_with_missing_field = { | 300 |     my $file_transport_with_missing_field = { | 
        
          | 300 |         host    => 'localhost', | 301 |         host    => 'localhost', | 
        
          | 301 |         passive => '1' | 302 |         passive => '1' | 
        
          | 302 |     }; | 303 |     }; | 
        
          | 303 |  | 304 |  | 
          
            
              | 304 |     $t->put_ok( | 305 |     $t->put_ok( "//$userid:$password@/api/v1/config/file_transports/$file_transport_id" => json => | 
            
              | 305 |         "//$userid:$password@/api/v1/config/sftp_servers/$sftp_server_id" => json => $sftp_server_with_missing_field ) | 306 |             $file_transport_with_missing_field )->status_is(400) | 
            
              | 306 |         ->status_is(400)->json_is( "/errors" => [ { message => "Missing property.", path => "/body/name" } ] ); | 307 |         ->json_is( "/errors" => [ { message => "Missing property.", path => "/body/name" } ] ); | 
        
          | 307 |  | 308 |  | 
        
          | 308 |     # Full object update on PUT | 309 |     # Full object update on PUT | 
          
            
              | 309 |     my $sftp_server_with_updated_field = { | 310 |     my $file_transport_with_updated_field = { | 
        
          | 310 |         name     => "Some name", | 311 |         name     => "Some name", | 
        
          | 311 |         password => "some_pass", | 312 |         password => "some_pass", | 
        
          | 312 |     }; | 313 |     }; | 
        
          | 313 |  | 314 |  | 
          
            
              | 314 |     $t->put_ok( | 315 |     $t->put_ok( "//$userid:$password@/api/v1/config/file_transports/$file_transport_id" => json => | 
            
              | 315 |         "//$userid:$password@/api/v1/config/sftp_servers/$sftp_server_id" => json => $sftp_server_with_updated_field ) | 316 |             $file_transport_with_updated_field )->status_is(200)->json_is( '/name' => 'Some name' ); | 
            
              | 316 |         ->status_is(200)->json_is( '/name' => 'Some name' ); |  |  | 
        
          | 317 |  | 317 |  | 
        
          | 318 |     # Authorized attempt to write invalid data | 318 |     # Authorized attempt to write invalid data | 
          
            
              | 319 |     my $sftp_server_with_invalid_field = { | 319 |     my $file_transport_with_invalid_field = { | 
        
          | 320 |         blah => "Blah", | 320 |         blah => "Blah", | 
        
          | 321 |         name => 'Some name' | 321 |         name => 'Some name' | 
        
          | 322 |     }; | 322 |     }; | 
        
          | 323 |  | 323 |  | 
          
            
              | 324 |     $t->put_ok( | 324 |     $t->put_ok( "//$userid:$password@/api/v1/config/file_transports/$file_transport_id" => json => | 
            
              | 325 |         "//$userid:$password@/api/v1/config/sftp_servers/$sftp_server_id" => json => $sftp_server_with_invalid_field ) | 325 |             $file_transport_with_invalid_field )->status_is(400)->json_is( | 
            
              | 326 |         ->status_is(400)->json_is( |  |  | 
        
          | 327 |         "/errors" => [ | 326 |         "/errors" => [ | 
        
          | 328 |             { | 327 |             { | 
        
          | 329 |                 message => "Properties not allowed: blah.", | 328 |                 message => "Properties not allowed: blah.", | 
        
          | 330 |                 path    => "/body" | 329 |                 path    => "/body" | 
        
          | 331 |             } | 330 |             } | 
        
          | 332 |         ] | 331 |         ] | 
          
            
              | 333 |         ); | 332 |             ); | 
        
          | 334 |  | 333 |  | 
          
            
              | 335 |     my $sftp_server_to_delete = $builder->build_object( | 334 |     my $file_transport_to_delete = $builder->build_object( | 
        
          | 336 |         { | 335 |         { | 
        
          | 337 |             class => 'Koha::File::Transports', | 336 |             class => 'Koha::File::Transports', | 
        
          | 338 |             value => { | 337 |             value => { | 
  
    | Lines 343-361
          subtest 'update() tests' => sub {
      
      
        Link Here | 
        
          | 343 |             }, | 342 |             }, | 
        
          | 344 |         } | 343 |         } | 
        
          | 345 |     ); | 344 |     ); | 
          
            
              | 346 |     my $non_existent_id = $sftp_server_to_delete->id; | 345 |     my $non_existent_id = $file_transport_to_delete->id; | 
            
              | 347 |     $sftp_server_to_delete->delete; | 346 |     $file_transport_to_delete->delete; | 
        
          | 348 |  | 347 |  | 
          
            
              | 349 |     $t->put_ok( | 348 |     $t->put_ok( "//$userid:$password@/api/v1/config/file_transports/$non_existent_id" => json => | 
            
              | 350 |         "//$userid:$password@/api/v1/config/sftp_servers/$non_existent_id" => json => $sftp_server_with_updated_field ) | 349 |             $file_transport_with_updated_field )->status_is(404); | 
            
              | 351 |         ->status_is(404); |  |  | 
        
          | 352 |  | 350 |  | 
        
          | 353 |     # Wrong method (POST) | 351 |     # Wrong method (POST) | 
          
            
              | 354 |     $sftp_server_with_updated_field->{sftp_server_id} = 2; | 352 |     $file_transport_with_updated_field->{file_transport_id} = 2; | 
        
          | 355 |  | 353 |  | 
          
            
              | 356 |     $t->post_ok( | 354 |     $t->post_ok( "//$userid:$password@/api/v1/config/file_transports/$file_transport_id" => json => | 
            
              | 357 |         "//$userid:$password@/api/v1/config/sftp_servers/$sftp_server_id" => json => $sftp_server_with_updated_field ) | 355 |             $file_transport_with_updated_field )->status_is(404); | 
            
              | 358 |         ->status_is(404); |  |  | 
        
          | 359 |  | 356 |  | 
        
          | 360 |     $schema->storage->txn_rollback; | 357 |     $schema->storage->txn_rollback; | 
        
          | 361 | }; | 358 | }; | 
  
    | Lines 386-392
          subtest 'delete() tests' => sub {
      
      
        Link Here | 
        
          | 386 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 383 |     $patron->set_password( { password => $password, skip_validation => 1 } ); | 
        
          | 387 |     my $unauth_userid = $patron->userid; | 384 |     my $unauth_userid = $patron->userid; | 
        
          | 388 |  | 385 |  | 
          
            
              | 389 |     my $sftp_server_id = $builder->build_object( | 386 |     my $file_transport_id = $builder->build_object( | 
        
          | 390 |         { | 387 |         { | 
        
          | 391 |             class => 'Koha::File::Transports', | 388 |             class => 'Koha::File::Transports', | 
        
          | 392 |             value => { | 389 |             value => { | 
  
    | Lines 399-410
          subtest 'delete() tests' => sub {
      
      
        Link Here | 
        
          | 399 |     )->id; | 396 |     )->id; | 
        
          | 400 |  | 397 |  | 
        
          | 401 |     # Unauthorized attempt to delete | 398 |     # Unauthorized attempt to delete | 
          
            
              | 402 |     $t->delete_ok("//$unauth_userid:$password@/api/v1/config/sftp_servers/$sftp_server_id")->status_is(403); | 399 |     $t->delete_ok("//$unauth_userid:$password@/api/v1/config/file_transports/$file_transport_id")->status_is(403); | 
        
          | 403 |  | 400 |  | 
          
            
              | 404 |     $t->delete_ok("//$userid:$password@/api/v1/config/sftp_servers/$sftp_server_id")->status_is( 204, 'SWAGGER3.2.4' ) | 401 |     $t->delete_ok("//$userid:$password@/api/v1/config/file_transports/$file_transport_id") | 
            
              | 405 |         ->content_is( '', 'SWAGGER3.3.4' ); | 402 |         ->status_is( 204, 'SWAGGER3.2.4' )->content_is( '', 'SWAGGER3.3.4' ); | 
        
          | 406 |  | 403 |  | 
          
            
              | 407 |     $t->delete_ok("//$userid:$password@/api/v1/config/sftp_servers/$sftp_server_id")->status_is(404); | 404 |     $t->delete_ok("//$userid:$password@/api/v1/config/file_transports/$file_transport_id")->status_is(404); | 
        
          | 408 |  | 405 |  | 
        
          | 409 |     $schema->storage->txn_rollback; | 406 |     $schema->storage->txn_rollback; | 
        
          | 410 | }; | 407 | }; | 
            
              | 411 | -  |  |  |