From 1f53299a665cd1f074ca29d5d525627b7de74d5a Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Tue, 3 Nov 2015 18:42:38 +0200 Subject: [PATCH] Bug 14536 - PageObject squashable - Waitingreserves --- .../prog/en/modules/circ/waitingreserves.tt | 32 +-- t/db_dependent/Circulation/Waitingreserves.t | 149 ++++++++++++++ t/lib/Page/Circulation/Waitingreserves.pm | 215 +++++++++++++++++++++ 3 files changed, 380 insertions(+), 16 deletions(-) create mode 100644 t/db_dependent/Circulation/Waitingreserves.t create mode 100644 t/lib/Page/Circulation/Waitingreserves.pm diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt index bcc2f7c..54c5ad7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt @@ -88,22 +88,22 @@ [% FOREACH reserveloo IN reserveloop %] - [% reserveloo.waitingdate | $KohaDates %] - [% reserveloo.lastpickupdate %] - [% INCLUDE 'biblio-default-view.inc' biblionumber = reserveloo.biblionumber %] + [% reserveloo.waitingdate | $KohaDates %] + [% reserveloo.lastpickupdate %] + [% INCLUDE 'biblio-default-view.inc' biblionumber = reserveloo.biblionumber %] [% reserveloo.title |html %] [% reserveloo.subtitle |html %]   ([% reserveloo.itemtype %])
Barcode: [% reserveloo.barcode %] - [% reserveloo.borrowername %], [% reserveloo.borrowerfirstname %]
[% reserveloo.borrowerphone %]
+ [% reserveloo.borrowername %], [% reserveloo.borrowerfirstname %]
[% reserveloo.borrowerphone %]
[% IF ( reserveloo.borrowermail ) %] [% reserveloo.borrowermail %][% END %] - [% reserveloo.homebranch %]
[% reserveloo.itemcallnumber %] - [% reserveloo.copynumber %] - [% reserveloo.enumchron %] - + [% reserveloo.homebranch %]
[% reserveloo.itemcallnumber %] + [% reserveloo.copynumber %] + [% reserveloo.enumchron %] +
@@ -150,21 +150,21 @@ [% FOREACH overloo IN overloop %] -

[% overloo.waitingdate | $KohaDates %]

- [% overloo.lastpickupdate %] - [% INCLUDE 'biblio-default-view.inc' biblionumber = overloo.biblionumber %][% overloo.title |html %] [% overloo.subtitle |html %] +

[% overloo.waitingdate | $KohaDates %]

+ [% overloo.lastpickupdate %] + [% INCLUDE 'biblio-default-view.inc' biblionumber = overloo.biblionumber %][% overloo.title |html %] [% overloo.subtitle |html %] [% UNLESS ( item_level_itypes ) %][% IF ( overloo.itemtype ) %]  ([% overloo.itemtype %])[% END %][% END %]
Barcode: [% overloo.barcode %] - [% overloo.borrowername %], [% overloo.borrowerfirstname %]
[% overloo.borrowerphone %]
+ [% overloo.borrowername %], [% overloo.borrowerfirstname %]
[% overloo.borrowerphone %]
[% IF ( overloo.borrowermail ) %] [% overloo.borrowermail %][% END %] - [% overloo.homebranch %] [% overloo.itemcallnumber %] - [% overloo.copynumber %] - [% overloo.enumchron %] - + [% overloo.homebranch %] [% overloo.itemcallnumber %] + [% overloo.copynumber %] + [% overloo.enumchron %] + diff --git a/t/db_dependent/Circulation/Waitingreserves.t b/t/db_dependent/Circulation/Waitingreserves.t new file mode 100644 index 0000000..338ff7e --- /dev/null +++ b/t/db_dependent/Circulation/Waitingreserves.t @@ -0,0 +1,149 @@ +#!/usr/bin/perl + +# Copyright 2015 Open Source Freedom Fighters +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More; +use Try::Tiny; + +use t::lib::Page::Circulation::Waitingreserves; +use t::lib::TestObjects::ObjectFactory; +use t::lib::TestObjects::HoldFactory; +use t::lib::TestObjects::SystemPreferenceFactory; +use Koha::Auth::PermissionManager; + +##Enable debug mode for PageObject tests. +#$ENV{KOHA_PAGEOBJECT_DEBUG} = 1; + +##Setting up the test context +my $testContext = {}; + +my $password = '1234'; +my ($holds, $borrowers); +subtest "Setting up test context" => \&settingUpTestContext; +sub settingUpTestContext { + eval { #run in a eval-block so we don't die without tearing down the test context + + t::lib::TestObjects::SystemPreferenceFactory->createTestGroup([ + {preference => 'PickupExpiredHoldsOverReportDuration', + value => 2, + }, + {preference => 'ExpireReservesMaxPickUpDelay', + value => 1, + }, + {preference => 'ReservesMaxPickUpDelay', + value => 6, + }, + ], undef, $testContext); + + my $borrowerFactory = t::lib::TestObjects::BorrowerFactory->new(); + $borrowers = $borrowerFactory->createTestGroup([ + {firstname => 'Olli-Antti', + surname => 'Kivi', + cardnumber => '1A01', + branchcode => 'CPL', + userid => 'mini_admin', + password => $password, + }, + ], undef, $testContext); + my $permissionManager = Koha::Auth::PermissionManager->new(); + $permissionManager->grantPermission($borrowers->{'1A01'}, 'circulate', 'circulate_remaining_permissions'); + + $holds = t::lib::TestObjects::HoldFactory->createTestGroup([ + {cardnumber => '1A01', + isbn => '987Kivi', + barcode => '1N01', + branchcode => 'CPL', + waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 9)->iso8601(), + reservenotes => 'expire3daysAgo', + }, + {cardnumber => '1A01', + isbn => '987Kivi', + barcode => '1N02', + branchcode => 'CPL', + waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 8)->iso8601(), + reservenotes => 'expire2daysAgo', + row => 3, #for the following tests, this hold should be on row 3 in the holds over -table + }, + {cardnumber => '1A01', + isbn => '987Kivi', + barcode => '1N03', + branchcode => 'CPL', + waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 7)->iso8601(), + reservenotes => 'expire1dayAgo1', + row => 1, #for the following tests, this hold should be on row 3 in the holds over -table + }, + {cardnumber => '1A01', + isbn => '987Kivi', + barcode => '1N04', + branchcode => 'CPL', + waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 7)->iso8601(), + reservenotes => 'expire1dayAgo2', + row => 2, #for the following tests, this hold should be on row 3 in the holds over -table + }, + {cardnumber => '1A01', + isbn => '987Kivi', + barcode => '1N05', + branchcode => 'CPL', + waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 6)->iso8601(), + reservenotes => 'expiresToday', + }, + {cardnumber => '1A01', + isbn => '987Kivi', + barcode => '1N06', + branchcode => 'CPL', + waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 5)->iso8601(), + reservenotes => 'expiresTomorrow', + }, + ], undef, $testContext); + + ok(1, "Test context set without crashing"); + + }; + if ($@) { #Catch all leaking errors and gracefully terminate. + ok(0, "Test context set without crashing"); + warn $@; + tearDown(); + exit 1; + } +} + +subtest "Display expired waiting reserves" => \&displayExpiredWaitingReserves; +sub displayExpiredWaitingReserves { + eval { #run in a eval-block so we don't die without tearing down the test context + + my $waitingreserves = t::lib::Page::Circulation::Waitingreserves->new(); + $waitingreserves->doPasswordLogin($borrowers->{'1A01'}->userid(), $password) + ->showHoldsOver()->assertHoldRowsVisible($holds) + ->doPasswordLogout(); + $waitingreserves->quit(); + + }; + if ($@) { #Catch all leaking errors and gracefully terminate. + warn $@; + } +} + +##All tests done, tear down test context +tearDown(); +done_testing; + +sub tearDown { + t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); +} diff --git a/t/lib/Page/Circulation/Waitingreserves.pm b/t/lib/Page/Circulation/Waitingreserves.pm new file mode 100644 index 0000000..426dc9e --- /dev/null +++ b/t/lib/Page/Circulation/Waitingreserves.pm @@ -0,0 +1,215 @@ +package t::lib::Page::Circulation::Waitingreserves; + +# Copyright 2015 Open Source Freedom Fighters +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; +use Scalar::Util qw(blessed); +use Test::More; + +use base qw(t::lib::Page::Intra); + +use Koha::Exception::BadParameter; + +=head NAME t::lib::Page::Circulation::Waitingreserve + +=head SYNOPSIS + +waitingreserves.pl PageObject providing page functionality as a service! + +=cut + +=head new + + my $circulation = t::lib::Page::Circulation::Waitingreserves->new({borrowernumber => "1"}); + +Instantiates a WebDriver and loads the circ/waitingreserves.pl. +@PARAM1 HASHRef of optional and MANDATORY parameters +Optional extra parameters: + allbranches => 1 #Show reserves from all branches + +@RETURNS t::lib::Page::Circulation::Waitingreserves, ready for user actions! +=cut + +sub new { + my ($class, $params) = @_; + unless (ref($params) eq 'HASH' || (blessed($params) && $params->isa('t::lib::Page') )) { + $params = {}; + } + $params->{resource} = '/cgi-bin/koha/circ/waitingreserves.pl'; + $params->{type} = 'staff'; + + $params->{getParams} = []; + #Handle optional parameters + if ($params->{allbranches}) { + push @{$params->{getParams}}, "allbranches=".$params->{allbranches}; + } + + my $self = $class->SUPER::new($params); + + #Set special page-dependent parameters + $self->{waitingreserves}->{tabDisplayed} = 'waiting'; + return $self; +} + +################################################################################ +=head UI Mapping helper subroutines +See. Selenium documentation best practices for UI element mapping to common language descriptions. +=cut +################################################################################ + +sub _getTablist { + my ($self) = @_; + my $d = $self->getDriver(); + + my $holdswaiting_a = $d->find_element("ul a[href*='#holdswaiting']", 'css'); + my $holdsover_a = $d->find_element("ul a[href*='#holdsover']", 'css'); + + my $e = {}; + $e->{holdswaiting} = $holdswaiting_a; + $e->{holdsover} = $holdsover_a; + return $e; +} + +=head _getHoldsRows + @RETURNS HASHRef of + HASHRef of HASHes of Selenium::Driver::Webelement-objects matching the table rows and columns. + Also some special identifiers will be extracted. + eg. { + "1" => { + waitingdate => Selenium::Driver::Webelement, + lastpickupdate => Selenium::Driver::Webelement, + ... + barcode => '167N03651343', + biblionumber => 854323, + }, + "2" => { + ... + } + } + +=cut +sub _getHoldsRows { + my ($self) = @_; + my $d = $self->getDriver(); + + my $waitingOrOverdue = $self->{waitingreserves}->{tabDisplayed}; + my $tableId = ($waitingOrOverdue && $waitingOrOverdue eq 'overdue') ? 'holdso' : 'holdst'; + + my $holdsRows_tr; + eval { #We might not have any rows + $holdsRows_tr = $d->find_elements("table#$tableId tbody tr", 'css'); + }; + my %holdsRows; + for(my $i=0 ; $i[$i]; + $row->{waitingdate} = $d->find_child_element($row, "td.waitingdate", 'css'); + $row->{lastpickupdate} = $d->find_child_element($row, "td.lastpickupdate", 'css'); + $row->{resobjects} = $d->find_child_element($row, "td.resobjects", 'css'); + $row->{borrower} = $d->find_child_element($row, "td.borrower", 'css'); + $row->{location} = $d->find_child_element($row, "td.location", 'css'); + $row->{copynumber} = $d->find_child_element($row, "td.copynumber", 'css'); + $row->{enumchron} = $d->find_child_element($row, "td.enumchron", 'css'); + $row->{action} = $d->find_child_element($row, "td.action", 'css'); + $holdsRows{$i} = $row; + + #Extract textual identifiers + my $titleText = $row->{resobjects}->get_text(); + if ($titleText =~ /Barcode:\s+(\S+)/) { + $row->{barcode} = $1; + } + else { + warn __PACKAGE__."->assertHoldRowsVisible():> Couldn't extract barcode from title-column '$titleText'\n"; + } + } + + return \%holdsRows; +} + +################################################################################ +=head PageObject Services + +=cut +################################################################################ + +sub viewAllLibraries { + my ($self) = @_; + my $d = $self->getDriver(); + $self->debugTakeSessionSnapshot(); + + my $view_all_libraries_a = $d->find_element("a[href*='waitingreserves.pl?allbranches=1']", 'css'); + $view_all_libraries_a->click(); + + $self->debugTakeSessionSnapshot(); + return $self; +} + +sub showHoldsWaiting { + my ($self) = @_; + my $d = $self->getDriver(); + $self->debugTakeSessionSnapshot(); + + my $e = $self->_getTablist(); + my $showWaiting_a = $e->{holdswaiting}; + $showWaiting_a->click(); + $self->{waitingreserves}->{tabDisplayed} = 'waiting'; + + $self->debugTakeSessionSnapshot(); + return $self; +} + +sub showHoldsOver { + my ($self) = @_; + my $d = $self->getDriver(); + $self->debugTakeSessionSnapshot(); + + my $e = $self->_getTablist(); + my $showOver_a = $e->{holdsover}; + $showOver_a->click(); + $self->{waitingreserves}->{tabDisplayed} = 'overdue'; + + $self->debugTakeSessionSnapshot(); + return $self; +} + +=head assertHoldRowsVisible + +@PARAM1 ARRAYref of HASHes. Represents the holds that must be present in the displayed holds table + eg. [{ + barcode => '167N0032112', + }, + ] +@RETURN t::lib::Page::Circulation::Waitingreserves-object +=cut +sub assertHoldRowsVisible { + my ($self, $holds) = @_; + my $d = $self->getDriver(); + $self->debugTakeSessionSnapshot(); + + my $holdRows = $self->_getHoldsRows(); + for (my $i=0 ; $i[$i]; + my $targetRow = $holdRows->{ $i }; + is($targetRow->{barcode}, $h->{barcode}, + "assertHoldRowsVisible: Row ".$i." barcodes '".$targetRow->{barcode}."' and '".$h->{barcode}."' match."); + } + + return $self; +} + +1; -- 1.9.1