Bug 13757: (regression tests) Empty attributes should delete existing
[koha.git] / t / db_dependent / Koha / Patron / Modifications.t
blob3ea8aee5fa56afe6e7fa85f76b1dba9759b972e4
1 #!/usr/bin/perl
3 # This file is part of Koha.
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.
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.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
18 use Modern::Perl;
20 use Test::More tests => 6;
21 use Test::Exception;
23 use t::lib::TestBuilder;
25 use Digest::MD5 qw( md5_base64 md5_hex );
26 use Try::Tiny;
28 use C4::Context;
29 use C4::Members;
30 use C4::Members::Attributes qw( GetBorrowerAttributes );
31 use Koha::Patrons;
33 BEGIN {
34 use_ok('Koha::Patron::Modification');
35 use_ok('Koha::Patron::Modifications');
38 my $schema = Koha::Database->new->schema;
39 my $builder = t::lib::TestBuilder->new;
41 subtest 'new() tests' => sub {
43 plan tests => 3;
45 $schema->storage->txn_begin;
47 Koha::Patron::Modifications->search->delete;
49 # Create new pending modification
50 Koha::Patron::Modification->new(
51 { verification_token => '1234567890',
52 surname => 'Hall',
53 firstname => 'Kyle'
55 )->store();
57 ## Get the new pending modification
58 my $borrower = Koha::Patron::Modifications->find(
59 { verification_token => '1234567890' } );
61 ## Verify we get the same data
62 is( $borrower->surname, 'Hall',
63 'Found modification has matching surname' );
65 throws_ok {
66 Koha::Patron::Modification->new(
67 { verification_token => '1234567890',
68 surname => 'Hall',
69 firstname => 'Daria'
71 )->store();
73 'Koha::Exceptions::Patron::Modification::DuplicateVerificationToken',
74 'Attempting to add a duplicate verification raises the correct exception';
75 is( $@,
76 'Duplicate verification token 1234567890',
77 'Exception carries the right message'
80 $schema->storage->txn_rollback;
83 subtest 'store( extended_attributes ) tests' => sub {
85 plan tests => 4;
87 $schema->storage->txn_begin;
89 Koha::Patron::Modifications->search->delete;
91 my $patron
92 = $builder->build( { source => 'Borrower' } )->{borrowernumber};
93 my $verification_token = md5_hex( time().{}.rand().{}.$$ );
94 my $valid_json_text = '[{"code":"CODE","value":"VALUE"}]';
95 my $invalid_json_text = '[{"code":"CODE";"value":"VALUE"}]';
97 Koha::Patron::Modification->new(
98 { verification_token => $verification_token,
99 borrowernumber => $patron,
100 surname => 'Hall',
101 extended_attributes => $valid_json_text
103 )->store();
105 my $patron_modification
106 = Koha::Patron::Modifications->search( { borrowernumber => $patron } )
107 ->next;
109 is( $patron_modification->surname,
110 'Hall', 'Patron modification correctly stored with valid JSON data' );
111 is( $patron_modification->extended_attributes,
112 $valid_json_text,
113 'Patron modification correctly stored with valid JSON data' );
115 $verification_token = md5_hex( time().{}.rand().{}.$$ );
116 throws_ok {
117 Koha::Patron::Modification->new(
118 { verification_token => $verification_token,
119 borrowernumber => $patron,
120 surname => 'Hall',
121 extended_attributes => $invalid_json_text
123 )->store();
125 'Koha::Exceptions::Patron::Modification::InvalidData',
126 'Trying to store invalid JSON in extended_attributes field raises exception';
128 is( $@, 'The passed extended_attributes is not valid JSON' );
130 $schema->storage->txn_rollback;
133 subtest 'approve tests' => sub {
135 plan tests => 18;
137 $schema->storage->txn_begin;
139 Koha::Patron::Modifications->search->delete;
141 my $patron_hashref = $builder->build( { source => 'Borrower' } );
142 $builder->build(
143 { source => 'BorrowerAttributeType', value => { code => 'CODE_1' } }
145 $builder->build(
146 { source => 'BorrowerAttributeType', value => { code => 'CODE_2' } }
148 my $verification_token = md5_hex( time().{}.rand().{}.$$ );
149 my $valid_json_text
150 = '[{"code":"CODE_1","value":"VALUE_1"},{"code":"CODE_2","value":"VALUE_2"}]';
151 my $patron_modification = Koha::Patron::Modification->new(
152 { borrowernumber => $patron_hashref->{borrowernumber},
153 firstname => 'Kyle',
154 verification_token => $verification_token,
155 extended_attributes => $valid_json_text
157 )->store();
159 ok( $patron_modification->approve,
160 'Patron modification correctly approved' );
161 my $patron = Koha::Patrons->find( $patron_hashref->{borrowernumber} );
162 isnt(
163 $patron->firstname,
164 $patron_hashref->{firstname},
165 'Patron modification changed firstname'
167 is( $patron->firstname, 'Kyle',
168 'Patron modification set the right firstname' );
169 my @patron_attributes = GetBorrowerAttributes( $patron->borrowernumber );
170 is( $patron_attributes[0][0]->{code},
171 'CODE_1', 'Patron modification correctly saved attribute code' );
172 is( $patron_attributes[0][0]->{value},
173 'VALUE_1', 'Patron modification correctly saved attribute value' );
175 # Create a new Koha::Patron::Modification, skip extended_attributes to
176 # bypass checks
177 $patron_modification = Koha::Patron::Modification->new(
178 { borrowernumber => $patron_hashref->{borrowernumber},
179 firstname => 'Kylie',
180 verification_token => $verification_token
182 )->store();
184 # Add invalid JSON to extended attributes
185 $patron_modification->extended_attributes(
186 '[{"code":"CODE";"values:VALUES"}]');
187 throws_ok { $patron_modification->approve }
188 'Koha::Exceptions::Patron::Modification::InvalidData',
189 'The right exception is thrown if invalid data is on extended_attributes';
191 $patron = Koha::Patrons->find( $patron_hashref->{borrowernumber} );
192 isnt( $patron->firstname, 'Kylie', 'Patron modification didn\'t apply' );
194 # Try changing only a portion of the attributes
195 my $bigger_json
196 = '[{"code":"CODE_2","value":"Tomasito"},{"code":"CODE_2","value":"None"}]';
197 $verification_token = md5_hex( time() . {} . rand() . {} . $$ );
199 $patron_modification = Koha::Patron::Modification->new(
200 { borrowernumber => $patron->borrowernumber,
201 extended_attributes => $bigger_json,
202 verification_token => $verification_token
204 )->store();
205 ok( $patron_modification->approve,
206 'Patron modification correctly approved' );
207 @patron_attributes
208 = map { $_->unblessed }
209 Koha::Patron::Attributes->search(
210 { borrowernumber => $patron->borrowernumber } );
212 is( $patron_attributes[0]->{code},
213 'CODE_1', 'Untouched attribute type is preserved (code)' );
214 is( $patron_attributes[0]->{attribute},
215 'VALUE_1', 'Untouched attribute type is preserved (attribute)' );
217 is( $patron_attributes[1]->{code},
218 'CODE_2', 'Attribute updated correctly (code)' );
219 is( $patron_attributes[1]->{attribute},
220 'Tomasito', 'Attribute updated correctly (attribute)' );
222 is( $patron_attributes[2]->{code},
223 'CODE_2', 'Attribute updated correctly (code)' );
224 is( $patron_attributes[2]->{attribute},
225 'None', 'Attribute updated correctly (attribute)' );
227 my $empty_code_json = '[{"code":"CODE_2","value":""}]';
228 $verification_token = md5_hex( time() . {} . rand() . {} . $$ );
230 $patron_modification = Koha::Patron::Modification->new(
231 { borrowernumber => $patron->borrowernumber,
232 extended_attributes => $empty_code_json,
233 verification_token => $verification_token
235 )->store();
236 ok( $patron_modification->approve,
237 'Patron modification correctly approved' );
238 @patron_attributes
239 = map { $_->unblessed }
240 Koha::Patron::Attributes->search(
241 { borrowernumber => $patron->borrowernumber } );
243 is( $patron_attributes[0]->{code},
244 'CODE_1', 'Untouched attribute type is preserved (code)' );
245 is( $patron_attributes[0]->{attribute},
246 'VALUE_1', 'Untouched attribute type is preserved (attribute)' );
248 my $count = Koha::Patron::Attributes->search({ borrowernumber => $patron->borrowernumber, code => 'CODE_2' })->count;
249 is( $count, 0, 'Attributes deleted when modification contained an empty one');
251 $schema->storage->txn_rollback;
254 subtest 'pending_count() and pending() tests' => sub {
256 plan tests => 7;
258 $schema->storage->txn_begin;
260 Koha::Patron::Modifications->search->delete;
261 my $library_1 = $builder->build( { source => 'Branch' } )->{branchcode};
262 my $library_2 = $builder->build( { source => 'Branch' } )->{branchcode};
263 my $patron_1
264 = $builder->build(
265 { source => 'Borrower', value => { branchcode => $library_1 } } )
266 ->{borrowernumber};
267 my $patron_2
268 = $builder->build(
269 { source => 'Borrower', value => { branchcode => $library_2 } } )
270 ->{borrowernumber};
271 my $patron_3
272 = $builder->build(
273 { source => 'Borrower', value => { branchcode => $library_2 } } )
274 ->{borrowernumber};
275 my $verification_token_1 = md5_hex( time().{}.rand().{}.$$ );
276 my $verification_token_2 = md5_hex( time().{}.rand().{}.$$ );
277 my $verification_token_3 = md5_hex( time().{}.rand().{}.$$ );
280 my $modification_1 = Koha::Patron::Modification->new(
281 { borrowernumber => $patron_1,
282 surname => 'Hall',
283 firstname => 'Kyle',
284 verification_token => $verification_token_1
286 )->store();
288 is( Koha::Patron::Modifications->pending_count,
289 1, 'pending_count() correctly returns 1' );
291 my $modification_2 = Koha::Patron::Modification->new(
292 { borrowernumber => $patron_2,
293 surname => 'Smith',
294 firstname => 'Sandy',
295 verification_token => $verification_token_2
297 )->store();
299 my $modification_3 = Koha::Patron::Modification->new(
300 { borrowernumber => $patron_3,
301 surname => 'Smith',
302 firstname => 'Sandy',
303 verification_token => $verification_token_3
305 )->store();
307 is( Koha::Patron::Modifications->pending_count,
308 3, 'pending_count() correctly returns 3' );
310 is( Koha::Patron::Modifications->pending_count($library_1),
311 1, 'pending_count() correctly returns 1 if filtered by library' );
313 is( Koha::Patron::Modifications->pending_count($library_2),
314 2, 'pending_count() correctly returns 2 if filtered by library' );
316 $modification_1->approve;
318 is( Koha::Patron::Modifications->pending_count,
319 2, 'pending_count() correctly returns 2' );
321 $modification_2->approve;
323 is( Koha::Patron::Modifications->pending_count,
324 1, 'pending_count() correctly returns 1' );
326 $modification_3->approve;
328 is( Koha::Patron::Modifications->pending_count,
329 0, 'pending_count() correctly returns 0' );
331 $schema->storage->txn_rollback;