From fee8c60dc7a1fc7036259c090d8c46059bcf49d6 Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Wed, 20 Aug 2008 11:21:48 -0500 Subject: [PATCH] bug 2503: tests for C4::Circulation I'm adding some tests for C4::Circulation methods that I'm altering to allow the offline circulation tool to use C4::Circulation to upload its data. These test a bit of the old functionality and try to show that the new functionality does what I think it does. C4::Circ::Addissue to tests issuedate these also test AddRenewal. tests for C4::Circ::MarkIssueReturned Signed-off-by: Galen Charlton --- t/lib/KohaTest/Circulation.pm | 86 +++++++++++++ t/lib/KohaTest/Circulation/AddIssue.pm | 120 ++++++++++++++++++ .../KohaTest/Circulation/MarkIssueReturned.pm | 85 +++++++++++++ t/lib/KohaTest/Dates/Usage.pm | 2 +- t/lib/KohaTest/Scripts/longoverdue.pm | 8 +- 5 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 t/lib/KohaTest/Circulation/AddIssue.pm create mode 100644 t/lib/KohaTest/Circulation/MarkIssueReturned.pm diff --git a/t/lib/KohaTest/Circulation.pm b/t/lib/KohaTest/Circulation.pm index 5e26457f06..1648400588 100644 --- a/t/lib/KohaTest/Circulation.pm +++ b/t/lib/KohaTest/Circulation.pm @@ -52,5 +52,91 @@ sub methods : Test( 1 ) { can_ok( $self->testing_class, @methods ); } +=head3 setup_add_biblios + +everything in the C4::Circulation really requires items, so let's do this in the setup phase. + +=cut + +sub setup_add_biblios : Tests( setup => 8 ) { + my $self = shift; + + # we want to use a fresh batch of items, so clear these lists: + delete $self->{'items'}; + delete $self->{'biblios'}; + + $self->add_biblios( add_items => 1 ); +} + + +=head3 checkout_first_item + +named parameters: + borrower => borrower hashref, computed from $self->{'memberid'} if not given + barcode => item barcode, barcode of $self->{'items'}[0] if not given + issuedate => YYYY-MM-DD of date to mark issue checked out. defaults to today. + +=cut + +sub checkout_first_item { + my $self = shift; + my $params = shift; + + # get passed in borrower, or default to the one in $self. + my $borrower = $params->{'borrower'}; + if ( ! defined $borrower ) { + my $borrowernumber = $self->{'memberid'}; + $borrower = C4::Members::GetMemberDetails( $borrowernumber ); + } + + # get the barcode passed in, or default to the first one in the items list + my $barcode = $params->{'barcode'}; + if ( ! defined $barcode ) { + return unless $self->{'items'}[0]{'itemnumber'}; + $barcode = $self->get_barcode_from_itemnumber( $self->{'items'}[0]{'itemnumber'} ); + } + + # get issuedate from parameters. Default to undef, which will be interpreted as today + my $issuedate = $params->{'issuedate'}; + + my ( $issuingimpossible, $needsconfirmation ) = C4::Circulation::CanBookBeIssued( $borrower, $barcode ); + + my $datedue = C4::Circulation::AddIssue( + $borrower, # borrower + $barcode, # barcode + undef, # datedue + undef, # cancelreserve + $issuedate # issuedate + ); + + my $issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + + return $issues->{'date_due'}; +} + +=head3 get_barcode_from_itemnumber + +pass in an itemnumber, returns a barcode. + +Should this get moved up to KohaTest.pm? Or, is there a better alternative in C4? + +=cut + +sub get_barcode_from_itemnumber { + my $self = shift; + my $itemnumber = shift; + + my $sql = <dbh() or return; + my $sth = $dbh->prepare($sql) or return; + $sth->execute($itemnumber) or return; + my ($barcode) = $sth->fetchrow_array; + return $barcode; +} + 1; diff --git a/t/lib/KohaTest/Circulation/AddIssue.pm b/t/lib/KohaTest/Circulation/AddIssue.pm new file mode 100644 index 0000000000..4e02d16461 --- /dev/null +++ b/t/lib/KohaTest/Circulation/AddIssue.pm @@ -0,0 +1,120 @@ +package KohaTest::Circulation::AddIssue; +use base qw(KohaTest::Circulation); + +use strict; +use warnings; + +use Test::More; + +=head2 basic_usage + +basic usage of C4::Circulation::AddIssue + +Note: This logic is repeated in +KohaTest::Circulation::checkout_first_item, but without tests. This +includes tests at each step to make it easier to track down what's +broken as we go along. + +=cut + +sub basic_usage : Test( 11 ) { + my $self = shift; + + my $borrowernumber = $self->{'memberid'}; + ok( $borrowernumber, "we're going to work with borrower: $borrowernumber" ); + + my $borrower = C4::Members::GetMemberDetails( $borrowernumber ); + ok( $borrower, '...and we were able to look up that borrower' ); + is( $borrower->{'borrowernumber'}, $borrowernumber, '...and they have the right borrowernumber' ); + + my $itemnumber = $self->{'items'}[0]{'itemnumber'}; + ok( $itemnumber, "We're going to checkout itemnumber $itemnumber" ); + my $barcode = $self->get_barcode_from_itemnumber($itemnumber); + ok( $barcode, "...which has barcode $barcode" ); + + my $before_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + # Note that we can't check for $before_issues as undef because GetItemIssue always returns a populated hashref + ok( ! defined $before_issues->{'borrowernumber'}, '...and is not currently checked out' ) + or diag( Data::Dumper->Dump( [ $before_issues ], [ 'before_issues' ] ) ); + + my ( $issuingimpossible, $needsconfirmation ) = C4::Circulation::CanBookBeIssued( $borrower, $barcode ); + is( scalar keys %$issuingimpossible, 0, 'the item CanBookBeIssued' ) + or diag( Data::Dumper->Dump( [ $issuingimpossible, $needsconfirmation ], [ qw( issuingimpossible needsconfirmation ) ] ) ); + is( scalar keys %$needsconfirmation, 0, '...and the transaction does not needsconfirmation' ) + or diag( Data::Dumper->Dump( [ $issuingimpossible, $needsconfirmation ], [ qw( issuingimpossible needsconfirmation ) ] ) ); + + my $datedue = C4::Circulation::AddIssue( $borrower, $barcode ); + { + local $TODO = 'AddIssue does not actually return the due date'; + ok( $datedue, "the item has been issued and it is due: $datedue" ); + } + + my $after_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + is( $after_issues->{'borrowernumber'}, $borrowernumber, '...and now it is checked out to our borrower' ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'after_issues' ] ) ); + + my $loanlength = Date::Calc::Delta_Days( split( /-/, $after_issues->{'issuedate'} ), split( /-/, $after_issues->{'date_due'} ) ); + ok( $loanlength, "the loanlength is $loanlength days" ); + + # save this here since we refer to it in set_issuedate. + $self->{'loanlength'} = $loanlength; + +} + +=head2 set_issuedate + +Make sure that we can set the issuedate of an issue. + +Also, since we are specifying an issuedate and not a due date, the due +date should be calculated from the issuedate, not today. + +=cut + +sub set_issuedate : Test( 7 ) { + my $self = shift; + + my $before_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + ok( ! defined $before_issues->{'borrowernumber'}, 'At this beginning, this item was not checked out.' ) + or diag( Data::Dumper->Dump( [ $before_issues ], [ 'before_issues' ] ) ); + + my $issuedate = $self->random_date(); + ok( $issuedate, "Check out an item on $issuedate" ); + my $datedue = $self->checkout_first_item( { issuedate => $issuedate } ); + ok( $datedue, "...and it's due on $datedue" ); + + my $after_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + is( $after_issues->{'borrowernumber'}, $self->{'memberid'}, 'We found this item checked out to our member.' ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'issues' ] ) ); + is( $after_issues->{'issuedate'}, $issuedate, "...and it was issued on $issuedate" ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'after_issues' ] ) ); + + my $loanlength = Date::Calc::Delta_Days( split( /-/, $after_issues->{'issuedate'} ), split( /-/, $after_issues->{'date_due'} ) ); + ok( $loanlength, "the loanlength is $loanlength days" ); + is( $loanlength, $self->{'loanlength'} ); +} + +sub set_issuedate_on_renewal : Test( 6 ) { + my $self = shift; + + my $before_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + ok( ! defined $before_issues->{'borrowernumber'}, 'At this beginning, this item was not checked out.' ) + or diag( Data::Dumper->Dump( [ $before_issues ], [ 'before_issues' ] ) ); + + my $datedue = $self->checkout_first_item( { issuedate => $self->yesterday() } ); + ok( $datedue, "The item is checked out and it's due on $datedue" ); + + my $issuedate = $self->random_date(); + ok( $issuedate, "Check out an item again on $issuedate" ); + # This will actually be a renewal + $datedue = $self->checkout_first_item( { issuedate => $issuedate } ); + ok( $datedue, "...and it's due on $datedue" ); + + my $after_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + is( $after_issues->{'borrowernumber'}, $self->{'memberid'}, 'We found this item checked out to our member.' ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'issues' ] ) ); + is( $after_issues->{'issuedate'}, $issuedate, "...and it was issued on $issuedate" ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'after_issues' ] ) ); + +} + +1; diff --git a/t/lib/KohaTest/Circulation/MarkIssueReturned.pm b/t/lib/KohaTest/Circulation/MarkIssueReturned.pm new file mode 100644 index 0000000000..5722bcfe96 --- /dev/null +++ b/t/lib/KohaTest/Circulation/MarkIssueReturned.pm @@ -0,0 +1,85 @@ +package KohaTest::Circulation::MarkIssueReturned; +use base qw(KohaTest::Circulation); + +use strict; +use warnings; + +use Test::More; + +=head2 basic_usage + +basic usage of C4::Circulation::MarkIssueReturned + +=cut + +sub basic_usage : Test( 4 ) { + my $self = shift; + + my $before_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + ok( ! defined $before_issues->{'borrowernumber'}, 'our item is not checked out' ) + or diag( Data::Dumper->Dump( [ $before_issues ], [ 'before_issues' ] ) ); + + my $datedue = $self->checkout_first_item(); + ok( $datedue, "Now it is checked out and due on $datedue" ); + + my $after_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + is( $after_issues->{'borrowernumber'}, $self->{'memberid'}, 'Our item is checked out to our borrower' ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'after_issues' ] ) ); + + C4::Circulation::MarkIssueReturned( $self->{'memberid'}, $self->{'items'}[0]{'itemnumber'} ); + + my $after_return = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + ok( ! defined $after_return->{'borrowernumber'}, 'The item is no longer checked out' ) + or diag( Data::Dumper->Dump( [ $after_return ], [ 'after_return' ] ) ); + +} + +=head2 set_returndate + +check an item out, then, check it back in, specifying the returndate. + +verify that it's checked back in and the returndate is correct. + +=cut + +sub set_retundate : Test( 7 ) { + my $self = shift; + + # It's not checked out to start with + my $before_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + ok( ! defined $before_issues->{'borrowernumber'}, 'our item is not checked out' ) + or diag( Data::Dumper->Dump( [ $before_issues ], [ 'before_issues' ] ) ); + + # check it out + my $datedue = $self->checkout_first_item(); + ok( $datedue, "Now it is checked out and due on $datedue" ); + + # verify that it has been checked out + my $after_issues = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + is( $after_issues->{'borrowernumber'}, $self->{'memberid'}, 'Our item is checked out to our borrower' ) + or diag( Data::Dumper->Dump( [ $after_issues ], [ 'after_issues' ] ) ); + + # mark it as returned on some date + my $returndate = $self->random_date(); + ok( $returndate, "return this item on $returndate" ); + + C4::Circulation::MarkIssueReturned( $self->{'memberid'}, + $self->{'items'}[0]{'itemnumber'}, + undef, + $returndate ); + + # validate that it is no longer checked out. + my $after_return = C4::Circulation::GetItemIssue( $self->{'items'}[0]{'itemnumber'} ); + ok( ! defined $after_return->{'borrowernumber'}, 'The item is no longer checked out' ) + or diag( Data::Dumper->Dump( [ $after_return ], [ 'after_return' ] ) ); + + # grab the history for this item and make sure it looks right + my $history = C4::Circulation::GetItemIssues( $self->{'items'}[0]{'itemnumber'}, 1 ); + is( scalar @$history, 1, 'this item has been checked out one time.' ) + or diag( Data::Dumper->Dump( [ $history ], [ 'history' ] ) ); + is( $history->[0]{'returndate'}, $returndate, "...and it was returned on $returndate" ); + +} + + +1; diff --git a/t/lib/KohaTest/Dates/Usage.pm b/t/lib/KohaTest/Dates/Usage.pm index 9dc75eddd4..8815c89103 100644 --- a/t/lib/KohaTest/Dates/Usage.pm +++ b/t/lib/KohaTest/Dates/Usage.pm @@ -20,7 +20,7 @@ sub startup_init_constants : Tests(startup => 0) { $self->{formats} = [ sort keys %{ $self->{thash} } ]; } -sub check_formats : Test( 10 ) { +sub check_formats : Test( 8 ) { my $self = shift; my $syspref = C4::Dates->new->format(); diff --git a/t/lib/KohaTest/Scripts/longoverdue.pm b/t/lib/KohaTest/Scripts/longoverdue.pm index ea1c317311..f99e3f1813 100644 --- a/t/lib/KohaTest/Scripts/longoverdue.pm +++ b/t/lib/KohaTest/Scripts/longoverdue.pm @@ -37,7 +37,7 @@ sub create_overdue_item : Test( startup => 12 ) { } -sub set_overdue_item_lost : Test( 12 ) { +sub set_overdue_item_lost : Test( 13 ) { my $self = shift; my $item = C4::Items::GetItem( $self->{'overdueitemnumber'} ); @@ -69,10 +69,8 @@ sub set_overdue_item_lost : Test( 12 ) { is( keys %$needsconfirmation, 0, 'issuing needs no confirmation' ); my $issue_due_date = C4::Circulation::AddIssue( $borrower, $item->{'barcode'}, $duedate ); - TODO: { - local $TODO = 'C4::Circulation::AddIssue returns undef insead of the due date'; - ok( $issue_due_date, 'due date' ); - } + ok( $issue_due_date, 'due date' ); + is( $issue_due_date, $duedate, 'AddIssue returned the same date we passed to it' ); # I have to make this in a different format since that's how the database holds it. my $duedateyyyymmdd = sprintf( '%04d-%02d-%02d', -- 2.39.5