View | Details | Raw Unified | Return to bug 14536
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt (-16 / +16 lines)
Lines 88-109 Link Here
88
               </tr></thead>
88
               </tr></thead>
89
               <tbody>[% FOREACH reserveloo IN reserveloop %]
89
               <tbody>[% FOREACH reserveloo IN reserveloop %]
90
                <tr>
90
                <tr>
91
                    <td><span title="[% reserveloo.waitingdate %]">[% reserveloo.waitingdate | $KohaDates %]</span></td>
91
                    <td class="waitingdate"><span title="[% reserveloo.waitingdate %]">[% reserveloo.waitingdate | $KohaDates %]</span></td>
92
                    <td>[% reserveloo.lastpickupdate %]</td>
92
                    <td class="lastpickupdate">[% reserveloo.lastpickupdate %]</td>
93
                    <td>[% INCLUDE 'biblio-default-view.inc' biblionumber = reserveloo.biblionumber %]
93
                    <td class="title">[% INCLUDE 'biblio-default-view.inc' biblionumber = reserveloo.biblionumber %]
94
                        [% reserveloo.title |html %] [% reserveloo.subtitle |html %]
94
                        [% reserveloo.title |html %] [% reserveloo.subtitle |html %]
95
                        </a>
95
                        </a>
96
                            &nbsp; (<b>[% reserveloo.itemtype %]</b>)
96
                            &nbsp; (<b>[% reserveloo.itemtype %]</b>)
97
                            <br />Barcode: [% reserveloo.barcode %]
97
                            <br />Barcode: [% reserveloo.barcode %]
98
                    </td>
98
                    </td>
99
                    <td><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% reserveloo.borrowernum %]">[% reserveloo.borrowername %], [% reserveloo.borrowerfirstname %]</a><br />[% reserveloo.borrowerphone %]<br />
99
                    <td class="borrower"><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% reserveloo.borrowernum %]">[% reserveloo.borrowername %], [% reserveloo.borrowerfirstname %]</a><br />[% reserveloo.borrowerphone %]<br />
100
                        [% IF ( reserveloo.borrowermail ) %]<a href="mailto:[% reserveloo.email %]?subject=Reservation: [% reserveloo.title %]">
100
                        [% IF ( reserveloo.borrowermail ) %]<a href="mailto:[% reserveloo.email %]?subject=Reservation: [% reserveloo.title %]">
101
                        [% reserveloo.borrowermail %]</a>[% END %]
101
                        [% reserveloo.borrowermail %]</a>[% END %]
102
                    </td>
102
                    </td>
103
                    <td>[% reserveloo.homebranch %]<br />[% reserveloo.itemcallnumber %]</td>
103
                    <td class="location">[% reserveloo.homebranch %]<br />[% reserveloo.itemcallnumber %]</td>
104
                    <td>[% reserveloo.copynumber %]</td>
104
                    <td class="copynumber">[% reserveloo.copynumber %]</td>
105
                    <td>[% reserveloo.enumchron %]</td>
105
                    <td class="enumchron">[% reserveloo.enumchron %]</td>
106
                    <td>
106
                    <td class="action">
107
                        <form name="cancelReserve" action="waitingreserves.pl" method="post">
107
                        <form name="cancelReserve" action="waitingreserves.pl" method="post">
108
                            <input type="hidden" name="borrowernumber" value="[% reserveloo.borrowernum %]" />
108
                            <input type="hidden" name="borrowernumber" value="[% reserveloo.borrowernum %]" />
109
                            <input type="hidden" name="itemnumber" value="[% reserveloo.itemnumber %]" />
109
                            <input type="hidden" name="itemnumber" value="[% reserveloo.itemnumber %]" />
Lines 150-170 Link Here
150
               </tr></thead>
150
               </tr></thead>
151
               <tbody>[% FOREACH overloo IN overloop %]
151
               <tbody>[% FOREACH overloo IN overloop %]
152
                    <tr>
152
                    <tr>
153
                        <td><p><span title="[% overloo.waitingdate %]">[% overloo.waitingdate | $KohaDates %]</span></p></td>
153
                        <td class="waitingdate"><p><span title="[% overloo.waitingdate %]">[% overloo.waitingdate | $KohaDates %]</span></p></td>
154
                        <td>[% overloo.lastpickupdate %]</td>
154
                        <td class="lastpickupdate">[% overloo.lastpickupdate %]</td>
155
                        <td>[% INCLUDE 'biblio-default-view.inc' biblionumber = overloo.biblionumber %][% overloo.title |html %] [% overloo.subtitle |html %]
155
                        <td class="title">[% INCLUDE 'biblio-default-view.inc' biblionumber = overloo.biblionumber %][% overloo.title |html %] [% overloo.subtitle |html %]
156
                        </a>
156
                        </a>
157
                            [% UNLESS ( item_level_itypes ) %][% IF ( overloo.itemtype ) %]&nbsp; (<b>[% overloo.itemtype %]</b>)[% END %][% END %]
157
                            [% UNLESS ( item_level_itypes ) %][% IF ( overloo.itemtype ) %]&nbsp; (<b>[% overloo.itemtype %]</b>)[% END %][% END %]
158
                        <br />Barcode: [% overloo.barcode %]
158
                        <br />Barcode: [% overloo.barcode %]
159
                    </td>
159
                    </td>
160
                    <td><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% overloo.borrowernum %]">[% overloo.borrowername %], [% overloo.borrowerfirstname %]</a><br />[% overloo.borrowerphone %]<br />
160
                    <td class="borrower"><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% overloo.borrowernum %]">[% overloo.borrowername %], [% overloo.borrowerfirstname %]</a><br />[% overloo.borrowerphone %]<br />
161
                        [% IF ( overloo.borrowermail ) %]<a href="mailto:[% overloo.email %]?subject=Reservation: [% overloo.title |url %]">
161
                        [% IF ( overloo.borrowermail ) %]<a href="mailto:[% overloo.email %]?subject=Reservation: [% overloo.title |url %]">
162
        [% overloo.borrowermail %]</a>[% END %]
162
        [% overloo.borrowermail %]</a>[% END %]
163
                    </td>
163
                    </td>
164
                    <td>[% overloo.homebranch %] [% overloo.itemcallnumber %]</td>
164
                    <td class="location">[% overloo.homebranch %] [% overloo.itemcallnumber %]</td>
165
                    <td>[% overloo.copynumber %]</td>
165
                    <td class="copynumber">[% overloo.copynumber %]</td>
166
                    <td>[% overloo.enumchron %]</td>
166
                    <td class="enumchron">[% overloo.enumchron %]</td>
167
                    <td><form name="cancelReserve" action="waitingreserves.pl" method="post">
167
                    <td class="action"><form name="cancelReserve" action="waitingreserves.pl" method="post">
168
                            <input type="hidden" name="borrowernumber" value="[% overloo.borrowernum %]" />
168
                            <input type="hidden" name="borrowernumber" value="[% overloo.borrowernum %]" />
169
                            <input type="hidden" name="itemnumber" value="[% overloo.itemnumber %]" />
169
                            <input type="hidden" name="itemnumber" value="[% overloo.itemnumber %]" />
170
                            <input type="hidden" name="fbr" value="[% overloo.holdingbranch %]" />
170
                            <input type="hidden" name="fbr" value="[% overloo.holdingbranch %]" />
(-)a/t/db_dependent/Circulation/Waitingreserves.t (+149 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More;
23
use Try::Tiny;
24
25
use t::lib::Page::Circulation::Waitingreserves;
26
use t::lib::TestObjects::ObjectFactory;
27
use t::lib::TestObjects::HoldFactory;
28
use t::lib::TestObjects::SystemPreferenceFactory;
29
use Koha::Auth::PermissionManager;
30
31
##Enable debug mode for PageObject tests.
32
#$ENV{KOHA_PAGEOBJECT_DEBUG} = 1;
33
34
##Setting up the test context
35
my $testContext = {};
36
37
my $password = '1234';
38
my ($holds, $borrowers);
39
subtest "Setting up test context" => \&settingUpTestContext;
40
sub settingUpTestContext {
41
    eval { #run in a eval-block so we don't die without tearing down the test context
42
43
        t::lib::TestObjects::SystemPreferenceFactory->createTestGroup([
44
            {preference => 'PickupExpiredHoldsOverReportDuration',
45
             value => 2,
46
            },
47
            {preference => 'ExpireReservesMaxPickUpDelay',
48
             value => 1,
49
            },
50
            {preference => 'ReservesMaxPickUpDelay',
51
             value => 6,
52
            },
53
            ], undef, $testContext);
54
55
        my $borrowerFactory = t::lib::TestObjects::BorrowerFactory->new();
56
        $borrowers = $borrowerFactory->createTestGroup([
57
                    {firstname  => 'Olli-Antti',
58
                     surname    => 'Kivi',
59
                     cardnumber => '1A01',
60
                     branchcode => 'CPL',
61
                     userid     => 'mini_admin',
62
                     password   => $password,
63
                    },
64
                ], undef, $testContext);
65
        my $permissionManager = Koha::Auth::PermissionManager->new();
66
        $permissionManager->grantPermission($borrowers->{'1A01'}, 'circulate', 'circulate_remaining_permissions');
67
68
        $holds = t::lib::TestObjects::HoldFactory->createTestGroup([
69
            {cardnumber  => '1A01',
70
             isbn        => '987Kivi',
71
             barcode     => '1N01',
72
             branchcode  => 'CPL',
73
             waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 9)->iso8601(),
74
             reservenotes => 'expire3daysAgo',
75
            },
76
            {cardnumber  => '1A01',
77
             isbn        => '987Kivi',
78
             barcode     => '1N02',
79
             branchcode  => 'CPL',
80
             waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 8)->iso8601(),
81
             reservenotes => 'expire2daysAgo',
82
             row         => 3, #for the following tests, this hold should be on row 3 in the holds over -table
83
            },
84
            {cardnumber  => '1A01',
85
             isbn        => '987Kivi',
86
             barcode     => '1N03',
87
             branchcode  => 'CPL',
88
             waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 7)->iso8601(),
89
             reservenotes => 'expire1dayAgo1',
90
             row         => 1, #for the following tests, this hold should be on row 3 in the holds over -table
91
            },
92
            {cardnumber  => '1A01',
93
             isbn        => '987Kivi',
94
             barcode     => '1N04',
95
             branchcode  => 'CPL',
96
             waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 7)->iso8601(),
97
             reservenotes => 'expire1dayAgo2',
98
             row         => 2, #for the following tests, this hold should be on row 3 in the holds over -table
99
            },
100
            {cardnumber  => '1A01',
101
             isbn        => '987Kivi',
102
             barcode     => '1N05',
103
             branchcode  => 'CPL',
104
             waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 6)->iso8601(),
105
             reservenotes => 'expiresToday',
106
            },
107
            {cardnumber  => '1A01',
108
             isbn        => '987Kivi',
109
             barcode     => '1N06',
110
             branchcode  => 'CPL',
111
             waitingdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 5)->iso8601(),
112
             reservenotes => 'expiresTomorrow',
113
            },
114
        ], undef, $testContext);
115
116
        ok(1, "Test context set without crashing");
117
118
    };
119
    if ($@) { #Catch all leaking errors and gracefully terminate.
120
        ok(0, "Test context set without crashing");
121
        warn $@;
122
        tearDown();
123
        exit 1;
124
    }
125
}
126
127
subtest "Display expired waiting reserves" => \&displayExpiredWaitingReserves;
128
sub displayExpiredWaitingReserves {
129
    eval { #run in a eval-block so we don't die without tearing down the test context
130
131
        my $waitingreserves = t::lib::Page::Circulation::Waitingreserves->new();
132
        $waitingreserves->doPasswordLogin($borrowers->{'1A01'}->userid(), $password)
133
            ->showHoldsOver()->assertHoldRowsVisible($holds)
134
            ->doPasswordLogout();
135
        $waitingreserves->quit();
136
137
    };
138
    if ($@) { #Catch all leaking errors and gracefully terminate.
139
        warn $@;
140
    }
141
}
142
143
##All tests done, tear down test context
144
tearDown();
145
done_testing;
146
147
sub tearDown {
148
    t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext);
149
}
(-)a/t/lib/Page/Circulation/Waitingreserves.pm (-1 / +215 lines)
Line 0 Link Here
0
- 
1
package t::lib::Page::Circulation::Waitingreserves;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
use Test::More;
23
24
use base qw(t::lib::Page::Intra);
25
26
use Koha::Exception::BadParameter;
27
28
=head NAME t::lib::Page::Circulation::Waitingreserve
29
30
=head SYNOPSIS
31
32
waitingreserves.pl PageObject providing page functionality as a service!
33
34
=cut
35
36
=head new
37
38
    my $circulation = t::lib::Page::Circulation::Waitingreserves->new({borrowernumber => "1"});
39
40
Instantiates a WebDriver and loads the circ/waitingreserves.pl.
41
@PARAM1 HASHRef of optional and MANDATORY parameters
42
Optional extra parameters:
43
    allbranches => 1 #Show reserves from all branches
44
45
@RETURNS t::lib::Page::Circulation::Waitingreserves, ready for user actions!
46
=cut
47
48
sub new {
49
    my ($class, $params) = @_;
50
    unless (ref($params) eq 'HASH' || (blessed($params) && $params->isa('t::lib::Page') )) {
51
        $params = {};
52
    }
53
    $params->{resource} = '/cgi-bin/koha/circ/waitingreserves.pl';
54
    $params->{type}     = 'staff';
55
56
    $params->{getParams} = [];
57
    #Handle optional parameters
58
    if ($params->{allbranches}) {
59
        push @{$params->{getParams}}, "allbranches=".$params->{allbranches};
60
    }
61
62
    my $self = $class->SUPER::new($params);
63
64
    #Set special page-dependent parameters
65
    $self->{waitingreserves}->{tabDisplayed} = 'waiting';
66
    return $self;
67
}
68
69
################################################################################
70
=head UI Mapping helper subroutines
71
See. Selenium documentation best practices for UI element mapping to common language descriptions.
72
=cut
73
################################################################################
74
75
sub _getTablist {
76
    my ($self) = @_;
77
    my $d = $self->getDriver();
78
79
    my $holdswaiting_a = $d->find_element("ul a[href*='#holdswaiting']", 'css');
80
    my $holdsover_a = $d->find_element("ul a[href*='#holdsover']", 'css');
81
82
    my $e = {};
83
    $e->{holdswaiting} = $holdswaiting_a;
84
    $e->{holdsover} = $holdsover_a;
85
    return $e;
86
}
87
88
=head _getHoldsRows
89
    @RETURNS HASHRef of
90
         HASHRef of HASHes of Selenium::Driver::Webelement-objects matching the table rows and columns.
91
         Also some special identifiers will be extracted.
92
         eg. {
93
            "1" => {
94
                waitingdate => Selenium::Driver::Webelement,
95
                lastpickupdate => Selenium::Driver::Webelement,
96
                ...
97
                barcode => '167N03651343',
98
                biblionumber => 854323,
99
            },
100
            "2" => {
101
                ...
102
            }
103
         }
104
105
=cut
106
sub _getHoldsRows {
107
    my ($self) = @_;
108
    my $d = $self->getDriver();
109
110
    my $waitingOrOverdue = $self->{waitingreserves}->{tabDisplayed};
111
    my $tableId = ($waitingOrOverdue && $waitingOrOverdue eq 'overdue') ? 'holdso' : 'holdst';
112
113
    my $holdsRows_tr;
114
    eval { #We might not have any rows
115
        $holdsRows_tr = $d->find_elements("table#$tableId tbody tr", 'css');
116
    };
117
    my %holdsRows;
118
    for(my $i=0 ; $i<scalar(@$holdsRows_tr) ; $i++) {
119
        #Iterate every apiKey in the apiKeys table and prefetch the interesting data as text and available action elements.
120
        my $row = $holdsRows_tr->[$i];
121
        $row->{waitingdate}    = $d->find_child_element($row, "td.waitingdate", 'css');
122
        $row->{lastpickupdate} = $d->find_child_element($row, "td.lastpickupdate", 'css');
123
        $row->{resobjects}     = $d->find_child_element($row, "td.resobjects", 'css');
124
        $row->{borrower}       = $d->find_child_element($row, "td.borrower", 'css');
125
        $row->{location}       = $d->find_child_element($row, "td.location", 'css');
126
        $row->{copynumber}     = $d->find_child_element($row, "td.copynumber", 'css');
127
        $row->{enumchron}      = $d->find_child_element($row, "td.enumchron", 'css');
128
        $row->{action}         = $d->find_child_element($row, "td.action", 'css');
129
        $holdsRows{$i} = $row;
130
131
        #Extract textual identifiers
132
        my $titleText = $row->{resobjects}->get_text();
133
        if ($titleText =~ /Barcode:\s+(\S+)/) {
134
            $row->{barcode} = $1;
135
        }
136
        else {
137
            warn __PACKAGE__."->assertHoldRowsVisible():> Couldn't extract barcode from title-column '$titleText'\n";
138
        }
139
    }
140
141
    return \%holdsRows;
142
}
143
144
################################################################################
145
=head PageObject Services
146
147
=cut
148
################################################################################
149
150
sub viewAllLibraries {
151
    my ($self) = @_;
152
    my $d = $self->getDriver();
153
    $self->debugTakeSessionSnapshot();
154
155
    my $view_all_libraries_a = $d->find_element("a[href*='waitingreserves.pl?allbranches=1']", 'css');
156
    $view_all_libraries_a->click();
157
158
    $self->debugTakeSessionSnapshot();
159
    return $self;
160
}
161
162
sub showHoldsWaiting {
163
    my ($self) = @_;
164
    my $d = $self->getDriver();
165
    $self->debugTakeSessionSnapshot();
166
167
    my $e = $self->_getTablist();
168
    my $showWaiting_a = $e->{holdswaiting};
169
    $showWaiting_a->click();
170
    $self->{waitingreserves}->{tabDisplayed} = 'waiting';
171
172
    $self->debugTakeSessionSnapshot();
173
    return $self;
174
}
175
176
sub showHoldsOver {
177
    my ($self) = @_;
178
    my $d = $self->getDriver();
179
    $self->debugTakeSessionSnapshot();
180
181
    my $e = $self->_getTablist();
182
    my $showOver_a = $e->{holdsover};
183
    $showOver_a->click();
184
    $self->{waitingreserves}->{tabDisplayed} = 'overdue';
185
186
    $self->debugTakeSessionSnapshot();
187
    return $self;
188
}
189
190
=head assertHoldRowsVisible
191
192
@PARAM1 ARRAYref of HASHes. Represents the holds that must be present in the displayed holds table
193
        eg. [{
194
            barcode => '167N0032112',
195
        },
196
        ]
197
@RETURN t::lib::Page::Circulation::Waitingreserves-object
198
=cut
199
sub assertHoldRowsVisible {
200
    my ($self, $holds) = @_;
201
    my $d = $self->getDriver();
202
    $self->debugTakeSessionSnapshot();
203
204
    my $holdRows = $self->_getHoldsRows();
205
    for (my $i=0 ; $i<scalar(@$holds) ; $i++) {
206
        my $h = $holds->[$i];
207
        my $targetRow = $holdRows->{ $i };
208
        is($targetRow->{barcode}, $h->{barcode},
209
           "assertHoldRowsVisible: Row ".$i." barcodes '".$targetRow->{barcode}."' and '".$h->{barcode}."' match.");
210
    }
211
212
    return $self;
213
}
214
215
1;

Return to bug 14536