From ebd91f1911ae2c7f487d9b9e02921a5a62698f4a Mon Sep 17 00:00:00 2001 From: Bryce Date: Wed, 27 May 2026 23:25:47 -0700 Subject: [PATCH] test: strengthen assertions and add AC6 save round-trip test --- .../edit_simple_advanced_mode_test.clj | 108 +++++++++++++++--- 1 file changed, 94 insertions(+), 14 deletions(-) diff --git a/test/clj/auto_ap/ssr/transaction/edit_simple_advanced_mode_test.clj b/test/clj/auto_ap/ssr/transaction/edit_simple_advanced_mode_test.clj index 13741f46..fd5b9e7a 100644 --- a/test/clj/auto_ap/ssr/transaction/edit_simple_advanced_mode_test.clj +++ b/test/clj/auto_ap/ssr/transaction/edit_simple_advanced_mode_test.clj @@ -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")