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

(-)a/t/db_dependent/Koha/Patron.t (-1 / +140 lines)
Lines 19-25 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 46;
22
use Test::More tests => 49;
23
use Test::NoWarnings;
23
use Test::NoWarnings;
24
use Test::Exception;
24
use Test::Exception;
25
use Test::Warn;
25
use Test::Warn;
Lines 3562-3564 subtest "create_hold_group, hold_groups, visual_hold_group_id tests" => sub { Link Here
3562
3562
3563
    $schema->storage->txn_rollback;
3563
    $schema->storage->txn_rollback;
3564
};
3564
};
3565
3566
subtest "is_eligible_for_self_renewal" => sub {
3567
    plan tests => 8;
3568
3569
    $schema->storage->txn_begin;
3570
3571
    my $category = $builder->build_object(
3572
        {
3573
            class => 'Koha::Patron::Categories',
3574
            value => {
3575
                self_renewal_enabled     => 0,  self_renewal_availability_start => 10, self_renewal_if_expired => 10,
3576
                self_renewal_fines_block => 10, noissuescharge                  => 10
3577
            }
3578
        }
3579
    );
3580
3581
    my $patron = $builder->build_object(
3582
        {
3583
            class => 'Koha::Patrons',
3584
            value => { categorycode => $category->categorycode, dateexpiry => dt_from_string(), debarred => undef }
3585
        }
3586
    );
3587
3588
    is( $patron->is_eligible_for_self_renewal, 0, "Category not enabled" );
3589
3590
    $category->self_renewal_enabled(1)->store();
3591
    $patron->delete()->store()->discard_changes();
3592
    is( $patron->is_eligible_for_self_renewal, 1, "Category now enabled" );
3593
3594
    $patron->debarred('2026-01-01')->store;
3595
    is( $patron->is_eligible_for_self_renewal, 0, "Patron debarred" );
3596
    $patron->debarred(undef)->store;
3597
    $patron->delete()->store()->discard_changes();
3598
3599
    # Move expiry date outside the window
3600
    $patron->dateexpiry( dt_from_string()->add( days => 11 ) )->store;
3601
    is( $patron->is_eligible_for_self_renewal, 0, "Patron not yet within the expiry window" );
3602
3603
    # Shift the expiry window to cover new expiry date
3604
    $category->self_renewal_availability_start(12)->store();
3605
    $patron->delete()->store()->discard_changes();
3606
    is( $patron->is_eligible_for_self_renewal, 1, "Patron is back within the expiry window" );
3607
3608
    # Shift the date to now already be expired
3609
    $patron->dateexpiry( dt_from_string()->subtract( days => 11 ) )->store;
3610
    is( $patron->is_eligible_for_self_renewal, 0, "Patron can only self renew within 10 days of expiry" );
3611
3612
    # Expand the expiry window
3613
    $category->self_renewal_if_expired(12)->store();
3614
    $patron->delete()->store()->discard_changes();
3615
    is( $patron->is_eligible_for_self_renewal, 1, "Patron is back within the expiry window" );
3616
3617
    t::lib::Mocks::mock_preference( 'noissuescharge', 10 );
3618
3619
    my $fee1 = $builder->build_object(
3620
        {
3621
            class => 'Koha::Account::Lines',
3622
            value => {
3623
                borrowernumber    => $patron->borrowernumber,
3624
                amountoutstanding => 11,
3625
                debit_type_code   => 'OVERDUE',
3626
            }
3627
        }
3628
    )->store;
3629
    is( $patron->is_eligible_for_self_renewal, 0, "Patron is outside the charge limits" );
3630
3631
    $schema->storage->txn_rollback;
3632
};
3633
3634
subtest "request_modification" => sub {
3635
    plan tests => 5;
3636
3637
    $schema->storage->txn_begin;
3638
3639
    my $patron = $builder->build_object(
3640
        {
3641
            class => 'Koha::Patrons',
3642
        }
3643
    );
3644
3645
    my $modification_data = { firstname => 'Newname', changed_fields => 'firstname' };
3646
    t::lib::Mocks::mock_preference( 'OPACPatronDetails',                1 );
3647
    t::lib::Mocks::mock_preference( 'AutoApprovePatronProfileSettings', 0 );
3648
3649
    $patron->request_modification($modification_data);
3650
3651
    my @modifications = Koha::Patron::Modifications->search( { borrowernumber => $patron->borrowernumber } )->as_list;
3652
    is( scalar(@modifications), 1, "New modification has replaced any existing mods" );
3653
3654
    my $modification = $modifications[0];
3655
    is( $modification->changed_fields, 'firstname',                     'Fields correctly set' );
3656
    is( $modification->firstname,      $modification_data->{firstname}, 'Fields correctly set' );
3657
3658
    t::lib::Mocks::mock_preference( 'AutoApprovePatronProfileSettings', 1 );
3659
    $patron->request_modification($modification_data);
3660
3661
    @modifications = Koha::Patron::Modifications->search( { borrowernumber => $patron->borrowernumber } )->as_list;
3662
    is( scalar(@modifications),                0, "New modification has been approved and deleted" );
3663
    is( $patron->discard_changes()->firstname, $modification_data->{firstname}, 'Name updated' );
3664
3665
    $schema->storage->txn_rollback;
3666
};
3667
3668
subtest "create_expiry_notice_parameters" => sub {
3669
    plan tests => 1;
3670
3671
    $schema->storage->txn_begin;
3672
3673
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
3674
3675
    my $patron = $builder->build_object(
3676
        {
3677
            class => 'Koha::Patrons',
3678
            value => { branchcode => $library->branchcode }
3679
        }
3680
    );
3681
3682
    my $expected_return = {
3683
        'letter_params' => {
3684
            'borrowernumber' => $patron->borrowernumber,
3685
            'branchcode'     => $library->branchcode,
3686
            'tables'         => {
3687
                'borrowers' => $patron->borrowernumber,
3688
                'branches'  => $library->branchcode
3689
            },
3690
            'module'      => 'members',
3691
            'letter_code' => 'MEMBERSHIP_RENEWED',
3692
            'lang'        => $patron->lang
3693
        },
3694
        'message_name' => 'Patron_Expiry',
3695
        'forceprint'   => 0
3696
    };
3697
3698
    my $letter_params = $patron->create_expiry_notice_parameters(
3699
        { letter_code => 'MEMBERSHIP_RENEWED', forceprint => 0, is_notice_mandatory => 0 } );
3700
3701
    is_deeply( $letter_params, $expected_return, 'Letter params generated correctly' );
3702
    $schema->storage->txn_rollback;
3703
};
(-)a/t/db_dependent/api/v1/patrons_self_renewal.t (-1 / +214 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::NoWarnings;
21
use Test::More tests => 3;
22
use Test::Mojo;
23
24
use t::lib::TestBuilder;
25
use t::lib::Mocks;
26
27
use Koha::Database;
28
use Koha::DateUtils qw( dt_from_string );
29
30
my $schema  = Koha::Database->new->schema;
31
my $builder = t::lib::TestBuilder->new();
32
33
my $t = Test::Mojo->new('Koha::REST::V1');
34
35
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
36
37
subtest 'start()' => sub {
38
    plan tests => 9;
39
40
    $schema->storage->txn_begin;
41
42
    Koha::Patron::Attribute::Types->search()->delete;
43
44
    my $category = $builder->build_object(
45
        {
46
            class => 'Koha::Patron::Categories',
47
            value => {
48
                self_renewal_enabled         => 0, self_renewal_availability_start => 10, self_renewal_if_expired => 10,
49
                self_renewal_fines_block     => 10, noissuescharge                 => 10,
50
                self_renewal_failure_message => 'This is a failure message'
51
            }
52
        }
53
    );
54
55
    my $patron = $builder->build_object(
56
        {
57
            class => 'Koha::Patrons',
58
            value => { categorycode => $category->categorycode, dateexpiry => dt_from_string(), debarred => undef }
59
        }
60
    );
61
62
    my $password = 'thePassword123';
63
    $patron->set_password( { password => $password, skip_validation => 1 } );
64
    my $userid = $patron->userid;
65
66
    $t->get_ok("//$userid:$password@/api/v1/public/patrons/self_renewal")->status_is( 403, 'REST3.2.2' )
67
        ->json_is( { error => "You are not eligible for self-renewal" } );
68
69
    $category->self_renewal_enabled(1)->store();
70
71
    t::lib::Mocks::mock_preference( 'OPACPatronDetails', 1 );
72
73
    $t->get_ok("//$userid:$password@/api/v1/public/patrons/self_renewal")->status_is( 200, 'REST3.2.2' )->json_is(
74
        {
75
            verification_checks   => [],
76
            self_renewal_settings => {
77
                self_renewal_failure_message => $category->self_renewal_failure_message,
78
                opac_patron_details          => 1
79
            }
80
        }
81
    );
82
83
    my $attribute_type = $builder->build_object(
84
        {
85
            class => 'Koha::Patron::Attribute::Types',
86
            value => { unique_id => 1, repeatable => 0, category_code => undef, self_renewal_verification_check => 1 }
87
        }
88
    );
89
    my $non_renewal_attribute_type = $builder->build_object(
90
        {
91
            class => 'Koha::Patron::Attribute::Types',
92
            value => { unique_id => 1, repeatable => 0, category_code => undef, self_renewal_verification_check => 0 }
93
        }
94
    );
95
    my $new_category = $builder->build_object(
96
        {
97
            class => 'Koha::Patron::Categories',
98
            value => {
99
                self_renewal_enabled         => 1, self_renewal_availability_start => 10, self_renewal_if_expired => 10,
100
                self_renewal_fines_block     => 10, noissuescharge                 => 10,
101
                self_renewal_failure_message => 'This is a failure message'
102
            }
103
        }
104
    );
105
    my $wrong_category_attribute_type = $builder->build_object(
106
        {
107
            class => 'Koha::Patron::Attribute::Types',
108
            value => {
109
                unique_id                       => 1, repeatable => 0, category_code => $new_category->categorycode,
110
                self_renewal_verification_check => 0
111
            }
112
        }
113
    );
114
    $t->get_ok("//$userid:$password@/api/v1/public/patrons/self_renewal")->status_is( 200, 'REST3.2.2' )->json_is(
115
        {
116
            verification_checks   => [ $attribute_type->unblessed ],
117
            self_renewal_settings => {
118
                self_renewal_failure_message => $category->self_renewal_failure_message,
119
                opac_patron_details          => 1
120
            }
121
        }
122
    );
123
124
    $schema->storage->txn_rollback;
125
};
126
127
subtest 'submit()' => sub {
128
    plan tests => 11;
129
130
    $schema->storage->txn_begin;
131
132
    my $category = $builder->build_object(
133
        {
134
            class => 'Koha::Patron::Categories',
135
            value => {
136
                self_renewal_enabled         => 0, self_renewal_availability_start => 10, self_renewal_if_expired => 10,
137
                self_renewal_fines_block     => 10, noissuescharge                 => 10,
138
                self_renewal_failure_message => 'This is a failure message'
139
            }
140
        }
141
    );
142
    my $branch = $builder->build_object( { class => 'Koha::Libraries' } );
143
144
    my $patron = $builder->build_object(
145
        {
146
            class => 'Koha::Patrons',
147
            value => {
148
                branchcode => $branch->branchcode, categorycode => $category->categorycode,
149
                dateexpiry => dt_from_string(),    debarred     => undef, lang => 'default'
150
            }
151
        }
152
    );
153
154
    my $password = 'thePassword123';
155
    $patron->set_password( { password => $password, skip_validation => 1 } );
156
    my $userid = $patron->userid;
157
158
    $t->post_ok( "//$userid:$password@/api/v1/public/patrons/self_renewal" => json => {} )
159
        ->status_is( 403, 'REST3.2.2' )->json_is( { error => "You are not eligible for self-renewal" } );
160
161
    t::lib::Mocks::mock_preference( 'OPACPatronDetails',                1 );
162
    t::lib::Mocks::mock_preference( 'AutoApprovePatronProfileSettings', 0 );
163
    $category->self_renewal_enabled(1)->store();
164
165
    my $date;
166
    if ( C4::Context->preference('BorrowerRenewalPeriodBase') eq 'combination' ) {
167
        $date =
168
            ( dt_from_string gt dt_from_string( $patron->dateexpiry ) )
169
            ? dt_from_string
170
            : dt_from_string( $patron->dateexpiry );
171
    } else {
172
        $date =
173
            C4::Context->preference('BorrowerRenewalPeriodBase') eq 'dateexpiry'
174
            ? dt_from_string( $patron->dateexpiry )
175
            : dt_from_string;
176
    }
177
    my $expiry_date = $patron->category->get_expiry_date($date);
178
179
    my $renewal_notice = $builder->build_object(
180
        {
181
            class => 'Koha::Notice::Templates',
182
            value => {
183
                module                 => 'members',
184
                code                   => 'MEMBERSHIP_RENEWED',
185
                branchcode             => $branch->branchcode,
186
                message_transport_type => 'print',
187
                lang                   => 'default'
188
            }
189
        }
190
    );
191
192
    my $counter = Koha::Notice::Messages->search( { borrowernumber => $patron->borrowernumber } )->count;
193
    $t->post_ok( "//$userid:$password@/api/v1/public/patrons/self_renewal" => json => {} )
194
        ->status_is( 201, 'REST3.2.2' )
195
        ->json_is( { expiry_date => $expiry_date->truncate( to => 'day' ), confirmation_sent => 1 } );
196
    is(
197
        Koha::Notice::Messages->search( { borrowernumber => $patron->borrowernumber } )->count, $counter + 1,
198
        "Notice queued"
199
    );
200
201
    # Test that modifications are created correctly
202
    t::lib::Mocks::mock_preference( 'OPACPatronDetails', 1 );
203
    my $modification_data = { firstname => 'Newname' };
204
    $patron->dateexpiry( dt_from_string() )->store();
205
206
    $t->post_ok( "//$userid:$password@/api/v1/public/patrons/self_renewal" => json => $modification_data )
207
        ->status_is( 201, 'REST3.2.2' )
208
        ->json_is( { expiry_date => $expiry_date->truncate( to => 'day' ), confirmation_sent => 1 } );
209
210
    my @modifications = Koha::Patron::Modifications->search( { borrowernumber => $patron->borrowernumber } )->as_list;
211
    is( scalar(@modifications), 1, "New modification has replaced any existing mods" );
212
213
    $schema->storage->txn_rollback;
214
};

Return to bug 26355