test: strengthen assertions and add AC6 save round-trip test

This commit is contained in:
2026-05-27 23:25:47 -07:00
parent c9a587a8c5
commit ebd91f1911

View File

@@ -2,6 +2,7 @@
(:require
[auto-ap.datomic :refer [conn]]
[auto-ap.integration.util :refer [wrap-setup]]
[auto-ap.solr]
[auto-ap.ssr.components.multi-modal :as mm]
[auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.transaction.edit :refer [clientize-vendor
@@ -13,6 +14,10 @@
[datomic.api :as dc]
[hiccup.core :as hiccup]))
;; Private save-handler accessible via var reference
(def ^:private save-handler
#'auto-ap.ssr.transaction.edit/save-handler)
(use-fixtures :each wrap-setup)
;;; ---------------------------------------------------------------------------
@@ -40,8 +45,8 @@
(testing "AC2: exactly one account → simple mode"
(is (= :simple (manual-mode-initial {:db/id 123
:transaction/accounts [{:transaction-account/account 456
:transaction-account/location "Shared"
:transaction-account/amount 100.0}]}))))
:transaction-account/location "Shared"
:transaction-account/amount 100.0}]}))))
(testing "AC3: two or more accounts → advanced mode"
(is (= :advanced (manual-mode-initial {:db/id 123
@@ -92,7 +97,13 @@
;; Response should contain the manual-coding-section div
(is (string? body))
(is (re-find #"manual-coding-section" body)
"Response should contain the manual-coding-section element")))
"Response should contain the manual-coding-section element")
;; The vendor's default account ID should appear in the rendered HTML
(is (re-find (re-pattern (str account-id)) body)
"Response should contain the vendor's default account ID")
;; The account's name should appear in the rendered HTML
(is (re-find #"Test Account" body)
"Response should contain the vendor's default account name")))
(testing "AC5: selecting vendor when account already set does NOT overwrite existing account"
(let [result @(dc/transact conn [{:db/id "vendor-id"
@@ -119,9 +130,9 @@
client-id (tempid->id result "client-id")
;; existing-accounts already set means vendor should NOT overwrite
existing-accounts [{:db/id "row-id"
:transaction-account/account other-account-id
:transaction-account/location "DT"
:transaction-account/amount 100.0}]
:transaction-account/account other-account-id
:transaction-account/location "DT"
:transaction-account/amount 100.0}]
request {:multi-form-state (mm/->MultiStepFormState
{:db/id tx-id
:transaction/client client-id
@@ -139,12 +150,72 @@
(is (string? body))
(is (re-find #"manual-coding-section" body)
"Response body should contain the manual-coding-section element")
;; The key behavior: the handler only populates accounts when empty
;; Since existing-accounts were provided, vendor's default should NOT appear
;; We verify this by checking that the other-account-id is still referenced
;; (the handler logic: default-account only filled when existing-accounts is empty)
(is (not (nil? other-account-id))
"Other account ID should still be valid (not overwritten)"))))
;; The original account ID must still appear in the rendered HTML
(is (re-find (re-pattern (str other-account-id)) body)
"Response should contain the original (pre-existing) account ID")
;; The vendor's default account ID must NOT appear — it was not used
(is (not (re-find (re-pattern (str (tempid->id result "account-id"))) body))
"Response should NOT contain the vendor's default account ID when existing account is set"))))
;;; ---------------------------------------------------------------------------
;;; AC 6: save round-trip — manual mode saves vendor + account to DB
;;; ---------------------------------------------------------------------------
(deftest save-manual-round-trip-test
(testing "AC6: submitting simple-mode form saves vendor and single account/location to DB"
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Save Vendor"}
{:db/id "account-id"
:account/name "Save Account"
:account/type :account-type/expense}
{:db/id "client-id"
:client/code "SAVECL"
:client/locations ["DT"]}
{:db/id "transaction-id"
:transaction/amount 100.0
:transaction/date #inst "2023-01-01"
:transaction/id (str (java.util.UUID/randomUUID))
:transaction/client "client-id"}])
tx-id (tempid->id result "transaction-id")
vendor-id (tempid->id result "vendor-id")
account-id (tempid->id result "account-id")
client-id (tempid->id result "client-id")
new-row-id (str (java.util.UUID/randomUUID))
snapshot {:db/id tx-id
:transaction/client client-id
:action :manual
:transaction/vendor vendor-id
:transaction/amount 100.0
:transaction/accounts [{:db/id new-row-id
:transaction-account/account account-id
:transaction-account/location "Shared"
:transaction-account/amount 100.0}]}
request {:multi-form-state (mm/->MultiStepFormState snapshot [] snapshot)
:entity {:db/id tx-id
:transaction/client {:db/id client-id}
:transaction/amount 100.0}
:identity {:user/role "admin"}}]
(with-redefs [auto-ap.solr/impl (auto-ap.solr/->InMemSolrClient (atom {}))]
(save-handler request))
;; Verify the transaction was saved to DB with vendor and accounts
(let [saved (dc/pull (dc/db conn)
'[:db/id
{:transaction/vendor [:db/id]}
{:transaction/accounts [{:transaction-account/account [:db/id]}
:transaction-account/location
:transaction-account/amount]}]
tx-id)]
(is (= vendor-id (-> saved :transaction/vendor :db/id))
"Vendor should be saved on the transaction")
(is (= 1 (count (:transaction/accounts saved)))
"Exactly one account row should be saved")
(is (= account-id (-> saved :transaction/accounts first :transaction-account/account :db/id))
"The correct account should be saved")
;; "Shared" is spread to client-specific locations by maybe-spread-locations
(is (= "DT" (-> saved :transaction/accounts first :transaction-account/location))
"The location should be saved (Shared spreads to client locations)")
(is (= 100.0 (-> saved :transaction/accounts first :transaction-account/amount))
"The amount should be saved")))))
;;; ---------------------------------------------------------------------------
;;; AC 7-9: edit-wizard-toggle-mode-handler — mode toggling
@@ -187,7 +258,16 @@
"Response body should contain the coding section element")
;; Advanced mode has Switch to simple mode link (when <=1 row)
(is (re-find #"Switch to simple mode" body)
"After toggling to advanced mode (from simple with 1 row), 'Switch to simple mode' should appear")))
"After toggling to advanced mode (from simple with 1 row), 'Switch to simple mode' should appear")
;; The account-grid-body section should be present in the advanced mode HTML
(is (re-find #"account-grid-body" body)
"Advanced mode response should contain the account-grid-body element")
;; The account ID from the simple-mode row should appear in the advanced table HTML
(is (re-find (re-pattern (str account-id)) body)
"Advanced mode response should contain the account ID from the simple-mode row")
;; The account name should appear in the advanced table HTML
(is (re-find #"Toggle Account" body)
"Advanced mode response should contain the account name from the simple-mode row")))
(testing "AC8: advanced → simple (1 row) re-renders in simple mode"
(let [result @(dc/transact conn [{:db/id "client-id"
@@ -347,7 +427,7 @@
:vendor/name "Clientized Vendor"
:vendor/default-account "global-account-id"
:vendor/account-overrides [{:vendor-account-override/client "client-id"
:vendor-account-override/account "client-specific-account-id"}]}])
:vendor-account-override/account "client-specific-account-id"}]}])
vendor-id (tempid->id result "vendor-id")
client-id (tempid->id result "client-id")
client-specific-account-id (tempid->id result "client-specific-account-id")