593bb50a1a5360743c10af8fcccdbb2056eab9ec
[koha.git] / t / db_dependent / Members / Attributes.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Copyright 2014  Biblibre SARL
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 C4::Context;
23 use C4::Members;
24 use C4::Members::AttributeTypes;
25 use Koha::Database;
26 use t::lib::TestBuilder;
27 use t::lib::Mocks;
28
29 use Test::Exception;
30 use Test::More tests => 33;
31
32 use_ok('C4::Members::Attributes');
33
34 my $schema = Koha::Database->schema;
35 $schema->storage->txn_begin;
36 my $builder = t::lib::TestBuilder->new;
37 my $dbh = C4::Context->dbh;
38 $dbh->{RaiseError} = 1;
39
40 $dbh->do(q|DELETE FROM issues|);
41 $dbh->do(q|DELETE FROM borrowers|);
42 $dbh->do(q|DELETE FROM borrower_attributes|);
43 $dbh->do(q|DELETE FROM borrower_attribute_types|);
44 my $library = $builder->build({
45     source => 'Branch',
46 });
47
48 my $patron = $builder->build(
49     {   source => 'Borrower',
50         value  => {
51             firstname    => 'my firstname',
52             surname      => 'my surname',
53             branchcode => $library->{branchcode},
54         }
55     }
56 );
57 t::lib::Mocks::mock_userenv({ branchcode => $library->{branchcode} });
58 my $borrowernumber = $patron->{borrowernumber};
59
60 my $attribute_type1 = C4::Members::AttributeTypes->new('my code1', 'my description1');
61 $attribute_type1->unique_id(1);
62 $attribute_type1->store();
63
64 my $attribute_type2 = C4::Members::AttributeTypes->new('my code2', 'my description2');
65 $attribute_type2->opac_display(1);
66 $attribute_type2->staff_searchable(1);
67 $attribute_type2->store();
68
69 my $new_library = $builder->build( { source => 'Branch' } );
70 my $attribute_type_limited = C4::Members::AttributeTypes->new('my code3', 'my description3');
71 $attribute_type_limited->branches([ $new_library->{branchcode} ]);
72 $attribute_type_limited->store;
73
74 $patron = Koha::Patrons->find($borrowernumber);
75 my $borrower_attributes = $patron->extended_attributes;
76 is( $borrower_attributes->count, 0, 'extended_attributes returns the correct number of borrower attributes' );
77
78 my $attributes = [
79     {
80         attribute => 'my attribute1',
81         code => $attribute_type1->code(),
82     },
83     {
84         attribute => 'my attribute2',
85         code => $attribute_type2->code(),
86     },
87     {
88         attribute => 'my attribute limited',
89         code => $attribute_type_limited->code(),
90     }
91 ];
92
93 $patron->extended_attributes->filter_by_branch_limitations->delete;
94 my $set_borrower_attributes = $patron->extended_attributes($attributes);
95 is( ref($set_borrower_attributes), 'Koha::Patron::Attributes', '');
96 is( $set_borrower_attributes->count, 3, '');
97 $borrower_attributes = $patron->extended_attributes;
98 is( $borrower_attributes->count, 3, 'extended_attributes returns the correct number of borrower attributes' );
99 my $attr_0 = $borrower_attributes->next;
100 is( $attr_0->code, $attributes->[0]->{code}, 'setter for extended_attributes sestores the correct code correctly' );
101 is( $attr_0->type->description, $attribute_type1->description(), 'setter for extended_attributes stores the field description correctly' );
102 is( $attr_0->attribute, $attributes->[0]->{attribute}, 'setter for extended_attributes stores the field value correctly' );
103 my $attr_1 = $borrower_attributes->next;
104 is( $attr_1->code, $attributes->[1]->{code}, 'setter for extended_attributes stores the field code correctly' );
105 is( $attr_1->type->description, $attribute_type2->description(), 'setter for extended_attributes stores the field description correctly' );
106 is( $attr_1->attribute, $attributes->[1]->{attribute}, 'setter for extended_attributes stores the field value correctly' );
107
108 $attributes = [
109     {
110         attribute => 'my attribute1',
111         code => $attribute_type1->code(),
112     },
113     {
114         attribute => 'my attribute2',
115         code => $attribute_type2->code(),
116     }
117 ];
118 $patron->extended_attributes->filter_by_branch_limitations->delete;
119 $patron->extended_attributes($attributes);
120 $borrower_attributes = $patron->extended_attributes;
121 is( $borrower_attributes->count, 3, 'setter for extended_attributes should not have removed the attributes limited to another branch' );
122
123 # TODO This is not implemented yet
124 #$borrower_attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber, undef, 'branch_limited');
125 #is( @$borrower_attributes, 2, 'GetBorrowerAttributes returns the correct number of borrower attributes filtered on library' );
126
127 $patron = Koha::Patrons->find($borrowernumber);
128 my $extended_attributes = $patron->extended_attributes;
129 my $attribute_value = $extended_attributes->search({ code => 'my invalid code' });
130 is( $attribute_value->count, 0, 'non existent attribute should return empty result set');
131 $attribute_value = $patron->get_extended_attribute('my invalid code');
132 is( $attribute_value, undef, 'non existent attribute should undef');
133
134 $attribute_value = $patron->get_extended_attribute($attributes->[0]->{code});
135 is( $attribute_value->attribute, $attributes->[0]->{attribute}, 'get_extended_attribute returns the correct attribute value' );
136 $attribute_value = $patron->get_extended_attribute($attributes->[1]->{code});
137 is( $attribute_value->attribute, $attributes->[1]->{attribute}, 'get_extended_attribute returns the correct attribute value' );
138
139
140 my $attribute = {
141     attribute => 'my attribute3',
142     code => $attribute_type1->code(),
143 };
144 $patron->extended_attributes->search({'me.code' => $attribute->{code}})->filter_by_branch_limitations->delete;
145 $patron->add_extended_attribute($attribute);
146 $borrower_attributes = $patron->extended_attributes;
147 is( $borrower_attributes->count, 3, 'delete then add a new attribute does not change the number of borrower attributes' );
148 $attr_0 = $borrower_attributes->next;
149 is( $attr_0->code, $attribute->{code}, 'delete then add a new attribute updates the field code correctly' );
150 is( $attr_0->type->description, $attribute_type1->description(), 'delete then add a new attribute updates the field description correctly' );
151 is( $attr_0->attribute, $attribute->{attribute}, 'delete then add a new attribute updates the field value correctly' );
152
153
154 lives_ok { # Editing, new value, same patron
155     Koha::Patron::Attribute->new(
156         {
157             code           => $attribute->{code},
158             attribute      => 'new value',
159             borrowernumber => $patron->borrowernumber
160         }
161     )->check_unique_id;
162 } 'no exception raised';
163 lives_ok { # Editing, same value, same patron
164     Koha::Patron::Attribute->new(
165         {
166             code           => $attributes->[1]->{code},
167             attribute      => $attributes->[1]->{attribute},
168             borrowernumber => $patron->borrowernumber
169         }
170     )->check_unique_id;
171 } 'no exception raised';
172 throws_ok { # Creating a new one, but already exists!
173     Koha::Patron::Attribute->new(
174         { code => $attribute->{code}, attribute => $attribute->{attribute} } )
175       ->check_unique_id;
176 } 'Koha::Exceptions::Patron::Attribute::UniqueIDConstraint';
177
178
179 my $borrower_numbers = C4::Members::Attributes::SearchIdMatchingAttribute('attribute1');
180 is( @$borrower_numbers, 0, 'SearchIdMatchingAttribute searchs only in attributes with staff_searchable=1' );
181 for my $attr( split(' ', $attributes->[1]->{attribute}) ) {
182     $borrower_numbers = C4::Members::Attributes::SearchIdMatchingAttribute($attr);
183     is( $borrower_numbers->[0], $borrowernumber, 'SearchIdMatchingAttribute returns the borrower numbers matching' );
184 }
185
186
187 $patron->get_extended_attribute($attribute->{code})->delete;
188 $borrower_attributes = $patron->extended_attributes;
189 is( $borrower_attributes->count, 2, 'delete attribute by code' );
190 $attr_0 = $borrower_attributes->next;
191 is( $attr_0->code, $attributes->[1]->{code}, 'delete attribute by code');
192 is( $attr_0->type->description, $attribute_type2->description(), 'delete attribute by code');
193 is( $attr_0->attribute, $attributes->[1]->{attribute}, 'delete attribute by code');
194
195 $patron->get_extended_attribute($attributes->[1]->{code})->delete;
196 $borrower_attributes = $patron->extended_attributes;
197 is( $borrower_attributes->count, 1, 'delete attribute by code' );
198
199 # Regression tests for bug 16504
200 t::lib::Mocks::mock_userenv({ branchcode => $new_library->{branchcode} });
201 my $another_patron = $builder->build_object(
202     {   class  => 'Koha::Patrons',
203         value  => {
204             firstname    => 'my another firstname',
205             surname      => 'my another surname',
206             branchcode => $new_library->{branchcode},
207         }
208     }
209 );
210 $attributes = [
211     {
212         attribute => 'my attribute1',
213         code => $attribute_type1->code(),
214     },
215     {
216         attribute => 'my attribute2',
217         code => $attribute_type2->code(),
218     },
219     {
220         attribute => 'my attribute limited',
221         code => $attribute_type_limited->code(),
222     }
223 ];
224
225 $another_patron->extended_attributes->filter_by_branch_limitations->delete;
226 $another_patron->extended_attributes($attributes);
227 $borrower_attributes = $another_patron->extended_attributes;
228 is( $borrower_attributes->count, 3, 'setter for extended_attributes should have added the 3 attributes for another patron');
229 $borrower_attributes = $patron->extended_attributes;
230 is( $borrower_attributes->count, 1, 'setter for extended_attributes should not have removed the attributes of other patrons' );