From: Jason Boyer Date: Wed, 22 Sep 2021 13:03:01 +0000 (-0400) Subject: Some basic pgtap tests X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=1403eea62aa10ec81e161adc6d0cbe521f35b5cf;p=working%2FEvergreen.git Some basic pgtap tests Signed-off-by: Jason Boyer --- diff --git a/Open-ILS/src/sql/Pg/t/lp1174498-mmpbt-verification.pg b/Open-ILS/src/sql/Pg/t/lp1174498-mmpbt-verification.pg new file mode 100644 index 0000000000..0251a46152 --- /dev/null +++ b/Open-ILS/src/sql/Pg/t/lp1174498-mmpbt-verification.pg @@ -0,0 +1,291 @@ +-- Make sure that money.materialized_payment_by_billing_type can handle what's thrown at it + +\set mmpbt materialized_payment_by_billing_type +\set mbxs materialized_billable_xact_summary + +\set patron 109 +\set staff 223 + + +-- convenince funcs + +CREATE OR REPLACE FUNCTION fake_it_make_it(id BIGINT, patron BIGINT, staff BIGINT, copy BIGINT) RETURNS BOOLEAN +AS $$ + + INSERT INTO action.circulation + (id, usr, xact_start, xact_finish, target_copy, circ_lib, circ_staff, renewal_remaining, + grace_period, due_date, duration_rule, recurring_fine_rule, max_fine_rule) + VALUES + (id, patron, (now() - '4 weeks'::interval), null, copy, 5, staff, 0, + '1 day', (now() - '3 weeks'::interval), 1, 1, 1); + + SELECT TRUE; + +$$ LANGUAGE SQL; + + +CREATE OR REPLACE FUNCTION u_owe_me(xact BIGINT, days_ago INT, amount NUMERIC(6,2)) RETURNS BOOLEAN +AS $$ + + INSERT INTO money.billing + (xact, billing_ts, amount, billing_type, btype) + VALUES + (xact, (now() - (days_ago::TEXT || ' days')::interval), COALESCE(amount, 0.25), 'srsly', 1); + + SELECT TRUE; + +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION spray_bills(xact BIGINT, num_bills INT, amount NUMERIC(6,2)) RETURNS BOOLEAN +AS $$ +BEGIN + LOOP + PERFORM u_owe_me(xact, num_bills, amount); + num_bills := num_bills -1; + EXIT WHEN num_bills = 0; + END LOOP; + + RETURN TRUE; + +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION un_atm(xact BIGINT, days_ago INT, type TEXT, amount NUMERIC(6,2)) RETURNS BOOLEAN +AS $$ +BEGIN + + amount := COALESCE(amount, 0.25); + + EXECUTE $E$INSERT INTO money.$E$ || type || $E$ (xact, payment_ts, amount_collected, amount, accepting_usr) $E$ || + $E$VALUES ($E$ || xact || $E$, (now() - '$E$ || days_ago::TEXT || $E$ days'::interval), $E$ || amount || $E$, $E$ || amount || $E$, 1)$E$; + + RETURN TRUE; + +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION make_it_rain(xact BIGINT, num_pays INT, type TEXT, amount NUMERIC(6,2)) RETURNS BOOLEAN +AS $$ +BEGIN + + LOOP + PERFORM un_atm(xact, num_pays, type, amount); + num_pays := num_pays -1; + EXIT WHEN num_pays = 0; + END LOOP; + + RETURN TRUE; + +END; +$$ LANGUAGE plpgsql; + + + +-- pgTAP Time + +BEGIN; + +SELECT * FROM no_plan(); +-- SELECT plan(); -- come back to this... + +-- Scenario setup + +-- no billing, no payment, no problem + +\set id -1000 +\set copy 401 + +SELECT fake_it_make_it(:id, :patron, :staff, :copy); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 0, 'No billings, no payments, no mmpbt'); + +-- 1 billing, no payment + +\set id -1001 +\set copy 408 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT u_owe_me(:id, 21); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 0, 'No payment, no mmpbt'); + + +-- 1 bill, 1 complete payment + +\set id -1002 +\set copy 415 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT u_owe_me(:id, 21); +SELECT un_atm(:id, 21, 'cash_payment', NULL); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 1, '1 payment, 1 entry'); + + +-- 1 bill 1 partial paynent + +\set id -1003 +\set copy 422 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT u_owe_me(:id, 21); +SELECT un_atm(:id, 21, 'cash_payment', 0.15); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 1, '1 partial payment, 1 entry'); +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id AND amount = 0.15)::INTEGER, 1, '... for the right amount'); + + +-- 1 bill, multiple payments, complete + +\set id -1004 +\set copy 429 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT u_owe_me(:id, 21); +SELECT un_atm(:id, 21, 'cash_payment', 0.15); +SELECT un_atm(:id, 20, 'cash_payment', 0.10); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 2, '1 partial payment, 1 entry'); +SELECT is( (SELECT sum(amount) FROM money.:"mmpbt" WHERE xact = :id ), 0.25, '... for the right amount'); + +-- 2 bills, 1 payment, complete + +\set id -1005 +\set copy 436 + +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT spray_bills(:id, 2, NULL); +SELECT un_atm(:id, 21, 'cash_payment', 0.50); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 2, '2 bills, 1 complete payment'); +SELECT ok( (SELECT total_paid FROM money.:"mbxs" WHERE id = :id) = + (SELECT SUM(amount) FROM money.:"mmpbt" WHERE xact = :id), 'correct amounts'); + +-- 2 bills, 3 payments, partial +-- bill 1, payment 1, .25 +-- bill 1, payment 2, .25 +-- bill 2, payment 2, .05 +-- bill 2, payment 3, .20 + +\set id -1006 +\set copy 443 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT spray_bills(:id, 2, 0.50); -- $1 +SELECT un_atm(:id, 21, 'cash_payment', 0.25); +SELECT un_atm(:id, 20, 'cash_payment', 0.30); +SELECT un_atm(:id, 19, 'cash_payment', 0.20); -- $.75, spread across 4 entries + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 4, '2 bills, 2 partial payments spread across them'); +SELECT ok( (SELECT total_paid FROM money.:"mbxs" WHERE id = :id) = + (SELECT SUM(amount) FROM money.:"mmpbt" WHERE xact = :id), 'correct amounts'); + +-- 2 bills, 1 void, 1 paid in full + +\set id -1007 +\set copy 450 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT spray_bills(:id, 2, NULL); -- $.50 +UPDATE money.billing SET voided = TRUE, voider = 1, void_time = now() WHERE xact = :id AND + id IN (SELECT MIN(id) FROM money.billing WHERE xact = :id LIMIT 1); +SELECT un_atm(:id, 21, 'cash_payment', NULL); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 1, '1 unvoided bill, 1 full payment'); +SELECT ok( (SELECT total_paid FROM money.:"mbxs" WHERE id = :id) = + (SELECT SUM(amount) FROM money.:"mmpbt" WHERE xact = :id), 'correct amount'); + +-- 2 bills, 1 voided, 1 adjusted + +\set id -1008 +\set copy 457 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT spray_bills(:id, 2, NULL); -- $.50 +UPDATE money.billing SET voided = TRUE, voider = 1 WHERE xact = :id AND id IN (SELECT MIN(id) FROM money.billing WHERE xact = :id LIMIT 1); +SELECT un_atm(:id, 21, 'account_adjustment', NULL); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 1, '1 unvoided bill, 1 adjusted payment'); +SELECT ok( (SELECT total_paid FROM money.:"mbxs" WHERE id = :id) = + (SELECT SUM(amount) FROM money.:"mmpbt" WHERE xact = :id), 'correct amount'); + + + +-- a simplification of a real transaction that caused problems in the past +-- 45 voided billings of various sizes, 2 non-voided billings for 32.20, +-- 38 account_adjustments for .25 amount, 1 for 22.70, and 1 forgive_payment for 32.20 + +\set id -1009 +\set copy 471 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT spray_bills(:id, 20, NULL); +SELECT spray_bills(:id, 20, NULL); +SELECT u_owe_me(:id, 6, 15.00); +SELECT u_owe_me(:id, 5, 17.20); +SELECT u_owe_me(:id, 4, 9.50); +SELECT u_owe_me(:id, 3, 32.20); +SELECT u_owe_me(:id, 3, 6.00); +UPDATE money.billing SET voided = TRUE, voider = 1, void_time = now() WHERE xact = :id; +SELECT u_owe_me(:id, 1, 32.20); +SELECT u_owe_me(:id, 1, 32.20); + +SELECT make_it_rain(:id, 20, 'account_adjustment', 0.25); +SELECT make_it_rain(:id, 18, 'account_adjustment', 0.25); +SELECT un_atm(:id, 1, 'account_adjustment', 22.70); +SELECT un_atm(:id, 1, 'forgive_payment', 32.20); + +SELECT is( (SELECT COUNT(DISTINCT billing) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 2, 'Simplified real transaction bills'); +SELECT is( (SELECT COUNT(DISTINCT payment) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 40, 'Simplified real transaction payments'); +SELECT ok( (SELECT total_paid FROM money.:"mbxs" WHERE id = :id) = + (SELECT SUM(amount) FROM money.:"mmpbt" WHERE xact = :id), 'correct amount'); + +-- DEBUGGERY +\o mmpbt_out +\t +\a +SELECT * FROM money.:"mmpbt" WHERE xact = :id; +SELECT ''; +SELECT * FROM money.billing WHERE xact = :id; +SELECT ''; +SELECT * FROM money.bnm_payment_view WHERE xact = :id; +\a +\t +\o + + +-- BANANAS +-- You can't realistically cause some of these situations in the client, +-- but they're still no reason for things to break. + +-- 0 bills, mystery payment + +\set id -1010 +\set copy 478 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT un_atm(:id, 21, 'cash_payment', NULL); + +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 0, '0 bills, 1 unexpected payment'); + +-- 1 bill, 1 extra large payment + +\set id -1011 +\set copy 485 +SELECT fake_it_make_it(:id, :patron, :staff, :copy); +SELECT u_owe_me(:id, 21, 0.50); +SELECT un_atm(:id, 21, 'cash_payment', 0.75); +SELECT is( (SELECT COUNT(id) FROM money.:"mmpbt" WHERE xact = :id)::INTEGER, 1, '1 bill, too large payment'); +SELECT ok( (SELECT total_owed FROM money.:"mbxs" WHERE id = :id) = -- Note you can't use total_paid here, because it's busted, remember? + (SELECT SUM(amount) FROM money.:"mmpbt" WHERE xact = :id), 'correct amount'); + + + + + + + + + + +SELECT * FROM finish(); +ROLLBACK; + +-- cleanup +DROP FUNCTION fake_it_make_it(BIGINT, BIGINT, BIGINT, BIGINT); +DROP FUNCTION u_owe_me(BIGINT, INT, NUMERIC(6,2)); +DROP FUNCTION spray_bills(BIGINT, INT, NUMERIC(6,2)); +DROP FUNCTION un_atm(BIGINT, INT, TEXT, NUMERIC(6,2)); +DROP FUNCTION make_it_rain(BIGINT, INT, TEXT, NUMERIC(6,2)); +