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