Bugzilla – Attachment 176533 Details for
Bug 38689
EDIFACT errors should log to a staff accessible location
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 38689: Improve test coverage
Bug-38689-Improve-test-coverage.patch (text/plain), 34.59 KB, created by
Martin Renvoize (ashimema)
on 2025-01-14 17:17:19 UTC
(
hide
)
Description:
Bug 38689: Improve test coverage
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2025-01-14 17:17:19 UTC
Size:
34.59 KB
patch
obsolete
>From 4e97c0d87f1ffb15a10607b8b1b82fb459be226e Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@ptfs-europe.com> >Date: Mon, 13 Jan 2025 18:12:39 +0000 >Subject: [PATCH] Bug 38689: Improve test coverage > >This patch drastically enhances the existing tests. We add tests for >the various codepaths for handling EDI QUOTES including LIN segment >splitting for multi-fund orders. >--- > t/db_dependent/Koha/EDI.t | 790 ++++++++++++++++++++++--------- > t/edi_testfiles/QUOTES_BIG.CEQ | 1 + > t/edi_testfiles/QUOTES_MULTI.CEQ | 1 + > 3 files changed, 557 insertions(+), 235 deletions(-) > create mode 100644 t/edi_testfiles/QUOTES_BIG.CEQ > create mode 100644 t/edi_testfiles/QUOTES_MULTI.CEQ > >diff --git a/t/db_dependent/Koha/EDI.t b/t/db_dependent/Koha/EDI.t >index e9016014de8..4f87260716a 100755 >--- a/t/db_dependent/Koha/EDI.t >+++ b/t/db_dependent/Koha/EDI.t >@@ -20,7 +20,7 @@ > use Modern::Perl; > use FindBin qw( $Bin ); > >-use Test::More tests => 3; >+use Test::More tests => 2; > use Test::Warn; > use Test::MockModule; > >@@ -30,305 +30,617 @@ use t::lib::TestBuilder; > > use Koha::EDI qw(process_quote process_invoice); > use Koha::Edifact::Transport; >+use Koha::Edifact::File::Errors; >+use Koha::DateUtils qw(dt_from_string); > > my $schema = Koha::Database->new->schema; > my $builder = t::lib::TestBuilder->new; > my $logger = t::lib::Mocks::Logger->new(); > > subtest 'process_quote' => sub { >- plan tests => 16; >+ plan tests => 5; > > $schema->storage->txn_begin; > >- # Add our test quote file to the database for testing against >- my $account = $builder->build( >- { >- source => 'VendorEdiAccount', >- value => { >- description => 'test vendor', transport => 'FILE', >- } >- } >- ); >- my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); >- my $filename = 'QUOTES_SMALL.CEQ'; >- ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' ); >- >- my $trans = Koha::Edifact::Transport->new( $account->{id} ); >- $trans->working_directory($dirname); >- >- my $mhash = $trans->message_hash(); >- $mhash->{message_type} = 'QUOTE'; >- $trans->ingest( $mhash, $filename ); >- >- my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); >- >- # Test quote expects REF to be a valid and active fund code >+ # Common setup for all test cases >+ my $test_san = '5013546098818'; >+ my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); > my $active_period = $builder->build( > { > source => 'Aqbudgetperiod', > value => { budget_period_active => 1 } > } > ); >- my $fund = $builder->build( >- { >- source => 'Aqbudget', >- value => { >- budget_code => 'REF', >- budget_period_id => $active_period->{budget_period_id} >- } >- } >- ); >+ t::lib::Mocks::mock_preference( 'CataloguingLog', 0 ); > >- # The quote expects a ROT1 stock rotation roata to exist >- my $rota = $builder->build_object( >- { >- class => 'Koha::StockRotationRotas', >- value => { title => 'ROT1' } >- } >- ); >- $builder->build( >- { >- source => 'Stockrotationstage', >- value => { rota_id => $rota->rota_id }, >- } >- ); >+ # Test 1: Basic Quote Processing >+ subtest 'basic_quote_processing' => sub { >+ plan tests => 27; >+ >+ $schema->storage->txn_begin; >+ >+ my $account = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'test vendor', >+ transport => 'FILE', >+ plugin => '', >+ san => $test_san, >+ orders_enabled => 1, >+ auto_orders => 0, >+ } >+ } >+ ); >+ my $ean = $builder->build( >+ { >+ source => 'EdifactEan', >+ value => { >+ description => 'test ean', >+ branchcode => undef, >+ ean => $test_san >+ } >+ } >+ ); >+ >+ my $filename = 'QUOTES_SMALL.CEQ'; >+ ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' ); >+ >+ # Setup the fund code >+ my $fund = $builder->build( >+ { >+ source => 'Aqbudget', >+ value => { >+ budget_code => 'REF', >+ budget_period_id => $active_period->{budget_period_id} >+ } >+ } >+ ); > >- t::lib::Mocks::mock_preference( 'CataloguingLog', 0 ); >+ # Setup stock rotation >+ my $rota = $builder->build_object( >+ { >+ class => 'Koha::StockRotationRotas', >+ value => { title => 'ROT1' } >+ } >+ ); >+ $builder->build( >+ { >+ source => 'Stockrotationstage', >+ value => { rota_id => $rota->rota_id }, >+ } >+ ); >+ >+ my $trans = Koha::Edifact::Transport->new( $account->{id} ); >+ $trans->working_directory($dirname); >+ >+ my $mhash = $trans->message_hash(); >+ $mhash->{message_type} = 'QUOTE'; >+ $trans->ingest( $mhash, $filename ); >+ >+ my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); >+ >+ ok( $quote, 'Quote message created in database' ); >+ is( $quote->status, 'new', 'Initial quote status is new' ); >+ >+ t::lib::Mocks::mock_preference( 'AcqCreateItem', 'ordering' ); >+ >+ # Process quote and check results >+ my $die; >+ eval { >+ process_quote($quote); >+ 1; >+ } or do { >+ $die = $@; >+ }; >+ ok( !$die, 'Basic quote processed without dying' ); >+ >+ # Test for expected logs for the passed quote file >+ is( $logger->count, 8, "8 log lines recorded for passed quote file" ); >+ >+ #$logger->diag(); >+ $logger->trace_like( >+ qr/Created basket:.*/, >+ "Trace recorded adding basket" >+ )->trace_like( >+ qr/Checking db for matches.*/, >+ "Trace recorded checking db for matches" >+ )->trace_like( >+ qr/Added biblio:.*/, >+ "Trace recoded adding new biblio" >+ )->trace_like( >+ qr/Order created:.*/, >+ "Trace recorded adding order" >+ )->trace_like( >+ qr/Added item:.*/, >+ "Trace recorded adding new item" >+ )->trace_like( >+ qr/Item added to rota.*/, >+ "Trace recrded adding item to rota" >+ )->debug_like( >+ qr/.*specialUpdate biblioserver$/, >+ "Trace recorded biblioserver index" >+ )->clear(); >+ >+ # No errors expected for QUOTE_SMALL >+ my $errors = Koha::Edifact::File::Errors->search(); >+ is( $errors->count, 0, '0 errors recorded for simple quote' ); >+ >+ # Status changed to received >+ $quote->get_from_storage; >+ is( $quote->status, 'received', 'Quote status set to received' ); >+ >+ # Generate basket >+ my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >+ is( $baskets->count, 1, "One basket created for single message quote file" ); >+ >+ my $basket = $baskets->next; >+ is( $basket->basketname, $filename, "Basket uses EDI filename for name" ); >+ >+ # Order lines >+ my $orders = $basket->orders; >+ is( $orders->count, 1, "One order line created for single record quote file" ); >+ >+ my $order = $orders->next; >+ ok( $order->biblionumber, 'Biblionumber assigned to order' ); >+ is( $order->entrydate, dt_from_string()->ymd(), 'Entry date set correctly' ); >+ >+ # Fund allocation >+ $fund = $order->fund; >+ ok( $fund, 'Fund allocated to order' ); >+ is( $fund->budget_code, 'REF', 'Correct fund allocated for order' ); >+ >+ # Test 008 handling >+ my $biblio = $order->biblio; >+ my $record = $biblio->record; >+ my $record_field = $record->field('008'); >+ is( exists( $record_field->{_data} ), 1, '008 field added when missing from quote' ); >+ >+ # Item allocation >+ my $items = $order->items; >+ is( >+ $items->count, 1, >+ "One item created when AcqCreateItem is set to 'ordering' for single record, single quantity quote file" >+ ); >+ >+ # Test stock rotation handling >+ my $item = $items->next; >+ my $on_rota = Koha::StockRotationItems->search( { itemnumber_id => $item->itemnumber } ); >+ is( $on_rota->count, 1, "Item added to rotation" ); >+ is( $on_rota->next->stage->rota->id, $rota->id, "Correct rotation assigned" ); >+ >+ # Confirm no ORDER message generated for 'auto_orders => 0' >+ is( $basket->closedate, undef, 'Basket left open for auto_orders disabled' ); >+ my $edi_orders = $schema->resultset('EdifactMessage')->search( >+ { >+ message_type => 'ORDERS', >+ basketno => $basket->basketno, >+ } >+ ); >+ is( $edi_orders->count, 0, 'ORDER message not created for auto_orders disabled' ); > >- # Process the test quote file >- my $error; >- eval { >- process_quote($quote); >- 1; >- } or do { >- $error = $@; >+ $logger->clear(); >+ $schema->storage->txn_rollback; > }; >- ok( !$error, 'process_quote completed without dying' ); >- >- # Test for expected warnings for the passed quote file >- is( $logger->count, 8, "8 log lines recorded for passed quote file" ); > >- #$logger->diag(); >- $logger->trace_like( >- qr/Created basket:.*/, >- "Trace recorded adding basket" >- )->trace_like( >- qr/Checking db for matches.*/, >- "Trace recorded checking db for matches" >- )->trace_like( >- qr/New biblio added.*/, >- "Trace recoded adding new biblio" >- )->trace_like( >- qr/Order created:.*/, >- "Trace recorded adding order" >- )->trace_like( >- qr/Added item:.*/, >- "Trace recorded adding new item" >- )->trace_like( >- qr/Item added to rota.*/, >- "Trace recrded adding item to rota" >- )->debug_like( >- qr/.*specialUpdate biblioserver$/, >- "Trace recorded biblioserver index" >- )->clear(); >+ # Test 2: Auto Orders Processing >+ subtest 'auto_orders_processing' => sub { >+ plan tests => 7; >+ >+ $schema->storage->txn_begin; >+ my $account = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'auto order vendor', >+ transport => 'FILE', >+ plugin => '', >+ san => $test_san, >+ orders_enabled => 1, >+ auto_orders => 1, >+ } >+ } >+ ); >+ my $ean = $builder->build( >+ { >+ source => 'EdifactEan', >+ value => { >+ description => 'test ean', >+ branchcode => undef, >+ ean => $test_san >+ } >+ } >+ ); >+ >+ # Setup the fund >+ $builder->build( >+ { >+ source => 'Aqbudget', >+ value => { >+ budget_code => 'REF', >+ budget_period_id => $active_period->{budget_period_id} >+ } >+ } >+ ); > >- # Test for quote status change >- $quote->get_from_storage; >- is( $quote->status, 'received', 'Quote status was set to received' ); >+ my $filename = 'QUOTES_SMALL.CEQ'; >+ my $trans = Koha::Edifact::Transport->new( $account->{id} ); >+ $trans->working_directory($dirname); > >- # Tests for generated basket for passed quote file >- my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >- is( $baskets->count, 1, "1 basket created for a single quote file" ); >- my $basket = $baskets->next; >+ my $mhash = $trans->message_hash(); >+ $mhash->{message_type} = 'QUOTE'; >+ $trans->ingest( $mhash, $filename ); > >- my $orders = $basket->orders; >- is( $orders->count, 1, "1 order line attached to basket when only 1 order is in the edi message" ); >- my $order = $orders->next; >+ my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); > >- my $biblio = $order->biblio; >+ # Process quote and check results >+ my $die; >+ eval { >+ process_quote($quote); >+ 1; >+ } or do { >+ $die = $@; >+ }; >+ ok( !$die, 'Basic quote processed, with auto_orders enabled, without dying' ); > >- my $items = $order->items; >- is( $items->count, 1, "1 item added when AcqCreateItem eq ordering and 1 item is in the EDI quote" ); >- my $item = $items->next; >+ my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >+ is( $baskets->count, 1, "Basket created" ); > >- # Test that item is added to rota appropriately >- my $on_rota = Koha::StockRotationItems->search( { itemnumber_id => $item->itemnumber } ); >- is( $on_rota->count, 1, "Item added to stockrotation rota" ); >+ my $basket = $baskets->next; >+ ok( $basket->closedate, 'Basket automatically closed for auto_orders' ); > >- my $rota_item = $on_rota->next; >- is( $rota_item->stage->rota->id, $rota->id, "Item is on correct rota" ); >+ my $orders = $basket->orders; >+ is( $orders->count, 1, "One order created" ); > >- $schema->storage->txn_rollback; >-}; >+ my $order = $orders->next; >+ ok( $order->biblionumber, 'Biblionumber assigned to order' ); > >-subtest '_handle_008_field' => sub { >- plan tests => 4; >+ # Check EDI order generation >+ my $edi_orders = $schema->resultset('EdifactMessage')->search( >+ { >+ message_type => 'ORDERS', >+ basketno => $basket->basketno, >+ } >+ ); >+ is( $edi_orders->count, 1, 'EDI order message created' ); >+ is( $edi_orders->next->status, 'Pending', 'EDI order status is Pending' ); > >- $schema->storage->txn_begin; >+ $logger->clear(); >+ $schema->storage->txn_rollback; >+ }; > >- # Add our test quote file to the database for testing against >- my $account = $builder->build( >- { >- source => 'VendorEdiAccount', >- value => { >- description => 'test vendor', transport => 'FILE', >+ # Test 3: Multiple item quote >+ subtest 'multi-item quote' => sub { >+ plan tests => 18; >+ >+ $schema->storage->txn_begin; >+ >+ # Create vendor EDI account >+ my $account = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'multi-item vendor', >+ transport => 'FILE', >+ plugin => '', >+ } > } >+ ); >+ my $ean = $builder->build( >+ { >+ source => 'EdifactEan', >+ value => { >+ description => 'test ean', >+ branchcode => undef, >+ ean => $test_san >+ } >+ } >+ ); >+ >+ # Setup multiple funds >+ my %funds; >+ for my $code (qw(REF LOAN)) { >+ $funds{$code} = $builder->build( >+ { >+ source => 'Aqbudget', >+ value => { >+ budget_code => $code, >+ budget_period_id => $active_period->{budget_period_id} >+ } >+ } >+ ); > } >- ); >- my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); >- my $filename = 'QUOTES_SMALL.CEQ'; >- ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' ); > >- my $trans = Koha::Edifact::Transport->new( $account->{id} ); >- $trans->working_directory($dirname); >+ # Setup multiple rota >+ my %rota; >+ for my $title (qw(TEST FAST SLOW)) { >+ $rota{$title} = $builder->build_object( >+ { >+ class => 'Koha::StockRotationRotas', >+ value => { title => $title } >+ } >+ ); >+ $builder->build( >+ { >+ source => 'Stockrotationstage', >+ value => { rota_id => $rota{$title}->rota_id }, >+ } >+ ); >+ } > >- my $mhash = $trans->message_hash(); >- $mhash->{message_type} = 'QUOTE'; >- $trans->ingest( $mhash, $filename ); >+ my $description = <<~"END"; >+ Loaded QUOTE file with 1 Message that contains 2 LIN segments with the first >+ consistent of 1 item and the second with 3 items with 2 different funds. >+ END >+ diag($description); > >- my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); >+ my $filename = 'QUOTES_MULTI.CEQ'; >+ my $trans = Koha::Edifact::Transport->new( $account->{id} ); >+ $trans->working_directory($dirname); >+ my $mhash = $trans->message_hash(); >+ $mhash->{message_type} = 'QUOTE'; >+ $trans->ingest( $mhash, $filename ); > >- # Test quote expects REF to be a valid and active fund code >- my $active_period = $builder->build( >- { >- source => 'Aqbudgetperiod', >- value => { budget_period_active => 1 } >- } >- ); >- my $fund = $builder->build( >- { >- source => 'Aqbudget', >- value => { >- budget_code => 'REF', >- budget_period_id => $active_period->{budget_period_id} >+ my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); >+ process_quote($quote); >+ >+ #$logger->diag(); >+ >+ my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >+ is( $baskets->count, 1, "One basket created for quote" ); >+ >+ my $basket = $baskets->next; >+ my $orders = $basket->orders; >+ is( $orders->count, 3, "Three order lines created for quote" ); >+ >+ my %biblios; >+ my $orderline = 0; >+ while ( my $order = $orders->next ) { >+ $orderline++; >+ diag( "Looking at order: " . $orderline ); >+ if ( $orderline == 1 ) { >+ >+ # Fund allocation >+ my $fund = $order->fund; >+ is( $fund->budget_code, 'REF', 'Correct fund allocated for first orderline' ); >+ >+ # Check biblio >+ ok( $order->biblionumber, 'Biblionumber assigned to order' ); >+ $biblios{ $order->biblionumber }++; >+ >+ # Check items created >+ my $items = $order->items; >+ is( $items->count, 1, 'One item created for the first orderline' ); >+ >+ # Check first order GIR details >+ my $item = $items->next; >+ my $rota = $item->stockrotationitem; >+ ok( $rota, 'Item was assigned to a rota' ); >+ is( $rota->stage->rota->title, 'TEST', "Item was assigned to the correct rota" ); >+ >+ } elsif ( $orderline == 2 ) { >+ >+ # Fund allocation >+ my $fund = $order->fund; >+ is( $fund->budget_code, 'LOAN', 'Correct fund allocated for second orderline' ); >+ >+ # Check biblio >+ ok( $order->biblionumber, 'Biblionumber assigned to order' ); >+ $biblios{ $order->biblionumber }++; >+ >+ # Check items created >+ my $items = $order->items; >+ is( $items->count, 2, 'Two items created for the second orderline' ); >+ >+ # Check second order GIR details >+ my %rotas; >+ while ( my $item = $items->next ) { >+ my $rota = $item->stockrotationitem; >+ ok( $rota, 'Item was assigned to a rota' ); >+ $rotas{ $rota->stage->rota->title }++; >+ } >+ is( $rotas{'FAST'}, 1, "One item added to 'FAST' rota" ); >+ is( $rotas{'SLOW'}, 1, "One item added to 'SLOW' rota" ); >+ } elsif ( $orderline == 3 ) { >+ diag("Second LIN split into 2 Orderlines, one for each Fund"); >+ >+ # Fund allocation >+ my $fund = $order->fund; >+ is( $fund->budget_code, 'REF', 'Correct fund allocated for third orderline' ); >+ >+ # Check biblio >+ ok( $order->biblionumber, 'Biblionumber assigned to order' ); >+ $biblios{ $order->biblionumber }++; >+ >+ # Check items created >+ my $items = $order->items; >+ is( $items->count, 1, 'One item created for the third orderline' ); >+ >+ # Check first order GIR details >+ my $item = $items->next; >+ my $rota = $item->stockrotationitem; >+ ok( !$rota, 'Item was not assigned to a rota' ); > } > } >- ); > >- # The quote expects a ROT1 stock rotation roata to exist >- my $rota = $builder->build_object( >- { >- class => 'Koha::StockRotationRotas', >- value => { title => 'ROT1' } >- } >- ); >- $builder->build( >- { >- source => 'Stockrotationstage', >- value => { rota_id => $rota->rota_id }, >- } >- ); >+ $logger->clear(); >+ $schema->storage->txn_rollback; >+ }; > >- # Process the test quote file >- process_quote($quote); >+ # Test 4: Invalid Fund Error Handling >+ subtest 'invalid_fund_handling' => sub { >+ plan tests => 21; > >- $quote->get_from_storage; >+ $schema->storage->txn_begin; > >- # Tests for generated basket for passed quote file >- my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >- my $basket = $baskets->next; >+ my $account = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'error test vendor', >+ transport => 'FILE', >+ } >+ } >+ ); >+ my $ean = $builder->build( >+ { >+ source => 'EdifactEan', >+ value => { >+ description => 'test ean', >+ branchcode => undef, >+ ean => $test_san >+ } >+ } >+ ); > >- my $orders = $basket->orders; >- my $order = $orders->next; >+ my $description = <<~"END"; >+ Loading QUOTE file with 1 Message that contains 2 LIN segments with the first >+ consistent of 1 item and the second with 3 items with 2 different undefined funds. >+ END >+ diag($description); > >- my $biblio = $order->biblio; >- my $record = $biblio->record; >- my $record_field = $record->field('008'); >+ my $filename = 'QUOTES_MULTI.CEQ'; >+ my $trans = Koha::Edifact::Transport->new( $account->{id} ); >+ $trans->working_directory($dirname); > >- is( exists( $record_field->{_data} ), 1, 'Field has been added' ); >+ my $mhash = $trans->message_hash(); >+ $mhash->{message_type} = 'QUOTE'; >+ $trans->ingest( $mhash, $filename ); > >- # Test without calling the 008 handler >- $account = $builder->build( >- { >- source => 'VendorEdiAccount', >- value => { >- description => 'test vendor', transport => 'FILE', >- } >- } >- ); >- $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); >- $filename = 'QUOTES_SMALL_2.CEQ'; >- ok( -e $dirname . $filename, 'File QUOTES_SMALL_2.CEQ found' ); >+ my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); > >- $trans = Koha::Edifact::Transport->new( $account->{id} ); >- $trans->working_directory($dirname); >+ process_quote($quote); > >- $mhash = $trans->message_hash(); >- $mhash->{message_type} = 'QUOTE'; >- $trans->ingest( $mhash, $filename ); >+ #$logger->diag(); >+ $logger->trace_like( >+ qr/Created basket:.*/, >+ "Trace recorded basket added" >+ )->trace_is( >+ qq/Checking db for matches with 9781529923766/, >+ "Trace recorded isbn lookup" >+ )->trace_like( >+ qr/Added biblio:.*/, >+ "Trace recorded adding new biblio" >+ )->trace_is( >+ qq/Skipping orderline with invalid budget: REF/, >+ "Trace recorded skipping orderline with invalid fund" >+ )->trace_is( >+ qq/Checking db for matches with 9781785044342/, >+ "Trace recorded isbn lookup" >+ )->trace_like( >+ qr/Added biblio:.*/, >+ "Trace recorded adding new biblio" >+ )->trace_is( >+ qq/Skipping item with invalid budget: LOAN/, >+ "Trace recorded skipping item with invalid fund" >+ )->trace_is( >+ qq/Skipping item with invalid budget: REF/, >+ "Trace recorded skipping item with invalid fund" >+ )->trace_is( >+ qq/Skipping item with invalid budget: LOAN/, >+ "Trace recorded skipping item with invalid fund" >+ ); >+ >+ # Errors should be recorded for skipped sections >+ my $errors = Koha::Edifact::File::Errors->search(); >+ is( $errors->count, 4, '4 errors recorded for missing funds in quote' ); >+ >+ my $error = $errors->next; >+ ok( $error->section, 'First error section is present' ); >+ is( $error->details, 'Skipped orderline line with invalid budget: REF', 'First error details is correct' ); >+ >+ $error = $errors->next; >+ ok( $error->section, 'Second error section is present' ); >+ is( $error->details, 'Skipped GIR line with invalid budget: LOAN', 'Second error details is correct' ); >+ >+ $error = $errors->next; >+ ok( $error->section, 'Third error section is present' ); >+ is( $error->details, 'Invalid budget REF found', 'Third error details is correct' ); >+ >+ $error = $errors->next; >+ ok( $error->section, 'Fourth error section is present' ); >+ is( $error->details, 'Invalid budget LOAN found', 'Fourth error details is correct' ); >+ >+ $quote->get_from_storage; >+ is( $quote->status, 'error', 'Quote status set to error for invalid fund' ); >+ >+ my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >+ is( $baskets->count, 1, 'Basket still created despite errors' ); >+ >+ my $orders = $baskets->next->orders; >+ is( $orders->count, 0, 'No orders created with invalid fund' ); >+ >+ $logger->clear(); >+ $schema->storage->txn_rollback; >+ }; > >- $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); >+ # Test 5: Multiple message quote file >+ subtest 'multiple_message_handling' => sub { >+ plan tests => 3; > >- # Test quote expects REF to be a valid and active fund code >- $active_period = $builder->build( >- { >- source => 'Aqbudgetperiod', >- value => { budget_period_active => 1 } >- } >- ); >- $fund = $builder->build( >- { >- source => 'Aqbudget', >- value => { >- budget_code => 'REF2', >- budget_period_id => $active_period->{budget_period_id} >+ $schema->storage->txn_begin; >+ >+ my $account = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'error test vendor', >+ transport => 'FILE', >+ } > } >- } >- ); >+ ); >+ my $ean = $builder->build( >+ { >+ source => 'EdifactEan', >+ value => { >+ description => 'test ean', >+ branchcode => undef, >+ ean => $test_san >+ } >+ } >+ ); > >- # The quote expects a ROT1 stock rotation roata to exist >- $rota = $builder->build_object( >- { >- class => 'Koha::StockRotationRotas', >- value => { title => 'ROT2' } >- } >- ); >- $builder->build( >- { >- source => 'Stockrotationstage', >- value => { rota_id => $rota->rota_id }, >- } >- ); >+ my $description = <<~"END"; >+ Loading QUOTE file with 2 messages >+ END >+ diag($description); > >- # Process the test quote file >- my $edi_module = Test::MockModule->new('Koha::EDI'); >- $edi_module->mock( >- '_check_for_existing_bib', >- sub { >- my $bib_record = shift; >- return; >- } >- ); >- $edi_module->mock( >- '_handle_008_field', >- sub { >- my $bib_record = shift; >- return $bib_record; >- } >- ); >- process_quote($quote); >+ my $filename = 'QUOTES_BIG.CEQ'; >+ my $trans = Koha::Edifact::Transport->new( $account->{id} ); >+ $trans->working_directory($dirname); >+ >+ my $mhash = $trans->message_hash(); >+ $mhash->{message_type} = 'QUOTE'; >+ $trans->ingest( $mhash, $filename ); > >- $quote->get_from_storage; >+ my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); >+ >+ process_quote($quote); > >- # Tests for generated basket for passed quote file >- $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >- $basket = $baskets->next; >+ #$logger->diag(); > >- $orders = $basket->orders; >- $order = $orders->next; >+ my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); >+ is( $baskets->count, 2, 'Two baskets added for file containing 2 messages' ); > >- $biblio = $order->biblio; >- $record = $biblio->record; >- $record_field = $record->field('008'); >+ # First basket >+ my $basket = $baskets->next; >+ is( $basket->basketname, $filename, "Basket uses EDI filename for name" ); > >- is( $record_field->{_data}, undef, 'Field has not been added' ); >+ # Second basket >+ $basket = $baskets->next; >+ is( $basket->basketname, $filename, "Basket uses EDI filename for name" ); > >+ $logger->clear(); >+ $schema->storage->txn_rollback; >+ }; >+ >+ # Clean up > $logger->clear(); > $schema->storage->txn_rollback; > }; > > subtest 'process_invoice' => sub { >- plan tests => 19; >+ plan tests => 20; > > $schema->storage->txn_begin; > >@@ -403,6 +715,7 @@ subtest 'process_invoice' => sub { > 1; > } or do { > $error = $@; >+ diag($error); > }; > ok( !$error, 'process_invoice completed without dying' ); > >@@ -453,6 +766,13 @@ subtest 'process_invoice' => sub { > 'Warn recorded for unmatched item' > )->clear(); > >+ # Errors should be recorded for skipped sections >+ my $errors = Koha::Edifact::File::Errors->search(); >+ is( $errors->count, 6, '6 errors recorded for invoice' ); >+ while ( my $error = $errors->next ) { >+ diag( $error->details ); >+ } >+ > my $invoice3 = Koha::Acquisition::Invoices->search( { invoicenumber => 'INV00003' }, { rows => 1 } )->single; > ok( $invoice3, "Invoice added to database" ); > is( $invoice3->booksellerid, $account->{vendor_id}, 'Invoice has test booksellerid' ); >diff --git a/t/edi_testfiles/QUOTES_BIG.CEQ b/t/edi_testfiles/QUOTES_BIG.CEQ >new file mode 100644 >index 00000000000..0613a17d149 >--- /dev/null >+++ b/t/edi_testfiles/QUOTES_BIG.CEQ >@@ -0,0 +1 @@ >+UNA:+.? 'UNB+UNOC:3+5013546027173+5013546098818+240123:0945+1044416+ASKEDI:+QUOTES++++'UNH+1044416001+QUOTES:D:96A:UN:EAN002'BGM+31C::28+WO0800131+9'DTM+137:20240123:102'RFF+ON:orders 23/1'CUX+2:GBP:12'NAD+BY+5013546098818::9'NAD+SU+5013546027173::9'LIN+1++9781529923766:EN'PIA+5+152992376X:IB'IMD+L+010+:::Thompson'IMD+L+011+:::Louise'IMD+L+050+:::Lucky'IMD+L+060+:::learning to live again'IMD+L+120+:::Ebury Spotlight'IMD+L+170+:::2024'IMD+L+180+:::304'IMD+L+220+:::Hbk'IMD+L+230+:::791.45'IMD+L+250+:::AN'QTY+1:1'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+REF:LFN+791.45:LCL'GIR+001+22.00:LCV'GIR+001+ROT1:LRP'PRI+AAE:22.00'RFF+QLI:WO0800131000001'UNS+S'CNT+2:1'UNT+27+1044416001'UNZ+1+1044416'UNA:+.? 'UNB+UNOC:3+5013546027173+5013546098818+230713:1031+1044417+ASKEDI+QUOTES++++'UNH+1+QUOTES:D:96A:UN:EAN002'BGM+31C::28+WO0800132+9'DTM+137:20230713:102'NAD+BY+5412345000013::9'NAD+SU+4012345000094::9'CUX+2:GBP:9'LIN+1++9781529923766:EN'PIA+1+152992376X:SA'IMD+L+010+:::Thompson'IMD+L+011+:::Louise'IMD+L+050+:::Lucky'IMD+L+060+:::Learning to live again'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+REF:LFN+791.45:LCL'GIR+001+22.00:LCV'GIR+001+TEST:LRP'QTY+21:1:PCE'MOA+203:25.99'RFF+ABO:REF'LIN+2++9781785044342:EN'PIA+5+1785044346:IB'IMD+L+010+:::Hansen'IMD+L+011+:::Anders'IMD+L+050+:::The attention fix'IMD+L+060+:::how to focus in a world that wants to distract you'QTY+1:3'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+LOAN:LFN+153.733:LCL'GIR+001+14.99:LCV'GIR+001+FAST:LRP'GIR+002+BOOK:LST+ANF:LSQ+FFL:LLO+REF:LFN+153.733:LCL'GIR+002+14.99:LCV'GIR+003+BOOK:LST+ANF:LSQ+FPL:LLO+LOAN:LFN+153.733:LCL'GIR+003+14.99:LCV'GIR+003+SLOW:LRP'PRI+AAE:14.99'RFF+QLI:WO0774049000002'UNS+S'MOA+86:87.97'UNT+34+1'UNZ+1+1' >diff --git a/t/edi_testfiles/QUOTES_MULTI.CEQ b/t/edi_testfiles/QUOTES_MULTI.CEQ >new file mode 100644 >index 00000000000..2393cd44fa3 >--- /dev/null >+++ b/t/edi_testfiles/QUOTES_MULTI.CEQ >@@ -0,0 +1 @@ >+UNA:+.? 'UNB+UNOC:3+5013546027173+5013546098818+230713:1031+1044417+ASKEDI+QUOTES++++'UNH+1+QUOTES:D:96A:UN:EAN002'BGM+31C::28+WO0800132+9'DTM+137:20230713:102'NAD+BY+5412345000013::9'NAD+SU+4012345000094::9'CUX+2:GBP:9'LIN+1++9781529923766:EN'PIA+1+152992376X:SA'IMD+L+010+:::Thompson'IMD+L+011+:::Louise'IMD+L+050+:::Lucky'IMD+L+060+:::Learning to live again'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+REF:LFN+791.45:LCL'GIR+001+22.00:LCV'GIR+001+TEST:LRP'QTY+21:1:PCE'MOA+203:25.99'RFF+ABO:REF'LIN+2++9781785044342:EN'PIA+5+1785044346:IB'IMD+L+010+:::Hansen'IMD+L+011+:::Anders'IMD+L+050+:::The attention fix'IMD+L+060+:::how to focus in a world that wants to distract you'QTY+1:3'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+LOAN:LFN+153.733:LCL'GIR+001+14.99:LCV'GIR+001+FAST:LRP'GIR+002+BOOK:LST+ANF:LSQ+FFL:LLO+REF:LFN+153.733:LCL'GIR+002+14.99:LCV'GIR+003+BOOK:LST+ANF:LSQ+FPL:LLO+LOAN:LFN+153.733:LCL'GIR+003+14.99:LCV'GIR+003+SLOW:LRP'PRI+AAE:14.99'RFF+QLI:WO0774049000002'UNS+S'MOA+86:87.97'UNT+34+1'UNZ+1+1' >-- >2.47.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 38689
:
175788
|
175789
|
175790
|
175793
|
175794
|
175795
|
175796
|
175797
|
175809
|
175810
|
175811
|
175812
|
175813
|
175814
|
175815
|
175816
|
175817
|
176127
|
176128
|
176129
|
176130
|
176131
|
176132
|
176133
|
176134
|
176173
|
176174
|
176175
|
176176
|
176177
|
176178
|
176179
|
176180
|
176181
|
176182
|
176183
|
176373
|
176374
|
176375
|
176376
|
176377
|
176378
|
176379
|
176380
|
176381
|
176382
|
176524
|
176525
|
176526
|
176527
|
176528
|
176529
|
176530
|
176531
|
176532
|
176533
|
176605
|
176606
|
176607
|
176608
|
176609
|
176610
|
176611
|
176612
|
176613
|
176614