From 310a0d54be9bf141141d0a8647f0af9c8f3120ca Mon Sep 17 00:00:00 2001 From: Jason Etheridge Date: Wed, 17 Jul 2013 17:55:07 -0400 Subject: [PATCH 1/1] tests against stock test data and live Evergreen I'm running these on a machine where Evergreen has been installed with the stock test data. Repeat invocations of the tests will cause test failures, as they don't completely cleanup after themselves (the goal long-term is to rely on complete database wipes between invocations). Manual cleanup right now could include doing the following in psql: DELETE FROM actor.workstation WHERE name ~ '.t$'; and paying the bills on the admin user (otherwise, once a Max Fines penalty is generated, checkout tests will fail). opensrf@dev141:~/git/Evergreen/Open-ILS/src/perlmods (livetests)$ make livecheck 2> /dev/null perl Build.PL --destdir || make -s build-perl-fail Creating new 'MYMETA.yml' with configuration results Creating new 'Build' script for 'OpenILS' version '2.4' ./Build test --test_files live_t || make -s build-perl-fail live_t/00-simple.t ..................... ok live_t/01-auth.t ....................... ok live_t/02-simple_circ.t ................ ok live_t/03-overdue_circ.t ............... ok live_t/04-overdue_with_closed_dates.t .. ok All tests successful. Files=5, Tests=62, 11 wallclock secs ( 0.25 usr 0.16 sys + 3.52 cusr 0.63 csys = 4.56 CPU) Result: PASS and opensrf@dev141:~/git/Evergreen/Open-ILS/src/perlmods (livetests)$ prove -v live_t/ live_t/00-simple.t ..................... 1..2 # Simple tests against the open-ils.storage service and the stock test data. ok 1 - open-ils.storage.direct.actor.user.retrieve returned aou object ok 2 - User with id = 1 is admin user ok live_t/01-auth.t ....................... 1..4 # Simple tests against the open-ils.auth service, memcached, and the stock test data. # authtime is 7200, authtoken is a3f2d06775fb670284450ad1f1d6ea00 ok 1 - Have an authtoken ok 2 - Default authtime for staff login is 7200 seconds ok 3 - Can retrieve authtoken from memcached ok 4 - Authtoken is removed from memcached after logout ok live_t/02-simple_circ.t ................ 1..14 # Test circulation of item CONC70000345 against the admin user. ok 1 - open-ils.storage.direct.actor.user.retrieve returned aou object ok 2 - User with id = 1 is admin user ok 3 - open-ils.storage.direct.asset.copy.retrieve returned acp object ok 4 - Item with id = 310 has barcode CONC70000345 ok 5 - Item with id = 310 has status of Reshelving or Available # authtime is 7200, authtoken is f7c9ae35165ec74ab5e8ce5b84673da8 ok 6 - Have an authtoken ok 7 - Registered a new workstation # authtime is 7200, authtoken is f7c9ae35165ec74ab5e8ce5b84673da8 ok 8 - Have an authtoken associated with the workstation ok 9 - Checkout request returned a HASH ok 10 - Checkout returned a SUCCESS event ok 11 - Item with id = 310 has status of Checked Out after fresh Storage request ok 12 - Checkin request returned a HASH ok 13 - Checkin returned a SUCCESS event ok 14 - Item with id = 310 has status of Reshelving or Available after fresh Storage request ok live_t/03-overdue_circ.t ............... 1..20 # Test fine generation on checkin against the admin user. ok 1 - open-ils.storage.direct.actor.user.retrieve returned aou object ok 2 - User with id = 1 is admin user ok 3 - open-ils.storage.direct.asset.copy.retrieve returned acp object ok 4 - Item with id = 810 has barcode CONC71000345 ok 5 - Item with id = 810 has status of Reshelving or Available # authtime is 7200, authtoken is 5ab4ae5b9a09c7fd04b4eb0dabf19da5 ok 6 - Have an authtoken ok 7 - Registered a new workstation # authtime is 7200, authtoken is 5ab4ae5b9a09c7fd04b4eb0dabf19da5 ok 8 - Have an authtoken associated with the workstation ok 9 - Checkout request returned a HASH ok 10 - Checkout returned a SUCCESS event ok 11 - Checkout response object has payload object ok 12 - Payload object has circ object ok 13 - Circ objection has loan duration of "7 days" ok 14 - Item with id = 810 has status of Checked Out after fresh Storage request ok 15 - Zero bills associated with circulation ok 16 - rewrote circ to have happened 20 days ago ok 17 - Checkin request returned a HASH ok 18 - Checkin returned a SUCCESS event ok 19 - Item with id = 810 has status of Reshelving or Available after fresh Storage request ok 20 - Thirteen bills associated with circulation ok live_t/04-overdue_with_closed_dates.t .. 1..22 # Test fine generation with closed date on checkin against the admin user. ok 1 - open-ils.storage.direct.actor.user.retrieve returned aou object ok 2 - User with id = 1 is admin user ok 3 - open-ils.storage.direct.asset.copy.retrieve returned acp object ok 4 - Item with id = 1310 has barcode CONC72000345 ok 5 - Item with id = 1310 has status of Reshelving or Available # authtime is 7200, authtoken is dd4b533f677dd5ec6d177312eca2e86b ok 6 - Have an authtoken ok 7 - Registered a new workstation # authtime is 7200, authtoken is dd4b533f677dd5ec6d177312eca2e86b ok 8 - Have an authtoken associated with the workstation ok 9 - Created a closed date for 10 days ago ok 10 - Checkout request returned a HASH ok 11 - Checkout returned a SUCCESS event ok 12 - Checkout response object has payload object ok 13 - Payload object has circ object ok 14 - Circ objection has loan duration of "7 days" ok 15 - Item with id = 1310 has status of Checked Out after fresh Storage request ok 16 - Zero bills associated with circulation ok 17 - rewrote circ to have happened 20 days ago ok 18 - Checkin request returned a HASH ok 19 - Checkin returned a SUCCESS event ok 20 - Item with id = 1310 has status of Reshelving or Available after fresh Storage request ok 21 - Twelve bills associated with circulation (instead of 13, thanks to closed date) ok 22 - Removed closed date ok All tests successful. Files=5, Tests=62, 10 wallclock secs ( 0.06 usr 0.04 sys + 3.29 cusr 0.50 csys = 3.89 CPU) Result: PASS Signed-off-by: Jason Etheridge Signed-off-by: Bill Erickson --- Open-ILS/src/perlmods/Makefile.am | 3 + Open-ILS/src/perlmods/live_t/00-simple.t | 37 ++ Open-ILS/src/perlmods/live_t/01-auth.t | 167 ++++++++ Open-ILS/src/perlmods/live_t/02-simple_circ.t | 270 ++++++++++++ .../src/perlmods/live_t/03-overdue_circ.t | 347 ++++++++++++++++ .../live_t/04-overdue_with_closed_dates.t | 390 ++++++++++++++++++ 6 files changed, 1214 insertions(+) create mode 100644 Open-ILS/src/perlmods/live_t/00-simple.t create mode 100644 Open-ILS/src/perlmods/live_t/01-auth.t create mode 100644 Open-ILS/src/perlmods/live_t/02-simple_circ.t create mode 100644 Open-ILS/src/perlmods/live_t/03-overdue_circ.t create mode 100644 Open-ILS/src/perlmods/live_t/04-overdue_with_closed_dates.t diff --git a/Open-ILS/src/perlmods/Makefile.am b/Open-ILS/src/perlmods/Makefile.am index ac507d1ed9..b4431101ff 100644 --- a/Open-ILS/src/perlmods/Makefile.am +++ b/Open-ILS/src/perlmods/Makefile.am @@ -25,6 +25,9 @@ all: build-perl check: build-perl ./Build test || make -s build-perl-fail +livecheck: build-perl + ./Build test --test_files live_t || make -s build-perl-fail + install: build-perl ./Build install diff --git a/Open-ILS/src/perlmods/live_t/00-simple.t b/Open-ILS/src/perlmods/live_t/00-simple.t new file mode 100644 index 0000000000..f6f0c02359 --- /dev/null +++ b/Open-ILS/src/perlmods/live_t/00-simple.t @@ -0,0 +1,37 @@ +#!perl + +use Test::More tests => 2; + +diag("Simple tests against the open-ils.storage service and the stock test data."); + +use strict; use warnings; +use OpenSRF::System; +use OpenSRF::AppSession; +use OpenILS::Utils::Fieldmapper; +use OpenSRF::Utils::SettingsClient; + +my $config = `osrf_config --sysconfdir`; +chomp $config; +$config .= '/opensrf_core.xml'; + +OpenSRF::System->bootstrap_client(config_file => $config); +Fieldmapper->import(IDL => + OpenSRF::Utils::SettingsClient->new->config_value("IDL")); + +my $ses = OpenSRF::AppSession->create('open-ils.storage'); +my $req = $ses->request('open-ils.storage.direct.actor.user.retrieve', 1); +if (my $resp = $req->recv) { + if (my $user = $resp->content) { + is( + ref $user, + 'Fieldmapper::actor::user', + 'open-ils.storage.direct.actor.user.retrieve returned aou object' + ); + is( + $user->usrname, + 'admin', + 'User with id = 1 is admin user' + ); + } +} + diff --git a/Open-ILS/src/perlmods/live_t/01-auth.t b/Open-ILS/src/perlmods/live_t/01-auth.t new file mode 100644 index 0000000000..a5220400c4 --- /dev/null +++ b/Open-ILS/src/perlmods/live_t/01-auth.t @@ -0,0 +1,167 @@ +#!perl + +use Test::More tests => 4; + +diag("Simple tests against the open-ils.auth service, memcached, and the stock test data."); + +use strict; +use warnings; +use Data::Dumper; +use OpenSRF::System; +use OpenSRF::AppSession; +use Digest::MD5 qw(md5_hex); +use OpenILS::Application::AppUtils; +use OpenSRF::Utils::SettingsClient; + +# Some useful objects +our $cache = "OpenSRF::Utils::Cache"; +our $apputils = "OpenILS::Application::AppUtils"; +our $memcache; +our $authtoken; +our $authtime; + +#---------------------------------------------------------------- +# Exit a script +#---------------------------------------------------------------- +sub err { + my ($pkg, $file, $line, $sub) = _caller(); + no warnings; + die "Script halted with error ". + "($pkg : $file : $line : $sub):\n" . shift() . "\n"; +} + +#---------------------------------------------------------------- +# This is not the function you're looking for +#---------------------------------------------------------------- +sub _caller { + my ($pkg, $file, $line, $sub) = caller(2); + if(!$line) { + ($pkg, $file, $line) = caller(1); + $sub = ""; + } + return ($pkg, $file, $line, $sub); +} + +#---------------------------------------------------------------- +# Connect to the servers +#---------------------------------------------------------------- +sub osrf_connect { + my $config = `osrf_config --sysconfdir`; + chomp $config; + $config .= '/opensrf_core.xml'; + err("Bootstrap config required") unless $config; + OpenSRF::System->bootstrap_client( config_file => $config ); +} + +#---------------------------------------------------------------- +# Get a handle for the memcache object +#---------------------------------------------------------------- +sub osrf_cache { + $cache->use; + $memcache = $cache->new('global') unless $memcache; + return $memcache; +} + +#---------------------------------------------------------------- +# Is the given object an OILS event? +#---------------------------------------------------------------- +sub oils_is_event { + my $e = shift; + if( $e and ref($e) eq 'HASH' ) { + return 1 if defined($e->{ilsevent}); + } + return 0; +} + +#---------------------------------------------------------------- +# If the given object is an event, this prints the event info +# and exits the script +#---------------------------------------------------------------- +sub oils_event_die { + my $evt = shift; + my ($pkg, $file, $line, $sub) = _caller(); + if(oils_is_event($evt)) { + if($evt->{ilsevent}) { + diag("\nReceived Event($pkg : $file : $line : $sub): \n" . Dumper($evt)); + exit 1; + } + } +} + +#---------------------------------------------------------------- +# Login to the auth server and set the global $authtoken var +#---------------------------------------------------------------- +sub oils_login { + my( $username, $password, $type ) = @_; + + $type |= "staff"; + + my $seed = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.init', $username ); + err("No auth seed") unless $seed; + + my $response = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.complete', + { username => $username, + password => md5_hex($seed . md5_hex($password)), + type => $type }); + + err("No auth response returned on login") unless $response; + + oils_event_die($response); + + $authtime = $response->{payload}->{authtime}; + $authtoken = $response->{payload}->{authtoken}; + diag("authtime is $authtime, authtoken is $authtoken"); + return $authtoken; +} + +#---------------------------------------------------------------- +# Destroys the login session on the server +#---------------------------------------------------------------- +sub oils_logout { + $apputils->simplereq( + 'open-ils.auth', + 'open-ils.auth.session.delete', (@_ ? shift : $authtoken) ); +} + +#---------------------------------------------------------------- +# var $response = simplereq( $service, $method, @params ); +#---------------------------------------------------------------- +sub simplereq { return $apputils->simplereq(@_); } +sub osrf_request { return $apputils->simplereq(@_); } + +#---------------------------------------------------------------- +# The tests... assumes stock sample data, full-auto install by +# eg_wheezy_installer.sh, etc. +#---------------------------------------------------------------- + +osrf_connect(); +oils_login('admin','demo123','staff'); + +ok( + $authtoken, + 'Have an authtoken' +); +is( + $authtime, + 7200, + 'Default authtime for staff login is 7200 seconds' +); + +osrf_cache(); +my $cached_obj = $memcache->get_cache("oils_auth_$authtoken"); + +ok( + ref $cached_obj, + 'Can retrieve authtoken from memcached' +); + +oils_logout(); + +$cached_obj = $memcache->get_cache("oils_auth_$authtoken"); +ok( + ! $cached_obj, + 'Authtoken is removed from memcached after logout' +); + diff --git a/Open-ILS/src/perlmods/live_t/02-simple_circ.t b/Open-ILS/src/perlmods/live_t/02-simple_circ.t new file mode 100644 index 0000000000..5d366e2a73 --- /dev/null +++ b/Open-ILS/src/perlmods/live_t/02-simple_circ.t @@ -0,0 +1,270 @@ +#!perl + +use Test::More tests => 14; + +diag("Test circulation of item CONC70000345 against the admin user."); + +use constant WORKSTATION_NAME => 'BR4-test-02-simple-circ.t'; +use constant WORKSTATION_LIB => 7; +use constant ITEM_BARCODE => 'CONC70000345'; +use constant ITEM_ID => 310; + +use strict; +use warnings; +use Data::Dumper; +use OpenSRF::System; +use OpenSRF::AppSession; +use Digest::MD5 qw(md5_hex); +use OpenILS::Utils::Fieldmapper; +use OpenILS::Application::AppUtils; +use OpenSRF::Utils::SettingsClient; + +# Some useful objects +our $cache = "OpenSRF::Utils::Cache"; +our $apputils = "OpenILS::Application::AppUtils"; +our $memcache; +our $authtoken; +our $authtime; + +#---------------------------------------------------------------- +# Exit a script +#---------------------------------------------------------------- +sub err { + my ($pkg, $file, $line, $sub) = _caller(); + no warnings; + die "Script halted with error ". + "($pkg : $file : $line : $sub):\n" . shift() . "\n"; +} + +#---------------------------------------------------------------- +# This is not the function you're looking for +#---------------------------------------------------------------- +sub _caller { + my ($pkg, $file, $line, $sub) = caller(2); + if(!$line) { + ($pkg, $file, $line) = caller(1); + $sub = ""; + } + return ($pkg, $file, $line, $sub); +} + +#---------------------------------------------------------------- +# Connect to the servers +#---------------------------------------------------------------- +sub osrf_connect { + my $config = `osrf_config --sysconfdir`; + chomp $config; + $config .= '/opensrf_core.xml'; + err("Bootstrap config required") unless $config; + OpenSRF::System->bootstrap_client( config_file => $config ); + Fieldmapper->import(IDL => + OpenSRF::Utils::SettingsClient->new->config_value("IDL")); +} + +#---------------------------------------------------------------- +# Is the given object an OILS event? +#---------------------------------------------------------------- +sub oils_is_event { + my $e = shift; + if( $e and ref($e) eq 'HASH' ) { + return 1 if defined($e->{ilsevent}); + } + return 0; +} + +#---------------------------------------------------------------- +# If the given object is an event, this prints the event info +# and exits the script +#---------------------------------------------------------------- +sub oils_event_die { + my $evt = shift; + my ($pkg, $file, $line, $sub) = _caller(); + if(oils_is_event($evt)) { + if($evt->{ilsevent}) { + diag("\nReceived Event($pkg : $file : $line : $sub): \n" . Dumper($evt)); + exit 1; + } + } +} + +#---------------------------------------------------------------- +# Login to the auth server and set the global $authtoken var +#---------------------------------------------------------------- +sub oils_login { + my( $username, $password, $type, $ws ) = @_; + + $type |= "staff"; + + my $seed = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.init', $username ); + err("No auth seed") unless $seed; + + my $response = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.complete', + { username => $username, + password => md5_hex($seed . md5_hex($password)), + type => $type, workstation => $ws }); + + err("No auth response returned on login") unless $response; + + oils_event_die($response); + + $authtime = $response->{payload}->{authtime}; + $authtoken = $response->{payload}->{authtoken}; + diag("authtime is $authtime, authtoken is $authtoken"); + return $authtoken; +} + +#---------------------------------------------------------------- +# Destroys the login session on the server +#---------------------------------------------------------------- +sub oils_logout { + $apputils->simplereq( + 'open-ils.auth', + 'open-ils.auth.session.delete', (@_ ? shift : $authtoken) ); +} + +#---------------------------------------------------------------- +# var $response = simplereq( $service, $method, @params ); +#---------------------------------------------------------------- +sub simplereq { return $apputils->simplereq(@_); } +sub osrf_request { return $apputils->simplereq(@_); } + +#---------------------------------------------------------------- + +sub register_workstation { + my $resp = osrf_request( + 'open-ils.actor', + 'open-ils.actor.workstation.register', + $authtoken, WORKSTATION_NAME, WORKSTATION_LIB); + return $resp; +} + +sub do_checkout { + my( $patronid, $barcode ) = @_; + my $args = { patron => $patronid, barcode => $barcode }; + my $resp = osrf_request( + 'open-ils.circ', + 'open-ils.circ.checkout.full', $authtoken, $args ); + return $resp; +} + +sub do_checkin { + my $barcode = shift; + my $args = { barcode => $barcode }; + my $resp = osrf_request( + 'open-ils.circ', + 'open-ils.circ.checkin', $authtoken, $args ); + return $resp; +} + +#---------------------------------------------------------------- +# The tests... assumes stock sample data, full-auto install by +# eg_wheezy_installer.sh, etc. +#---------------------------------------------------------------- + +osrf_connect(); +my $storage_ses = OpenSRF::AppSession->create('open-ils.storage'); + +my $user_req = $storage_ses->request('open-ils.storage.direct.actor.user.retrieve', 1); +if (my $user_resp = $user_req->recv) { + if (my $user = $user_resp->content) { + is( + ref $user, + 'Fieldmapper::actor::user', + 'open-ils.storage.direct.actor.user.retrieve returned aou object' + ); + is( + $user->usrname, + 'admin', + 'User with id = 1 is admin user' + ); + } +} + +my $item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + is( + ref $item, + 'Fieldmapper::asset::copy', + 'open-ils.storage.direct.asset.copy.retrieve returned acp object' + ); + is( + $item->barcode, + ITEM_BARCODE, + 'Item with id = ' . ITEM_ID . ' has barcode ' . ITEM_BARCODE + ); + ok( + $item->status == 7 || $item->status == 0, + 'Item with id = ' . ITEM_ID . ' has status of Reshelving or Available' + ); + } +} + +oils_login('admin','demo123','staff'); +ok( + $authtoken, + 'Have an authtoken' +); +my $ws = register_workstation(); +ok( + ! ref $ws, + 'Registered a new workstation' +); + +oils_logout(); +oils_login('admin','demo123','staff',WORKSTATION_NAME); +ok( + $authtoken, + 'Have an authtoken associated with the workstation' +); + +my $checkout_resp = do_checkout(1, ITEM_BARCODE); +is( + ref $checkout_resp, + 'HASH', + 'Checkout request returned a HASH' +); +is( + $checkout_resp->{ilsevent}, + 0, + 'Checkout returned a SUCCESS event' +); + +$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', 310); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + is( + $item->status, + 1, + 'Item with id = ' . ITEM_ID . ' has status of Checked Out after fresh Storage request' + ); + } +} + +my $checkin_resp = do_checkin(ITEM_BARCODE); +is( + ref $checkin_resp, + 'HASH', + 'Checkin request returned a HASH' +); +is( + $checkin_resp->{ilsevent}, + 0, + 'Checkin returned a SUCCESS event' +); + +$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + ok( + $item->status == 7 || $item->status == 0, + 'Item with id = ' . ITEM_ID . ' has status of Reshelving or Available after fresh Storage request' + ); + } +} + +oils_logout(); + + diff --git a/Open-ILS/src/perlmods/live_t/03-overdue_circ.t b/Open-ILS/src/perlmods/live_t/03-overdue_circ.t new file mode 100644 index 0000000000..f073e3e9f8 --- /dev/null +++ b/Open-ILS/src/perlmods/live_t/03-overdue_circ.t @@ -0,0 +1,347 @@ +#!perl + +use Test::More tests => 20; + +diag("Test fine generation on checkin against the admin user."); + +use constant WORKSTATION_NAME => 'BR4-test-03-overdue-circ.t'; +use constant WORKSTATION_LIB => 7; +use constant ITEM_BARCODE => 'CONC71000345'; +use constant ITEM_ID => 810; + +use strict; +use warnings; +use Data::Dumper; +use OpenSRF::System; +use OpenSRF::AppSession; +use Digest::MD5 qw(md5_hex); +use OpenILS::Utils::Fieldmapper; +use OpenILS::Application::AppUtils; +use DateTime; +use DateTime::Format::ISO8601; +use OpenSRF::Utils qw/cleanse_ISO8601/; +use OpenSRF::Utils::SettingsClient; + +# Some useful objects +our $cache = "OpenSRF::Utils::Cache"; +our $apputils = "OpenILS::Application::AppUtils"; +our $memcache; +our $authtoken; +our $authtime; + +#---------------------------------------------------------------- +# Exit a script +#---------------------------------------------------------------- +sub err { + my ($pkg, $file, $line, $sub) = _caller(); + no warnings; + die "Script halted with error ". + "($pkg : $file : $line : $sub):\n" . shift() . "\n"; +} + +#---------------------------------------------------------------- +# This is not the function you're looking for +#---------------------------------------------------------------- +sub _caller { + my ($pkg, $file, $line, $sub) = caller(2); + if(!$line) { + ($pkg, $file, $line) = caller(1); + $sub = ""; + } + return ($pkg, $file, $line, $sub); +} + +#---------------------------------------------------------------- +# Connect to the servers +#---------------------------------------------------------------- +sub osrf_connect { + my $config = `osrf_config --sysconfdir`; + chomp $config; + $config .= '/opensrf_core.xml'; + err("Bootstrap config required") unless $config; + OpenSRF::System->bootstrap_client( config_file => $config ); + Fieldmapper->import(IDL => + OpenSRF::Utils::SettingsClient->new->config_value("IDL")); +} + +#---------------------------------------------------------------- +# Is the given object an OILS event? +#---------------------------------------------------------------- +sub oils_is_event { + my $e = shift; + if( $e and ref($e) eq 'HASH' ) { + return 1 if defined($e->{ilsevent}); + } + return 0; +} + +#---------------------------------------------------------------- +# If the given object is an event, this prints the event info +# and exits the script +#---------------------------------------------------------------- +sub oils_event_die { + my $evt = shift; + my ($pkg, $file, $line, $sub) = _caller(); + if(oils_is_event($evt)) { + if($evt->{ilsevent}) { + diag("\nReceived Event($pkg : $file : $line : $sub): \n" . Dumper($evt)); + exit 1; + } + } +} + +#---------------------------------------------------------------- +# Login to the auth server and set the global $authtoken var +#---------------------------------------------------------------- +sub oils_login { + my( $username, $password, $type, $ws ) = @_; + + $type |= "staff"; + + my $seed = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.init', $username ); + err("No auth seed") unless $seed; + + my $response = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.complete', + { username => $username, + password => md5_hex($seed . md5_hex($password)), + type => $type, workstation => $ws }); + + err("No auth response returned on login") unless $response; + + oils_event_die($response); + + $authtime = $response->{payload}->{authtime}; + $authtoken = $response->{payload}->{authtoken}; + diag("authtime is $authtime, authtoken is $authtoken"); + return $authtoken; +} + +#---------------------------------------------------------------- +# Destroys the login session on the server +#---------------------------------------------------------------- +sub oils_logout { + $apputils->simplereq( + 'open-ils.auth', + 'open-ils.auth.session.delete', (@_ ? shift : $authtoken) ); +} + +#---------------------------------------------------------------- +# var $response = simplereq( $service, $method, @params ); +#---------------------------------------------------------------- +sub simplereq { return $apputils->simplereq(@_); } +sub osrf_request { return $apputils->simplereq(@_); } + +#---------------------------------------------------------------- + +sub register_workstation { + my $resp = osrf_request( + 'open-ils.actor', + 'open-ils.actor.workstation.register', + $authtoken, WORKSTATION_NAME, WORKSTATION_LIB); + return $resp; +} + +sub do_checkout { + my( $patronid, $barcode ) = @_; + my $args = { patron => $patronid, barcode => $barcode }; + my $resp = osrf_request( + 'open-ils.circ', + 'open-ils.circ.checkout.full', $authtoken, $args ); + return $resp; +} + +sub do_checkin { + my $barcode = shift; + my $args = { barcode => $barcode }; + my $resp = osrf_request( + 'open-ils.circ', + 'open-ils.circ.checkin', $authtoken, $args ); + return $resp; +} + +#---------------------------------------------------------------- +# The tests... assumes stock sample data, full-auto install by +# eg_wheezy_installer.sh, etc. +#---------------------------------------------------------------- + +osrf_connect(); +my $storage_ses = OpenSRF::AppSession->create('open-ils.storage'); +my $circ_ses = OpenSRF::AppSession->create('open-ils.circ'); +my $cstore_ses = OpenSRF::AppSession->connect('open-ils.cstore'); + +my $user_req = $storage_ses->request('open-ils.storage.direct.actor.user.retrieve', 1); +if (my $user_resp = $user_req->recv) { + if (my $user = $user_resp->content) { + is( + ref $user, + 'Fieldmapper::actor::user', + 'open-ils.storage.direct.actor.user.retrieve returned aou object' + ); + is( + $user->usrname, + 'admin', + 'User with id = 1 is admin user' + ); + } +} + +my $item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + is( + ref $item, + 'Fieldmapper::asset::copy', + 'open-ils.storage.direct.asset.copy.retrieve returned acp object' + ); + is( + $item->barcode, + ITEM_BARCODE, + 'Item with id = ' . ITEM_ID . ' has barcode ' . ITEM_BARCODE + ); + ok( + $item->status == 7 || $item->status == 0, + 'Item with id = ' . ITEM_ID . ' has status of Reshelving or Available' + ); + } +} + +oils_login('admin','demo123','staff'); +ok( + $authtoken, + 'Have an authtoken' +); +my $ws = register_workstation(); +ok( + ! ref $ws, + 'Registered a new workstation' +); + +oils_logout(); +oils_login('admin','demo123','staff',WORKSTATION_NAME); +ok( + $authtoken, + 'Have an authtoken associated with the workstation' +); + +my $checkout_resp = do_checkout(1, ITEM_BARCODE); +is( + ref $checkout_resp, + 'HASH', + 'Checkout request returned a HASH' +); +is( + $checkout_resp->{ilsevent}, + 0, + 'Checkout returned a SUCCESS event' +); +ok( + ref $checkout_resp->{payload}, + 'Checkout response object has payload object' +); +ok( + ref $checkout_resp->{payload}->{circ}, + 'Payload object has circ object' +); +is( + $checkout_resp->{payload}->{circ}->duration, + '7 days', + 'Circ objection has loan duration of "7 days"' +); + +my $circ = $checkout_resp->{payload}->{circ}; + +$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + is( + $item->status, + 1, + 'Item with id = ' . ITEM_ID . ' has status of Checked Out after fresh Storage request' + ); + } +} + +my $bill_req = $circ_ses->request( + 'open-ils.circ.money.billing.retrieve.all', + $authtoken, + $circ->id +); +if (my $bill_resp = $bill_req->recv) { + if (my $bills = $bill_resp->content) { + is( + scalar( @{ $bills } ), + 0, + 'Zero bills associated with circulation' + ); + } +} + +my $xact_start = DateTime::Format::ISO8601->parse_datetime(cleanse_ISO8601($circ->xact_start))->epoch; +my $due_date = DateTime::Format::ISO8601->parse_datetime(cleanse_ISO8601($circ->due_date))->epoch; +my $twenty_days = OpenSRF::Utils->interval_to_seconds('480 h 0 m 0 s'); + +# Rewrite history; technically we should rewrite status_changed_item on the copy as well, but, meh... +$circ->xact_start( $apputils->epoch2ISO8601($xact_start - $twenty_days) ); +$circ->due_date( $apputils->epoch2ISO8601($due_date - $twenty_days) ); + +my $xact = $cstore_ses->request('open-ils.cstore.transaction.begin')->gather(1); +my $update_req = $cstore_ses->request( + 'open-ils.cstore.direct.action.circulation.update', + $circ +); +if (my $update_resp = $update_req->gather(1)) { + pass( + 'rewrote circ to have happened 20 days ago' + ); +} else { + fail( + 'rewrote circ to have happened 20 days ago' + ); +} +$cstore_ses->request('open-ils.cstore.transaction.commit')->gather(1); + +######## + +my $checkin_resp = do_checkin(ITEM_BARCODE); +is( + ref $checkin_resp, + 'HASH', + 'Checkin request returned a HASH' +); +is( + $checkin_resp->{ilsevent}, + 0, + 'Checkin returned a SUCCESS event' +); + +$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + ok( + $item->status == 7 || $item->status == 0, + 'Item with id = ' . ITEM_ID . ' has status of Reshelving or Available after fresh Storage request' + ); + } +} + +$bill_req = $circ_ses->request( + 'open-ils.circ.money.billing.retrieve.all', + $authtoken, + $circ->id +); +if (my $bill_resp = $bill_req->recv) { + if (my $bills = $bill_resp->content) { + is( + scalar( @{ $bills } ), + 13, + 'Thirteen bills associated with circulation' + ); + } +} + + +oils_logout(); + + diff --git a/Open-ILS/src/perlmods/live_t/04-overdue_with_closed_dates.t b/Open-ILS/src/perlmods/live_t/04-overdue_with_closed_dates.t new file mode 100644 index 0000000000..efcc693598 --- /dev/null +++ b/Open-ILS/src/perlmods/live_t/04-overdue_with_closed_dates.t @@ -0,0 +1,390 @@ +#!perl + +use Test::More tests => 22; + +diag("Test fine generation with closed date on checkin against the admin user."); + +use constant WORKSTATION_NAME => 'BR4-test-04-overdue-with-closed-dates.t'; +use constant WORKSTATION_LIB => 7; +use constant ITEM_BARCODE => 'CONC72000345'; +use constant ITEM_ID => 1310; + +use strict; +use warnings; +use Data::Dumper; +use OpenSRF::System; +use OpenSRF::AppSession; +use Digest::MD5 qw(md5_hex); +use OpenILS::Utils::Fieldmapper; +use OpenILS::Application::AppUtils; +use DateTime; +use DateTime::Format::ISO8601; +use OpenSRF::Utils qw/cleanse_ISO8601/; +use OpenSRF::Utils::SettingsClient; + +# Some useful objects +our $cache = "OpenSRF::Utils::Cache"; +our $apputils = "OpenILS::Application::AppUtils"; +our $memcache; +our $authtoken; +our $authtime; + +#---------------------------------------------------------------- +# Exit a script +#---------------------------------------------------------------- +sub err { + my ($pkg, $file, $line, $sub) = _caller(); + no warnings; + die "Script halted with error ". + "($pkg : $file : $line : $sub):\n" . shift() . "\n"; +} + +#---------------------------------------------------------------- +# This is not the function you're looking for +#---------------------------------------------------------------- +sub _caller { + my ($pkg, $file, $line, $sub) = caller(2); + if(!$line) { + ($pkg, $file, $line) = caller(1); + $sub = ""; + } + return ($pkg, $file, $line, $sub); +} + +#---------------------------------------------------------------- +# Connect to the servers +#---------------------------------------------------------------- +sub osrf_connect { + my $config = `osrf_config --sysconfdir`; + chomp $config; + $config .= '/opensrf_core.xml'; + err("Bootstrap config required") unless $config; + OpenSRF::System->bootstrap_client( config_file => $config ); + Fieldmapper->import(IDL => + OpenSRF::Utils::SettingsClient->new->config_value("IDL")); +} + +#---------------------------------------------------------------- +# Is the given object an OILS event? +#---------------------------------------------------------------- +sub oils_is_event { + my $e = shift; + if( $e and ref($e) eq 'HASH' ) { + return 1 if defined($e->{ilsevent}); + } + return 0; +} + +#---------------------------------------------------------------- +# If the given object is an event, this prints the event info +# and exits the script +#---------------------------------------------------------------- +sub oils_event_die { + my $evt = shift; + my ($pkg, $file, $line, $sub) = _caller(); + if(oils_is_event($evt)) { + if($evt->{ilsevent}) { + diag("\nReceived Event($pkg : $file : $line : $sub): \n" . Dumper($evt)); + exit 1; + } + } +} + +#---------------------------------------------------------------- +# Login to the auth server and set the global $authtoken var +#---------------------------------------------------------------- +sub oils_login { + my( $username, $password, $type, $ws ) = @_; + + $type |= "staff"; + + my $seed = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.init', $username ); + err("No auth seed") unless $seed; + + my $response = $apputils->simplereq( 'open-ils.auth', + 'open-ils.auth.authenticate.complete', + { username => $username, + password => md5_hex($seed . md5_hex($password)), + type => $type, workstation => $ws }); + + err("No auth response returned on login") unless $response; + + oils_event_die($response); + + $authtime = $response->{payload}->{authtime}; + $authtoken = $response->{payload}->{authtoken}; + diag("authtime is $authtime, authtoken is $authtoken"); + return $authtoken; +} + +#---------------------------------------------------------------- +# Destroys the login session on the server +#---------------------------------------------------------------- +sub oils_logout { + $apputils->simplereq( + 'open-ils.auth', + 'open-ils.auth.session.delete', (@_ ? shift : $authtoken) ); +} + +#---------------------------------------------------------------- +# var $response = simplereq( $service, $method, @params ); +#---------------------------------------------------------------- +sub simplereq { return $apputils->simplereq(@_); } +sub osrf_request { return $apputils->simplereq(@_); } + +#---------------------------------------------------------------- + +sub register_workstation { + my $resp = osrf_request( + 'open-ils.actor', + 'open-ils.actor.workstation.register', + $authtoken, WORKSTATION_NAME, WORKSTATION_LIB); + return $resp; +} + +sub do_checkout { + my( $patronid, $barcode ) = @_; + my $args = { patron => $patronid, barcode => $barcode }; + my $resp = osrf_request( + 'open-ils.circ', + 'open-ils.circ.checkout.full', $authtoken, $args ); + return $resp; +} + +sub do_checkin { + my $barcode = shift; + my $args = { barcode => $barcode }; + my $resp = osrf_request( + 'open-ils.circ', + 'open-ils.circ.checkin', $authtoken, $args ); + return $resp; +} + +sub create_closed_date { + my $ten_days = OpenSRF::Utils->interval_to_seconds('240 h 0 m 0 s'); + my $almost_twenty_four_hours = OpenSRF::Utils->interval_to_seconds('23 h 59 m 59 s'); + #$circ->due_date( $apputils->epoch2ISO8601($due_date - $twenty_days) ); + + my $aoucd = Fieldmapper::actor::org_unit::closed_date->new; + $aoucd->org_unit(WORKSTATION_LIB); + $aoucd->reason('04-overdue_with_closed_dates.t'); + $aoucd->close_start( + $apputils->epoch2ISO8601( + DateTime->today()->epoch() - $ten_days + ) + ); + $aoucd->close_end( + $apputils->epoch2ISO8601( + DateTime->today()->epoch() - $ten_days + $almost_twenty_four_hours + ) + ); + my $resp = osrf_request( + 'open-ils.actor', + 'open-ils.actor.org_unit.closed.create', + $authtoken, $aoucd); + return $resp; +} + +sub delete_closed_date { + my $aoucd = shift; + my $resp = osrf_request( + 'open-ils.actor', + 'open-ils.actor.org_unit.closed.delete', + $authtoken, ref $aoucd ? $aoucd->id : $aoucd ); + return $resp; +} + +#---------------------------------------------------------------- +# The tests... assumes stock sample data, full-auto install by +# eg_wheezy_installer.sh, etc. +#---------------------------------------------------------------- + +osrf_connect(); +my $storage_ses = OpenSRF::AppSession->create('open-ils.storage'); +my $circ_ses = OpenSRF::AppSession->create('open-ils.circ'); +my $cstore_ses = OpenSRF::AppSession->connect('open-ils.cstore'); + +my $user_req = $storage_ses->request('open-ils.storage.direct.actor.user.retrieve', 1); +if (my $user_resp = $user_req->recv) { + if (my $user = $user_resp->content) { + is( + ref $user, + 'Fieldmapper::actor::user', + 'open-ils.storage.direct.actor.user.retrieve returned aou object' + ); + is( + $user->usrname, + 'admin', + 'User with id = 1 is admin user' + ); + } +} + +my $item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + is( + ref $item, + 'Fieldmapper::asset::copy', + 'open-ils.storage.direct.asset.copy.retrieve returned acp object' + ); + is( + $item->barcode, + ITEM_BARCODE, + 'Item with id = ' . ITEM_ID . ' has barcode ' . ITEM_BARCODE + ); + ok( + $item->status == 7 || $item->status == 0, + 'Item with id = ' . ITEM_ID . ' has status of Reshelving or Available' + ); + } +} + +oils_login('admin','demo123','staff'); +ok( + $authtoken, + 'Have an authtoken' +); +my $ws = register_workstation(); +ok( + ! ref $ws, + 'Registered a new workstation' +); + +oils_logout(); +oils_login('admin','demo123','staff',WORKSTATION_NAME); +ok( + $authtoken, + 'Have an authtoken associated with the workstation' +); + +my $closed_date_obj = create_closed_date(); +is( + ref $closed_date_obj, + 'Fieldmapper::actor::org_unit::closed_date', + 'Created a closed date for 10 days ago' +); + +my $checkout_resp = do_checkout(1, ITEM_BARCODE); +is( + ref $checkout_resp, + 'HASH', + 'Checkout request returned a HASH' +); +is( + $checkout_resp->{ilsevent}, + 0, + 'Checkout returned a SUCCESS event' +); +ok( + ref $checkout_resp->{payload}, + 'Checkout response object has payload object' +); +ok( + ref $checkout_resp->{payload}->{circ}, + 'Payload object has circ object' +); +is( + $checkout_resp->{payload}->{circ}->duration, + '7 days', + 'Circ objection has loan duration of "7 days"' +); + +my $circ = $checkout_resp->{payload}->{circ}; + +$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + is( + $item->status, + 1, + 'Item with id = ' . ITEM_ID . ' has status of Checked Out after fresh Storage request' + ); + } +} + +my $bill_req = $circ_ses->request( + 'open-ils.circ.money.billing.retrieve.all', + $authtoken, + $circ->id +); +if (my $bill_resp = $bill_req->recv) { + if (my $bills = $bill_resp->content) { + is( + scalar( @{ $bills } ), + 0, + 'Zero bills associated with circulation' + ); + } +} + +my $xact_start = DateTime::Format::ISO8601->parse_datetime(cleanse_ISO8601($circ->xact_start))->epoch; +my $due_date = DateTime::Format::ISO8601->parse_datetime(cleanse_ISO8601($circ->due_date))->epoch; +my $twenty_days = OpenSRF::Utils->interval_to_seconds('480 h 0 m 0 s'); + +# Rewrite history; technically we should rewrite status_changed_item on the copy as well, but, meh... +$circ->xact_start( $apputils->epoch2ISO8601($xact_start - $twenty_days) ); +$circ->due_date( $apputils->epoch2ISO8601($due_date - $twenty_days) ); + +my $xact = $cstore_ses->request('open-ils.cstore.transaction.begin')->gather(1); +my $update_req = $cstore_ses->request( + 'open-ils.cstore.direct.action.circulation.update', + $circ +); +if (my $update_resp = $update_req->gather(1)) { + pass( + 'rewrote circ to have happened 20 days ago' + ); +} else { + fail( + 'rewrote circ to have happened 20 days ago' + ); +} +$cstore_ses->request('open-ils.cstore.transaction.commit')->gather(1); + +######## + +my $checkin_resp = do_checkin(ITEM_BARCODE); +is( + ref $checkin_resp, + 'HASH', + 'Checkin request returned a HASH' +); +is( + $checkin_resp->{ilsevent}, + 0, + 'Checkin returned a SUCCESS event' +); + +$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', ITEM_ID); +if (my $item_resp = $item_req->recv) { + if (my $item = $item_resp->content) { + ok( + $item->status == 7 || $item->status == 0, + 'Item with id = ' . ITEM_ID . ' has status of Reshelving or Available after fresh Storage request' + ); + } +} + +$bill_req = $circ_ses->request( + 'open-ils.circ.money.billing.retrieve.all', + $authtoken, + $circ->id +); +if (my $bill_resp = $bill_req->recv) { + if (my $bills = $bill_resp->content) { + is( + scalar( @{ $bills } ), + 12, + 'Twelve bills associated with circulation (instead of 13, thanks to closed date)' + ); + } +} + +my $tmp = delete_closed_date($closed_date_obj); +is($tmp, 1, 'Removed closed date'); + +oils_logout(); + + -- 2.43.2