Bug 15131: Add AllowItemsOnHoldCheckoutSCO to UsageStats
[koha.git] / t / db_dependent / UsageStats.t
1 # Copyright 2015 BibLibre
2 #
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, see <http://www.gnu.org/licenses>.
16
17 use Modern::Perl;
18 use Test::More tests => 57;
19 use t::lib::Mocks qw(mock_preference);
20 use POSIX qw(strftime);
21 use Data::Dumper;
22
23 BEGIN {
24     use_ok('C4::UsageStats');
25     use_ok('C4::Context');
26     use_ok('C4::Biblio');
27     use_ok( 'C4::AuthoritiesMarc', qw(AddAuthority) );
28     use_ok('C4::Reserves');
29     use_ok('MARC::Record');
30     use_ok('Koha::Acquisition::Order');
31 }
32
33 can_ok(
34     'C4::UsageStats', qw(
35       NeedUpdate
36       BuildReport
37       ReportToCommunity
38       _count )
39 );
40
41 my $dbh = C4::Context->dbh;
42 $dbh->{AutoCommit} = 0;
43 $dbh->{RaiseError} = 1;
44
45 $dbh->do('DELETE FROM issues');
46 $dbh->do('DELETE FROM biblio');
47 $dbh->do('DELETE FROM items');
48 $dbh->do('DELETE FROM auth_header');
49 $dbh->do('DELETE FROM old_issues');
50 $dbh->do('DELETE FROM old_reserves');
51 $dbh->do('DELETE FROM borrowers');
52 $dbh->do('DELETE FROM aqorders');
53 $dbh->do('DELETE FROM subscription');
54
55 #################################################
56 #             Testing Subs
57 #################################################
58
59 # ---------- Testing NeedUpdate -----------------
60
61 #Mocking C4::Context->preference("UsageStatsLastUpdateTime") to 0
62 my $now = strftime( "%s", localtime );
63 t::lib::Mocks::mock_preference( "UsageStatsLastUpdateTime", 0 );
64
65 my $update = C4::UsageStats->NeedUpdate;
66 is( $update, 1, "There is no last update, update needed" );
67
68 #Mocking C4::Context->preference("UsageStatsLastUpdateTime") to now
69 $now = strftime( "%s", localtime );
70 t::lib::Mocks::mock_preference( "UsageStatsLastUpdateTime", $now );
71
72 $update = C4::UsageStats->NeedUpdate;
73 is( $update, 0, "Last update just be done, no update needed " );
74
75 # ---------- Testing BuildReport ----------------
76
77 #Test report->library -----------------
78 #mock to 0
79 t::lib::Mocks::mock_preference( "UsageStatsID",          0 );
80 t::lib::Mocks::mock_preference( "UsageStatsLibraryName", 0 );
81 t::lib::Mocks::mock_preference( "UsageStatsLibraryUrl",  0 );
82 t::lib::Mocks::mock_preference( "UsageStatsLibraryType", 0 );
83 t::lib::Mocks::mock_preference( "UsageStatsCountry",     0 );
84
85 my $report = C4::UsageStats->BuildReport();
86
87 isa_ok( $report,            'HASH', '$report is a HASH' );
88 isa_ok( $report->{library}, 'HASH', '$report->{library} is a HASH' );
89 is( scalar( keys %{$report->{library}} ), 5,  "There are 5 fields in $report->{library}" );
90 is( $report->{library}->{id},             0,  "UsageStatsID           is good" );
91 is( $report->{library}->{name},           '', "UsageStatsLibraryName  is good" );
92 is( $report->{library}->{url},            '', "UsageStatsLibraryUrl   is good" );
93 is( $report->{library}->{type},           '', "UsageStatsLibraryType  is good" );
94 is( $report->{library}->{country},        '', "UsageStatsCountry      is good" );
95
96 #mock with values
97 t::lib::Mocks::mock_preference( "UsageStatsID",          1 );
98 t::lib::Mocks::mock_preference( "UsageStatsLibraryName", 'NAME' );
99 t::lib::Mocks::mock_preference( "UsageStatsLibraryUrl",  'URL' );
100 t::lib::Mocks::mock_preference( "UsageStatsLibraryType", 'TYPE' );
101 t::lib::Mocks::mock_preference( "UsageStatsCountry",     'COUNTRY' );
102
103 $report = C4::UsageStats->BuildReport();
104
105 isa_ok( $report,            'HASH', '$report is a HASH' );
106 isa_ok( $report->{library}, 'HASH', '$report->{library} is a HASH' );
107 is( scalar( keys %{$report->{library}} ), 5,         "There are 5 fields in $report->{library}" );
108 is( $report->{library}->{id},             1,         "UsageStatsID            is good" );
109 is( $report->{library}->{name},           'NAME',    "UsageStatsLibraryName   is good" );
110 is( $report->{library}->{url},            'URL',     "UsageStatsLibraryUrl    is good" );
111 is( $report->{library}->{type},           'TYPE',    "UsageStatsLibraryType   is good" );
112 is( $report->{library}->{country},        'COUNTRY', "UsageStatsCountry       is good" );
113
114 #Test report->volumetry ---------------
115 #with original values
116 $report = C4::UsageStats->BuildReport();
117
118 isa_ok( $report,              'HASH', '$report is a HASH' );
119 isa_ok( $report->{volumetry}, 'HASH', '$report->{volumetry} is a HASH' );
120 is( scalar( keys %{$report->{volumetry}} ), 8, "There are 8 fields in $report->{volumetry}" );
121 is( $report->{volumetry}->{biblio},         0, "There is no biblio" );
122 is( $report->{volumetry}->{items},          0, "There is no items" );
123 is( $report->{volumetry}->{auth_header},    0, "There is no auth_header" );
124 is( $report->{volumetry}->{old_issues},     0, "There is no old_issues" );
125 is( $report->{volumetry}->{old_reserves},   0, "There is no old_reserves" );
126 is( $report->{volumetry}->{borrowers},      0, "There is no borrowers" );
127 is( $report->{volumetry}->{aqorders},       0, "There is no aqorders" );
128 is( $report->{volumetry}->{subscription},   0, "There is no subscription" );
129
130 #after adding objects
131 construct_objects_needed();
132
133 $report = C4::UsageStats->BuildReport();
134
135 isa_ok( $report,              'HASH', '$report is a HASH' );
136 isa_ok( $report->{volumetry}, 'HASH', '$report->{volumetry} is a HASH' );
137 is( scalar( keys %{$report->{volumetry}} ), 8, "There are 8 fields in $report->{volumetry}" );
138 is( $report->{volumetry}->{biblio},         3, "There are 3 biblio" );
139 is( $report->{volumetry}->{items},          3, "There are 3 items" );
140 is( $report->{volumetry}->{auth_header},    2, "There are 2 auth_header" );
141 is( $report->{volumetry}->{old_issues},     1, "There is  1 old_issues" );
142 is( $report->{volumetry}->{old_reserves},   1, "There is  1 old_reserves" );
143 is( $report->{volumetry}->{borrowers},      3, "There are 3 borrowers" );
144 is( $report->{volumetry}->{aqorders},       1, "There is  1 aqorders" );
145 is( $report->{volumetry}->{subscription},   1, "There is  1 subscription" );
146
147 #Test report->systempreferences -------
148 #mock to 0
149 mocking_systempreferences_to_a_set_value(0);
150
151 $report = C4::UsageStats->BuildReport();
152 isa_ok( $report,                      'HASH', '$report is a HASH' );
153 isa_ok( $report->{systempreferences}, 'HASH', '$report->{systempreferences} is a HASH' );
154 verif_systempreferences_values( $report, 0 );
155
156 #mock with values
157 mocking_systempreferences_to_a_set_value(1);
158
159 $report = C4::UsageStats->BuildReport();
160 isa_ok( $report,                      'HASH', '$report is a HASH' );
161 isa_ok( $report->{systempreferences}, 'HASH', '$report->{systempreferences} is a HASH' );
162 verif_systempreferences_values( $report, 1 );
163
164 #Test if unwanted syspref are not sent
165 is( $report->{systempreferences}->{useDischarge}, undef, 'useDischarge should not be shared');
166 is( $report->{systempreferences}->{OpacUserJS},   undef, 'OpacUserJS   should not be shared');
167
168 # ---------- Testing ReportToCommunity ----------
169
170 # ---------- Testing _count ---------------------
171 my $query = '
172   SELECT count(*)
173   FROM   borrowers
174   ';
175 my $count = $dbh->selectrow_array($query);
176
177 my $nb_fields = C4::UsageStats::_count('borrowers');
178 is( $nb_fields, $count, "_count return the good number of fields" );
179
180 #################################################
181 #             Subs
182 #################################################
183
184 # Adding :
185 # 3 borrowers
186 # 4 biblio
187 # 3 biblio items
188 # 3 items
189 # 2 auth_header
190 # 1 old_issues
191 # 1 old_reserves
192 # 1 subscription
193 # 1 aqorders
194 sub construct_objects_needed {
195
196     # ---------- 3 borrowers  ---------------------
197     my $surname1     = 'Borrower 1';
198     my $surname2     = 'Borrower 2';
199     my $surname3     = 'Borrower 3';
200     my $firstname1   = 'firstname 1';
201     my $firstname2   = 'firstname 2';
202     my $firstname3   = 'firstname 3';
203     my $cardnumber1  = 'test_card1';
204     my $cardnumber2  = 'test_card2';
205     my $cardnumber3  = 'test_card3';
206     my $categorycode = Koha::Database->new()->schema()->resultset('Category')->first()->categorycode();
207     my $branchcode   = Koha::Database->new()->schema()->resultset('Branch')->first()->branchcode();
208
209     my $query = '
210     INSERT INTO borrowers
211       (surname, firstname, cardnumber, branchcode, categorycode)
212     VALUES (?,?,?,?,?)';
213     my $insert_sth = $dbh->prepare($query);
214     $insert_sth->execute( $surname1, $firstname1, $cardnumber1, $branchcode, $categorycode );
215     my $borrowernumber1 = $dbh->last_insert_id( undef, undef, 'borrowers', undef );
216     $insert_sth->execute( $surname2, $firstname2, $cardnumber2, $branchcode, $categorycode );
217     my $borrowernumber2 = $dbh->last_insert_id( undef, undef, 'borrowers', undef );
218     $insert_sth->execute( $surname3, $firstname3, $cardnumber3, $branchcode, $categorycode );
219     my $borrowernumber3 = $dbh->last_insert_id( undef, undef, 'borrowers', undef );
220
221     # ---------- 3 biblios -----------------------
222     my $title1  = 'Title 1';
223     my $title2  = 'Title 2';
224     my $title3  = 'Title 3';
225     my $author1 = 'Author 1';
226     my $author2 = 'Author 2';
227     my $author3 = 'Author 3';
228
229     $query = '
230     INSERT INTO biblio
231       (title, author)
232     VALUES (?,?)';
233     $insert_sth = $dbh->prepare($query);
234     $insert_sth->execute( $title1, $author1 );
235     my $biblionumber1 = $dbh->last_insert_id( undef, undef, 'biblio', undef );
236     $insert_sth->execute( $title2, undef );
237     my $biblionumber2 = $dbh->last_insert_id( undef, undef, 'biblio', undef );
238     $insert_sth->execute( $title3, $author3 );
239     my $biblionumber3 = $dbh->last_insert_id( undef, undef, 'biblio', undef );
240
241     # ---------- 3 biblio items  -------------------------
242     $query = '
243     INSERT INTO biblioitems
244       (biblionumber, itemtype, marcxml)
245     VALUES (?,?,?)';
246     $insert_sth = $dbh->prepare($query);
247     $insert_sth->execute( $biblionumber1, 'Book', '' );
248     my $biblioitemnumber1 = $dbh->last_insert_id( undef, undef, 'biblioitems', undef );
249     $insert_sth->execute( $biblionumber2, 'Music', '' );
250     my $biblioitemnumber2 = $dbh->last_insert_id( undef, undef, 'biblioitems', undef );
251     $insert_sth->execute( $biblionumber3, 'Book', '' );
252     my $biblioitemnumber3 = $dbh->last_insert_id( undef, undef, 'biblioitems', undef );
253
254     # ---------- 3 items  -------------------------
255     my $barcode1 = '111111';
256     my $barcode2 = '222222';
257     my $barcode3 = '333333';
258
259     $query = '
260     INSERT INTO items
261       (biblionumber, biblioitemnumber, barcode, itype)
262     VALUES (?,?,?,?)';
263     $insert_sth = $dbh->prepare($query);
264     $insert_sth->execute( $biblionumber1, $biblioitemnumber1, $barcode1, 'Book' );
265     my $item_number1 = $dbh->last_insert_id( undef, undef, 'items', undef );
266     $insert_sth->execute( $biblionumber2, $biblioitemnumber2, $barcode2, 'Music' );
267     my $item_number2 = $dbh->last_insert_id( undef, undef, 'items', undef );
268     $insert_sth->execute( $biblionumber3, $biblioitemnumber3, $barcode3, 'Book' );
269     my $item_number3 = $dbh->last_insert_id( undef, undef, 'items', undef );
270
271     # ---------- Add 2 auth_header
272     $query = '
273     INSERT INTO auth_header
274       (authtypecode)
275     VALUES (?)';
276     $insert_sth = $dbh->prepare($query);
277     $insert_sth->execute('authtypecode1');
278     my $authid1 = $dbh->last_insert_id( undef, undef, 'auth_header', undef );
279     $insert_sth->execute('authtypecode2');
280     my $authid2 = $dbh->last_insert_id( undef, undef, 'auth_header', undef );
281
282     # ---------- Add 1 old_issues
283     $query = '
284     INSERT INTO old_issues
285       (borrowernumber, branchcode, itemnumber)
286     VALUES (?,?,?)';
287     $insert_sth = $dbh->prepare($query);
288     $insert_sth->execute( $borrowernumber1, $branchcode, $item_number1 );
289     my $issue_id1 = $dbh->last_insert_id( undef, undef, 'old_issues', undef );
290
291     # ---------- Add 1 old_reserves
292     AddReserve( $branchcode, $borrowernumber1, $biblionumber1, '', 1, undef, undef, '', 'Title', undef, undef );
293     my $reserves1   = GetReservesFromBiblionumber( { biblionumber => $biblionumber1 } );
294     my $reserve_id1 = $reserves1->[0]->{reserve_id};
295     my $reserve1    = CancelReserve( { reserve_id => $reserve_id1 } );
296
297     # ---------- Add 1 aqbudgets
298     $query = '
299     INSERT INTO aqbudgets
300       (budget_amount)
301     VALUES (?)';
302     $insert_sth = $dbh->prepare($query);
303     $insert_sth->execute("20.0");
304     my $aqbudgets1 = $dbh->last_insert_id( undef, undef, 'aqbudgets', undef );
305
306     # ---------- Add 1 aqorders
307     $query = '
308     INSERT INTO aqorders
309       (budget_id, basketno, biblionumber, invoiceid, subscriptionid)
310     VALUES (?,?,?,?,?)';
311     $insert_sth = $dbh->prepare($query);
312     $insert_sth->execute( $aqbudgets1, undef, undef, undef, undef );
313     my $aqorders1 = $dbh->last_insert_id( undef, undef, 'aqorders', undef );
314
315     # --------- Add 1 subscription
316     $query = '
317     INSERT INTO subscription
318       (biblionumber)
319     VALUES (?)';
320     $insert_sth = $dbh->prepare($query);
321     $insert_sth->execute($biblionumber1);
322     my $subscription1 = $dbh->last_insert_id( undef, undef, 'subscription', undef );
323
324 }
325
326 #Change systempreferences values to $set_value
327 sub mocking_systempreferences_to_a_set_value {
328     my $set_value = shift;
329
330     foreach (
331         qw/
332         AcqCreateItem
333         AcqWarnOnDuplicateInvoice
334         AcqViewBaskets
335         BasketConfirmations
336         OrderPdfFormat
337         casAuthentication
338         casLogout
339         AllowPKIAuth
340         DebugLevel
341         delimiter
342         noItemTypeImages
343         virtualshelves
344         AutoLocation
345         IndependentBranches
346         SessionStorage
347         Persona
348         AuthDisplayHierarchy
349         AutoCreateAuthorities
350         BiblioAddsAuthorities
351         dontmerge
352         UseAuthoritiesForTracings
353         CatalogModuleRelink
354         hide_marc
355         IntranetBiblioDefaultView
356         LabelMARCView
357         OpacSuppression
358         SeparateHoldings
359         UseControlNumber
360         advancedMARCeditor
361         DefaultClassificationSource
362         EasyAnalyticalRecords
363         autoBarcode
364         item-level_itypes
365         marcflavour
366         PrefillItem
367         z3950NormalizeAuthor
368         SpineLabelAutoPrint
369         SpineLabelShowPrintOnBibDetails
370         BlockReturnOfWithdrawnItems
371         CalculateFinesOnReturn
372         AgeRestrictionOverride
373         AllFinesNeedOverride
374         AllowFineOverride
375         AllowItemsOnHoldCheckout
376         AllowItemsOnHoldCheckoutSCO
377         AllowNotForLoanOverride
378         AllowRenewalLimitOverride
379         AllowReturnToBranch
380         AllowTooManyOverride
381         AutomaticItemReturn
382         AutoRemoveOverduesRestrictions
383         CircControl
384         HomeOrHoldingBranch
385         HomeOrHoldingBranchReturn
386         InProcessingToShelvingCart
387         IssueLostItem
388         IssuingInProcess
389         ManInvInNoissuesCharge
390         OverduesBlockCirc
391         RenewalPeriodBase
392         RenewalSendNotice
393         RentalsInNoissuesCharge
394         ReturnBeforeExpiry
395         ReturnToShelvingCart
396         TransfersMaxDaysWarning
397         UseBranchTransferLimits
398         useDaysMode
399         UseTransportCostMatrix
400         UseCourseReserves
401         finesCalendar
402         FinesIncludeGracePeriod
403         finesMode
404         RefundLostOnReturnControl
405         WhenLostChargeReplacementFee
406         WhenLostForgiveFine
407         AllowHoldDateInFuture
408         AllowHoldPolicyOverride
409         AllowHoldsOnDamagedItems
410         AllowHoldsOnPatronsPossessions
411         AutoResumeSuspendedHolds
412         canreservefromotherbranches
413         decreaseLoanHighHolds
414         DisplayMultiPlaceHold
415         emailLibrarianWhenHoldIsPlaced
416         ExpireReservesMaxPickUpDelay
417         OPACAllowHoldDateInFuture
418         OPACAllowUserToChooseBranch
419         ReservesControlBranch
420         ReservesNeedReturns
421         SuspendHoldsIntranet
422         SuspendHoldsOpac
423         TransferWhenCancelAllWaitingHolds
424         AllowAllMessageDeletion
425         AllowOfflineCirculation
426         CircAutocompl
427         CircAutoPrintQuickSlip
428         DisplayClearScreenButton
429         FilterBeforeOverdueReport
430         FineNotifyAtCheckin
431         itemBarcodeFallbackSearch
432         itemBarcodeInputFilter
433         previousIssuesDefaultSortOrder
434         RecordLocalUseOnReturn
435         soundon
436         SpecifyDueDate
437         todaysIssuesDefaultSortOrder
438         UpdateTotalIssuesOnCirc
439         UseTablesortForCirc
440         WaitingNotifyAtCheckin
441         AllowSelfCheckReturns
442         AutoSelfCheckAllowed
443         FRBRizeEditions
444         OPACFRBRizeEditions
445         AmazonCoverImages
446         OPACAmazonCoverImages
447         Babeltheque
448         BakerTaylorEnabled
449         GoogleJackets
450         HTML5MediaEnabled
451         IDreamBooksReadometer
452         IDreamBooksResults
453         IDreamBooksReviews
454         LibraryThingForLibrariesEnabled
455         LocalCoverImages
456         OPACLocalCoverImages
457         NovelistSelectEnabled
458         XISBN
459         OpenLibraryCovers
460         OpenLibrarySearch
461         UseKohaPlugins
462         SyndeticsEnabled
463         TagsEnabled
464         CalendarFirstDayOfWeek
465         opaclanguagesdisplay
466         AuthoritiesLog
467         BorrowersLog
468         CataloguingLog
469         FinesLog
470         IssueLog
471         LetterLog
472         ReturnLog
473         SubscriptionLog
474         BiblioDefaultView
475         COinSinOPACResults
476         DisplayOPACiconsXSLT
477         hidelostitems
478         HighlightOwnItemsOnOPAC
479         OpacAddMastheadLibraryPulldown
480         OPACDisplay856uAsImage
481         OpacHighlightedWords
482         OpacKohaUrl
483         OpacMaintenance
484         OpacPublic
485         OpacSeparateHoldings
486         OPACShowBarcode
487         OPACShowCheckoutName
488         OpacShowFiltersPulldownMobile
489         OPACShowHoldQueueDetails
490         OpacShowLibrariesPulldownMobile
491         OpacShowRecentComments
492         OPACShowUnusedAuthorities
493         OpacStarRatings
494         opacthemes
495         OPACURLOpenInNewWindow
496         OpacAuthorities
497         opacbookbag
498         OpacBrowser
499         OpacBrowseResults
500         OpacCloud
501         OPACFinesTab
502         OpacHoldNotes
503         OpacItemLocation
504         OpacPasswordChange
505         OPACPatronDetails
506         OPACpatronimages
507         OPACPopupAuthorsSearch
508         OpacTopissue
509         opacuserlogin
510         QuoteOfTheDay
511         RequestOnOpac
512         reviewson
513         ShowReviewer
514         ShowReviewerPhoto
515         SocialNetworks
516         suggestion
517         AllowPurchaseSuggestionBranchChoice
518         OpacAllowPublicListCreation
519         OpacAllowSharingPrivateLists
520         OpacRenewalAllowed
521         OpacRenewalBranch
522         OPACViewOthersSuggestions
523         SearchMyLibraryFirst
524         singleBranchMode
525         AnonSuggestions
526         EnableOpacSearchHistory
527         OPACPrivacy
528         opacreadinghistory
529         TrackClicks
530         PatronSelfRegistration
531         OPACShelfBrowser
532         AutoEmailOpacUser
533         AutoEmailPrimaryAddress
534         autoMemberNum
535         BorrowerRenewalPeriodBase
536         checkdigit
537         EnableBorrowerFiles
538         EnhancedMessagingPreferences
539         ExtendedPatronAttributes
540         intranetreadinghistory
541         memberofinstitution
542         patronimages
543         TalkingTechItivaPhoneNotification
544         uppercasesurnames
545         IncludeSeeFromInSearches
546         OpacGroupResults
547         QueryAutoTruncate
548         QueryFuzzy
549         QueryStemming
550         QueryWeightFields
551         TraceCompleteSubfields
552         TraceSubjectSubdivisions
553         UseICU
554         UseQueryParser
555         defaultSortField
556         displayFacetCount
557         OPACdefaultSortField
558         OPACItemsResultsDisplay
559         expandedSearchOption
560         IntranetNumbersPreferPhrase
561         OPACNumbersPreferPhrase
562         opacSerialDefaultTab
563         RenewSerialAddsSuggestion
564         RoutingListAddReserves
565         RoutingSerials
566         SubscriptionHistory
567         Display856uAsImage
568         DisplayIconsXSLT
569         template
570         yuipath
571         HidePatronName
572         intranetbookbag
573         StaffDetailItemSelection
574         viewISBD
575         viewLabeledMARC
576         viewMARC
577         ILS-DI
578         OAI-PMH
579         version
580         AudioAlerts
581         /
582       ) {
583         t::lib::Mocks::mock_preference( $_, $set_value );
584     }
585 }
586
587 #Test if all systempreferences are at $value_to_test
588 sub verif_systempreferences_values {
589     my ( $report, $value_to_test ) = @_;
590
591     my @missings;
592     foreach my $key ( keys %{$report->{systempreferences}} ) {
593         if ( $report->{systempreferences}->{$key} ne $value_to_test ) {
594             warn $key;
595             push @missings, $key;
596         }
597     }
598     unless ( @missings ) {
599         ok(1, 'All prefs are present');
600     } else {
601         ok(0, 'Some prefs are missing: ' . Dumper(\@missings));
602     }
603 }
604
605 $dbh->rollback;