From 6235927d7725dfdd595b8ff067b067318a7d3c17 Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Fri, 29 Nov 2013 11:34:46 +0100 Subject: [PATCH] Bug 11425: Add unit tests package Koha::Item::Search::Field function C4::SQLHelper::GetColumns function C4::Items::SearchItems --- C4/Items.pm | 17 ++++- Koha/Item/Search/Field.pm | 4 + t/db_dependent/Items.t | 127 ++++++++++++++++++++++++++++++- t/db_dependent/Koha/Item/Search/Field.t | 39 ++++++++++ t/db_dependent/SQLHelper.t | 7 +- 5 files changed, 188 insertions(+), 6 deletions(-) create mode 100755 t/db_dependent/Koha/Item/Search/Field.t diff --git a/C4/Items.pm b/C4/Items.pm index ba95f9e..db1cdcd 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -2645,12 +2645,13 @@ sub _SearchItems_build_where_fragment { =head2 SearchItems - my ($items, $total) = SearchItemsByField($filters, $params); + my ($items, $total) = SearchItems($filter, $params); Perform a search among items -$filters is a reference to an array of filters, where each filter is a hash with -the following keys: +$filter is a reference to a hash which can be a filter, or a combination of filters. + +A filter has the following keys: =over 2 @@ -2662,7 +2663,15 @@ the following keys: =back -A logical AND is used to combine filters. +A combination of filters hash the following keys: + +=over 2 + +=item * conjunction: 'AND' or 'OR' + +=item * filters: array ref of filters + +=back $params is a reference to a hash that can contain the following parameters: diff --git a/Koha/Item/Search/Field.pm b/Koha/Item/Search/Field.pm index 6b1e137..74c1cf2 100644 --- a/Koha/Item/Search/Field.pm +++ b/Koha/Item/Search/Field.pm @@ -19,6 +19,8 @@ sub AddItemSearchField { my ( $name, $label, $tagfield, $tagsubfield, $av_category ) = @$field{qw(name label tagfield tagsubfield authorised_values_category)}; + return unless ($name and $label and $tagfield); + my $dbh = C4::Context->dbh; my $query = q{ INSERT INTO items_search_fields (name, label, tagfield, tagsubfield, authorised_values_category) @@ -36,6 +38,8 @@ sub ModItemSearchField { my ( $name, $label, $tagfield, $tagsubfield, $av_category ) = @$field{qw(name label tagfield tagsubfield authorised_values_category)}; + return unless ($name and $label and $tagfield); + my $dbh = C4::Context->dbh; my $query = q{ UPDATE items_search_fields diff --git a/t/db_dependent/Items.t b/t/db_dependent/Items.t index 5ec8d34..ac30fc8 100755 --- a/t/db_dependent/Items.t +++ b/t/db_dependent/Items.t @@ -20,8 +20,9 @@ use Modern::Perl; use MARC::Record; use C4::Biblio; +use C4::Branch; -use Test::More tests => 3; +use Test::More tests => 4; BEGIN { use_ok('C4::Items'); @@ -37,8 +38,10 @@ subtest 'General Add, Get and Del tests' => sub { $dbh->{AutoCommit} = 0; $dbh->{RaiseError} = 1; + # Helper biblio. diag("Creating biblio instance for testing."); + C4::Context->set_preference('marcflavour', 'MARC21'); my ($bibnum, $bibitemnum) = get_biblio(); # Add an item. @@ -75,8 +78,17 @@ subtest 'GetHiddenItemnumbers tests' => sub { $dbh->{RaiseError} = 1; # Create a new biblio + C4::Context->set_preference('marcflavour', 'MARC21'); my ($biblionumber, $biblioitemnumber) = get_biblio(); + # Add branches if they don't exist + if (not defined GetBranchDetail('CPL')) { + ModBranch({add => 1, branchcode => 'CPL', branchname => 'Centerville'}); + } + if (not defined GetBranchDetail('MPL')) { + ModBranch({add => 1, branchcode => 'MPL', branchname => 'Midway'}); + } + # Add two items my ($item1_bibnum, $item1_bibitemnum, $item1_itemnumber) = AddItem( { homebranch => 'CPL', @@ -142,6 +154,119 @@ subtest 'GetHiddenItemnumbers tests' => sub { $dbh->rollback; }; +subtest 'SearchItems test' => sub { + plan tests => 10; + + # Start transaction + $dbh->{AutoCommit} = 0; + $dbh->{RaiseError} = 1; + + C4::Context->set_preference('marcflavour', 'MARC21'); + my ($biblionumber) = get_biblio(); + + # Add branches if they don't exist + if (not defined GetBranchDetail('CPL')) { + ModBranch({add => 1, branchcode => 'CPL', branchname => 'Centerville'}); + } + if (not defined GetBranchDetail('MPL')) { + ModBranch({add => 1, branchcode => 'MPL', branchname => 'Midway'}); + } + + my (undef, $initial_items_count) = SearchItems(undef, {rows => 1}); + + # Add two items + my (undef, undef, $item1_itemnumber) = AddItem({ + homebranch => 'CPL', + holdingbranch => 'CPL', + }, $biblionumber); + my (undef, undef, $item2_itemnumber) = AddItem({ + homebranch => 'MPL', + holdingbranch => 'MPL', + }, $biblionumber); + + my ($items, $total_results); + + ($items, $total_results) = SearchItems(); + is($total_results, $initial_items_count + 2, "Created 2 new items"); + is(scalar @$items, $total_results, "SearchItems() returns all items"); + + ($items, $total_results) = SearchItems(undef, {rows => 1}); + is($total_results, $initial_items_count + 2); + is(scalar @$items, 1, "SearchItems(undef, {rows => 1}) returns only 1 item"); + + # Search all items where homebranch = 'CPL' + my $filter = { + field => 'homebranch', + query => 'CPL', + operator => '=', + }; + ($items, $total_results) = SearchItems($filter); + ok($total_results > 0, "There is at least one CPL item"); + my $all_items_are_CPL = 1; + foreach my $item (@$items) { + if ($item->{homebranch} ne 'CPL') { + $all_items_are_CPL = 0; + last; + } + } + ok($all_items_are_CPL, "All items returned by SearchItems are from CPL"); + + # Search all items where homebranch != 'CPL' + $filter = { + field => 'homebranch', + query => 'CPL', + operator => '!=', + }; + ($items, $total_results) = SearchItems($filter); + ok($total_results > 0, "There is at least one non-CPL item"); + my $all_items_are_not_CPL = 1; + foreach my $item (@$items) { + if ($item->{homebranch} eq 'CPL') { + $all_items_are_not_CPL = 0; + last; + } + } + ok($all_items_are_not_CPL, "All items returned by SearchItems are not from CPL"); + + # Search all items where biblio title (245$a) is like 'Silence in the %' + $filter = { + field => 'marc:245$a', + query => 'Silence in the %', + operator => 'like', + }; + ($items, $total_results) = SearchItems($filter); + ok($total_results >= 2, "There is at least 2 items with a biblio title like 'Silence in the %'"); + + # Search all items where biblio title is 'Silence in the library' + # and homebranch is 'CPL' + $filter = { + conjunction => 'AND', + filters => [ + { + field => 'marc:245$a', + query => 'Silence in the %', + operator => 'like', + }, + { + field => 'homebranch', + query => 'CPL', + operator => '=', + }, + ], + }; + ($items, $total_results) = SearchItems($filter); + my $found = 0; + foreach my $item (@$items) { + if ($item->{itemnumber} == $item1_itemnumber) { + $found = 1; + last; + } + } + ok($found, "item1 found"); + + $dbh->rollback; +}; + # Helper method to set up a Biblio. sub get_biblio { my $bib = MARC::Record->new(); diff --git a/t/db_dependent/Koha/Item/Search/Field.t b/t/db_dependent/Koha/Item/Search/Field.t new file mode 100755 index 0000000..1cbb544 --- /dev/null +++ b/t/db_dependent/Koha/Item/Search/Field.t @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +use Modern::Perl; +use Test::More tests => 11; + +use C4::Context; + +use_ok('Koha::Item::Search::Field'); +import Koha::Item::Search::Field qw(AddItemSearchField ModItemSearchField + DelItemSearchField GetItemSearchField GetItemSearchFields); + +my $dbh = C4::Context->dbh; +$dbh->{AutoCommit} = 0; + +# Start with empty table. +foreach my $field (GetItemSearchFields()) { + DelItemSearchField($field->{name}); +} +is(scalar GetItemSearchFields(), 0, "No existing search field"); + +# Missing keys in hashref parameter, so returns undef +ok(not (defined AddItemSearchField()), "missing keys => fail"); +ok(not (defined AddItemSearchField({})), "missing keys => fail"); +ok(not (defined AddItemSearchField({name => 'foo'})), "missing keys => fail"); +ok(not (defined AddItemSearchField({name => 'foo', label => 'Foo'})), "missing keys => fail"); + +# Success, the field hashref is returned +ok('HASH' eq ref AddItemSearchField({name => 'foo', label => 'Foo', tagfield => '001'}), "successful add"); + +# Check the table now contains one row. +is(scalar GetItemSearchFields(), 1, "Table now contains one row"); +my $field = GetItemSearchField('foo'); +is_deeply($field, {name => 'foo', label => 'Foo', tagfield => '001', tagsubfield => undef, authorised_values_category => undef}); + +ok((defined ModItemSearchField({name => 'foo', label => 'Foobar', tagfield => '100', 'tagsubfield' => 'a'})), "successful mod"); +$field = GetItemSearchField('foo'); +is_deeply($field, {name => 'foo', label => 'Foobar', tagfield => '100', tagsubfield => 'a', authorised_values_category => undef}); + +$dbh->rollback; diff --git a/t/db_dependent/SQLHelper.t b/t/db_dependent/SQLHelper.t index d6d2b99..f585736 100755 --- a/t/db_dependent/SQLHelper.t +++ b/t/db_dependent/SQLHelper.t @@ -10,7 +10,7 @@ use YAML; use C4::Debug; use C4::SQLHelper qw(:all); -use Test::More tests => 20; +use Test::More tests => 21; use_ok('C4::SQLHelper'); @@ -63,3 +63,8 @@ $status=DeleteInTable("borrowers",{borrowernumber=>$borrtmp}); ok($status>0 && !($@), "DeleteInTable OK"); $status=DeleteInTable("branches", {branchcode => 'ZZZZ'}); ok($status>0 && !($@), "DeleteInTable (branch) OK"); + +my @biblio_columns = C4::SQLHelper::GetColumns('biblio'); +my @expected_columns = qw(biblionumber frameworkcode author title unititle notes + serial seriestitle copyrightdate timestamp datecreated abstract); +is_deeply([sort @biblio_columns], [sort @expected_columns], "GetColumns('biblio') returns all columns of biblio table"); -- 1.7.10.4