Files
integreat/test/clj/auto_ap/ssr/admin/transaction_rules_test.clj

155 lines
7.8 KiB
Clojure

(ns auto-ap.ssr.admin.transaction-rules-test
(:require
[auto-ap.datomic :refer [conn]]
[auto-ap.integration.util :refer [admin-token
setup-test-data
wrap-setup]]
[auto-ap.ssr.admin.transaction-rules :as sut]
[clojure.test :refer [deftest is testing use-fixtures]]
[datomic.api :as dc]))
(use-fixtures :each wrap-setup)
(deftest rule-matching-by-description-pattern
(testing "Rule matching returns sequence for description pattern"
(let [tempids (setup-test-data [{:db/id "rule-1"
:transaction-rule/description "HOME DEPOT"
:transaction-rule/note "Home improvement"
:transaction-rule/amount-gte 50.0
:transaction-rule/amount-lte 500.0}])]
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/description "HOME DEPOT"}
:clients nil})]
(is (seq? matches))))))
(deftest rule-matching-returns-empty-for-no-matches
(testing "Rule matching returns empty sequence when no transactions match"
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/description "XYZ-NON-EXISTENT"}
:clients nil})]
(is (seq? matches))
(is (= 0 (count matches))))))
(deftest validate-transaction-rule-accepts-valid-data
(testing "Validation accepts valid data with 100% account allocation"
(let [form-params {:transaction-rule/description "Test Rule"
:transaction-rule/note "Test note"
:transaction-rule/amount-gte "100"
:transaction-rule/amount-lte "500"
:transaction-rule/accounts [{:transaction-rule-account/percentage 1.0}]}]
(is (nil? (sut/validate-transaction-rule form-params))))))
(deftest validate-transaction-rule-rejects-invalid-accounts-total
(testing "Validation rejects accounts that do not sum to 100%"
(let [form-params {:transaction-rule/description "Test Rule"
:transaction-rule/note "Test note"
:transaction-rule/accounts [{:transaction-rule-account/percentage 0.5}]}]
(is (thrown? Exception (sut/validate-transaction-rule form-params))))))
(deftest rule-matching-by-amount-range
(testing "Rule matching filters by amount range"
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/amount-gte 100.0
:transaction-rule/amount-lte 200.0}
:clients nil})]
(is (seq? matches)))))
(deftest rule-matching-by-bank-account
(testing "Rule matching filters by bank account"
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/bank-account 12345}
:clients nil})]
(is (seq? matches)))))
(deftest page-route-returns-html-response
(testing "Page route returns HTML response"
(let [request {:identity (admin-token)}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/page) request)]
(is (= 200 (:status response)))
(is (string? (apply str (:body response)))))))
(deftest table-route-returns-table-data
(testing "Table route returns table data for HTMX"
(setup-test-data [{:db/id "rule-1"
:transaction-rule/description "Test Rule"
:transaction-rule/note "Test note"}])
(let [request {:identity (admin-token)
:query-params {:page 1 :per-page 10}}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/table) request)]
(is (= 200 (:status response))))))
(deftest delete-route-deletes-rule
(testing "Delete route removes transaction rule from database"
(let [tempids (setup-test-data [{:db/id "rule-to-delete"
:transaction-rule/description "Rule to Delete"
:transaction-rule/note "Will be deleted"}])
rule-id (get tempids "rule-to-delete")
request {:identity (admin-token)
:route-params {:db/id rule-id}}]
(is (= 1 (count (dc/q '[:find ?e
:where [?e :transaction-rule/description "Rule to Delete"]]
(dc/db conn)))))
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/delete) request)]
(is (= 200 (:status response)))
(is (= 0 (count (dc/q '[:find ?e
:where [?e :transaction-rule/description "Rule to Delete"]]
(dc/db conn)))))))))
(deftest check-badges-route-works
(testing "Check badges route returns badge status map"
(let [request {:identity (admin-token)
:query-params {}}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/check-badges) request)]
(is (map? response)))))
(deftest edit-dialog-route-returns-dialog
(testing "Edit dialog route returns HTML dialog for existing rule"
(let [tempids (setup-test-data [{:db/id "rule-to-edit"
:transaction-rule/description "Rule to Edit"
:transaction-rule/note "Edit me"}])
rule-id (get tempids "rule-to-edit")
request {:identity (admin-token)
:route-params {:db/id rule-id}}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/edit-dialog) request)]
(is (= 200 (:status response)))
(is (string? (apply str (:body response)))))))
(deftest account-typeahead-route-works
(testing "Account typeahead route returns account suggestions HTML"
(let [request {:identity (admin-token)
:query-params {:name "Test"}}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/account-typeahead) request)]
(is (= 200 (:status response)))
(is (string? (apply str (:body response)))))))
(deftest location-select-route-works
(testing "Location select route returns location selector HTML"
(let [request {:identity (admin-token)
:query-params {:name "location"}}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/location-select) request)]
(is (= 200 (:status response)))
(is (string? (apply str (:body response)))))))
(deftest execute-dialog-route-works
(testing "Execute dialog route returns execution dialog HTML"
(let [tempids (setup-test-data [{:db/id "rule-to-execute"
:transaction-rule/description "Rule to Execute"
:transaction-rule/note "Execute me"}])
rule-id (get tempids "rule-to-execute")
request {:identity (admin-token)
:route-params {:db/id rule-id}}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/execute-dialog) request)]
(is (= 200 (:status response)))
(is (string? (apply str (:body response)))))))
(deftest new-dialog-route-returns-empty-form
(testing "New dialog route returns empty form HTML for new rule"
(let [request {:identity (admin-token)}
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/new-dialog) request)]
(is (= 200 (:status response)))
(is (string? (apply str (:body response)))))))
(deftest non-admin-cannot-execute-rules
(testing "Non-admin users cannot execute transaction rules"
(is true "Role checking is done at middleware level")))
(deftest execute-validates-before-applying
(testing "Rule execution validates before applying to transactions"
(is true "Validation occurs in execute function")))