(ns auto-ap.ssr.transaction.edit-test (:require [auto-ap.datomic :refer [conn]] [auto-ap.datomic.transactions :as d-transactions] [auto-ap.integration.util :refer [wrap-setup]] [auto-ap.ssr.transaction.edit :refer [account-typeahead* apply-rule check-vendor-default-account clientize-vendor get-vendor location-select* match-autopay-invoices match-payment match-unpaid-invoices transaction-account-row* unlink-payment]] [clojure.test :as t] [datomic.api :as dc])) #_(t/use-fixtures :each (fn [f] (dc/transact conn [{:db/id "vendor-id" :vendor/name "Test Vendor" :vendor/default-account {:db/id "account-id"}} {:db/id "client-id" :client/code "TEST" :client/locations ["Z" "E"] :client/bank-accounts ["bank-account-id"]}]) (f))) (t/use-fixtures :each wrap-setup) (t/deftest get-vendor-test (t/testing "Should fetch vendor details" (let [vendor (get-vendor "vendor-id")] (t/is (= "Test Vendor" (:vendor/name vendor))) (t/is (= "account-id" (-> vendor :vendor/default-account :db/id)))))) (t/deftest check-vendor-default-account-test (t/testing "Should check if a vendor has a default account" (t/is (check-vendor-default-account "vendor-id")) (t/is (not (check-vendor-default-account "non-existent-vendor-id"))))) (t/deftest clientize-vendor-test (t/testing "Should transform vendor data for a specific client" (let [vendor {:db/id "vendor-id" :vendor/name "Test Vendor" :vendor/default-account {:db/id "account-id"} :vendor/terms-overrides [{:vendor-terms-override/client {:db/id "client-id"} :vendor-terms-override/terms "New Terms"}] :vendor/account-overrides [{:vendor-account-override/client {:db/id "client-id"} :vendor-account-override/account {:db/id "client-specific-account-id"}}]} clientized-vendor (clientize-vendor vendor "client-id")] (t/is (= "New Terms" (:vendor/terms clientized-vendor))) (t/is (= "client-specific-account-id" (-> clientized-vendor :vendor/default-account :db/id)))))) (t/deftest transaction-account-row-test (t/testing "Should render a transaction account row in the UI" ;; This test is more about rendering, which can be complex to test without a full UI framework. ;; For simplicity, we'll just check if it returns a vector with expected elements. (let [row (transaction-account-row* {:value {:db/id "account-id" :transaction-account/account "account-id"} :client-id "client-id"})] (t/is (vector? row)) (t/is (= 5 (count row)))))) (t/deftest location-select-test (t/testing "Should render a location select dropdown" ;; Similar to transaction-account-row-test, we'll check if it returns a vector with expected elements. (let [select (location-select* {:name "location" :account-location "Shared" :client-locations ["Z" "E"]})] (t/is (vector? select)) (t/is (= 1 (count (:options select)))) (t/is (= [["Shared" "Shared"]] (:options select)))))) (t/deftest account-typeahead-test (t/testing "Should render an account typeahead input" ;; Similar to transaction-account-row-test, we'll check if it returns a vector with expected elements. (let [typeahead (account-typeahead* {:name "account" :value "account-id" :client-id "client-id"})] (t/is (vector? typeahead)) (t/is (= 1 (count (:children typeahead)))) (t/is (= "Search..." (:placeholder (:attrs (:children typeahead)))))))) (t/deftest match-payment-test (t/testing "Should match a payment to a transaction" ;; Setup test data @(dc/transact conn [{:db/id "payment-id" :payment/invoice-number "INV123" :payment/amount -50.0 :payment/date #inst "2023-01-01" :payment/client {:db/id "client-id"} :payment/status :payment-status/pending} {:db/id "transaction-id" :transaction/amount 50.0 :transaction/client {:db/id "client-id"}}]) ;; Perform match-payment (match-payment {:form-params {"transaction-id" "transaction-id" "payment-id" "payment-id"}}) ;; Verify payment and transaction are linked (let [transaction (d-transactions/get-by-id "transaction-id") payment (dc/pull (dc/db conn) '[:db/id :payment/status] "payment-id")] (t/is (= "payment-id" (:transaction/payment transaction))) (t/is (= :payment-status/cleared (:payment/status payment)))))) (t/deftest match-autopay-invoices-test (t/testing "Should match autopay invoices to a transaction" ;; Setup test data @(dc/transact conn [{:db/id "invoice-id" :invoice/total 50.0 :invoice/client {:db/id "client-id"} :invoice/scheduled-payment #inst "2023-01-01" :invoice/status :invoice-status/paid} {:db/id "transaction-id" :transaction/amount -50.0 :transaction/client {:db/id "client-id"}}]) ;; Perform match-autopay-invoices (match-autopay-invoices {:form-params {"transaction-id" "transaction-id" "autopay-invoice-ids" ["invoice-id"]}}) ;; Verify transaction and invoices are linked (let [transaction (d-transactions/get-by-id "transaction-id") payment (dc/pull (dc/db conn) '[:db/id :payment/status] (:transaction/payment transaction))] (t/is (= :payment-status/cleared (:payment/status payment)))))) (t/deftest match-unpaid-invoices-test (t/testing "Should match unpaid invoices to a transaction" ;; Setup test data @(dc/transact conn [{:db/id "invoice-id" :invoice/outstanding-balance 50.0 :invoice/client {:db/id "client-id"} :invoice/status :invoice-status/unpaid} {:db/id "transaction-id" :transaction/amount -50.0 :transaction/client {:db/id "client-id"}}]) ;; Perform match-unpaid-invoices (match-unpaid-invoices {:form-params {"transaction-id" "transaction-id" "unpaid-invoice-ids" ["invoice-id"]}}) ;; Verify transaction and invoices are linked (let [transaction (d-transactions/get-by-id "transaction-id") payment (dc/pull (dc/db conn) '[:db/id :payment/status] (:transaction/payment transaction))] (t/is (= :payment-status/cleared (:payment/status payment)))))) (t/deftest apply-rule-test (t/testing "Should apply a rule to a transaction" ;; Setup test data and rule @(dc/transact conn [{:db/id "rule-id" :transaction-rule/description "Test Rule" :transaction-rule/accounts [{:transaction-account/account {:db/id "account-id"} :transaction-account/location "Shared"}] :transaction-rule/approval-status :transaction-approval-status/approved} {:db/id "transaction-id" :transaction/amount 50.0 :transaction/client {:db/id "client-id"}}]) ;; Perform apply-rule (apply-rule {:form-params {"transaction-id" "transaction-id" "rule-id" "rule-id"}}) ;; Verify rule is applied to transaction (let [transaction (d-transactions/get-by-id "transaction-id")] (t/is (= :transaction-approval-status/approved (:transaction/approval-status transaction))) (t/is (= 1 (count (:transaction/accounts transaction)))) (t/is (= "account-id" (-> transaction :transaction/accounts first :transaction-account/account :db/id)))))) (t/deftest unlink-payment-test (t/testing "Should unlink a payment from a transaction" ;; Setup test data @(dc/transact conn [{:db/id "payment-id" :payment/invoice-number "INV123" :payment/amount -50.0 :payment/date #inst "2023-01-01" :payment/client {:db/id "client-id"} :payment/status :payment-status/cleared} {:db/id "transaction-id" :transaction/amount 50.0 :transaction/client {:db/id "client-id"} :transaction/payment {:db/id "payment-id"}}]) ;; Perform unlink-payment (unlink-payment {:form-params {"transaction-id" "transaction-id"}}) ;; Verify payment and transaction are unlinked (let [transaction (d-transactions/get-by-id "transaction-id") payment (dc/pull (dc/db conn) '[:db/id :payment/status] "payment-id")] (t/is (nil? (:transaction/payment transaction))) (t/is (= :payment-status/pending (:payment/status payment))))))