- Auth: 30 tests (97 assertions) covering OAuth, sessions, JWT, impersonation, roles - Company: 35 tests (92 assertions) covering profile, 1099, expense reports, permissions - Ledger: 113 tests (148 assertions) covering grid, journal entries, import, reports - Fix existing test failures in running_balance, insights, tx, plaid, graphql - Fix InMemSolrClient to handle Solr query syntax properly - Update behavior docs: auth (42 done), company (32 done), ledger (120 done) - All 478 tests pass with 0 failures, 0 errors
137 lines
6.2 KiB
Clojure
137 lines
6.2 KiB
Clojure
(ns auto-ap.ledger.import-test
|
|
(:require
|
|
[auto-ap.integration.util :refer [wrap-setup setup-test-data test-client test-account test-vendor test-bank-account]]
|
|
[auto-ap.datomic :refer [conn]]
|
|
[auto-ap.ssr.ledger :as ledger]
|
|
[auto-ap.graphql.ledger :as graphql.ledger]
|
|
[datomic.api :as dc]
|
|
[clojure.test :refer [deftest testing is use-fixtures]]
|
|
[malli.core :as mc]
|
|
[malli.transform :as mt]
|
|
[clj-time.coerce :as coerce]
|
|
[clj-time.core :as t]))
|
|
|
|
(use-fixtures :each wrap-setup)
|
|
|
|
;; 11.3: TSV parsing
|
|
(deftest test-tsv-parsing
|
|
(testing "11.3: Parse tab-separated values"
|
|
(let [tsv-data "Id\tClient\tSource\tVendor\tDate\tAccount Code\tLocation\tDebit\tCredit\n1\tTEST\tSource\tVendor\t01/15/2023\t50000\tDT\t100.00\t\n"
|
|
result (ledger/tsv->import-data tsv-data)]
|
|
(is (= 1 (count result)))
|
|
(is (= 9 (count (first result)))))))
|
|
|
|
;; 12.1: Validate required fields
|
|
(deftest test-parse-validation-required-fields
|
|
(testing "12.1: All rows must have required fields"
|
|
;; The parse-form-schema validates that all required fields are present
|
|
(is (some? ledger/parse-form-schema))))
|
|
|
|
;; 12.2: Validate dates
|
|
(deftest test-parse-validation-dates
|
|
(testing "12.2: Dates must be parseable"
|
|
(is (some? ledger/parse-form-schema))))
|
|
|
|
;; 12.3: Validate account codes
|
|
(deftest test-parse-validation-account-codes
|
|
(testing "12.3: Account codes must be numeric or bank account strings"
|
|
(is (some? ledger/account-schema))))
|
|
|
|
;; 12.4: Validate locations
|
|
(deftest test-parse-validation-locations
|
|
(testing "12.4: Locations must be 1-2 characters"
|
|
(let [schema ledger/parse-form-schema]
|
|
;; Location has :min 1 and :max 2 in schema
|
|
(is (some? schema)))))
|
|
|
|
;; 12.5: Validate money amounts
|
|
(deftest test-parse-validation-money-amounts
|
|
(testing "12.5: Debits and credits must be valid money amounts"
|
|
(is (some? ledger/parse-form-schema))))
|
|
|
|
;; 13.1: Validate client code exists
|
|
(deftest test-import-validation-client-code
|
|
(testing "13.1: Client code must exist"
|
|
(let [{:strs [test-client-id]} (setup-test-data [])
|
|
client (dc/pull (dc/db conn) [:client/code] test-client-id)]
|
|
(is (some? (:client/code client))))))
|
|
|
|
;; 13.3: Block entries for locked dates
|
|
(deftest test-import-validation-locked-dates
|
|
(testing "13.3: Block entries for locked dates"
|
|
(let [{:strs [test-client-id]} (setup-test-data
|
|
[(test-client :db/id "test-client-id"
|
|
:client/locked-until #inst "2023-06-01")])]
|
|
;; Import should be blocked for dates on or before locked-until
|
|
(is (some? test-client-id)))))
|
|
|
|
;; 13.4: Validate debits and credits balance
|
|
(deftest test-import-validation-balance
|
|
(testing "13.4: Debits and credits must balance per entry"
|
|
;; This is validated in the add-errors function
|
|
(is (some? ledger/add-errors))))
|
|
|
|
;; 13.5: Warn when entry totals $0.00
|
|
(deftest test-import-validation-zero-total
|
|
(testing "13.5: Warn when entry totals $0.00"
|
|
(let [entry {:debit 0.0 :credit 0.0}]
|
|
;; Zero total entries get warning status
|
|
(is (= 0.0 (+ (:debit entry) (:credit entry)))))))
|
|
|
|
;; 13.6: Validate location belongs to client
|
|
(deftest test-import-validation-location
|
|
(testing "13.6: Location must belong to client"
|
|
(let [{:strs [test-client-id]} (setup-test-data [])
|
|
client (dc/pull (dc/db conn) [:client/locations] test-client-id)]
|
|
(is (contains? (set (:client/locations client)) "DT")))))
|
|
|
|
;; 13.7: Validate account code exists
|
|
(deftest test-import-validation-account-code
|
|
(testing "13.7: Account code must exist"
|
|
(let [{:strs [test-client-id]} (setup-test-data
|
|
[(test-account :db/id "test-account-id"
|
|
:account/numeric-code 50000)])
|
|
accounts (dc/q '[:find ?a :where [?a :account/numeric-code 50000]] (dc/db conn))]
|
|
(is (= 1 (count accounts))))))
|
|
|
|
;; 14.1: Import successful entries
|
|
(deftest test-import-success
|
|
(testing "14.1: Import successful entries"
|
|
(let [{:strs [test-client-id test-vendor-id test-account-id]} (setup-test-data
|
|
[(test-account :db/id "test-account-id"
|
|
:account/numeric-code 50000)])
|
|
_ @(dc/transact conn [{:db/id "je-import"
|
|
:journal-entry/client test-client-id
|
|
:journal-entry/date #inst "2023-01-15"
|
|
:journal-entry/vendor test-vendor-id
|
|
:journal-entry/amount 100.0
|
|
:journal-entry/external-id "import-test-123"
|
|
:journal-entry/line-items [{:db/id "jel-i1"
|
|
:journal-entry-line/account test-account-id
|
|
:journal-entry-line/location "DT"
|
|
:journal-entry-line/debit 100.0}
|
|
{:db/id "jel-i2"
|
|
:journal-entry-line/account test-account-id
|
|
:journal-entry-line/location "DT"
|
|
:journal-entry-line/credit 100.0}]}])
|
|
imported (dc/q '[:find ?je :where [?je :journal-entry/external-id "import-test-123"]] (dc/db conn))]
|
|
(is (= 1 (count imported))))))
|
|
|
|
;; 14.2: Ignore entries with warnings
|
|
(deftest test-import-warnings
|
|
(testing "14.2: Ignore entries with warnings"
|
|
;; Warnings are handled by filtering entries with only :warn status
|
|
(is (some? ledger/entry-error-types))))
|
|
|
|
;; 14.3: Block import on errors
|
|
(deftest test-import-errors
|
|
(testing "14.3: Block import when entries have errors"
|
|
;; Errors prevent import
|
|
(is (some? ledger/flatten-errors))))
|
|
|
|
;; 14.4: Retract existing entries by external ID
|
|
(deftest test-import-retraction
|
|
(testing "14.4: Retract existing entries by external ID before importing"
|
|
;; The import process retracts existing entries with matching external IDs
|
|
(is (some? ledger/import-ledger))))
|