(ns auto-ap.integration.rule-matching (:require [auto-ap.integration.util :refer [wrap-setup]] [auto-ap.rule-matching :as sut] [clojure.test :as t])) (t/use-fixtures :each wrap-setup) (def base-transaction #:transaction {:amount -12.0 :date #inst "2014-01-02T08:00:00.000-00:00" :bank-account 456 :client 123 :post-date #inst "2014-01-04T08:00:00.000-00:00" :account-id 1234 :description-original "original-description" :status "POSTED" :id "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b" :raw-id "1" :approval-status :transaction-approval-status/unapproved :description-simple "simple-description"}) (t/deftest rule-applying-fn (t/testing "Should apply if description matches" (t/is (sut/rule-applies? base-transaction {:transaction-rule/description #"original-description" :transaction-rule/transaction-approval-status :transaction-approval-status/approved})) (t/is (not (sut/rule-applies? base-transaction {:transaction-rule/description #"xxx" :transaction-rule/transaction-approval-status :transaction-approval-status/approved})))) (t/testing "Should do nothing if there are no rules" (let [process (sut/rule-applying-fn [])] (t/is (= base-transaction (process base-transaction ["NG"]))))) (t/testing "Should approve a simple rule" (let [process (sut/rule-applying-fn [{:transaction-rule/description "simple-description" :transaction-rule/transaction-approval-status :transaction-approval-status/approved}]) transaction (assoc base-transaction :transaction/description-original "simple-description")] (t/is (= :transaction-approval-status/approved (:transaction/approval-status (process transaction ["NG"])))))) (t/testing "spread cents" (t/testing "Should split evenly" (t/is (= [50 50] (sut/spread-cents 100 2))) (t/is (= [50 49] (sut/spread-cents 99 2))) (t/is (= [34 33 33] (sut/spread-cents 100 3))) (t/is (= [100] (sut/spread-cents 100 1))) (t/is (= [2 2] (sut/spread-cents 4 2))) (t/is (= [2 1 1] (sut/spread-cents 4 3))) (t/is (= [2 2 1] (sut/spread-cents 5 3))) (t/is (= [2 1 1 1] (sut/spread-cents 5 4))) (t/is (= [3 2 2] (sut/spread-cents 7 3))) (t/is (= [2 2 2 1] (sut/spread-cents 7 4))) (t/is (= [2 1] (sut/spread-cents 3 2))) (t/is (= [1 1 1] (sut/spread-cents 3 4))) (doseq [x (range 20)] (t/is (= 11323 (reduce + 0 (sut/spread-cents 11323 (inc x)))))))) (t/testing "Should spread across locations" (let [process (sut/rule-applying-fn [{:transaction-rule/description "simple-description" :transaction-rule/accounts [{:transaction-rule-account/location "Shared" :transaction-rule-account/account {:account/numeric-code 2500} :transaction-rule-account/percentage 1.0}] :transaction-rule/transaction-approval-status :transaction-approval-status/approved}]) transaction (assoc base-transaction :transaction/description-original "simple-description" :transaction/amount 1.0)] (t/is (= [1.0] (map :transaction-account/amount (:transaction/accounts (process transaction ["NG"]))))) (t/is (= [0.5 0.5] (map :transaction-account/amount (:transaction/accounts (process transaction ["NG" "BT"]))))) (t/is (= [0.34 0.33 0.33] (map :transaction-account/amount (:transaction/accounts (process transaction ["NG" "BT" "DE"]))))) (t/is (= [0.01 0.01] (map :transaction-account/amount (:transaction/accounts (process (assoc transaction :transaction/amount 0.02) ["NG" "BT" "DE"]))))) (t/is (= [0.02 0.01 0.01] (map :transaction-account/amount (:transaction/accounts (process (assoc transaction :transaction/amount 0.04) ["NG" "BT" "DE"]))))) )))