(ns auto-ap.ssr.admin.accounts-test (:require [datomic.api :as dc :refer [q]] [auto-ap.datomic :refer [conn]] [auto-ap.integration.util :refer [wrap-setup test-account admin-token user-token setup-test-data test-client]] [auto-ap.ssr.admin.accounts :as sut] [clojure.test :refer [deftest is testing use-fixtures]] [malli.core :as mc])) (use-fixtures :each wrap-setup) ;; ============================================================================= ;; Schemas ;; ============================================================================= (deftest query-schema-test (testing "Should validate correct query params" (is (mc/validate sut/query-schema {:date-range {:start-date #inst "2021-01-01" :end-date #inst "2021-12-31"} :type "asset" :name "Cash" :code 11101 :page 1 :per-page 50 :sort "name" :sort-dir "asc"}))) (testing "Should allow optional fields" (is (mc/validate sut/query-schema {:page 1 :per-page 50}))) (testing "Should reject invalid type" (is (not (mc/validate sut/query-schema {:type "invalid-type"}))))) (deftest form-schema-test (testing "Should validate valid account form" (is (mc/validate sut/form-schema {:db/id "new" :account/numeric-code 11101 :account/name "Test Account" :account/type :account-type/asset :account/location "DT" :account/invoice-allowance :allowance/allowed :account/vendor-allowance :allowance/allowed :account/applicability :account-applicability/default}))) (testing "Should allow updating existing account" (is (mc/validate sut/form-schema {:db/id 123 :account/numeric-code 11102 :account/name "Updated Account" :account/type :account-type/liability}))) (testing "Should require name" (is (not (mc/validate sut/form-schema {:account/numeric-code 11101})))) (testing "Should reject invalid type" (is (not (mc/validate sut/form-schema {:account/numeric-code 11101 :account/name "Test" :account/type :invalid-type})))) (testing "Should accept client overrides" (is (mc/validate sut/form-schema {:account/numeric-code 11101 :account/name "Test" :account/client-overrides [{:account-client-override/client 1 :account-client-override/name "Override"}]})))) ;; ============================================================================= ;; Fetch IDs ;; ============================================================================= (deftest fetch-ids-by-type-test (testing "Should filter by account type" (let [_ (setup-test-data [(test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Asset Account" :account/type :account-type/asset) (test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Liability Account" :account/type :account-type/liability)])] (let [results (dc/q '[:find ?e ?n ?nc :in $ :where [?e :account/name ?n] [?e :account/numeric-code ?nc]] (dc/db conn))] (is (= 2 (count results))))))) ;; ============================================================================= ;; Fetch Page ;; ============================================================================= (deftest fetch-page-test (testing "Should return empty results when no accounts exist" (let [db (dc/db conn) [_ count] (sut/fetch-page {:query-params {}})] (is (= 0 count)) (is (empty? _))))) (deftest fetch-page-with-name-filter-test (testing "Should filter by name (case-insensitive)" (let [_ (setup-test-data [(test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Asset Account") (test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Liability Account")])] (let [[results count] (sut/fetch-page {:query-params {:name "asset"}})] (is (= 1 count)) (is (= 1 (count results))) (is (= "Asset Account" (:account/name (first results)))))))) (deftest fetch-page-with-code-filter-test (testing "Should filter by numeric code" (let [_ (setup-test-data [(test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Account 1") (test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Account 2")])] (let [[results count] (sut/fetch-page {:query-params {:code 11102}})] (is (= 1 count)) (is (= 1 (count results))) (is (= "Account 2" (:account/name (first results)))))))) (deftest fetch-page-with-type-filter-test (testing "Should filter by account type" (let [_ (setup-test-data [(test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Asset Account" :account/type :account-type/asset) (test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Liability Account" :account/type :account-type/liability)])] (let [[results count] (sut/fetch-page {:query-params {:type "liability"}})] (is (= 1 count)) (is (= 1 (count results))) (is (= "Liability Account" (:account/name (first results)))))))) (deftest fetch-page-pagination-test (testing "Should apply pagination" (let [_ (setup-test-data (for [i (range 15)] (test-account :db/id (str "acc-" i) :account/numeric-code (+ 11100 i) :account/name (str "Account " i))))] (let [[results count] (sut/fetch-page {:query-params {:page 1 :per-page 10}})] (is (= 10 count)) (is (= 10 (count results))) (is (= "Account 0" (:account/name (first results)))) (is (= "Account 9" (:account/name (last results)))))))) (deftest fetch-page-sort-test (testing "Should sort by name ascending" (let [_ (setup-test-data [(test-account :db/id "acc-3" :account/numeric-code 11103 :account/name "Charlie") (test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Alpha") (test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Beta")])] (let [[results count] (sut/fetch-page {:query-params {:sort "name" :sort-dir "asc"}})] (is (= 3 count)) (is (= "Alpha" (:account/name (first results)))) (is (= "Charlie" (:account/name (last results))))))) (testing "Should sort by code ascending" (let [_ (setup-test-data [(test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Beta") (test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Alpha")])] (let [[results count] (sut/fetch-page {:query-params {:sort "code" :sort-dir "asc"}})] (is (= 2 count)) (is (= 11101 (:account/numeric-code (first results)))) (is (= 11102 (:account/numeric-code (last results)))))))) (deftest fetch-page-combine-filters-test (testing "Should combine name and type filters" (let [_ (setup-test-data [(test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Cash Asset" :account/type :account-type/asset) (test-account :db/id "acc-2" :account/numeric-code 11102 :account/name "Cash Liability" :account/type :account-type/liability) (test-account :db/id "acc-3" :account/numeric-code 11103 :account/name "Bank Asset" :account/type :account-type/asset)])] (let [[results count] (sut/fetch-page {:query-params {:name "cash" :type "asset"}})] (is (= 1 count)) (is (= 1 (count results))) (is (= "Cash Asset" (:account/name (first results)))))))) (deftest fetch-page-mixed-case-name-filter-test (testing "Should handle case-insensitive name filtering" (let [_ (setup-test-data [(test-account :db/id "acc-1" :account/numeric-code 11101 :account/name "Cash Account")])] (let [[results count] (sut/fetch-page {:query-params {:name "CASH"}})] (is (= 1 count)) (is (= 1 (count results)))))))