Bug 30747: (follup-up) Add missing otherholdings_datelastborrowed column in settings
[koha.git] / t / db_dependent / ImportBatch.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4 use Test::More tests => 18;
5 use utf8;
6 use File::Basename;
7 use File::Temp qw/tempfile/;
8
9 use t::lib::Mocks;
10 use t::lib::TestBuilder;
11
12 use Koha::Database;
13
14 BEGIN {
15     # Mock pluginsdir before loading Plugins module
16     my $path = dirname(__FILE__) . '/../lib/plugins';
17     t::lib::Mocks::mock_config( 'pluginsdir', $path );
18
19     use_ok('Koha::Plugins');
20     use_ok('C4::ImportBatch', qw( AddImportBatch GetImportBatch AddBiblioToBatch AddItemsToImportBiblio GetRecordFromImportBiblio SetMatchedBiblionumber GetImportBiblios GetItemNumbersFromImportBatch CleanBatch DeleteBatch RecordsFromMarcPlugin ));
21 }
22
23 # Start transaction
24 my $schema  = Koha::Database->new->schema;
25 $schema->storage->txn_begin;
26 my $builder = t::lib::TestBuilder->new;
27 my $dbh = C4::Context->dbh;
28
29 # clear
30 $dbh->do('DELETE FROM import_batches');
31
32 my $sample_import_batch1 = {
33     matcher_id => 1,
34     template_id => 1,
35     branchcode => 'QRT',
36     overlay_action => 'create_new',
37     nomatch_action => 'create_new',
38     item_action => 'always_add',
39     import_status => 'staged',
40     batch_type => 'z3950',
41     file_name => 'test.mrc',
42     comments => 'test',
43     record_type => 'auth',
44 };
45
46 my $sample_import_batch2 = {
47     matcher_id => 2,
48     template_id => 2,
49     branchcode => 'QRZ',
50     overlay_action => 'create_new',
51     nomatch_action => 'create_new',
52     item_action => 'always_add',
53     import_status => 'staged',
54     batch_type => 'z3950',
55     file_name => 'test.mrc',
56     comments => 'test',
57     record_type => 'auth',
58 };
59
60 my $id_import_batch1 = C4::ImportBatch::AddImportBatch($sample_import_batch1);
61 my $id_import_batch2 = C4::ImportBatch::AddImportBatch($sample_import_batch2);
62
63 like( $id_import_batch1, '/^\d+$/', "AddImportBatch for sample_import_batch1 return an id" );
64 like( $id_import_batch2, '/^\d+$/', "AddImportBatch for sample_import_batch2 return an id" );
65
66 #Test GetImportBatch
67 my $importbatch2 = C4::ImportBatch::GetImportBatch( $id_import_batch2 );
68 delete $importbatch2->{upload_timestamp};
69 delete $importbatch2->{import_batch_id};
70 delete $importbatch2->{num_records};
71 delete $importbatch2->{num_items};
72 delete $importbatch2->{profile_id};
73 delete $importbatch2->{profile};
74
75 is_deeply( $importbatch2, $sample_import_batch2,
76     "GetImportBatch returns the right informations about $sample_import_batch2" );
77
78 my $importbatch1 = C4::ImportBatch::GetImportBatch( $id_import_batch1 );
79 delete $importbatch1->{upload_timestamp};
80 delete $importbatch1->{import_batch_id};
81 delete $importbatch1->{num_records};
82 delete $importbatch1->{num_items};
83 delete $importbatch1->{profile_id};
84 delete $importbatch1->{profile};
85
86 is_deeply( $importbatch1, $sample_import_batch1,
87     "GetImportBatch returns the right informations about $sample_import_batch1" );
88
89 my $record = MARC::Record->new;
90 # FIXME Create another MARC::Record which won't be modified
91 # AddItemsToImportBiblio will remove the items field from the record passed in parameter.
92 my $original_record = MARC::Record->new;
93 $record->leader('03174nam a2200445 a 4500');
94 $original_record->leader('03174nam a2200445 a 4500');
95 my ($item_tag, $item_subfield) = C4::Biblio::GetMarcFromKohaField( 'items.itemnumber' );
96 my @fields = (
97     MARC::Field->new(
98         100, '1', ' ',
99         a => 'Knuth, Donald Ervin',
100         d => '1938',
101     ),
102     MARC::Field->new(
103         245, '1', '4',
104         a => 'The art of computer programming',
105         c => 'Donald E. Knuth.',
106     ),
107     MARC::Field->new(
108         650, ' ', '0',
109         a => 'Computer programming.',
110         9 => '462',
111     ),
112     MARC::Field->new(
113         $item_tag, ' ', ' ',
114         e => 'my edition ❤',
115         i => 'my item part',
116     ),
117     MARC::Field->new(
118         $item_tag, ' ', ' ',
119         e => 'my edition 2',
120         i => 'my item part 2',
121     ),
122 );
123 $record->append_fields(@fields);
124 $original_record->append_fields(@fields);
125 my $import_record_id = AddBiblioToBatch( $id_import_batch1, 0, $record, 'utf8', int(rand(99999)), 0 );
126 AddItemsToImportBiblio( $id_import_batch1, $import_record_id, $record, 0 );
127
128 my $record_from_import_biblio_with_items = C4::ImportBatch::GetRecordFromImportBiblio( $import_record_id, 'embed_items' );
129 $original_record->leader($record_from_import_biblio_with_items->leader());
130 is_deeply( $record_from_import_biblio_with_items, $original_record, 'GetRecordFromImportBiblio should return the record with items if specified' );
131 my $utf8_field = $record_from_import_biblio_with_items->subfield($item_tag, 'e');
132 is($utf8_field, 'my edition ❤');
133 $original_record->delete_fields($original_record->field($item_tag)); #Remove items fields
134 my $record_from_import_biblio_without_items = C4::ImportBatch::GetRecordFromImportBiblio( $import_record_id );
135 $original_record->leader($record_from_import_biblio_without_items->leader());
136 is_deeply( $record_from_import_biblio_without_items, $original_record, 'GetRecordFromImportBiblio should return the record without items by default' );
137
138 my $another_biblio = $builder->build_sample_biblio;
139 C4::ImportBatch::SetMatchedBiblionumber( $import_record_id, $another_biblio->biblionumber );
140 my $import_biblios = GetImportBiblios( $import_record_id );
141 is( $import_biblios->[0]->{matched_biblionumber}, $another_biblio->biblionumber, 'SetMatchedBiblionumber  should set the correct biblionumber' );
142
143 # Add a few tests for GetItemNumbersFromImportBatch
144 my @a = GetItemNumbersFromImportBatch( $id_import_batch1 );
145 is( @a, 0, 'No item numbers expected since we did not commit' );
146 my $itemno = $builder->build_sample_item->itemnumber;
147 # Link this item to the import item to fool GetItemNumbersFromImportBatch
148 my $sql = "UPDATE import_items SET itemnumber=? WHERE import_record_id=?";
149 $dbh->do( $sql, undef, $itemno, $import_record_id );
150 @a = GetItemNumbersFromImportBatch( $id_import_batch1 );
151 is( @a, 2, 'Expecting two items now' );
152 is( $a[0], $itemno, 'Check the first returned itemnumber' );
153 # Now delete the item and check again
154 $dbh->do( "DELETE FROM items WHERE itemnumber=?", undef, $itemno );
155 @a = GetItemNumbersFromImportBatch( $id_import_batch1 );
156 is( @a, 0, 'No item numbers expected since we deleted the item' );
157 $dbh->do( $sql, undef, undef, $import_record_id ); # remove link again
158
159 # fresh data
160 my $sample_import_batch3 = {
161     matcher_id => 3,
162     template_id => 3,
163     branchcode => 'QRT',
164     overlay_action => 'create_new',
165     nomatch_action => 'create_new',
166     item_action => 'always_add',
167     import_status => 'staged',
168     batch_type => 'z3950',
169     file_name => 'test.mrc',
170     comments => 'test',
171     record_type => 'auth',
172 };
173
174 my $id_import_batch3 = C4::ImportBatch::AddImportBatch($sample_import_batch3);
175
176 # Test CleanBatch
177 C4::ImportBatch::CleanBatch( $id_import_batch3 );
178 my $import_record = get_import_record( $id_import_batch3 );
179 is( $import_record, "0E0", "Batch 3 has been cleaned" );
180
181 # Test DeleteBatch
182 C4::ImportBatch::DeleteBatch( $id_import_batch3 );
183 my $import_batch = C4::ImportBatch::GetImportBatch( $id_import_batch3 );
184 is( $import_batch, undef, "Batch 3 has been deleted");
185
186 subtest "RecordsFromMarcPlugin" => sub {
187     plan tests => 5;
188
189     # Create a test file
190     my ( $fh, $name ) = tempfile();
191     print $fh q|
192 003 = NLAmRIJ
193 100,a = Author
194 245,ind2 = 0
195 245,a = Silence in the library
196 500 , a= Some note
197
198 100,a = Another
199 245,a = Noise in the library|;
200     close $fh;
201
202     t::lib::Mocks::mock_config( 'enable_plugins', 1 );
203
204     my $plugins = Koha::Plugins->new;
205     $plugins->InstallPlugins;
206     my ($plugin) = $plugins->GetPlugins({ all => 1, metadata => { name => 'MarcFieldValues' } });
207     isnt( $plugin, undef, "Plugin found" );
208     my $records = C4::ImportBatch::RecordsFromMarcPlugin( $name, ref $plugin, 'UTF-8' );
209     is( @$records, 2, 'Two results returned' );
210     is( ref $records->[0], 'MARC::Record', 'Returned MARC::Record object' );
211     is( $records->[0]->subfield('245', 'a'), 'Silence in the library',
212         'Checked one field in first record' );
213     is( $records->[1]->subfield('100', 'a'), 'Another',
214         'Checked one field in second record' );
215 };
216
217 subtest "_get_commit_action" => sub {
218     plan tests => 24;
219     my $mock_import = Test::MockModule->new("C4::ImportBatch");
220
221     $mock_import->mock( GetBestRecordMatch => sub { return 5; } );
222     foreach my $record_type ( ('biblio','authority') ){
223         foreach my $match_action ( ('replace','create_new','ignore') ){
224             foreach my $no_match_action ( ('create_new','ignore') ){
225                 my ($result, $match, $item_result) =
226                     C4::ImportBatch::_get_commit_action($match_action, $no_match_action, 'always_add', 'auto_match', 42, $record_type);
227                 is( $result, $match_action, "When match found amd chosen we return the match_action for $record_type records with match action $match_action and no match action $no_match_action");
228             }
229         }
230     }
231
232     $mock_import->mock( GetBestRecordMatch => sub { my $matches = undef; return $matches; } );
233     foreach my $record_type ( ('biblio','authority') ){
234         foreach my $match_action ( ('replace','create_new','ignore') ){
235             foreach my $no_match_action ( ('create_new','ignore') ){
236                 my ($result, $match, $item_result) =
237                     C4::ImportBatch::_get_commit_action($match_action, $no_match_action, 'always_add', 'auto_match', 42, $record_type);
238                 is( $result, $no_match_action, "When no match found or chosen we return the match_action for $record_type records with match action $match_action and no match action $no_match_action");
239             }
240         }
241     }
242
243 };
244
245 sub get_import_record {
246     my $id_import_batch = shift;
247     return $dbh->do('SELECT * FROM import_records WHERE import_batch_id = ?', undef, $id_import_batch);
248 }
249
250 $schema->storage->txn_rollback;