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 <jason@esilibrary.com>
Signed-off-by: Bill Erickson <berick@esilibrary.com>
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
--- /dev/null
+#!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'
+ );
+ }
+}
+
--- /dev/null
+#!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'
+);
+
--- /dev/null
+#!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();
+
+
--- /dev/null
+#!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();
+
+
--- /dev/null
+#!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();
+
+