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

(-)a/t/db_dependent/api/v1/patrons_extended_attributes.t (-1 / +396 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 <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 4;
21
use Test::Mojo;
22
23
use t::lib::TestBuilder;
24
use t::lib::Mocks;
25
26
use Koha::Database;
27
28
my $schema  = Koha::Database->new->schema;
29
my $builder = t::lib::TestBuilder->new();
30
31
my $t = Test::Mojo->new('Koha::REST::V1');
32
33
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
34
35
subtest 'list_patron_attributes() tests' => sub {
36
37
    plan tests => 9;
38
39
    $schema->storage->txn_begin;
40
41
    my $patron = $builder->build_object({
42
        class => 'Koha::Patrons',
43
        value => { flags => 2 ** 2 } # 'catalogue' flag == 2
44
    });
45
    my $password = 'thePassword123';
46
    $patron->set_password({ password => $password, skip_validation => 1 });
47
    my $userid = $patron->userid;
48
49
    $t->get_ok("//$userid:$password@/api/v1/patrons/" . $patron->id . '/extended_attributes')
50
      ->status_is( 200, 'SWAGGER3.2.2' )
51
      ->json_is( [] );
52
53
    # Let's add 3 attributes
54
    foreach my $i ( 1..5 ) {
55
        $builder->build_object({ class => 'Koha::Patron::Attributes', value => { borrowernumber => $patron->id } });
56
    }
57
58
    $t->get_ok("//$userid:$password@/api/v1/patrons/" . $patron->id . '/extended_attributes')
59
      ->status_is( 200, 'SWAGGER3.2.2' )
60
      ->json_is( '' => $patron->extended_attributes->to_api, 'Extended attributes retrieved correctly' );
61
62
    my $non_existent_patron = $builder->build_object({ class => 'Koha::Patrons' });
63
    my $non_existent_patron_id = $non_existent_patron->id;
64
    # get rid of the patron
65
    $non_existent_patron->delete;
66
67
    $t->get_ok("//$userid:$password@/api/v1/patrons/" . $non_existent_patron_id . '/extended_attributes')
68
      ->status_is( 404 )
69
      ->json_is( '/error' => 'Patron not found' );
70
71
    $schema->storage->txn_rollback;
72
};
73
74
subtest 'add() tests' => sub {
75
76
    plan tests => 9;
77
78
    $schema->storage->txn_begin;
79
80
    my $patron = $builder->build_object({
81
        class => 'Koha::Patrons',
82
        value => { flags => 2 ** 4 } # 'borrowers' flag == 4
83
    });
84
    my $password = 'thePassword123';
85
    $patron->set_password({ password => $password, skip_validation => 1 });
86
    my $userid = $patron->userid;
87
88
    my $mandatory_attr_type = $builder->build_object(
89
        {
90
            class => 'Koha::Patron::Attribute::Types',
91
            value => {
92
                mandatory     => 1,
93
                repeatable    => 0,
94
                unique_id     => 0,
95
                category_code => undef
96
            }
97
        }
98
    );
99
    my $repeatable_attr_type = $builder->build_object(
100
        {
101
            class => 'Koha::Patron::Attribute::Types',
102
            value => {
103
                mandatory     => 0,
104
                repeatable    => 1,
105
                unique_id     => 0,
106
                category_code => undef
107
            }
108
        }
109
    );
110
    my $unique_attr_type = $builder->build_object(
111
        {
112
            class => 'Koha::Patron::Attribute::Types',
113
            value => {
114
                mandatory     => 0,
115
                repeatable    => 0,
116
                unique_id     => 1,
117
                category_code => undef
118
            }
119
        }
120
    );
121
122
    my $non_existent_patron = $builder->build_object({ class => 'Koha::Patrons' });
123
    my $non_existent_patron_id = $non_existent_patron->id;
124
    # get rid of the patron
125
    $non_existent_patron->delete;
126
127
    $t->post_ok( "//$userid:$password@/api/v1/patrons/"
128
          . $non_existent_patron_id
129
          . '/extended_attributes' => json =>
130
          { type => $repeatable_attr_type->code, value => 'something' } )
131
      ->status_is(404)->json_is( '/error' => 'Patron not found' );
132
133
    my $response = $t->post_ok( "//$userid:$password@/api/v1/patrons/"
134
          . $patron->id
135
          . '/extended_attributes' => json =>
136
          { type => $repeatable_attr_type->code, value => 'something' } )
137
      ->status_is(201)->tx->res->json;
138
139
    is_deeply(
140
        Koha::Patron::Attributes->find( $response->{extended_attribute_id} )->to_api,
141
        $response,
142
        "The returned object is on the DB"
143
    );
144
145
    subtest 'Repeatability tests' => sub {
146
        $t->post_ok( "//$userid:$password@/api/v1/patrons/"
147
            . $patron->id
148
            . '/extended_attributes' => json =>
149
            { type => $repeatable_attr_type->code, value => 'something' } )
150
        ->status_is(201, 'Repeatable attributes go through');
151
152
        # Let's add a non-repeatable one
153
        $patron->add_extended_attribute(
154
            { code => $unique_attr_type->code, attribute => 'non_repeatable_1' } );
155
        $t->post_ok( "//$userid:$password@/api/v1/patrons/"
156
            . $patron->id
157
            . '/extended_attributes' => json =>
158
            { type => $unique_attr_type->code, value => 'non_repeatable_2' } )
159
        ->status_is(409)
160
        ->json_is( '/error' =>
161
                'Tried to add more than one non-repeatable attributes. type='
162
            . $unique_attr_type->code
163
            . ' value=non_repeatable_2' );
164
    };
165
166
    subtest 'Attribute uniqueness tests' => sub {
167
168
        plan tests => 3;
169
170
        my $patron_2 = $builder->build_object( { class => 'Koha::Patrons' } );
171
        $t->post_ok( "//$userid:$password@/api/v1/patrons/"
172
            . $patron_2->id
173
            . '/extended_attributes' => json =>
174
            { type => $unique_attr_type->code, value => 'non_repeatable_1' } )
175
        ->status_is(409)
176
        ->json_is( '/error' =>
177
                'Your action breaks a unique constraint on the attribute. type='
178
            . $unique_attr_type->code
179
            . ' value=non_repeatable_1' );
180
    };
181
182
    subtest 'Invalid type tests' => sub {
183
184
        plan tests => 3;
185
186
        my $invalid_type_obj = $builder->build_object({ class => 'Koha::Patron::Attribute::Types' });
187
        my $invalid_type = $invalid_type_obj->code;
188
        $invalid_type_obj->delete;
189
190
        $t->post_ok( "//$userid:$password@/api/v1/patrons/"
191
            . $patron->id
192
            . '/extended_attributes' => json =>
193
            { type => $invalid_type, value => 'blah' } )
194
        ->status_is(400)
195
        ->json_is( '/error' => "Tried to use an invalid attribute type. type=$invalid_type" );
196
    };
197
198
    $schema->storage->txn_rollback;
199
};
200
201
subtest 'overwrite() tests' => sub {
202
203
    plan tests => 29;
204
205
    $schema->storage->txn_begin;
206
207
    Koha::Patron::Attribute::Types->delete;
208
209
    my $patron = $builder->build_object({
210
        class => 'Koha::Patrons',
211
        value => { flags => 2 ** 4 + 2 ** 2 } # 'borrowers' flag == 4
212
    });                                       # 'catalogue' flag == 2
213
    my $password = 'thePassword123';
214
    $patron->set_password({ password => $password, skip_validation => 1 });
215
    my $userid = $patron->userid;
216
217
    my $mandatory_attr_type = $builder->build_object(
218
        {
219
            class => 'Koha::Patron::Attribute::Types',
220
            value => {
221
                mandatory     => 1,
222
                repeatable    => 0,
223
                unique_id     => 0,
224
                category_code => undef
225
            }
226
        }
227
    );
228
    my $repeatable_attr_type = $builder->build_object(
229
        {
230
            class => 'Koha::Patron::Attribute::Types',
231
            value => {
232
                mandatory     => 0,
233
                repeatable    => 1,
234
                unique_id     => 0,
235
                category_code => undef
236
            }
237
        }
238
    );
239
    my $unique_attr_type = $builder->build_object(
240
        {
241
            class => 'Koha::Patron::Attribute::Types',
242
            value => {
243
                mandatory     => 0,
244
                repeatable    => 0,
245
                unique_id     => 1,
246
                category_code => undef
247
            }
248
        }
249
    );
250
    my $invalid_type_obj = $builder->build_object(
251
        {
252
            class => 'Koha::Patron::Attribute::Types'
253
        }
254
    );
255
    my $invalid_type = $invalid_type_obj->code;
256
    $invalid_type_obj->delete;
257
258
    my $non_existent_patron = $builder->build_object({ class => 'Koha::Patrons' });
259
    my $non_existent_patron_id = $non_existent_patron->id;
260
    # get rid of the patron
261
    $non_existent_patron->delete;
262
263
    $t->put_ok( "//$userid:$password@/api/v1/patrons/"
264
          . $non_existent_patron_id
265
          . '/extended_attributes' => json =>
266
          [ { type => $repeatable_attr_type->code, value => 'something' } ] )
267
      ->status_is(404)
268
      ->json_is( '/error' => 'Patron not found' );
269
270
    $t->put_ok( "//$userid:$password@/api/v1/patrons/"
271
          . $patron->id
272
          . '/extended_attributes' => json =>
273
          [ { type => $invalid_type, value => 'something' } ] )
274
      ->status_is(400)
275
      ->json_is( '/error' => "Tried to use an invalid attribute type. type=$invalid_type" );
276
277
    my $unique_value = 'The only one!';
278
    my $dummy_patron = $builder->build_object({ class => 'Koha::Patrons' });
279
    $dummy_patron->add_extended_attribute({ code => $unique_attr_type->code, attribute => $unique_value });
280
281
    $t->put_ok( "//$userid:$password@/api/v1/patrons/"
282
          . $patron->id
283
          . '/extended_attributes' => json =>
284
          [ { type => $unique_attr_type->code, value => $unique_value } ] )
285
      ->status_is(409)
286
      ->json_is( '/error' => "Your action breaks a unique constraint on the attribute. type=" . $unique_attr_type->code . " value=$unique_value" );
287
288
    my $value_1 = 'value_1';
289
    my $value_2 = 'value_2';
290
291
    $t->put_ok( "//$userid:$password@/api/v1/patrons/"
292
          . $patron->id
293
          . '/extended_attributes' => json =>
294
          [ { type => $unique_attr_type->code, value => $value_1 },
295
            { type => $unique_attr_type->code, value => $value_2 } ] )
296
      ->status_is(409)
297
      ->json_is( '/error' => "Tried to add more than one non-repeatable attributes. type=" . $unique_attr_type->code . " value=$value_2" );
298
299
    $t->put_ok( "//$userid:$password@/api/v1/patrons/"
300
          . $patron->id
301
          . '/extended_attributes' => json =>
302
          [ { type => $unique_attr_type->code, value => $value_1 } ] )
303
      ->status_is(400)
304
      ->json_is( '/error' => 'Missing mandatory attribute of type "' . $mandatory_attr_type->code . '".' );
305
306
    $patron->add_extended_attribute({ code => $repeatable_attr_type->code, attribute => 'repeatable_1' });
307
    $patron->add_extended_attribute({ code => $repeatable_attr_type->code, attribute => 'repeatable_2' });
308
    $patron->add_extended_attribute({ code => $mandatory_attr_type->code,  attribute => 'mandatory' });
309
    $patron->add_extended_attribute({ code => $unique_attr_type->code,  attribute => 'unique' });
310
311
    $t->get_ok("//$userid:$password@/api/v1/patrons/" . $patron->id . '/extended_attributes')
312
      ->status_is( 200, 'SWAGGER3.2.2' )
313
      ->json_is( '' => $patron->extended_attributes->to_api, 'Extended attributes retrieved correctly' );
314
315
    my $updated_attributes = [
316
        {
317
            type  => $repeatable_attr_type->code,
318
            value => 'updated_repeatable_1'
319
        },
320
        {
321
            type  => $repeatable_attr_type->code,
322
            value => 'updated_repeatable_2'
323
        },
324
        {
325
            type  => $repeatable_attr_type->code,
326
            value => 'updated_repeatable_3'
327
        },
328
        {
329
            type  => $mandatory_attr_type->code,
330
            value => 'updated_mandatory'
331
        }
332
    ];
333
334
    $t->put_ok( "//$userid:$password@/api/v1/patrons/"
335
          . $patron->id
336
          . '/extended_attributes' => json => $updated_attributes )
337
      ->status_is(200)
338
      ->json_is( '/0/type'  => $updated_attributes->[0]->{type} )
339
      ->json_is( '/0/value' => $updated_attributes->[0]->{value} )
340
      ->json_is( '/1/type'  => $updated_attributes->[1]->{type} )
341
      ->json_is( '/1/value' => $updated_attributes->[1]->{value} )
342
      ->json_is( '/2/type'  => $updated_attributes->[2]->{type} )
343
      ->json_is( '/2/value' => $updated_attributes->[2]->{value} )
344
      ->json_is( '/3/type'  => $updated_attributes->[3]->{type} )
345
      ->json_is( '/3/value' => $updated_attributes->[3]->{value} )
346
      ->json_hasnt( '/4');
347
348
    $schema->storage->txn_rollback;
349
};
350
351
subtest 'delete() tests' => sub {
352
353
    plan tests => 9;
354
355
    $schema->storage->txn_begin;
356
357
    my $patron = $builder->build_object({
358
        class => 'Koha::Patrons',
359
        value => { flags => 2 ** 4 } # 'borrowers' flag == 4
360
    });
361
    my $password = 'thePassword123';
362
    $patron->set_password({ password => $password, skip_validation => 1 });
363
    my $userid = $patron->userid;
364
365
    my $attr_type = $builder->build_object(
366
        {
367
            class => 'Koha::Patron::Attribute::Types',
368
            value => {
369
                mandatory     => 0,
370
                repeatable    => 1,
371
                unique_id     => 0,
372
                category_code => undef
373
            }
374
        }
375
    );
376
377
    my $dummy_patron = $builder->build_object({ class => 'Koha::Patrons' });
378
379
    my $attr = $dummy_patron->add_extended_attribute({ code => $attr_type->code, attribute => 'blah' });
380
381
    $t->delete_ok("//$userid:$password@/api/v1/patrons/" . $dummy_patron->id . '/extended_attributes/' . $attr->id )
382
      ->status_is(204, 'SWAGGER3.2.4')
383
      ->content_is('', 'SWAGGER3.3.4');
384
385
    $t->delete_ok("//$userid:$password@/api/v1/patrons/" . $dummy_patron->id . '/extended_attributes/' . $attr->id )
386
      ->status_is(404)
387
      ->json_is( '/error' => 'Attribute not found' );
388
389
    $dummy_patron->delete;
390
391
    $t->delete_ok("//$userid:$password@/api/v1/patrons/" . $dummy_patron->id . '/extended_attributes/' . $attr->id )
392
      ->status_is(404)
393
      ->json_is( '/error' => 'Patron not found' );
394
395
    $schema->storage->txn_rollback;
396
};

Return to bug 23666