From 3855ac3b7588b5f55e2250f40df50238b2ffe3a6 Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Tue, 22 Oct 2019 13:56:15 -0300
Subject: [PATCH] Bug 23860: Update tests to new style

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
---
 t/db_dependent/api/v1/patrons.t | 254 ++++++++++++++++----------------
 1 file changed, 124 insertions(+), 130 deletions(-)

diff --git a/t/db_dependent/api/v1/patrons.t b/t/db_dependent/api/v1/patrons.t
index 6e31319228..9579229bb4 100644
--- a/t/db_dependent/api/v1/patrons.t
+++ b/t/db_dependent/api/v1/patrons.t
@@ -31,12 +31,8 @@ use Koha::Patron::Debarments qw/AddDebarment/;
 my $schema  = Koha::Database->new->schema;
 my $builder = t::lib::TestBuilder->new;
 
-# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
-# this affects the other REST api tests
-t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
-
-my $remote_address = '127.0.0.1';
-my $t              = Test::Mojo->new('Koha::REST::V1');
+my $t = Test::Mojo->new('Koha::REST::V1');
+t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
 
 subtest 'list() tests' => sub {
     plan tests => 2;
@@ -50,40 +46,31 @@ subtest 'list() tests' => sub {
 
         $schema->storage->txn_begin;
 
-        my ( $patron_id, $session_id ) = create_user_and_session({ authorized => 1 });
-        my $patron = Koha::Patrons->find($patron_id);
+        my $librarian = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 2**4 }    # borrowers flag = 4
+            }
+        );
+        my $password = 'thePassword123';
+        $librarian->set_password( { password => $password, skip_validation => 1 } );
+        my $userid = $librarian->userid;
 
-        my $tx = $t->ua->build_tx(GET => '/api/v1/patrons');
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
-        $t->request_ok($tx)
+        $t->get_ok("//$userid:$password@/api/v1/patrons")
           ->status_is(200);
 
-        $tx = $t->ua->build_tx(GET => '/api/v1/patrons?cardnumber=' . $patron->cardnumber);
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
-        $t->request_ok($tx)
+        $t->get_ok("//$userid:$password@/api/v1/patrons?cardnumber=" . $librarian->cardnumber)
           ->status_is(200)
-          ->json_is('/0/cardnumber' => $patron->cardnumber);
+          ->json_is('/0/cardnumber' => $librarian->cardnumber);
 
-        $tx = $t->ua->build_tx(GET => '/api/v1/patrons?address2='.
-                                  $patron->address2);
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
-        $t->request_ok($tx)
+        $t->get_ok("//$userid:$password@/api/v1/patrons?address2=" . $librarian->address2)
           ->status_is(200)
-          ->json_is('/0/address2' => $patron->address2);
-
-        my $patron_2 = $builder->build_object({ class => 'Koha::Patrons' });
-        AddDebarment({ borrowernumber => $patron_2->id });
-        # re-read from DB
-        $patron_2->discard_changes;
-        my $ub = $patron_2->unblessed;
-
-        $tx = $t->ua->build_tx( GET => '/api/v1/patrons?restricted=' . Mojo::JSON->true );
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
-        $t->request_ok($tx)
+          ->json_is('/0/address2' => $librarian->address2);
+
+        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
+        AddDebarment({ borrowernumber => $patron->borrowernumber });
+
+        $t->get_ok("//$userid:$password@/api/v1/patrons?restricted=" . Mojo::JSON->true . "&cardnumber=" . $patron->cardnumber )
           ->status_is(200)
           ->json_has('/0/restricted')
           ->json_is( '/0/restricted' => Mojo::JSON->true )
@@ -105,12 +92,19 @@ subtest 'get() tests' => sub {
 
         $schema->storage->txn_begin;
 
+        my $librarian = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 2**4 }    # borrowers flag = 4
+            }
+        );
+        my $password = 'thePassword123';
+        $librarian->set_password( { password => $password, skip_validation => 1 } );
+        my $userid = $librarian->userid;
+
         my $patron = $builder->build_object({ class => 'Koha::Patrons' });
-        my ( undef, $session_id ) = create_user_and_session({ authorized => 1 });
 
-        my $tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $patron->id);
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $t->request_ok($tx)
+        $t->get_ok("//$userid:$password@/api/v1/patrons/" . $patron->id)
           ->status_is(200)
           ->json_is('/patron_id'        => $patron->id)
           ->json_is('/category_id'      => $patron->categorycode )
@@ -126,8 +120,7 @@ subtest 'add() tests' => sub {
 
     $schema->storage->txn_begin;
 
-    my $patron = Koha::REST::V1::Patrons::_to_api(
-        $builder->build_object( { class => 'Koha::Patrons' } )->TO_JSON );
+    my $patron = $builder->build_object( { class => 'Koha::Patrons' } )->to_api;
 
     unauthorized_access_tests('POST', undef, $patron);
 
@@ -139,7 +132,7 @@ subtest 'add() tests' => sub {
         $schema->storage->txn_begin;
 
         my $patron = $builder->build_object({ class => 'Koha::Patrons' });
-        my $newpatron = Koha::REST::V1::Patrons::_to_api( $patron->TO_JSON );
+        my $newpatron = $patron->to_api;
         # delete RO attributes
         delete $newpatron->{patron_id};
         delete $newpatron->{restricted};
@@ -151,13 +144,20 @@ subtest 'add() tests' => sub {
         # Delete library
         $library_to_delete->delete;
 
-        my ( undef, $session_id ) = create_user_and_session({ authorized => 1 });
+        my $librarian = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 2**4 }    # borrowers flag = 4
+            }
+        );
+        my $password = 'thePassword123';
+        $librarian->set_password( { password => $password, skip_validation => 1 } );
+        my $userid = $librarian->userid;
 
         $newpatron->{library_id} = $deleted_library_id;
-        my $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron );
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
+
         warning_like {
-            $t->request_ok($tx)
+            $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
               ->status_is(409)
               ->json_is('/error' => "Duplicate ID"); }
             qr/^DBD::mysql::st execute failed: Duplicate entry/;
@@ -171,31 +171,28 @@ subtest 'add() tests' => sub {
         $category_to_delete->delete;
 
         $newpatron->{category_id} = $deleted_category_id; # Test invalid patron category
-        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $t->request_ok($tx)
+
+        $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
           ->status_is(400)
           ->json_is('/error' => "Given category_id does not exist");
         $newpatron->{category_id} = $patron->categorycode;
 
         $newpatron->{falseproperty} = "Non existent property";
-        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $t->request_ok($tx)
+
+        $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
           ->status_is(400);
+
         delete $newpatron->{falseproperty};
 
         my $patron_to_delete = $builder->build_object({ class => 'Koha::Patrons' });
-        $newpatron = Koha::REST::V1::Patrons::_to_api($patron_to_delete->TO_JSON);
+        $newpatron = $patron_to_delete->to_api;
         # delete RO attributes
         delete $newpatron->{patron_id};
         delete $newpatron->{restricted};
         delete $newpatron->{anonymized};
         $patron_to_delete->delete;
 
-        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $t->request_ok($tx)
+        $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
           ->status_is(201, 'Patron created successfully')
           ->header_like(
             Location => qr|^\/api\/v1\/patrons/\d*|,
@@ -206,10 +203,8 @@ subtest 'add() tests' => sub {
           ->json_is( '/surname'    => $newpatron->{ surname })
           ->json_is( '/firstname'  => $newpatron->{ firstname });
 
-        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
         warning_like {
-            $t->request_ok($tx)
+            $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
               ->status_is(409)
               ->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' )
               ->json_has( '/conflict', 'cardnumber' ); }
@@ -231,21 +226,35 @@ subtest 'update() tests' => sub {
 
         $schema->storage->txn_begin;
 
-        t::lib::Mocks::mock_preference('minPasswordLength', 1);
-        my ( $patron_id_1, $session_id ) = create_user_and_session({ authorized => 1 });
-        my ( $patron_id_2, undef )       = create_user_and_session({ authorized => 0 });
+        my $authorized_patron = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 2**4 } # borrowers flag = 4
+            }
+        );
+        my $password = 'thePassword123';
+        $authorized_patron->set_password(
+            { password => $password, skip_validation => 1 } );
+        my $userid = $authorized_patron->userid;
+
+        my $unauthorized_patron = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 0 }
+            }
+        );
+        $unauthorized_patron->set_password( { password => $password, skip_validation => 1 } );
+        my $unauth_userid = $unauthorized_patron->userid;
 
-        my $patron_1  = Koha::Patrons->find($patron_id_1);
-        my $patron_2  = Koha::Patrons->find($patron_id_2);
-        my $newpatron = Koha::REST::V1::Patrons::_to_api($patron_2->TO_JSON);
+        my $patron_1  = $authorized_patron;
+        my $patron_2  = $unauthorized_patron;
+        my $newpatron = $unauthorized_patron->to_api;
         # delete RO attributes
         delete $newpatron->{patron_id};
         delete $newpatron->{restricted};
         delete $newpatron->{anonymized};
 
-        my $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/-1" => json => $newpatron );
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
-        $t->request_ok($tx)
+        $t->put_ok("//$userid:$password@/api/v1/patrons/-1" => json => $newpatron)
           ->status_is(404)
           ->json_has('/error', 'Fails when trying to PUT nonexistent patron');
 
@@ -255,12 +264,14 @@ subtest 'update() tests' => sub {
         # Delete library
         $category_to_delete->delete;
 
+        # Use an invalid category
         $newpatron->{category_id} = $deleted_category_id;
-        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/$patron_id_2" => json => $newpatron );
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
-        $t->request_ok($tx)
+
+        $t->put_ok("//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron)
           ->status_is(400)
           ->json_is('/error' => "Given category_id does not exist");
+
+        # Restore the valid category
         $newpatron->{category_id} = $patron_2->categorycode;
 
         # Create a library just to make sure its ID doesn't exist on the DB
@@ -269,45 +280,45 @@ subtest 'update() tests' => sub {
         # Delete library
         $library_to_delete->delete;
 
+        # Use an invalid library_id
         $newpatron->{library_id} = $deleted_library_id;
-        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron );
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
+
         warning_like {
-            $t->request_ok($tx)
+            $t->put_ok("//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron)
               ->status_is(400)
               ->json_is('/error' => "Given library_id does not exist"); }
             qr/^DBD::mysql::st execute failed: Cannot add or update a child row: a foreign key constraint fails/;
+
+        # Restore the valid library_id
         $newpatron->{library_id} = $patron_2->branchcode;
 
+        # Use an invalid attribute
         $newpatron->{falseproperty} = "Non existent property";
-        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron );
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
-        $t->request_ok($tx)
+
+        $t->put_ok( "//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron )
           ->status_is(400)
           ->json_is('/errors/0/message' =>
                     'Properties not allowed: falseproperty.');
+
+        # Get rid of the invalid attribute
         delete $newpatron->{falseproperty};
 
         # Set both cardnumber and userid to already existing values
         $newpatron->{cardnumber} = $patron_1->cardnumber;
         $newpatron->{userid}     = $patron_1->userid;
 
-        $tx = $t->ua->build_tx( PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron );
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
         warning_like {
-            $t->request_ok($tx)
+            $t->put_ok( "//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron )
               ->status_is(409)
               ->json_has( '/error' => "Fails when trying to update to an existing cardnumber or userid")
               ->json_is(  '/conflict', 'cardnumber' ); }
             qr/^DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key 'cardnumber'/;
 
-        $newpatron->{ cardnumber } = $patron_id_1.$patron_id_2;
-        $newpatron->{ userid }     = "user".$patron_id_1.$patron_id_2;
-        $newpatron->{ surname }    = "user".$patron_id_1.$patron_id_2;
+        $newpatron->{ cardnumber } = $patron_1->id . $patron_2->id;
+        $newpatron->{ userid }     = "user" . $patron_1->id.$patron_2->id;
+        $newpatron->{ surname }    = "user" . $patron_1->id.$patron_2->id;
 
-        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron);
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
-        $t->request_ok($tx)
+        $t->put_ok( "//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron )
           ->status_is(200, 'Patron updated successfully')
           ->json_has($newpatron);
         is(Koha::Patrons->find( $patron_2->id )->cardnumber,
@@ -329,17 +340,23 @@ subtest 'delete() tests' => sub {
 
         $schema->storage->txn_begin;
 
-        my ( undef, $session_id ) = create_user_and_session({ authorized => 1 });
-        my ( $patron_id, undef )  = create_user_and_session({ authorized => 0 });
+        my $authorized_patron = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 2**4 }    # borrowers flag = 4
+            }
+        );
+        my $password = 'thePassword123';
+        $authorized_patron->set_password(
+            { password => $password, skip_validation => 1 } );
+        my $userid = $authorized_patron->userid;
 
-        my $tx = $t->ua->build_tx(DELETE => "/api/v1/patrons/-1");
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $t->request_ok($tx)
+        $t->delete_ok("//$userid:$password@/api/v1/patrons/-1")
           ->status_is(404, 'Patron not found');
 
-        $tx = $t->ua->build_tx(DELETE => "/api/v1/patrons/$patron_id");
-        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
-        $t->request_ok($tx)
+        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
+
+        $t->delete_ok("//$userid:$password@/api/v1/patrons/" . $patron->borrowernumber)
           ->status_is(200, 'Patron deleted successfully');
 
         $schema->storage->txn_rollback;
@@ -433,47 +450,24 @@ sub unauthorized_access_tests {
     subtest 'unauthorized access tests' => sub {
         plan tests => 5;
 
-        my $tx = $t->ua->build_tx($verb => $endpoint => json => $json);
-        $t->request_ok($tx)
+        my $verb_ok = lc($verb) . '_ok';
+
+        $t->$verb_ok($endpoint => json => $json)
           ->status_is(401);
 
-        my ($borrowernumber, $session_id) = create_user_and_session({
-            authorized => 0 });
+        my $unauthorized_patron = $builder->build_object(
+            {
+                class => 'Koha::Patrons',
+                value => { flags => 0 }
+            }
+        );
+        my $password = "thePassword123!";
+        $unauthorized_patron->set_password(
+            { password => $password, skip_validation => 1 } );
+        my $unauth_userid = $unauthorized_patron->userid;
 
-        $tx = $t->ua->build_tx($verb => $endpoint => json => $json);
-        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
-        $t->request_ok($tx)
+        $t->$verb_ok( "//$unauth_userid:$password\@$endpoint" => json => $json )
           ->status_is(403)
           ->json_has('/required_permissions');
     };
 }
-
-sub create_user_and_session {
-
-    my $args  = shift;
-    my $flags = ( $args->{authorized} ) ? 16 : 0;
-
-    my $user = $builder->build(
-        {
-            source => 'Borrower',
-            value  => {
-                flags => $flags,
-                gonenoaddress => 0,
-                lost => 0,
-                email => 'nobody@example.com',
-                emailpro => 'nobody@example.com',
-                B_email => 'nobody@example.com'
-            }
-        }
-    );
-
-    # Create a session for the authorized user
-    my $session = C4::Auth::get_session('');
-    $session->param( 'number',   $user->{borrowernumber} );
-    $session->param( 'id',       $user->{userid} );
-    $session->param( 'ip',       '127.0.0.1' );
-    $session->param( 'lasttime', time() );
-    $session->flush;
-
-    return ( $user->{borrowernumber}, $session->id );
-}
-- 
2.23.0