Bug 22709: (follow-up) Move new test file into a Plugins subdirectory
[koha.git] / t / db_dependent / StockRotationStages.t
1 #!/usr/bin/perl
2
3 # Copyright PTFS Europe 2016
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 use Modern::Perl;
21
22 use Koha::Database;
23 use t::lib::TestBuilder;
24
25 use Test::More tests => 6;
26
27 my $schema = Koha::Database->new->schema;
28
29 use_ok('Koha::StockRotationStages');
30 use_ok('Koha::StockRotationStage');
31
32 my $builder = t::lib::TestBuilder->new;
33
34 subtest 'Basic object tests' => sub {
35     plan tests => 5;
36
37     $schema->storage->txn_begin;
38
39     my $library = $builder->build({ source => 'Branch' });
40     my $rota = $builder->build({ source => 'Stockrotationrota' });
41     my $stage = $builder->build({
42         source => 'Stockrotationstage',
43         value  => {
44             branchcode_id => $library->{branchcode},
45             rota_id       => $rota->{rota_id},
46         },
47     });
48
49     my $srstage = Koha::StockRotationStages->find($stage->{stage_id});
50     isa_ok(
51         $srstage,
52         'Koha::StockRotationStage',
53         "Correctly create and load a stock rotation stage."
54     );
55
56     # Relationship to library
57     isa_ok( $srstage->branchcode, 'Koha::Library', "Fetched related branch." );
58     is( $srstage->branchcode->branchcode, $library->{branchcode}, "Related branch OK." );
59
60     # Relationship to rota
61     isa_ok( $srstage->rota, 'Koha::StockRotationRota', "Fetched related rota." );
62     is( $srstage->rota->rota_id, $rota->{rota_id}, "Related rota OK." );
63
64     $schema->storage->txn_rollback;
65 };
66
67 subtest 'DBIx::Class::Ordered tests' => sub {
68     plan tests => 33;
69
70     $schema->storage->txn_begin;
71
72     my $library = $builder->build({ source => 'Branch' });
73     my $rota = $builder->build({ source => 'Stockrotationrota' });
74     my $stagefirst = $builder->build({
75         source   => 'Stockrotationstage',
76         value    => { rota_id  => $rota->{rota_id}, position => 1 }
77     });
78     my $stageprevious = $builder->build({
79         source   => 'Stockrotationstage',
80         value    => { rota_id  => $rota->{rota_id}, position => 2 }
81     });
82     my $stage = $builder->build({
83         source => 'Stockrotationstage',
84         value  => { rota_id => $rota->{rota_id}, position => 3 },
85     });
86     my $stagenext = $builder->build({
87         source   => 'Stockrotationstage',
88         value    => { rota_id  => $rota->{rota_id}, position => 4 }
89     });
90     my $stagelast = $builder->build({
91         source   => 'Stockrotationstage',
92         value    => { rota_id  => $rota->{rota_id}, position => 5 }
93     });
94
95     my $srstage = Koha::StockRotationStages->find($stage->{stage_id});
96
97     is($srstage->siblings->count, 4, "Siblings works.");
98     is($srstage->previous_siblings->count, 2, "Previous Siblings works.");
99     is($srstage->next_siblings->count, 2, "Next Siblings works.");
100
101     my $map = {
102         first_sibling    => $stagefirst,
103         previous_sibling => $stageprevious,
104         next_sibling     => $stagenext,
105         last_sibling     => $stagelast,
106     };
107     # Test plain relations:
108     while ( my ( $srxsr, $check ) = each %{$map} ) {
109         my $sr = $srstage->$srxsr;
110         isa_ok($sr, 'Koha::StockRotationStage', "Fetched using '$srxsr'.");
111         is($sr->stage_id, $check->{stage_id}, "'$srxsr' data is correct.");
112     };
113
114     # Test mutators
115     ## Move Previous
116     ok($srstage->move_previous, "Previous.");
117     is($srstage->previous_sibling->stage_id, $stagefirst->{stage_id}, "Previous, correct previous.");
118     is($srstage->next_sibling->stage_id, $stageprevious->{stage_id}, "Previous, correct next.");
119     ## Move Next
120     ok($srstage->move_next, "Back to middle.");
121     is($srstage->previous_sibling->stage_id, $stageprevious->{stage_id}, "Middle, correct previous.");
122     is($srstage->next_sibling->stage_id, $stagenext->{stage_id}, "Middle, correct next.");
123     ## Move First
124     ok($srstage->move_first, "First.");
125     is($srstage->previous_sibling, 0, "First, correct previous.");
126     is($srstage->next_sibling->stage_id, $stagefirst->{stage_id}, "First, correct next.");
127     ## Move Last
128     ok($srstage->move_last, "Last.");
129     is($srstage->previous_sibling->stage_id, $stagelast->{stage_id}, "Last, correct previous.");
130     is($srstage->next_sibling, 0, "Last, correct next.");
131     ## Move To
132
133     ### Out of range moves.
134     is(
135         $srstage->move_to($srstage->siblings->count + 2),
136         0, "Move above count of stages."
137     );
138     is($srstage->move_to(0), 0, "Move to 0th position.");
139     is($srstage->move_to(-1), 0, "Move to negative position.");
140
141     ### Move To
142     ok($srstage->move_to(3), "Move.");
143     is($srstage->previous_sibling->stage_id, $stageprevious->{stage_id}, "Move, correct previous.");
144     is($srstage->next_sibling->stage_id, $stagenext->{stage_id}, "Move, correct next.");
145
146     # Group manipulation
147     my $newrota = $builder->build({ source => 'Stockrotationrota' });
148     ok($srstage->move_to_group($newrota->{rota_id}), "Move to Group.");
149     is(Koha::StockRotationStages->find($srstage->stage_id)->rota_id, $newrota->{rota_id}, "Moved correctly.");
150
151     # Delete in ordered context
152     ok($srstage->delete, "Deleted OK.");
153     is(
154         Koha::StockRotationStages->find($stageprevious)->next_sibling->stage_id,
155         $stagenext->{stage_id},
156         "Delete, correctly re-ordered."
157     );
158
159     $schema->storage->txn_rollback;
160 };
161
162 subtest 'Relationship to stockrotationitems' => sub {
163     plan tests => 2;
164
165     $schema->storage->txn_begin;
166     my $stage = $builder->build({ source => 'Stockrotationstage' });
167
168     $builder->build({
169         source => 'Stockrotationitem',
170         value  => { stage_id => $stage->{stage_id} },
171     });
172     $builder->build({
173         source => 'Stockrotationitem',
174         value  => { stage_id => $stage->{stage_id} },
175     });
176     $builder->build({
177         source => 'Stockrotationitem',
178         value  => { stage_id => $stage->{stage_id} },
179     });
180
181     my $srstage = Koha::StockRotationStages->find($stage->{stage_id});
182     my $sritems = $srstage->stockrotationitems;
183     is(
184         $sritems->count, 3,
185         'Correctly fetched stockrotationitems associated with this stage'
186     );
187
188     isa_ok(
189         $sritems->next, 'Koha::StockRotationItem',
190         "Relationship correctly creates Koha::Objects."
191     );
192
193     $schema->storage->txn_rollback;
194 };
195
196
197 subtest 'Tests for investigate (singular)' => sub {
198
199     plan tests => 3;
200
201     # In this subtest series we will primarily be testing whether items end up
202     # in the correct 'branched' section of the stage-report.  We don't care
203     # for item reasons here, as they are tested in StockRotationItems.
204
205     # We will run tests on first on an empty report (the base-case) and then
206     # on a populated report.
207
208     # We will need:
209     # - Libraries which will hold the Items
210     # - Rota Which containing the related stages
211     #   + Stages on which we run investigate
212     #     * Items on the stages
213
214     $schema->storage->txn_begin;
215
216     # Libraries
217     my $library1 = $builder->build({ source => 'Branch' });
218     my $library2 = $builder->build({ source => 'Branch' });
219     my $library3 = $builder->build({ source => 'Branch' });
220
221     my $stage1lib = $builder->build({ source => 'Branch' });
222     my $stage2lib = $builder->build({ source => 'Branch' });
223     my $stage3lib = $builder->build({ source => 'Branch' });
224     my $stage4lib = $builder->build({ source => 'Branch' });
225
226     my $libraries = [ $library1, $library2, $library3, $stage1lib, $stage2lib,
227                       $stage3lib, $stage4lib ];
228
229     # Rota
230     my $rota = $builder->build({
231         source => 'Stockrotationrota',
232         value  => { cyclical => 0 },
233     });
234
235     # Stages
236     my $stage1 = $builder->build({
237         source => 'Stockrotationstage',
238         value  => {
239             rota_id => $rota->{rota_id},
240             branchcode_id => $stage1lib->{branchcode},
241             duration => 10,
242             position => 1,
243         },
244     });
245     my $stage2 = $builder->build({
246         source => 'Stockrotationstage',
247         value  => {
248             rota_id => $rota->{rota_id},
249             branchcode_id => $stage2lib->{branchcode},
250             duration => 20,
251             position => 2,
252         },
253     });
254     my $stage3 = $builder->build({
255         source => 'Stockrotationstage',
256         value  => {
257             rota_id => $rota->{rota_id},
258             branchcode_id => $stage3lib->{branchcode},
259             duration => 10,
260             position => 3,
261         },
262     });
263     my $stage4 = $builder->build({
264         source => 'Stockrotationstage',
265         value  => {
266             rota_id => $rota->{rota_id},
267             branchcode_id => $stage4lib->{branchcode},
268             duration => 20,
269             position => 4,
270         },
271     });
272
273     # Test on an empty report.
274     my $spec =  {
275         $library1->{branchcode} => 1,
276         $library2->{branchcode} => 1,
277         $library3->{branchcode} => 1,
278         $stage1lib->{branchcode} => 2,
279         $stage2lib->{branchcode} => 1,
280         $stage3lib->{branchcode} => 3,
281         $stage4lib->{branchcode} => 4
282     };
283     while ( my ( $code, $count ) = each %{$spec} ) {
284         my $cnt = 0;
285         while ( $cnt < $count ) {
286             my $item = $builder->build({
287                 source => 'Stockrotationitem',
288                 value  => {
289                     stage_id => $stage1->{stage_id},
290                     indemand => 0,
291                     fresh    => 1,
292                 }
293             });
294             my $dbitem = Koha::StockRotationItems->find($item);
295             $dbitem->itemnumber->homebranch($code)
296                 ->holdingbranch($code)->store;
297             $cnt++;
298         }
299     }
300     my $report = Koha::StockRotationStages
301         ->find($stage1->{stage_id})->investigate;
302     my $results = [];
303     foreach my $lib ( @{$libraries} ) {
304         my $items = $report->{branched}->{$lib->{branchcode}}->{items} || [];
305         push @{$results},
306             scalar @{$items};
307     }
308
309     # Items assigned to stag1lib -> log, hence $results[4] = 0;
310     is_deeply( $results, [ 1, 1, 1, 2, 1, 3, 4 ], "Empty report test 1.");
311
312     # Now we test by adding the next stage's items to the same report.
313     $spec =  {
314         $library1->{branchcode} => 3,
315         $library2->{branchcode} => 2,
316         $library3->{branchcode} => 1,
317         $stage1lib->{branchcode} => 4,
318         $stage2lib->{branchcode} => 2,
319         $stage3lib->{branchcode} => 0,
320         $stage4lib->{branchcode} => 3
321     };
322     while ( my ( $code, $count ) = each %{$spec} ) {
323         my $cnt = 0;
324         while ( $cnt < $count ) {
325             my $item = $builder->build({
326                 source => 'Stockrotationitem',
327                 value  => {
328                     stage_id => $stage2->{stage_id},
329                     indemand => 0,
330                     fresh => 1,
331                 }
332             });
333             my $dbitem = Koha::StockRotationItems->find($item);
334             $dbitem->itemnumber->homebranch($code)
335                 ->holdingbranch($code)->store;
336             $cnt++;
337         }
338     }
339
340     $report = Koha::StockRotationStages
341         ->find($stage2->{stage_id})->investigate($report);
342     $results = [];
343     foreach my $lib ( @{$libraries} ) {
344         my $items = $report->{branched}->{$lib->{branchcode}}->{items} || [];
345         push @{$results},
346             scalar @{$items};
347     }
348     is_deeply( $results, [ 4, 3, 2, 6, 3, 3, 7 ], "full report test.");
349
350     # Carry out db updates
351     foreach my $item (@{$report->{items}}) {
352         my $reason = $item->{reason};
353         if ( $reason eq 'repatriation' ) {
354             $item->{object}->repatriate;
355         } elsif ( grep { $reason eq $_ }
356                       qw/in-demand advancement initiation/ ) {
357             $item->{object}->advance;
358         }
359     }
360
361     $report = Koha::StockRotationStages
362         ->find($stage1->{stage_id})->investigate;
363     $results = [];
364     foreach my $lib ( @{$libraries} ) {
365         my $items = $report->{branched}->{$lib->{branchcode}}->{items} || [];
366         push @{$results},
367             scalar @{$items};
368     }
369     # All items have been 'initiated', which means they are either happily in
370     # transit or happily at the library they are supposed to be.  Either way
371     # they will register as 'not-ready' in the stock rotation report.
372     is_deeply( $results, [ 0, 0, 0, 0, 0, 0, 0 ], "All items now in logs.");
373
374     $schema->storage->txn_rollback;
375 };
376
377 1;