Bug 17314: Unit tests
[koha.git] / t / db_dependent / api / v1 / suggestions.t
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 => 5;
21 use Test::Mojo;
22
23 use t::lib::TestBuilder;
24 use t::lib::Mocks;
25
26 use Koha::Suggestions;
27 use Koha::Database;
28
29 use Data::Printer colored => 1;
30
31 my $schema  = Koha::Database->new->schema;
32 my $builder = t::lib::TestBuilder->new;
33
34 my $t = Test::Mojo->new('Koha::REST::V1');
35 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
36
37 subtest 'list() tests' => sub {
38
39     plan tests => 11;
40
41     $schema->storage->txn_begin;
42
43     my $librarian = $builder->build_object(
44         {
45             class => 'Koha::Patrons',
46             value => { flags => 2 ** 12 } # suggestions flag = 12
47         }
48     );
49     my $password = 'thePassword123';
50     $librarian->set_password( { password => $password, skip_validation => 1 } );
51     my $userid = $librarian->userid;
52
53     my $patron = $builder->build_object(
54         {
55             class => 'Koha::Patrons',
56             value => { flags => 0 }
57         }
58     );
59
60     $patron->set_password( { password => $password, skip_validation => 1 } );
61
62     my $unauth_userid = $patron->userid;
63     my $patron_id     = $patron->id;
64
65     ## Authorized user tests
66     # No suggestions by patron, so empty array should be returned
67     $t->get_ok("//$userid:$password@/api/v1/suggestions?q={\"suggested_by\":\"$patron_id\"}")
68       ->status_is(200)->json_is( [] );
69
70     my $suggestion_1 = $builder->build_object(
71         {
72             class => 'Koha::Suggestions',
73             value => { suggestedby => $patron_id, STATUS => 'ASKED' }
74         }
75     );
76
77     # One city created, should get returned
78     $t->get_ok("//$userid:$password@/api/v1/suggestions?q={\"suggested_by\":\"$patron_id\"}")
79       ->status_is(200)->json_is( [ $suggestion_1->to_api ] );
80
81     my $suggestion_2 = $builder->build_object(
82         {
83             class => 'Koha::Suggestions',
84             value => { suggestedby => $patron_id, STATUS => 'ASKED' }
85         }
86     );
87
88     # Two SMTP servers created, they should both be returned
89     $t->get_ok("//$userid:$password@/api/v1/suggestions?q={\"suggested_by\":\"$patron_id\"}")
90       ->status_is(200)
91       ->json_is( [ $suggestion_1->to_api, $suggestion_2->to_api, ] );
92
93     # Unauthorized access
94     $t->get_ok("//$unauth_userid:$password@/api/v1/suggestions")
95       ->status_is(403);
96
97     $schema->storage->txn_rollback;
98 };
99
100 subtest 'get() tests' => sub {
101
102     plan tests => 8;
103
104     $schema->storage->txn_begin;
105
106     my $librarian  = $builder->build_object(
107         {
108             class => 'Koha::Patrons',
109             value => { flags => 2 ** 12 } # suggestions flag = 12
110         }
111     );
112     my $password = 'thePassword123';
113     $librarian->set_password( { password => $password, skip_validation => 1 } );
114     my $userid = $librarian->userid;
115
116     my $patron = $builder->build_object(
117         {
118             class => 'Koha::Patrons',
119             value => { flags => 0 }
120         }
121     );
122
123     $patron->set_password( { password => $password, skip_validation => 1 } );
124     my $unauth_userid = $patron->userid;
125     my $patron_id = $patron->id;
126
127     my $suggestion = $builder->build_object(
128         {
129             class => 'Koha::Suggestions',
130             value => { suggestedby => $patron_id, STATUS => 'ASKED' }
131         }
132     );
133
134     $t->get_ok(
135         "//$userid:$password@/api/v1/suggestions/" . $suggestion->id )
136       ->status_is(200)->json_is( $suggestion->to_api );
137
138     $t->get_ok( "//$unauth_userid:$password@/api/v1/suggestions/"
139           . $suggestion->id )->status_is(403);
140
141     my $suggestion_to_delete = $builder->build_object( { class => 'Koha::Suggestions' } );
142     my $non_existent_id = $suggestion_to_delete->id;
143     $suggestion_to_delete->delete;
144
145     $t->get_ok(
146         "//$userid:$password@/api/v1/suggestions/$non_existent_id")
147       ->status_is(404)->json_is( '/error' => 'Suggestion not found.' );
148
149     $schema->storage->txn_rollback;
150 };
151
152 subtest 'add() tests' => sub {
153
154     plan tests => 15;
155
156     $schema->storage->txn_begin;
157
158     my $librarian = $builder->build_object(
159         {
160             class => 'Koha::Patrons',
161             value => { flags => 2 ** 12 } # suggestions flag = 12
162         }
163     );
164     my $password = 'thePassword123';
165     $librarian->set_password( { password => $password, skip_validation => 1 } );
166     my $userid = $librarian->userid;
167
168     my $patron = $builder->build_object(
169         {
170             class => 'Koha::Patrons',
171             value => { flags => 0 }
172         }
173     );
174
175     $patron->set_password( { password => $password, skip_validation => 1 } );
176
177     my $unauth_userid = $patron->userid;
178     my $patron_id     = $patron->id;
179
180     my $suggestion = $builder->build_object(
181         {
182             class => 'Koha::Suggestions',
183             value => { suggestedby => $patron_id, STATUS => 'ASKED' }
184         }
185     );
186     my $suggestion_data = $suggestion->to_api;
187     delete $suggestion_data->{suggestion_id};
188     $suggestion->delete;
189
190     # Unauthorized attempt to write
191     $t->post_ok(
192         "//$unauth_userid:$password@/api/v1/suggestions" => json =>
193           $suggestion_data )->status_is(403);
194
195     # Authorized attempt to write invalid data
196     my $suggestion_with_invalid_field = {
197         blah => 'blah'
198     };
199
200     $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
201           $suggestion_with_invalid_field )->status_is(400)->json_is(
202         "/errors" => [
203             {
204                 message => "Properties not allowed: blah.",
205                 path    => "/body"
206             }
207         ]
208           );
209
210     # Authorized attempt to write
211     my $generated_suggestion =
212       $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
213           $suggestion_data )->status_is( 201, 'SWAGGER3.2.1' )->header_like(
214         Location => qr|^\/api\/v1\/suggestions\/\d*|,
215         'SWAGGER3.4.1'
216     )->tx->res->json;
217
218     my $suggestion_id = $generated_suggestion->{suggestion_id};
219     is_deeply(
220         $generated_suggestion,
221         Koha::Suggestions->find($suggestion_id)->to_api,
222         'The object is returned'
223     );
224
225     # Authorized attempt to create with null id
226     $suggestion_data->{suggestion_id} = undef;
227     $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
228           $suggestion_data )->status_is(400)->json_has('/errors');
229
230     # Authorized attempt to create with existing id
231     $suggestion_data->{suggestion_id} = $suggestion_id;
232     $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
233           $suggestion_data )->status_is(400)->json_is(
234         "/errors" => [
235             {
236                 message => "Read-only.",
237                 path    => "/body/suggestion_id"
238             }
239         ]
240           );
241
242     $schema->storage->txn_rollback;
243 };
244
245 subtest 'update() tests' => sub {
246
247     plan tests => 12;
248
249     $schema->storage->txn_begin;
250
251     my $librarian = $builder->build_object(
252         {
253             class => 'Koha::Patrons',
254             value => { flags => 2 ** 12 } # suggestions flag = 12
255         }
256     );
257     my $password = 'thePassword123';
258     $librarian->set_password( { password => $password, skip_validation => 1 } );
259     my $userid = $librarian->userid;
260
261     my $patron = $builder->build_object(
262         {
263             class => 'Koha::Patrons',
264             value => { flags => 0 }
265         }
266     );
267
268     $patron->set_password( { password => $password, skip_validation => 1 } );
269     my $unauth_userid = $patron->userid;
270
271     my $suggestion_id = $builder->build_object(
272         {
273             class => 'Koha::Suggestions',
274             value => { STATUS => 'ASKED' }
275         }
276     )->id;
277
278     # Unauthorized attempt to update
279     $t->put_ok(
280         "//$unauth_userid:$password@/api/v1/suggestions/$suggestion_id"
281           => json => { name => 'New unauthorized name change' } )
282       ->status_is(403);
283
284     # Full object update on PUT
285     my $suggestion_with_updated_field = { reason => "Some reason", };
286
287     $t->put_ok(
288         "//$userid:$password@/api/v1/suggestions/$suggestion_id" =>
289           json => $suggestion_with_updated_field )->status_is(200)
290       ->json_is( '/reason' => 'Some reason' );
291
292     # Authorized attempt to write invalid data
293     my $suggestion_with_invalid_field = {
294         blah   => "Blah",
295         reason => 'Some reason'
296     };
297
298     $t->put_ok(
299         "//$userid:$password@/api/v1/suggestions/$suggestion_id" =>
300           json => $suggestion_with_invalid_field )->status_is(400)->json_is(
301         "/errors" => [
302             {
303                 message => "Properties not allowed: blah.",
304                 path    => "/body"
305             }
306         ]
307           );
308
309     my $suggestion_to_delete = $builder->build_object({ class => 'Koha::Suggestions' });
310     my $non_existent_id = $suggestion_to_delete->id;
311     $suggestion_to_delete->delete;
312
313     $t->put_ok(
314         "//$userid:$password@/api/v1/suggestions/$non_existent_id" =>
315           json => $suggestion_with_updated_field )->status_is(404);
316
317     # Wrong method (POST)
318     $suggestion_with_updated_field->{smtp_server_id} = 2;
319
320     $t->post_ok(
321         "//$userid:$password@/api/v1/suggestions/$suggestion_id" =>
322           json => $suggestion_with_updated_field )->status_is(404);
323
324     $schema->storage->txn_rollback;
325 };
326
327 subtest 'delete() tests' => sub {
328
329     plan tests => 7;
330
331     $schema->storage->txn_begin;
332
333     my $librarian = $builder->build_object(
334         {
335             class => 'Koha::Patrons',
336             value => { flags => 2 ** 12 } # suggestions flag = 12
337         }
338     );
339     my $password = 'thePassword123';
340     $librarian->set_password( { password => $password, skip_validation => 1 } );
341     my $userid = $librarian->userid;
342
343     my $patron = $builder->build_object(
344         {
345             class => 'Koha::Patrons',
346             value => { flags => 0 }
347         }
348     );
349
350     $patron->set_password( { password => $password, skip_validation => 1 } );
351     my $unauth_userid = $patron->userid;
352
353     my $suggestion_id = $builder->build_object({ class => 'Koha::Suggestions' } )->id;
354
355     # Unauthorized attempt to delete
356     $t->delete_ok(
357         "//$unauth_userid:$password@/api/v1/suggestions/$suggestion_id"
358     )->status_is(403);
359
360     $t->delete_ok(
361         "//$userid:$password@/api/v1/suggestions/$suggestion_id")
362       ->status_is( 204, 'SWAGGER3.2.4' )->content_is( q{}, 'SWAGGER3.3.4' );
363
364     $t->delete_ok(
365         "//$userid:$password@/api/v1/suggestions/$suggestion_id")
366       ->status_is(404);
367
368     $schema->storage->txn_rollback;
369 };