From ecc86ddca3b661dab27fda46c166c64b53615cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Cohen=20Arazi?= Date: Mon, 26 Jan 2026 16:30:31 -0300 Subject: [PATCH] Bug 41714: Add tests --- installer/data/mysql/mandatory/sysprefs.sql | 2 +- t/db_dependent/Heading.t | 66 +++++++++++- t/db_dependent/Heading/MARC21.t | 112 ++++++++++++++++++++ t/db_dependent/Heading_MARC21.t | 37 ------- 4 files changed, 178 insertions(+), 39 deletions(-) create mode 100755 t/db_dependent/Heading/MARC21.t delete mode 100755 t/db_dependent/Heading_MARC21.t diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index 6f96a24f98..c5fcffde00 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -78,7 +78,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('AuthoritiesLog','1',NULL,'If ON, log edit/create/delete actions on authorities.','YesNo'), ('AuthorityControlledIndicators','# PERSO_NAME 100 600 696 700 796 800 896\nmarc21, 100, ind1:auth1\nmarc21, 600, ind1:auth1, ind2:thesaurus\nmarc21, 696, ind1:auth1\nmarc21, 700, ind1:auth1\nmarc21, 796, ind1:auth1\nmarc21, 800, ind1:auth1\nmarc21, 896, ind1:auth1\n# CORPO_NAME 110 610 697 710 797 810 897\nmarc21, 110, ind1:auth1\nmarc21, 610, ind1:auth1, ind2:thesaurus\nmarc21, 697, ind1:auth1\nmarc21, 710, ind1:auth1\nmarc21, 797, ind1:auth1\nmarc21, 810, ind1:auth1\nmarc21, 897, ind1:auth1\n# MEETI_NAME 111 611 698 711 798 811 898\nmarc21, 111, ind1:auth1\nmarc21, 611, ind1:auth1, ind2:thesaurus\nmarc21, 698, ind1:auth1\nmarc21, 711, ind1:auth1\nmarc21, 798, ind1:auth1\nmarc21, 811, ind1:auth1\nmarc21, 898, ind1:auth1\n# UNIF_TITLE 130 440 630 699 730 799 830 899\nmarc21, 130, ind1:auth2\nmarc21, 240, , ind2:auth2\nmarc21, 440, , ind2:auth2\nmarc21, 630, ind1:auth2, ind2:thesaurus\nmarc21, 699, ind1:auth2\nmarc21, 730, ind1:auth2\nmarc21, 799, ind1:auth2\nmarc21, 830, , ind2:auth2\nmarc21, 899, ind1:auth2\n# CHRON_TERM 648 \nmarc21, 648, , ind2:thesaurus\n# TOPIC_TERM 650 654 656 657 658 690\nmarc21, 650, , ind2:thesaurus\n# GEOGR_NAME 651 662 691\nmarc21, 651, , ind2:thesaurus\n# GENRE/FORM 655 \nmarc21, 655, , ind2:thesaurus\n\n# UNIMARC: Always copy the indicators from the authority\nunimarc, *, ind1:auth1, ind2:auth2',NULL,'Authority controlled indicators per biblio field','Free'), ('AuthorityMergeLimit','50',NULL,'Maximum number of biblio records updated immediately when an authority record has been modified.','Integer'), -('LinkerUseFrameworkAuthTypes','0',NULL,'Use authority types defined in MARC bibliographic frameworks when linking headings to authorities (MARC21 only). When enabled, the authority type configured in the Default framework will be used instead of the hardcoded MARC21 defaults.','YesNo'), ('AuthorityMergeMode','loose','loose|strict','Authority merge mode','Choice'), ('AuthoritySeparator','--','10','Used to separate a list of authorities in a display. Usually --','free'), ('AuthorityXSLTDetailsDisplay','',NULL,'Enable XSL stylesheet control over authority details page display on intranet','Free'), @@ -399,6 +398,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('LinkerModule','Default','Default|FirstMatch|LastMatch','Chooses which linker module to use (see documentation).','Choice'), ('LinkerOptions','',NULL,'A pipe-separated list of options for the linker.','free'), ('LinkerRelink','1',NULL,'If ON the authority linker will relink headings that have previously been linked every time it runs.','YesNo'), +('LinkerUseFrameworkAuthTypes','0',NULL,'Use authority types defined in MARC bibliographic frameworks when linking headings to authorities (MARC21 only). When enabled, the authority type configured in the Default framework will be used instead of the hardcoded MARC21 defaults.','YesNo'), ('ListOwnerDesignated', '', NULL, 'Designated list owner at patron deletion', 'Free'), ('ListOwnershipUponPatronDeletion', 'delete', 'delete|transfer|transfer_public', 'Defines the action on their public or shared lists when patron is deleted', 'Choice'), ('LoadCheckoutsTableDelay','0',NULL,'Delay before auto-loading checkouts table on checkouts screen','Integer'), diff --git a/t/db_dependent/Heading.t b/t/db_dependent/Heading.t index 362528a310..5ff1c5173b 100755 --- a/t/db_dependent/Heading.t +++ b/t/db_dependent/Heading.t @@ -19,7 +19,7 @@ use strict; use warnings; use Test::NoWarnings; -use Test::More tests => 6; +use Test::More tests => 7; use open qw/ :std :utf8 /; @@ -403,3 +403,67 @@ subtest "authorities exact match tests" => sub { $schema->storage->txn_rollback; }; + +subtest 'LinkerUseFrameworkAuthTypes' => sub { + plan tests => 2; + + my $schema = Koha::Database->new->schema; + my $cache = Koha::Caches->get_instance; + $schema->storage->txn_begin; + + t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); + + subtest 'Preference disabled (default behavior)' => sub { + plan tests => 1; + + t::lib::Mocks::mock_preference( 'LinkerUseFrameworkAuthTypes', 0 ); + + my $field = MARC::Field->new( '650', ' ', '0', a => 'Test subject' ); + my $heading = C4::Heading->new_from_field($field); + + is( $heading->auth_type(), 'TOPIC_TERM', 'Uses hardcoded TOPIC_TERM when preference disabled' ); + }; + + subtest 'Preference enabled with framework override' => sub { + plan tests => 1; + + t::lib::Mocks::mock_preference( 'LinkerUseFrameworkAuthTypes', 1 ); + + # Ensure clean state + $schema->resultset('MarcSubfieldStructure')->search( + { + frameworkcode => '', + tagfield => [ '650', '600', '651' ], + } + )->delete; + + # Create test data with all required fields + $schema->resultset('MarcSubfieldStructure')->create( + { + frameworkcode => '', + tagfield => '650', + tagsubfield => 'a', + authtypecode => 'CUSTOM_TERM', + liblibrarian => 'Subject', + libopac => 'Subject', + repeatable => 0, + mandatory => 0, + tab => 6, + } + ); + + # Clear all caches + no warnings 'once'; + %C4::Heading::authority_type_cache = (); + $cache->clear_from_cache("MarcSubfieldStructure-"); + $cache->clear_from_cache("MarcStructure-0-"); + $cache->clear_from_cache("MarcStructure-1-"); + + my $field = MARC::Field->new( '650', ' ', '0', a => 'Test subject' ); + my $heading = C4::Heading->new_from_field($field); + + is( $heading->auth_type(), 'CUSTOM_TERM', 'Uses framework authority type when enabled' ); + }; + + $schema->storage->txn_rollback; +}; diff --git a/t/db_dependent/Heading/MARC21.t b/t/db_dependent/Heading/MARC21.t new file mode 100755 index 0000000000..5b26c8ef21 --- /dev/null +++ b/t/db_dependent/Heading/MARC21.t @@ -0,0 +1,112 @@ +#!/usr/bin/perl + +# This file is part of Koha +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::NoWarnings; +use Test::More tests => 6; + +use t::lib::Mocks; + +BEGIN { + use_ok( 'C4::Heading', qw( new_from_field ) ); +} + +t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); + +subtest 'Display and search forms' => sub { + plan tests => 3; + + my $field = MARC::Field->new( '650', ' ', '2', a => 'Uncles', x => 'Fiction' ); + my $heading = C4::Heading->new_from_field($field); + is( $heading->display_form(), 'Uncles--Fiction', 'Display form generation' ); + is( $heading->search_form(), 'Uncles generalsubdiv Fiction', 'Search form generation' ); + is( $heading->{thesaurus}, 'mesh', 'Thesaurus generation' ); +}; + +subtest 'Uniform titles' => sub { + plan tests => 3; + + my $field = MARC::Field->new( '830', ' ', '4', a => 'The dark is rising ;', v => '3' ); + my $heading = C4::Heading->new_from_field($field); + is( $heading->display_form(), 'The dark is rising ;', 'Display form generation' ); + is( $heading->search_form(), 'The dark is rising', 'Search form generation' ); + ok( !defined $heading->{thesaurus}, 'Thesaurus is not generated outside of 6XX fields' ); +}; + +subtest 'Personal names' => sub { + plan tests => 3; + + my $field = MARC::Field->new( '100', '1', '', a => 'Yankovic, Al', d => '1959-' ); + my $heading = C4::Heading->new_from_field($field); + is( $heading->display_form(), 'Yankovic, Al 1959-', 'Display form generation' ); + is( $heading->search_form(), 'Yankovic, Al 1959', 'Search form generation' ); + ok( !defined $heading->{thesaurus}, 'Thesaurus is not generated outside of 6XX fields' ); +}; + +subtest 'LinkerUseFrameworkAuthTypes' => sub { + plan tests => 3; + + my $schema = Koha::Database->new->schema; + my $cache = Koha::Caches->get_instance; + $schema->storage->txn_begin; + + # Test 1: Preference disabled uses hardcoded + t::lib::Mocks::mock_preference( 'LinkerUseFrameworkAuthTypes', 0 ); + my $field = MARC::Field->new( '650', ' ', '0', a => 'Test' ); + my $heading = C4::Heading->new_from_field($field); + is( $heading->auth_type(), 'TOPIC_TERM', 'Uses hardcoded TOPIC_TERM when preference disabled' ); + + # Test 2: Preference enabled with framework override + t::lib::Mocks::mock_preference( 'LinkerUseFrameworkAuthTypes', 1 ); + + $schema->resultset('MarcSubfieldStructure')->search( + { + frameworkcode => '', + tagfield => '650', + } + )->delete; + + $schema->resultset('MarcSubfieldStructure')->create( + { + frameworkcode => '', + tagfield => '650', + tagsubfield => 'a', + authtypecode => 'CUSTOM_TERM', + liblibrarian => 'Subject', + libopac => 'Subject', + repeatable => 0, + mandatory => 0, + tab => 6, + } + ); + + no warnings 'once'; + %C4::Heading::authority_type_cache = (); + $cache->clear_from_cache("MarcSubfieldStructure-"); + + $field = MARC::Field->new( '650', ' ', '0', a => 'Test' ); + $heading = C4::Heading->new_from_field($field); + is( $heading->auth_type(), 'CUSTOM_TERM', 'Uses framework override when preference enabled' ); + + # Test 3: Falls back to hardcoded for unconfigured tags + $field = MARC::Field->new( '600', ' ', '0', a => 'Person' ); + $heading = C4::Heading->new_from_field($field); + is( $heading->auth_type(), 'PERSO_NAME', 'Falls back to hardcoded for unconfigured tags' ); + + $schema->storage->txn_rollback; +}; diff --git a/t/db_dependent/Heading_MARC21.t b/t/db_dependent/Heading_MARC21.t deleted file mode 100755 index cc3da31eb9..0000000000 --- a/t/db_dependent/Heading_MARC21.t +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/perl -# -# This Koha test module is a stub! -# Add more tests here!!! - -use strict; -use warnings; - -use Test::NoWarnings; -use Test::More tests => 11; -use C4::Context; - -BEGIN { - use_ok( 'C4::Heading', qw( new_from_field ) ); -} - -SKIP: { - skip "MARC21 heading tests not applicable to UNIMARC", 2 if C4::Context->preference('marcflavour') eq 'UNIMARC'; - my $field = MARC::Field->new( '650', ' ', '2', a => 'Uncles', x => 'Fiction' ); - my $heading = C4::Heading->new_from_field($field); - is( $heading->display_form(), 'Uncles--Fiction', 'Display form generation' ); - is( $heading->search_form(), 'Uncles generalsubdiv Fiction', 'Search form generation' ); - is( $heading->{thesaurus}, 'mesh', 'Thesaurus generation' ); - - $field = MARC::Field->new( '830', ' ', '4', a => 'The dark is rising ;', v => '3' ); - $heading = C4::Heading->new_from_field($field); - is( $heading->display_form(), 'The dark is rising ;', 'Display form generation' ); - is( $heading->search_form(), 'The dark is rising', 'Search form generation' ); - ok( !defined $heading->{thesaurus}, 'Thesaurus is not generated outside of 6XX fields' ); - - $field = MARC::Field->new( '100', '1', '', a => 'Yankovic, Al', d => '1959-' ); - $heading = C4::Heading->new_from_field($field); - is( $heading->display_form(), 'Yankovic, Al 1959-', 'Display form generation' ); - is( $heading->search_form(), 'Yankovic, Al 1959', 'Search form generation' ); - ok( !defined $heading->{thesaurus}, 'Thesaurus is not generated outside of 6XX fields' ); - -} -- 2.50.1 (Apple Git-155)