Cleanup of simple/advanced mode

This commit is contained in:
2026-05-31 08:30:11 -07:00
parent e156d8bfd8
commit 38ae6f460f
2 changed files with 350 additions and 14 deletions

View File

@@ -106,7 +106,7 @@
(is (re-find #"Test Account" body)
"Response should contain the vendor's default account name")))
(testing "AC5: vendor selection in simple mode does NOT overwrite already-set account"
(testing "AC5: vendor selection in simple mode DOES overwrite already-set account"
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Test Vendor"}
{:db/id "account-id"
@@ -127,9 +127,10 @@
: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")
other-account-id (tempid->id result "other-account-id")
client-id (tempid->id result "client-id")
;; existing-accounts already set means vendor should NOT overwrite
;; existing-accounts already set — but simple mode should still overwrite
existing-accounts [{:db/id "row-id"
:transaction-account/account other-account-id
:transaction-account/location "DT"
@@ -150,12 +151,12 @@
;; The handler returns an html-response; verify the body is HTML
(is (re-find #"manual-coding-section" body)
"Response body should contain the manual-coding-section element")
;; 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"))))
;; The vendor's default account SHOULD appear (overwriting previous)
(is (re-find (re-pattern (str account-id)) body)
"Vendor change in simple mode should overwrite with vendor's default account")
;; The previous account should NOT appear
(is (not (re-find (re-pattern (str other-account-id)) body))
"Previous account should be replaced by vendor default"))))
;;; ---------------------------------------------------------------------------
;;; AC6: save round-trip — manual mode saves vendor + account to DB
@@ -996,3 +997,323 @@
"Vendor name should appear in the HTMX response")
(is (re-find (re-pattern (str vendor-id)) (:body response))
"Vendor ID should be preserved in the response HTML")))))
;;; ---------------------------------------------------------------------------
;;; Bug: vendor change does not populate account
;;; ---------------------------------------------------------------------------
(deftest vendor-change-simple-mode-overwrites-test
(testing "BUG: vendor change in simple mode should overwrite existing account"
;; When a vendor is changed in simple mode, it should always populate
;; the vendor's default account, even if an account was already set.
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Vendor With Default"}
{:db/id "vendor-account-id"
:account/name "Vendor Default Account"
:account/type :account-type/expense}
{:db/id "vendor-id"
:vendor/default-account "vendor-account-id"}
{:db/id "existing-account-id"
:account/name "Previously Selected Account"
:account/type :account-type/expense}
{:db/id "client-id"
:client/code "VENDORCL"
: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")
vendor-account-id (tempid->id result "vendor-account-id")
existing-account-id (tempid->id result "existing-account-id")
client-id (tempid->id result "client-id")
;; Simulate form state with an already-selected account (as the form submits)
existing-accounts [{:db/id "row-1"
:transaction-account/account existing-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
:transaction/accounts existing-accounts}
[]
{:mode "simple"
:transaction/vendor vendor-id
:transaction/accounts existing-accounts})
:entity {:db/id tx-id
:transaction/client {:db/id client-id}
:transaction/amount 100.0}}
response (edit-vendor-changed-handler request)
body (:body response)]
;; The vendor's default account SHOULD appear (overwriting the previous)
(is (re-find (re-pattern (str vendor-account-id)) body)
"BUG: Vendor change in simple mode should overwrite with vendor's default account")
;; The previously selected account should NOT appear
(is (not (re-find (re-pattern (str existing-account-id)) body))
"Previously selected account should be replaced by vendor default")
(is (re-find #"Vendor Default Account" body)
"Vendor default account name should appear"))))
(deftest vendor-change-advanced-mode-empty-row-test
(testing "BUG: vendor change in advanced mode should populate empty row"
;; In advanced mode with 1 empty row, changing vendor should populate it
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Vendor With Default"}
{:db/id "vendor-account-id"
:account/name "Vendor Default Account"
:account/type :account-type/expense}
{:db/id "vendor-id"
:vendor/default-account "vendor-account-id"}
{:db/id "client-id"
:client/code "ADVEMPTYCL"
: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")
vendor-account-id (tempid->id result "vendor-account-id")
client-id (tempid->id result "client-id")
;; Simulate advanced mode with 1 empty row (account=nil, as form submits)
empty-row [{:db/id "row-1"
:transaction-account/account nil
:transaction-account/location "Shared"
:transaction-account/amount 100.0}]
request {:multi-form-state (mm/->MultiStepFormState
{:db/id tx-id
:transaction/client client-id
:transaction/accounts empty-row}
[]
{:mode "advanced"
:transaction/vendor vendor-id
:transaction/accounts empty-row})
:entity {:db/id tx-id
:transaction/client {:db/id client-id}
:transaction/amount 100.0}}
response (edit-vendor-changed-handler request)
body (:body response)]
;; The vendor's default account SHOULD appear in the row
(is (re-find (re-pattern (str vendor-account-id)) body)
"BUG: Vendor change in advanced mode with empty row should populate it")
(is (re-find #"Vendor Default Account" body)
"Vendor default account name should appear in the row"))))
(deftest vendor-change-advanced-mode-filled-row-test
(testing "AC15b: vendor change in advanced mode with filled row should NOT overwrite"
;; In advanced mode with 1 row that already has an account selected,
;; changing vendor should NOT overwrite it
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Vendor With Default"}
{:db/id "vendor-account-id"
:account/name "Vendor Default Account"
:account/type :account-type/expense}
{:db/id "vendor-id"
:vendor/default-account "vendor-account-id"}
{:db/id "existing-account-id"
:account/name "Manually Selected Account"
:account/type :account-type/expense}
{:db/id "client-id"
:client/code "ADVFILLEDCL"
: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")
vendor-account-id (tempid->id result "vendor-account-id")
existing-account-id (tempid->id result "existing-account-id")
client-id (tempid->id result "client-id")
;; Advanced mode with 1 row that already has an account
filled-row [{:db/id "row-1"
:transaction-account/account existing-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
:transaction/accounts filled-row}
[]
{:mode "advanced"
:transaction/vendor vendor-id
:transaction/accounts filled-row})
:entity {:db/id tx-id
:transaction/client {:db/id client-id}
:transaction/amount 100.0}}
response (edit-vendor-changed-handler request)
body (:body response)]
;; The existing account should still be there
(is (re-find (re-pattern (str existing-account-id)) body)
"Existing account should remain when vendor changes in advanced mode with filled row")
;; The vendor's default account should NOT appear
(is (not (re-find (re-pattern (str vendor-account-id)) body))
"Vendor default should NOT overwrite filled row in advanced mode"))))
(deftest vendor-change-advanced-mode-two-rows-test
(testing "AC15c: vendor change in advanced mode with 2+ rows should NOT modify any"
;; In advanced mode with 2 or more rows, vendor change should not touch any row
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Vendor With Default"}
{:db/id "vendor-account-id"
:account/name "Vendor Default Account"
:account/type :account-type/expense}
{:db/id "vendor-id"
:vendor/default-account "vendor-account-id"}
{:db/id "account-1"
:account/name "Account One"
:account/type :account-type/expense}
{:db/id "account-2"
:account/name "Account Two"
:account/type :account-type/expense}
{:db/id "client-id"
:client/code "ADVTWOROWCL"
: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")
vendor-account-id (tempid->id result "vendor-account-id")
account-1 (tempid->id result "account-1")
account-2 (tempid->id result "account-2")
client-id (tempid->id result "client-id")
;; Advanced mode with 2 rows
two-rows [{:db/id "row-1"
:transaction-account/account account-1
:transaction-account/location "DT"
:transaction-account/amount 50.0}
{:db/id "row-2"
:transaction-account/account account-2
:transaction-account/location "DT"
:transaction-account/amount 50.0}]
request {:multi-form-state (mm/->MultiStepFormState
{:db/id tx-id
:transaction/client client-id
:transaction/accounts two-rows}
[]
{:mode "advanced"
:transaction/vendor vendor-id
:transaction/accounts two-rows})
:entity {:db/id tx-id
:transaction/client {:db/id client-id}
:transaction/amount 100.0}}
response (edit-vendor-changed-handler request)
body (:body response)]
;; Both existing accounts should remain
(is (re-find (re-pattern (str account-1)) body)
"First row account should remain")
(is (re-find (re-pattern (str account-2)) body)
"Second row account should remain")
;; Vendor default should NOT appear
(is (not (re-find (re-pattern (str vendor-account-id)) body))
"Vendor default should NOT modify rows when 2+ exist"))))
(deftest vendor-change-client-specific-override-test
(testing "BUG: vendor change should use client-specific account override if present"
;; When a vendor has a client-specific account override, changing vendor
;; should populate the client-specific account, not the global default.
(let [result @(dc/transact conn [{:db/id "global-account-id"
:account/name "Global Default"
:account/type :account-type/expense}
{:db/id "client-specific-account-id"
:account/name "Client Specific Account"
:account/type :account-type/expense}
{:db/id "client-id"
:client/code "CLIOVERRIDE"
:client/locations ["DT"]}
{:db/id "vendor-id"
: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-id (tempid->id result "vendor-id")
client-id (tempid->id result "client-id")
global-account-id (tempid->id result "global-account-id")
client-specific-account-id (tempid->id result "client-specific-account-id")
;; Simple mode with empty account row
empty-row [{:db/id "row-1"
:transaction-account/account nil
:transaction-account/location "Shared"
:transaction-account/amount 100.0}]
request {:multi-form-state (mm/->MultiStepFormState
{:db/id 999999
:transaction/client client-id
:transaction/accounts empty-row}
[]
{:mode "simple"
:transaction/vendor vendor-id
:transaction/accounts empty-row})
:entity {:db/id 999999
:transaction/client {:db/id client-id}
:transaction/amount 100.0}}
response (edit-vendor-changed-handler request)
body (:body response)]
;; The client-specific account should appear, not the global default
(is (re-find (re-pattern (str client-specific-account-id)) body)
"BUG: Vendor change should populate client-specific account override")
(is (re-find #"Client Specific Account" body)
"Client-specific account name should appear")
;; The global default should NOT appear
(is (not (re-find (re-pattern (str global-account-id)) body))
"Global vendor default should NOT appear when client override exists"))))
;;; Update AC5: simple mode SHOULD overwrite existing accounts
(deftest vendor-change-simple-mode-overwrites-ac5-test
(testing "AC5 UPDATED: vendor selection in simple mode DOES overwrite already-set account"
(let [result @(dc/transact conn [{:db/id "vendor-id"
:vendor/name "Test Vendor"}
{:db/id "account-id"
:account/name "Test Account"
:account/type :account-type/expense}
{:db/id "vendor-id"
:vendor/default-account "account-id"}
{:db/id "other-account-id"
:account/name "Other Account"
:account/type :account-type/expense}
{:db/id "client-id"
:client/code "TESTCL2"
: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")
other-account-id (tempid->id result "other-account-id")
client-id (tempid->id result "client-id")
;; existing-accounts already set — but simple mode should still overwrite
existing-accounts [{:db/id "row-id"
: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
:transaction/accounts existing-accounts}
[]
{:mode "simple"
:transaction/vendor vendor-id
:transaction/accounts existing-accounts})
:entity {:db/id tx-id
:transaction/client {:db/id client-id}
:transaction/amount 100.0}}
response (edit-vendor-changed-handler request)
body (:body response)]
;; The handler returns an html-response; verify the body is HTML
(is (re-find #"manual-coding-section" body)
"Response body should contain the manual-coding-section element")
;; The vendor's default account SHOULD appear (overwriting previous)
(is (re-find (re-pattern (str account-id)) body)
"BUG: Vendor change in simple mode should overwrite with vendor's default account")
;; The previous account should NOT appear
(is (not (re-find (re-pattern (str other-account-id)) body))
"Previous account should be replaced by vendor default"))))