Koha/t/db_dependent/Serials.t
Baptiste Wojtkowski cb01b25330 Bug 17047: SQL reports management with Mana-KB
Includes:

* code factorization
Some code from subscription & Mana-KB has been factorized in order to speed-up next developments

* SytemPreferences:
Mana Activation:
    - add a value "no, let me think about it", that is the default value.
    - as long as this value is selected, messages ask if user want to activate it ( in Administration and Add-subscription(page 2) )
AutoShareWithMana
    - Add the syspref AutoShareWithMana: user can automatically share infos with Mana-KB (not set by default)

* Interface :
    - On mana-search, rows are now sorted by date of last import, then by number of users
    - Windows redesigned to improve the user experience

* New Feature : report a mistake.
    - people can now report an invalid data (wrong, obsolete,...)
    - if a data is reported as invalid many time, it will appear differently
    - Added few tooltip (to explain the fields last import, nb of users, to explain the new feature)
    - When reporting a data as invalid, a comment can also be added. Koha will then display comments related to data in result lists

* API (svc/mana)
    - add svc/mana/addvaluetofield: allows to ask mana incrementing a field of a resource
    - no hardcoding for resources in the code of api (api needs to be called with a ressourcename)

* New feature : SQL report sharing
    - Create Koha::Report.pm and Koha::Reports.pm, objects class for Reports
    - New feature: share reports with Mana-KB
    - New feature: search report in Mana-KB with keywords
    - New feature: load reports from Mana-KB

Test plan:
    1 - Apply Patch + update database
    2 - Copy the three lines about mana config in etc/koha-conf.xml in ../etc/koha-conf.xml (after <backupdir> for example)
        <!-- URL of the mana KB server -->
        <!-- alternative value http://mana-test.koha-community.org to query the test server -->
        <mana_config>https://mana-kb.koha-community.org</mana_config>
    3 - Check Mana syspref and AutoShareWithMana syspref are not activated
    4 - Search the syspref ManaToken and follow the instructions
    5 - subscriptions
      - Try create a new subscription for a first serial  => Mana-KB shouldn't show you anything (except if the base hase been filled)
      - Share this serial with Mana-KB (on the serial individual's page there must be a Share button)
      - Try to create a new subscription for serial nr1 => a message should appear when you click on "next", click on "use", the fields should automaticaly appear
      - Activate AutoShareWithMana => Subscriptions
      - Create a new subscription for a second serial
      - There shouldn't be any Share button
      - Create a second subscription => the message should appear, click again on use

    6 - SQL Report
      - Create a new SQL report, without notes.
      - On the table with all report (reports > use saved), there should be the action "Share"
      - If you click on share, you have an error message
      - Create a new report, with a title and notes longer than 20 characters
      - You  can share it with mana => you will have a success message
      - On (report > use saved), there must be a message inviting you to search on Mana-KB for more results, enter a few word from title, notes, type of  the report you shared, it should appear. You can use it, it will load it into your report list.

    7 - Report mistakes.
      - On any table containing Mana-KB search results, you can report a mistake and add a comment.

    8 - For each previous test, try to send wrong data, to delete the security token, to send nothing: it should show a correct warning message.

Signed-off-by: Brendan A Gallagher <brendan@bywatersolutions.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

Rebased-by: Alex Arnaud <alex.arnaud@biblibre.com> (2018-07-04)
Signed-off-by: Michal Denar <black23@gmail.com>

Signed-off-by: Michal Denar <black23@gmail.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
2019-01-23 14:39:26 +00:00

358 lines
16 KiB
Perl
Executable file

#!/usr/bin/perl
#
# This Koha test module is a stub!
# Add more tests here!!!
use Modern::Perl;
use YAML;
use C4::Serials;
use C4::Serials::Frequency;
use C4::Serials::Numberpattern;
use C4::Debug;
use C4::Biblio;
use C4::Budgets;
use C4::Items;
use Koha::Database;
use Koha::DateUtils;
use Koha::Acquisition::Booksellers;
use t::lib::Mocks;
use t::lib::TestBuilder;
use Test::More tests => 46;
BEGIN {
use_ok('C4::Serials');
}
my $schema = Koha::Database->new->schema;
$schema->storage->txn_begin;
my $dbh = C4::Context->dbh;
my $builder = t::lib::TestBuilder->new();
# This could/should be used for all untested methods
my @methods = ('updateClaim');
can_ok('C4::Serials', @methods);
$dbh->do(q|UPDATE marc_subfield_structure SET value_builder="callnumber.pl" where kohafield="items.itemcallnumber" and frameworkcode=''|);
my $bookseller = Koha::Acquisition::Bookseller->new(
{
name => "my vendor",
address1 => "bookseller's address",
phone => "0123456",
active => 1
}
);
my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
my $budgetid;
my $bpid = AddBudgetPeriod({
budget_period_startdate => '2015-01-01',
budget_period_enddate => '2015-12-31',
budget_period_description => "budget desc"
});
my $budget_id = AddBudget({
budget_code => "ABCD",
budget_amount => "123.132",
budget_name => "Périodiques",
budget_notes => "This is a note",
budget_period_id => $bpid
});
my $frequency_id = AddSubscriptionFrequency({ description => "Test frequency 1" });
my $pattern_id = AddSubscriptionNumberpattern({
label => 'Test numberpattern 1',
description => 'Description for numberpattern 1',
numberingmethod => '{X}',
label1 => q{},
add1 => 1,
every1 => 1,
every1 => 1,
numbering1 => 1,
whenmorethan1 => 1,
});
my $notes = 'notes';
my $internalnotes = 'intnotes';
my $subscriptionid = NewSubscription(
undef, "", undef, undef, $budget_id, $biblionumber,
'2013-01-01', $frequency_id, undef, undef, undef,
undef, undef, undef, undef, undef, undef,
1, $notes,undef, '2013-01-01', undef, $pattern_id,
undef, undef, 0, $internalnotes, 0,
undef, undef, 0, undef, '2013-12-31', 0
);
my $subscriptioninformation = GetSubscription( $subscriptionid );
is( $subscriptioninformation->{notes}, $notes, 'NewSubscription should set notes' );
is( $subscriptioninformation->{internalnotes}, $internalnotes, 'NewSubscription should set internalnotes' );
my $subscription_history = C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid);
is( $subscription_history->{opacnote}, '', 'NewSubscription should not set subscriptionhistory opacnotes' );
is( $subscription_history->{librariannote}, '', 'NewSubscription should not set subscriptionhistory librariannotes' );
my @subscriptions = SearchSubscriptions({string => $subscriptioninformation->{bibliotitle}, orderby => 'title' });
isa_ok( \@subscriptions, 'ARRAY' );
@subscriptions = SearchSubscriptions({ issn => $subscriptioninformation->{issn}, orderby => 'title' });
isa_ok( \@subscriptions, 'ARRAY' );
@subscriptions = SearchSubscriptions({ ean => $subscriptioninformation->{ean}, orderby => 'title' });
isa_ok( \@subscriptions, 'ARRAY' );
@subscriptions = SearchSubscriptions({ biblionumber => $subscriptioninformation->{bibnum}, orderby => 'title' });
isa_ok( \@subscriptions, 'ARRAY' );
my $frequency = GetSubscriptionFrequency($subscriptioninformation->{periodicity});
my $old_frequency;
if (not $frequency->{unit}) {
$old_frequency = $frequency->{id};
$frequency->{unit} = "month";
$frequency->{unitsperissue} = 1;
$frequency->{issuesperunit} = 1;
$frequency->{description} = "Frequency created by t/db_dependant/Serials.t";
$subscriptioninformation->{periodicity} = AddSubscriptionFrequency($frequency);
$subscriptioninformation->{serialsadditems} = 1;
ModSubscription( @$subscriptioninformation{qw(
librarian branchcode aqbooksellerid cost aqbudgetid startdate
periodicity firstacquidate irregularity numberpattern locale
numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
letter manualhistory internalnotes serialsadditems staffdisplaycount
opacdisplaycount graceperiod location enddate subscriptionid
skip_serialseq
)} );
}
my $expirationdate = GetExpirationDate($subscriptionid) ;
ok( $expirationdate, "expiration date is not NULL" );
ok(C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription');
my ($serials_count, @serials) = GetSerials($subscriptionid);
ok($serials_count > 0, 'Subscription has at least one serial');
my $serial = $serials[0];
isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
subtest 'Values should not be erased on editing' => sub {
plan tests => 1;
( $biblionumber, $biblioitemnumber ) = get_biblio();
my ( $icn_tag, $icn_sf ) = GetMarcFromKohaField( 'items.itemcallnumber', '' );
my ( $it_tag, $it_sf ) = GetMarcFromKohaField( 'items.itype', '' );
my $itemtype = $builder->build( { source => 'Itemtype' } )->{itemtype};
my $itemcallnumber = 'XXXmy itemcallnumberXXX';
my $item_record = new MARC::Record;
$item_record->append_fields(
MARC::Field->new( '080', '', '', "a" => "default" ),
MARC::Field->new(
$icn_tag, '', '',
$icn_sf => $itemcallnumber,
$it_sf => $itemtype
)
);
my ( undef, undef, $itemnumber ) = C4::Items::AddItemFromMarc( $item_record, $biblionumber );
my $serialid = C4::Serials::NewIssue( "serialseq", $subscriptionid, $biblionumber,
1, undef, undef, "publisheddatetext", "notes" );
C4::Serials::AddItem2Serial( $serialid, $itemnumber );
my $serial_info = C4::Serials::GetSerialInformation($serialid);
my ($itemcallnumber_info) = grep { $_->{kohafield} eq 'items.itemcallnumber' }
@{ $serial_info->{items}[0]->{iteminformation} };
like( $itemcallnumber_info->{marc_value}, qr|value="$itemcallnumber"| );
};
# Delete created frequency
if ($old_frequency) {
my $freq_to_delete = $subscriptioninformation->{periodicity};
$subscriptioninformation->{periodicity} = $old_frequency;
ModSubscription( @$subscriptioninformation{qw(
librarian branchcode aqbooksellerid cost aqbudgetid startdate
periodicity firstacquidate irregularity numberpattern locale
numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
letter manualhistory internalnotes serialsadditems staffdisplaycount
opacdisplaycount graceperiod location enddate subscriptionid
skip_serialseq
)} );
DelSubscriptionFrequency($freq_to_delete);
}
# Test calling subs without parameters
is(C4::Serials::AddItem2Serial(), undef, 'test adding item to serial');
is(C4::Serials::GetFullSubscription(), undef, 'test getting full subscription');
is(C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data');
is(C4::Serials::GetSubscriptionsFromBiblionumber(), undef, 'test getting subscriptions form biblio number');
is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
subtest 'test_updateClaim' => sub {
plan tests => 11;
my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
# Given ... nothing much
# When ... Then ...
my $result_0 = C4::Serials::updateClaim(undef);
is($result_0, undef, 'Got the expected undef from update claim with nothin');
# Given ... 3 serial. 2 of them updated.
my $serialids_1 = [90980, 90981];
my $claimdate_1 = dt_from_string('2001-01-13'); # arbitrary date some time in the past.
my $claim_count_1 = 5;
Koha::Serial->new( { serialid => $serialids_1->[0], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
Koha::Serial->new( { serialid => $serialids_1->[1], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
Koha::Serial->new( { serialid => 90982, serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
# When ...
my $result_1 = C4::Serials::updateClaim($serialids_1);
# Then ...
is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[0]);
is($late_or_missing_issues_1_0[0]->{claimdate}, $today, 'Got the expected first different claim date from update claim');
is($late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1+1, 'Got the expected first claim count from update claim');
is($late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim');
my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[1]);
is($late_or_missing_issues_1_1[0]->{claimdate}, $today, 'Got the expected second different claim date from update claim');
is($late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1+1, 'Got the expected second claim count from update claim');
is($late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim');
my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues(undef, 90982);
is($late_or_missing_issues_1_2[0]->{claimdate}, output_pref({ dt => $claimdate_1, dateonly => 1}), 'Got the expected unchanged claim date from update claim');
is($late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1, 'Got the expected unchanged claim count from update claim');
is($late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim');
};
is(C4::Serials::check_routing(), undef, 'test checking route');
is(C4::Serials::addroutingmember(),undef, 'test adding route member');
# Unit tests for statuses management (Bug 11689)
$subscriptionid = NewSubscription(
undef, "", undef, undef, $budget_id, $biblionumber,
'2013-01-01', $frequency_id, undef, undef, undef,
undef, undef, undef, undef, undef, undef,
1, $notes,undef, '2013-01-01', undef, $pattern_id,
undef, undef, 0, $internalnotes, 0,
undef, undef, 0, undef, '2013-12-31', 0
);
my $total_issues;
( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
is( $total_issues, 1, "NewSubscription created a first serial" );
is( @serials, 1, "GetSerials returns the serial" );
my $subscription = C4::Serials::GetSubscription($subscriptionid);
my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
my $publisheddate = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
$frequency = C4::Serials::Frequency::GetSubscriptionFrequency($subscription->{periodicity});
my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, $frequency, 1);
my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
# Add 14 serials
my $counter = 0;
for my $status ( @statuses ) {
my $serialseq = "No.".$counter;
my ( $expected_serial ) = GetSerials2( $subscriptionid, [1] );
C4::Serials::ModSerialStatus( $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate, $publisheddate, $statuses[$counter], 'an useless note' );
$counter++;
}
# Here we have 15 serials with statuses : 2*2 + 5*3 + 2*4 + 1*41 + 1*42 + 1*43 + 1*44 + 1*5 + 1*1
my @serialsByStatus = C4::Serials::findSerialsByStatus(2,$subscriptionid);
is(@serialsByStatus,2,"findSerialsByStatus returns all serials with chosen status");
( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
my @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
my @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
is( @others, 6, "GetSerials returns all serials not arrived and not missing" );
( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
@arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
@others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
is( @others, 6, "GetSerials returns all serials not arrived and not missing if count given" );
$subscription = C4::Serials::GetSubscription($subscriptionid); # Retrieve the updated subscription
my @serialseqs;
for my $am ( @arrived_missing ) {
if ( grep {/^$am->{status}$/} qw( 4 41 42 43 44 ) ) {
push @serialseqs, $am->{serialseq}
} elsif ( grep {/^$am->{status}$/} qw( 5 ) ) {
push @serialseqs, 'not issued ' . $am->{serialseq};
}
}
is( $subscription->{missinglist}, join('; ', @serialseqs), "subscription missinglist is updated after ModSerialStatus" );
subtest "Do not generate an expected if one already exists" => sub {
plan tests => 2;
my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
#Find serialid for serial with status Expected
my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
#delete serial with status Expected
C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
@serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
# add 1 serial with status=Expected 1
C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
#Now we have two serials it have status expected
#put status delete for last serial
C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
#try if create or not another serial with status is expected
@serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
};
sub get_biblio {
my $bib = MARC::Record->new();
$bib->append_fields(
MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
);
my ($bibnum, $bibitemnum) = AddBiblio($bib, '');
return ($bibnum, $bibitemnum);
}