Bug 31351: (QA follow-up) Adjust tests accordingly
[koha.git] / t / db_dependent / Koha / BackgroundJob.t
1 #!/usr/bin/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::MockModule;
22 use Test::Exception;
23
24 use Koha::Database;
25 use Koha::BackgroundJobs;
26 use Koha::BackgroundJob::BatchUpdateItem;
27
28 use t::lib::Mocks;
29 use t::lib::Mocks::Logger;
30 use t::lib::TestBuilder;
31 use t::lib::Koha::BackgroundJob::BatchTest;
32
33 my $logger  = t::lib::Mocks::Logger->new;
34 my $schema  = Koha::Database->new->schema;
35 my $builder = t::lib::TestBuilder->new;
36
37 subtest '_derived_class() tests' => sub {
38
39     plan tests => 3;
40
41     $schema->storage->txn_begin;
42
43     my $job_object = Koha::BackgroundJob->new();
44     my $mapping = $job_object->type_to_class_mapping;
45
46     # pick the first
47     my $type = ( keys %{$mapping} )[0];
48
49     my $job = $builder->build_object(
50         {   class => 'Koha::BackgroundJobs',
51             value => { type => $type, data => 'Foo' }
52         }
53     );
54
55     my $derived = $job->_derived_class;
56
57     is( ref($derived), $mapping->{$type}, 'Job object class is correct' );
58     ok( $derived->in_storage, 'The object is correctly marked as in storage' );
59
60     $derived->data('Bar')->store->discard_changes;
61     $job->discard_changes;
62
63     is_deeply( $job->unblessed, $derived->unblessed, '_derived_class object refers to the same DB object and can be manipulated as expected' );
64
65     $schema->storage->txn_rollback;
66 };
67
68 subtest 'enqueue() tests' => sub {
69
70     plan tests => 7;
71
72     $schema->storage->txn_begin;
73
74     # FIXME: This all feels we need to do it better...
75     my $job_id = Koha::BackgroundJob::BatchUpdateItem->new->enqueue( { record_ids => [ 1, 2 ] } );
76     my $job    = Koha::BackgroundJobs->find($job_id)->_derived_class;
77
78     is( $job->size,           2,     'Two steps' );
79     is( $job->status,         'new', 'Initial status set correctly' );
80     is( $job->borrowernumber, undef, 'No userenv, borrowernumber undef' );
81
82     my $interface = C4::Context->interface;
83     my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
84     t::lib::Mocks::mock_userenv( { patron => $patron } );
85     my $job_context = {
86         number        => $patron->borrowernumber,
87         id            => $patron->userid,
88         cardnumber    => $patron->cardnumber,
89         firstname     => $patron->firstname,
90         surname       => $patron->surname,
91         branch        => $patron->library->branchcode,
92         branchname    => $patron->library->branchname,
93         flags         => $patron->flags,
94         emailaddress  => $patron->email,
95         register_id   => undef,
96         register_name => undef,
97         shibboleth    => undef,
98         desk_id       => undef,
99         desk_name     => undef,
100         interface     => $interface
101     };
102
103     $job_id = Koha::BackgroundJob::BatchUpdateItem->new->enqueue( { record_ids => [ 1, 2, 3 ] } );
104     $job    = Koha::BackgroundJobs->find($job_id)->_derived_class;
105
106     is( $job->size,           3,           'Three steps' );
107     is( $job->status,         'new',       'Initial status set correctly' );
108     is( $job->borrowernumber, $patron->id, 'Borrowernumber set from userenv' );
109     is_deeply( $job->json->decode( $job->context ), $job_context, 'Context set from userenv + interface' );
110
111     $schema->storage->txn_rollback;
112 };
113
114 subtest 'start(), step() and finish() tests' => sub {
115
116     plan tests => 19;
117
118     $schema->storage->txn_begin;
119
120     # FIXME: This all feels we need to do it better...
121     my $job_id = Koha::BackgroundJob::BatchUpdateItem->new->enqueue( { record_ids => [ 1, 2 ] } );
122     my $job    = Koha::BackgroundJobs->find($job_id)->_derived_class;
123
124     is( $job->started_on, undef, 'started_on not set yet' );
125     is( $job->size, 2, 'Two steps' );
126
127     $job->start;
128
129     isnt( $job->started_on, undef, 'started_on set' );
130     is( $job->status, 'started' );
131     is( $job->progress, 0, 'No progress yet' );
132
133     $job->step;
134     is( $job->progress, 1, 'First step' );
135     $job->step;
136     is( $job->progress, 2, 'Second step' );
137     throws_ok
138         { $job->step; }
139         'Koha::Exceptions::BackgroundJob::StepOutOfBounds',
140         'Tried to make a forbidden extra step';
141
142     is( $job->progress, 2, 'progress remains unchanged' );
143
144     my $data = { some => 'data' };
145
146     $job->status('cancelled')->store;
147     $job->finish( $data );
148
149     is( $job->status, 'cancelled', "'finish' leaves 'cancelled' untouched" );
150     isnt( $job->ended_on, undef, 'ended_on set' );
151     is_deeply( $job->json->decode( $job->data ), $data );
152
153     $job->status('started')->store;
154     $job->finish( $data );
155
156     is( $job->status, 'finished' );
157     isnt( $job->ended_on, undef, 'ended_on set' );
158     is_deeply( $job->json->decode( $job->data ), $data );
159
160     throws_ok
161         { $job->start; }
162         'Koha::Exceptions::BackgroundJob::InconsistentStatus',
163         'Exception thrown trying to start a finished job';
164
165     is( $@->expected_status, 'new' );
166
167     throws_ok
168         { $job->step; }
169         'Koha::Exceptions::BackgroundJob::InconsistentStatus',
170         'Exception thrown trying to start a finished job';
171
172     is( $@->expected_status, 'started' );
173
174     $schema->storage->txn_rollback;
175 };
176
177 subtest 'process tests' => sub {
178
179     plan tests => 5;
180
181     $schema->storage->txn_begin;
182
183     C4::Context->interface('intranet');
184     my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
185     t::lib::Mocks::mock_userenv( { patron => $patron } );
186     my $job_context = {
187         number        => $patron->borrowernumber,
188         id            => $patron->userid,
189         cardnumber    => $patron->cardnumber,
190         firstname     => $patron->firstname,
191         surname       => $patron->surname,
192         branch        => $patron->library->branchcode,
193         branchname    => $patron->library->branchname,
194         flags         => $patron->flags,
195         emailaddress  => $patron->email,
196         register_id   => undef,
197         register_name => undef,
198         shibboleth    => undef,
199         desk_id       => undef,
200         desk_name     => undef,
201     };
202
203     my $background_job_module = Test::MockModule->new('Koha::BackgroundJob');
204     $background_job_module->mock(
205         'type_to_class_mapping',
206         sub {
207             return { batch_test => 't::lib::Koha::BackgroundJob::BatchTest' };
208         }
209     );
210
211     my $job_id = t::lib::Koha::BackgroundJob::BatchTest->new->enqueue(
212         { size => 10, a => 'aaa', b => 'bbb' } );
213     my $job    = Koha::BackgroundJobs->find($job_id);
214
215     C4::Context->_new_userenv(-1);
216     C4::Context->interface('opac');
217     is( C4::Context->userenv, undef, "Userenv unset prior to calling process");
218     is( C4::Context->interface, 'opac', "Interface set to opac prior to calling process");
219
220     $job->process();
221     is_deeply( C4::Context->userenv, $job_context, "Userenv set from job context on process" );
222     is_deeply( C4::Context->interface, 'intranet', "Interface set from job context on process" );
223
224     # Manually add a job (->new->store) without context
225     my $json = $job->json; # sorry, quickly borrowing your json object
226     my $data = $json->encode({ a => 'a', b => 'b' });
227     my $incomplete_job = t::lib::Koha::BackgroundJob::BatchTest->new(
228         {   status         => 'new',
229             size           => 1,
230             borrowernumber => $patron->borrowernumber,
231             type           => 'batch_test',
232             data           => $data,
233         }
234     )->store;
235
236     $incomplete_job = Koha::BackgroundJobs->find( $incomplete_job->id );
237     $incomplete_job->process();
238     $logger->warn_is( "A background job didn't have context defined (" . $incomplete_job->id . ")" );
239
240     $schema->storage->txn_rollback;
241 };
242
243 subtest 'decoded_data() and set_encoded_data() tests' => sub {
244
245     plan tests => 3;
246
247     my $job = Koha::BackgroundJob::BatchUpdateItem->new->set_encoded_data( undef );
248     is( $job->decoded_data, undef );
249
250     my $data = { some => 'data' };
251
252     $job->set_encoded_data( $data );
253
254     is_deeply( $job->json->decode($job->data), $data );
255     is_deeply( $job->decoded_data, $data );
256 };